canvas学习开发初级版本的小游戏、后期会继续优化添加新的功能。
这个小游戏主要是dom和画布结合的练习
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()