Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // declare all our variables
- const WIDTH = 720
- const HEIGHT = 480
- const GROUNDHEIGHT = HEIGHT - 40
- const GRAVITY = -1
- const canvas = document.querySelector('#game')
- canvas.width = WIDTH
- canvas.height = HEIGHT
- const ctx = canvas.getContext('2d')
- const imgLoader = createImageLoader()
- const playerAnimations = Object.assign({},
- createAnimation('run', 'images/kenny/run', 6, 7),
- createAnimation('idle', 'images/kenny/idle', 2, 25),
- createAnimation('jump', 'images/kenny/jump', 1, 0, false),
- createAnimation('fall', 'images/kenny/fall', 1, 0, false),
- createAnimation('dead', 'images/kenny/hit', 1, 0, false)
- )
- imgLoader.loadAll()
- .then(() => { gameStart() })
- let prevLoop
- let prevDraws = []
- let keysPressed = []
- let player
- // create an image loader that will use promises to load all of the given images
- function createImageLoader() {
- let l = {}
- l.images = []
- l.loadImage = (src) => {
- let img = new Image()
- img.src = src
- let p = new Promise((resolve, reject) => {
- img.addEventListener('load', () => { resolve(img) })
- img.addEventListener('error', (err) => { reject(new Error('Image failed to load')) })
- })
- l.images.push(p)
- return img
- }
- l.loadAll = () => {
- return Promise.all(l.images)
- .then((images) => l.images = images)
- .catch((error) => { console.error(error) })
- }
- return l
- }
- // make an animation object with our parameters and loaded animation frames
- function createAnimation(name, path, length, time, loop = true) {
- let a = {}
- a[name] = {}
- a[name].frames = new Array(length).fill(null).map((val, indx) => imgLoader.loadImage(`${path}/${indx}.png`))
- a[name].frameTime = time
- a[name].loop = loop
- return a
- }
- // make a player object that will animate and jump
- function createPlayer(animations, x, scale = 1) {
- let p = {}
- p.state = 'run'
- p.prevState = p.state
- p.frame = 0
- p.frameTicks = 0
- p.animations = animations
- p.frameTime = p.animations[p.state].frameTime
- p.image = p.animations[p.state]['frames'][p.frame]
- p.scale = scale
- p.width = p.image.width * p.scale
- p.height = p.image.height * p.scale
- p.x = x
- p.y = GROUNDHEIGHT - p.height
- p.vel = 0
- p.forces = 0
- p.mass = 200
- p.getRight = () => {
- return p.x + p.width
- }
- p.getBottom = () => {
- return p.y + p.height
- }
- p.updateImage = () => {
- const bottom = p.getBottom()
- p.image = p.animations[p.state]['frames'][p.frame]
- p.width = p.image.width * p.scale
- p.height = p.image.height * p.scale
- p.y = bottom - p.height
- }
- p.updateAnimation = (delta) => {
- p.frameTicks += 0.06 * delta
- if ((p.animations[p.state].loop || p.frame < p.animations[p.state]['frames'].length - 1) && p.frameTicks >= p.frameTime) {
- p.frame++
- p.frameTicks = 0
- if (p.frame === p.animations[p.state]['frames'].length)
- p.frame = 0
- p.updateImage()
- }
- }
- p.setState = (state) => {
- if (state === p.state) return
- p.frame = 0
- p.frameTicks = 0
- p.state = state
- p.frameTime = p.animations[p.state].frameTime
- p.updateImage()
- }
- p.addForce = (amount) => {
- p.forces += amount
- }
- p.jump = () => {
- if (p.state === 'run' || p.state === 'idle') {
- p.prevState = p.state
- p.addForce(500)
- }
- }
- p.checkGround = (delta) => {
- const groundCollisions = [{ y: GROUNDHEIGHT }].filter((val) =>
- p.getBottom() - p.vel * delta >= val.y &&
- p.y < val.y
- )
- return groundCollisions
- }
- p.simulatePhysics = (delta) => {
- const onGroundTiles = p.checkGround(delta)
- if (!onGroundTiles.length || p.forces || p.vel) {
- const dt = !p.vel ? 1 : delta
- p.addForce(GRAVITY)
- const acceleration = p.forces / p.mass
- p.y -= dt * (p.vel + dt * acceleration / 2)
- const nextAcceleration = GRAVITY / p.mass
- p.vel += dt * (acceleration + nextAcceleration) / 2
- p.forces = 0
- }
- if (onGroundTiles.length && p.getBottom() !== onGroundTiles[0].y) {
- p.setState(p.prevState)
- p.y = onGroundTiles[0].y - p.height
- if (p.vel < 0)
- p.vel = 0
- }
- }
- p.update = (delta) => {
- p.simulatePhysics(delta)
- if (p.vel > 0)
- p.setState('jump')
- if (p.vel < 0)
- p.setState('fall')
- p.updateAnimation(delta)
- }
- p.draw = () => {
- ctx.drawImage(p.image, p.x, p.y, p.width, p.height)
- return [{
- x: p.x,
- y: p.y,
- width: p.width,
- height: p.height
- }]
- }
- return p
- }
- // when all images have loaded, create our needed objects and start drawing
- function gameStart() {
- ctx.fillStyle = '#FFFFFF'
- ctx.fillRect(0, 0, WIDTH, HEIGHT)
- player = createPlayer(playerAnimations, 100, 0.25)
- prevLoop = performance.now()
- window.requestAnimationFrame(gameLoop)
- document.addEventListener('keydown', (e) => {
- const key = e.key
- if (!keysPressed.includes(key))
- keysPressed.push(key)
- })
- }
- // update all our game objects
- function update(delta) {
- if (keysPressed.includes(' '))
- player.jump()
- keysPressed = []
- player.update(delta)
- }
- // clear the areas that were drawn last frame and draw updated objects
- function draw() {
- prevDraws.forEach((array) => {
- array.forEach((val) => {
- ctx.fillStyle = 'white'
- ctx.fillRect(
- Math.round(val.x),
- Math.round(val.y),
- Math.round(val.width),
- Math.round(val.height)
- )
- })
- })
- prevDraws = []
- prevDraws.push(player.draw())
- }
- // sync our game loop to the window framerate, then update and draw each frame
- function gameLoop(time) {
- const delta = time - prevLoop
- prevLoop = time
- update(delta)
- draw()
- window.requestAnimationFrame(gameLoop)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement