HTML5画布游戏没有按预期工作



下午好。

我目前正在使用HTML5开发一个简单的2D游戏。游戏的目标如下:玩家(一个大小为"n"的绿色球(必须在地图上移动(使用右、左、上、下箭头(,并收集较小大小的球。每次用户收集一个球,它的大小就会增加25%。当球变得如此之大以至于几乎不可能在地图上看到任何球时,游戏结束,在这种情况下;游戏结束";文本被加载到画布上。

我遇到的问题是,为了知道球员是否收集了某个球,我计算用户和所述球之间的距离。如果小于3,则视为已收集。为了计算这个距离,我用了一个数学公式。问题是,它不能正常工作。有时,当用户明显超过3的距离时,球就会消失我想修改代码,使球只有在用户触摸时才会消失。我试着把距离设置为===0,但这仍然会产生意想不到的结果。

这是源代码:

const canvas = document.getElementById("gameArea");
const ctx = canvas.getContext("2d");
let x = 100;
let y = 100;
let radius = 50;
let speed = 10;
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
let gameOver = false;
let points = [ [300, 500], [400, 700], [100, 600], [469, 586], [578, 234], [587, 489] ];
var gAccess = 0;
var multiplier = 1;
let counter = 0;
function drawGame() {
requestAnimationFrame(drawGame);
clearScreen();
inputs();
boundryCheck();
drawGreenBlob();
drawNextTarget();
checkCollision();
}
function checkCollision() {
let b = points[gAccess][0] - x;
let a = points[gAccess][1] - y;
var c = Math.sqrt(a * a + b * b);
if (c < 220) {
gAccess = (gAccess + 1) % points.length;
multiplier += 0.25;
counter++;
console.log(counter);
}
if (counter >= 25) {
gameover = true;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
drawgameOver();
}
}
function drawNextTarget() {
if (gameOver === true) return;
ctx.beginPath();
ctx.arc(points[gAccess][0], points[gAccess][0], radius / 3, 0, Math.PI * 2);
ctx.fill();
}
function drawgameOver() {
var ctx = canvas.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "black");
grd.addColorStop(1, "gray");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, canvas.width, canvas.height);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.font = "36px Arial";
ctx.fillText("Game Over!", 50, 50);
}

function boundryCheck() {
//up
if (y < radius) {
y = radius;
}
//down
if (y > canvas.height - radius) {
y = canvas.height - radius;
}
//left
if (x < radius) {
x = radius;
}
//right
if (x > canvas.width - radius) {
x = canvas.width - radius;
}
}
function inputs() {
if (upPressed) {
y = y - speed;
}
if (downPressed) {
y = y + speed;
}
if (leftPressed) {
x = x - speed;
}
if (rightPressed) {
x = x + speed;
}
}
function drawGreenBlob() {
ctx.fillStyle = "green";
if (upPressed) {
ctx.fillStyle = "red";
}
if (downPressed) {
ctx.fillStyle = "blue";
}
if (leftPressed) {
ctx.fillStyle = "yellow";
}
if (rightPressed) {
ctx.fillStyle = "purple";
}
ctx.beginPath();
ctx.arc(x, y, radius * multiplier, 0, Math.PI * 2);
ctx.fill();
}
function clearScreen() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
document.body.addEventListener("keydown", keyDown);
document.body.addEventListener("keyup", keyUp);
function keyDown(event) {
//up
if (event.keyCode == 38) {
upPressed = true;
}
//down
if (event.keyCode == 40) {
downPressed = true;
}
//left
if (event.keyCode == 37) {
leftPressed = true;
}
//right
if (event.keyCode == 39) {
rightPressed = true;
}
}
function keyUp(event) {
//up
if (event.keyCode == 38) {
upPressed = false;
}
//down
if (event.keyCode == 40) {
downPressed = false;
}
//left
if (event.keyCode == 37) {
leftPressed = false;
}
//right
if (event.keyCode == 39) {
rightPressed = false;
}
}
drawGame();
<canvas id="gameArea" width=800 height=800></canvas>

非常感谢您的帮助和关注。

就像@ChrisG提到的那样,您需要在checkCollision if语句中包含半径:
if (c < radius * multiplier + radius / 3) {

  • radius * multiplier是我们玩家的半径
  • radius / 3是球的半径

从技术上讲,这是在两个周长接触时发生碰撞。如果你想做出不同的东西,你可以改变数学,例如,如果我们把它改为负数,而不是加号,我们会在球员吞下球时产生幻觉。


您在function drawNextTarget()上也有一个错误,您没有选择正确的坐标:
ctx.arc(points[gAccess][0], points[gAccess][0],
VS
ctx.arc(points[gAccess][0], points[gAccess][1],

现在一切看起来都很好:

const canvas = document.getElementById("gameArea");
const ctx = canvas.getContext("2d");
let x = 100;
let y = 100;
let radius = 50;
let speed = 10;
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
let gameOver = false;
let points = [ [300, 500], [400, 700], [100, 600], [469, 586], [578, 234], [587, 489] ];
var gAccess = 0;
var multiplier = 1;
let counter = 0;
function drawGame() {
requestAnimationFrame(drawGame);
clearScreen();
inputs();
boundryCheck();
drawGreenBlob();
drawNextTarget();
checkCollision();
}
function checkCollision() {
let b = points[gAccess][0] - x;
let a = points[gAccess][1] - y;
var c = Math.sqrt(a * a + b * b);
if (c < radius * multiplier + radius / 3) {
gAccess = (gAccess + 1) % points.length;
multiplier += 0.25;
counter++;
console.log(counter);
}
if (counter >= 25) {
gameover = true;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
drawgameOver();
}
}
function drawNextTarget() {
if (gameOver === true) return;
ctx.beginPath();
ctx.arc(points[gAccess][0], points[gAccess][1], radius / 3, 0, Math.PI * 2);
ctx.fill();
}
function drawgameOver() {
var ctx = canvas.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "black");
grd.addColorStop(1, "gray");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, canvas.width, canvas.height);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.font = "36px Arial";
ctx.fillText("Game Over!", 50, 50);
}

function boundryCheck() {
//up
if (y < radius) {
y = radius;
}
//down
if (y > canvas.height - radius) {
y = canvas.height - radius;
}
//left
if (x < radius) {
x = radius;
}
//right
if (x > canvas.width - radius) {
x = canvas.width - radius;
}
}
function inputs() {
if (upPressed) {
y = y - speed;
}
if (downPressed) {
y = y + speed;
}
if (leftPressed) {
x = x - speed;
}
if (rightPressed) {
x = x + speed;
}
}
function drawGreenBlob() {
ctx.fillStyle = "green";
if (upPressed) {
ctx.fillStyle = "red";
}
if (downPressed) {
ctx.fillStyle = "blue";
}
if (leftPressed) {
ctx.fillStyle = "yellow";
}
if (rightPressed) {
ctx.fillStyle = "purple";
}
ctx.beginPath();
ctx.arc(x, y, radius * multiplier, 0, Math.PI * 2);
ctx.fill();
}
function clearScreen() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
document.body.addEventListener("keydown", keyDown);
document.body.addEventListener("keyup", keyUp);
function keyDown(event) {
//up
if (event.keyCode == 38) {
upPressed = true;
}
//down
if (event.keyCode == 40) {
downPressed = true;
}
//left
if (event.keyCode == 37) {
leftPressed = true;
}
//right
if (event.keyCode == 39) {
rightPressed = true;
}
}
function keyUp(event) {
//up
if (event.keyCode == 38) {
upPressed = false;
}
//down
if (event.keyCode == 40) {
downPressed = false;
}
//left
if (event.keyCode == 37) {
leftPressed = false;
}
//right
if (event.keyCode == 39) {
rightPressed = false;
}
}
drawGame();
<canvas id="gameArea" width=800 height=800></canvas>

最新更新