飞扬的 jack小游戏(一)

91 阅读1分钟

canvas学习开发初级版本的小游戏、后期会继续优化添加新的功能。

这个小游戏主要是dom和画布结合的练习

2023-04-02 20.50.08.gif

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const gameContainer = document.getElementById('game-container')

canvas.width = 400
canvas.height = 600

const SPEED = 5
const FLAP_SPEED = -5
const PIPE_WIDTH = 50
const PIPE_GAP = 125

let playerVelocity = 0
let playerAcceleration = 0.1

let scoreDiv = document.getElementById('score-display')
let score = 0
let highScore = 0
let scored = false;

document.body.onkeyup = function (e) {
  if (e.code == 'Space') {
    playerVelocity = FLAP_SPEED
  }
}

document
  .getElementById('restart-button')
  .addEventListener('click', function () {
    hideEndMenu()
    resetGame()
    loop()
  })

const playerFlay = new Image()
playerFlay.src =
  'image/spritesheets/jet_pack_man_no_weapon_white_helmet_flying.png'

class Player {
  constructor() {
    this.frameX = 0
    this.frameY = 0
    this.spriteWidth = 692
    this.spriteHeight = 599
    this.width = this.spriteWidth / 10
    this.height = this.spriteHeight / 10
    this.x = -100
    this.y = canvas.height / 2 - this.height
  }

  update() {
    if (this.x < 50) {
      this.x += SPEED
    }

    playerVelocity += playerAcceleration
    this.y += playerVelocity
  }

  draw() {
    ctx.save()
    ctx.translate(this.x, this.y)
    ctx.drawImage(
      playerFlay,
      this.frameX * this.spriteWidth,
      this.frameY * this.spriteHeight,
      this.spriteWidth,
      this.spriteHeight,
      -0,
      -0,
      this.width,
      this.height
    )
    ctx.restore()
  }

  render() {
    this.update()
    this.draw()
  }
}

let player = new Player()

console.log('player', player)

class Pipe {
  constructor() {
    this.pipeX = 400
    this.pipeY = canvas.height - 200
  }

  update() {
    this.pipeX -= 1.5

    if (this.pipeX < -50) {
      this.pipeX = 400
      this.pipeY = Math.random() * (canvas.height - PIPE_GAP) + PIPE_WIDTH
    }
  }

  draw() {
    ctx.fillStyle = '#333'
    ctx.fillRect(this.pipeX, -100, PIPE_WIDTH, this.pipeY)
    ctx.fillRect(
      this.pipeX,
      this.pipeY + PIPE_GAP,
      PIPE_WIDTH,
      canvas.height - this.pipeY
    )
  }

  render() {
    this.update()
    this.draw()
  }
}

const pipe = new Pipe()

function collisionCheck() {
  const playerBox = {
    x: player.x,
    y: player.y,
    width: player.width,
    height: player.height
  }

  const topPipeBox = {
    x: pipe.pipeX,
    y: pipe.pipeY - PIPE_GAP + player.height,
    width: PIPE_WIDTH,
    height: pipe.pipeY
  }

  const bottomPipeBox = {
    x: pipe.pipeX,
    y: pipe.pipeY + PIPE_GAP + player.height,
    width: PIPE_WIDTH,
    height: canvas.height - pipe.pipeY - PIPE_GAP
  }

  if (
    playerBox.x + playerBox.width > topPipeBox.x &&
    playerBox.x < topPipeBox.x + topPipeBox.width &&
    playerBox.y < topPipeBox.y
  ) {
    return true
  }

  if (
    playerBox.x + playerBox.width > bottomPipeBox.x &&
    playerBox.x < bottomPipeBox.x + bottomPipeBox.width &&
    playerBox.y + playerBox.height > bottomPipeBox.y
  ) {
    return true
  }

  if (player.y < 0 || player.y + player.x > canvas.height) {
    return true
  }

  return false
}

function hideEndMenu() {
  document.getElementById('end-menu').style.display = 'none'
  gameContainer.classList.remove('backdrop-blur')
}

function showEndMenu() {
  document.getElementById('end-menu').style.display = 'block'
  gameContainer.classList.add('backdrop-blur')
  document.getElementById('end-score').innerHTML = score
  if (highScore < score) {
    highScore = score
  }
  document.getElementById('best-score').innerHTML = highScore
}

function resetGame() {
  player.x = -100
  player.y = (canvas.height / 2 - player.height)

  birdVelocity = 0
  birdAcceleration = 0.1

  pipe.pipeX = 400
  pipe.pipeY = canvas.height - 200

  score = 0
  scoreDiv.innerHTML = score;
}

function endGame() {
  showEndMenu()
}

function increaseScore() {
    if(player.x > pipe.pipeX + PIPE_WIDTH && 
        (player.y < pipe.pipeY + PIPE_GAP || 
            player.pipeY + player.width > player.pipeY + PIPE_GAP) && 
          !scored) {
        score++;
        scoreDiv.innerHTML = score;
        scored = true;
    }

    if (player.x < pipe.pipeX + PIPE_WIDTH) {
        scored = false;
    }
}

function loop() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  player.render()
  pipe.render()
  if (collisionCheck()) {
    endGame()
    return
  }
  increaseScore()
  requestAnimationFrame(loop)
}
loop()