Advertisement
GabeLinux

Web - 6 - 5

Feb 13th, 2017
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // declare all our variables
  2. const WIDTH = 720
  3. const HEIGHT = 480
  4. const GROUNDHEIGHT = HEIGHT - 40
  5. const GRAVITY = -1
  6.  
  7. const canvas = document.querySelector('#game')
  8. canvas.width = WIDTH
  9. canvas.height = HEIGHT
  10.  
  11. const ctx = canvas.getContext('2d')
  12.  
  13. const imgLoader = createImageLoader()
  14.  
  15. const playerAnimations = Object.assign({},
  16.   createAnimation('run', 'images/kenny/run', 6, 7),
  17.   createAnimation('idle', 'images/kenny/idle', 2, 25),
  18.   createAnimation('jump', 'images/kenny/jump', 1, 0, false),
  19.   createAnimation('fall', 'images/kenny/fall', 1, 0, false),
  20.   createAnimation('dead', 'images/kenny/hit', 1, 0, false)
  21. )
  22.  
  23. imgLoader.loadAll()
  24.   .then(() => { gameStart() })
  25.  
  26. let prevLoop
  27. let prevDraws = []
  28. let keysPressed = []
  29. let player
  30.  
  31. // create an image loader that will use promises to load all of the given images
  32. function createImageLoader() {
  33.   let l = {}
  34.   l.images = []
  35.  
  36.   l.loadImage = (src) => {
  37.     let img = new Image()
  38.     img.src = src
  39.  
  40.     let p = new Promise((resolve, reject) => {
  41.       img.addEventListener('load', () => { resolve(img) })
  42.       img.addEventListener('error', (err) => { reject(new Error('Image failed to load')) })
  43.     })
  44.  
  45.     l.images.push(p)
  46.  
  47.     return img
  48.   }
  49.  
  50.   l.loadAll = () => {
  51.     return Promise.all(l.images)
  52.       .then((images) => l.images = images)
  53.       .catch((error) => { console.error(error) })
  54.   }
  55.  
  56.   return l
  57. }
  58.  
  59. // make an animation object with our parameters and loaded animation frames
  60. function createAnimation(name, path, length, time, loop = true) {
  61.   let a = {}
  62.   a[name] = {}
  63.  
  64.   a[name].frames = new Array(length).fill(null).map((val, indx) => imgLoader.loadImage(`${path}/${indx}.png`))
  65.   a[name].frameTime = time
  66.   a[name].loop = loop
  67.  
  68.   return a
  69. }
  70.  
  71. // make a player object that will animate and jump
  72. function createPlayer(animations, x, scale = 1) {
  73.   let p = {}
  74.  
  75.   p.state = 'run'
  76.   p.prevState = p.state
  77.  
  78.   p.frame = 0
  79.   p.frameTicks = 0
  80.   p.animations = animations
  81.  
  82.   p.frameTime = p.animations[p.state].frameTime
  83.   p.image = p.animations[p.state]['frames'][p.frame]
  84.  
  85.   p.scale = scale
  86.   p.width = p.image.width * p.scale
  87.   p.height = p.image.height * p.scale
  88.   p.x = x
  89.   p.y = GROUNDHEIGHT - p.height
  90.  
  91.   p.vel = 0
  92.   p.forces = 0
  93.   p.mass = 200
  94.  
  95.   p.getRight = () => {
  96.     return p.x + p.width
  97.   }
  98.  
  99.   p.getBottom = () => {
  100.     return p.y + p.height
  101.   }
  102.  
  103.   p.updateImage = () => {
  104.     const bottom = p.getBottom()
  105.     p.image = p.animations[p.state]['frames'][p.frame]
  106.     p.width = p.image.width * p.scale
  107.     p.height = p.image.height * p.scale
  108.     p.y = bottom - p.height
  109.   }
  110.  
  111.   p.updateAnimation = (delta) => {
  112.     p.frameTicks += 0.06 * delta
  113.  
  114.     if ((p.animations[p.state].loop || p.frame < p.animations[p.state]['frames'].length - 1) && p.frameTicks >= p.frameTime) {
  115.       p.frame++
  116.       p.frameTicks = 0
  117.  
  118.       if (p.frame === p.animations[p.state]['frames'].length)
  119.         p.frame = 0
  120.  
  121.       p.updateImage()
  122.     }
  123.   }
  124.  
  125.   p.setState = (state) => {
  126.     if (state === p.state) return
  127.  
  128.     p.frame = 0
  129.     p.frameTicks = 0
  130.     p.state = state
  131.     p.frameTime = p.animations[p.state].frameTime
  132.  
  133.     p.updateImage()
  134.   }
  135.  
  136.   p.addForce = (amount) => {
  137.     p.forces += amount
  138.   }
  139.  
  140.   p.jump = () => {
  141.     if (p.state === 'run' || p.state === 'idle') {
  142.       p.prevState = p.state
  143.       p.addForce(500)
  144.     }
  145.   }
  146.  
  147.   p.checkGround = (delta) => {
  148.     const groundCollisions = [{ y: GROUNDHEIGHT }].filter((val) =>
  149.       p.getBottom() - p.vel * delta >= val.y &&
  150.       p.y < val.y
  151.     )
  152.  
  153.     return groundCollisions
  154.   }
  155.  
  156.   p.simulatePhysics = (delta) => {
  157.     const onGroundTiles = p.checkGround(delta)
  158.  
  159.     if (!onGroundTiles.length || p.forces || p.vel) {
  160.       const dt = !p.vel ? 1 : delta
  161.       p.addForce(GRAVITY)
  162.  
  163.       const acceleration = p.forces / p.mass
  164.       p.y -= dt * (p.vel + dt * acceleration / 2)
  165.  
  166.       const nextAcceleration = GRAVITY / p.mass
  167.       p.vel += dt * (acceleration + nextAcceleration) / 2
  168.  
  169.       p.forces = 0
  170.     }
  171.  
  172.     if (onGroundTiles.length && p.getBottom() !== onGroundTiles[0].y) {
  173.       p.setState(p.prevState)
  174.       p.y = onGroundTiles[0].y - p.height
  175.       if (p.vel < 0)
  176.         p.vel = 0
  177.     }
  178.   }
  179.  
  180.   p.update = (delta) => {
  181.     p.simulatePhysics(delta)
  182.  
  183.     if (p.vel > 0)
  184.       p.setState('jump')
  185.  
  186.     if (p.vel < 0)
  187.       p.setState('fall')
  188.  
  189.     p.updateAnimation(delta)
  190.   }
  191.  
  192.   p.draw = () => {
  193.     ctx.drawImage(p.image, p.x, p.y, p.width, p.height)
  194.  
  195.     return [{
  196.       x: p.x,
  197.       y: p.y,
  198.       width: p.width,
  199.       height: p.height
  200.     }]
  201.   }
  202.  
  203.   return p
  204. }
  205.  
  206.  
  207. // when all images have loaded, create our needed objects and start drawing
  208. function gameStart() {
  209.   ctx.fillStyle = '#FFFFFF'
  210.   ctx.fillRect(0, 0, WIDTH, HEIGHT)
  211.  
  212.   player = createPlayer(playerAnimations, 100, 0.25)
  213.  
  214.   prevLoop = performance.now()
  215.   window.requestAnimationFrame(gameLoop)
  216.  
  217.   document.addEventListener('keydown', (e) => {
  218.     const key = e.key
  219.  
  220.     if (!keysPressed.includes(key))
  221.       keysPressed.push(key)
  222.   })
  223. }
  224.  
  225.  
  226. // update all our game objects
  227. function update(delta) {
  228.   if (keysPressed.includes(' '))
  229.     player.jump()
  230.  
  231.   keysPressed = []
  232.  
  233.   player.update(delta)
  234. }
  235.  
  236. // clear the areas that were drawn last frame and draw updated objects
  237. function draw() {
  238.   prevDraws.forEach((array) => {
  239.     array.forEach((val) => {
  240.       ctx.fillStyle = 'white'
  241.       ctx.fillRect(
  242.         Math.round(val.x),
  243.         Math.round(val.y),
  244.         Math.round(val.width),
  245.         Math.round(val.height)
  246.       )
  247.     })
  248.   })
  249.  
  250.   prevDraws = []
  251.  
  252.   prevDraws.push(player.draw())
  253. }
  254.  
  255. // sync our game loop to the window framerate, then update and draw each frame
  256. function gameLoop(time) {
  257.   const delta = time - prevLoop
  258.   prevLoop = time
  259.  
  260.   update(delta)
  261.   draw()
  262.  
  263.   window.requestAnimationFrame(gameLoop)
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement