gpt4 book ai didi

javascript - Canvas 矩形和球碰撞不起作用

转载 作者:行者123 更新时间:2023-12-03 02:56:11 25 4
gpt4 key购买 nike

我正在制作一个 html5 Canvas 游戏,但遇到碰撞问题。问题是,当球与任何平台碰撞时,球重力应为 -1,并以与平台相同的速度上升,但它仅适用于最后一个平台和左侧平台。我该如何修复它?谢谢!

HTML:

<html>
<head>
<title>Falldown</title>
</head>
<body>
<canvas id="canvas" width = "380" height= "640"></canvas>
<script src="beta.js"></script>
</body>
</html>

JS 代码:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var isMenu = true;
var isPlaying = false;
var testing = true;
var pressingLeft = false;
var pressingRight = false;

var Platforms = [];

var difficulty = 1;

var gravity = 1;

var Player = {
color: "red",
radius: 7.5,
stepY: 1.5,
x: 175,
y: 75
};

function RectCircleColliding(circle, rect) {
var distX = Math.abs(circle.x - rect.x - rect.width / 2);
var distY = Math.abs(circle.y - rect.y - 20 / 2);

if (distX > (rect.width / 2 + circle.radius)) return false;
if (distY > (20 / 2 + circle.radius)) return false;

if (distX <= (rect.width / 2)) return true;
if (distY <= (20 / 2)) return true;

var dx = distX - rect.width / 2;
var dy = distY - 20 / 2;
return (dx * dx + dy * dy <= (circle.radius * circle.radius));
}

function drawBackground() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);

if (isMenu && !isPlaying) {
createText("60px monospace", "white", "FallDown", 45, 130);
createText("34px Arial", "white", "PLAY", 130, 260);
createText("34px Arial", "white", "LEADERBOARD", 50, 340);
createText("34px Arial", "white", "SETTINGS", 90, 420);
} else {
if (testing) {
Platforms = [];
for (var i = 0; i < 13; i++) {
Platforms.push({
"x": 10,
"y": 160 + (i * 70),
"width": (Math.random() * canvas.width) - 60
});
}
testing = false;
}

for (var i in Platforms) {
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, Platforms[i].y, Platforms[i].width, 20);

var totalTest = Platforms[i].width + 60;
ctx.fillRect(totalTest + 30, Platforms[i].y, canvas.width - totalTest, 20);

Platforms[i].y -= 1;

if (RectCircleColliding(Player, Platforms[i])) {
gravity = -1;
} else {
gravity = 1;
}
}

detectBorderCollision();
detectPlayerCollision();
drawPlayer();
drawBorder();

if (Platforms.length === 7) Platforms = [];
}
}

function detectBorderCollision() {
if (Player.x > 370 - Player.radius) {
Player.x = 370 - Player.radius;
} else if (Player.x < 3.8 + Player.radius * 2) {
Player.x = 3.8 + Player.radius * 2
}
}

function detectPlayerCollision() {

}

function drawPlayer() {
ctx.beginPath();
ctx.fillStyle = Player.color;
ctx.arc(Player.x, Player.y, Player.radius, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();

Player.y += gravity;

if (pressingRight) {
Player.x += 2;
} else if (pressingLeft) {
Player.x -= 2;
}

/*
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, 160, 300, 20);
*/
}

function drawBorder() {
ctx.beginPath();
ctx.strokeStyle = "#00ffff";
ctx.lineWidth = 10;
ctx.moveTo(5, 0);
ctx.lineTo(5, 640);

ctx.moveTo(375, 0);
ctx.lineTo(375, 640);
ctx.stroke();
ctx.closePath();
}

function createText(font, color, value, posX, posY) {
ctx.font = font;
ctx.fillStyle = color;
ctx.fillText(value, posX, posY)
}

function isInside(realX, realY, x1, x2, y1, y2) {
return (realX > x1 && realX < x2) && (realY > y1 && realY < y2)
}

function drawGame() {
drawBackground();
}

function startDrawing() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGame();
requestAnimationFrame(startDrawing);
}

function Init() {
requestAnimationFrame(startDrawing);

canvas.addEventListener("click", function(evt) {
var rect = canvas.getBoundingClientRect();
var mouseX = evt.clientX - rect.left;
var mouseY = evt.clientY - rect.top;

if (isMenu && !isPlaying) {
if (isInside(mouseX, mouseY, 115, 230, 220, 270)) {
isPlaying = true;
isMenu = false;
} else if (isInside(mouseX, mouseY, 35, 320, 300, 345)) {
console.log("Leaderboard");
} else if (isInside(mouseX, mouseY, 75, 270, 380, 430)) {
console.log("Settings");
}
}

});

window.addEventListener("keydown", function(evt) {
if (!isMenu && isPlaying) {
if (evt.keyCode === 39) { // right
pressingRight = true;
} else if (evt.keyCode === 37) { // left
pressingLeft = true;
}
}
});

window.addEventListener("keyup", function(evt) {
if (!isMenu && isPlaying) {
if (evt.keyCode === 39) { // right
pressingRight = false;
} else if (evt.keyCode === 37) { // left
pressingLeft = false;
}
}
});
}

Init();

最佳答案

您的代码中有太多魔数(Magic Number),调试起来既困难又乏味。将所有数字文字替换为描述值所代表含义的标识符。

drawBackground函数部分的以下修改会导致与左侧平台的所有碰撞正常工作,但并不完美。

var hasCollided;

for (var i in Platforms) {
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, Platforms[i].y, Platforms[i].width, 20);

var totalTest = Platforms[i].width + 60;
ctx.fillRect(totalTest + 30, Platforms[i].y, canvas.width - totalTest, 20);

Platforms[i].y -= 1;

if (!hasCollided) {
if (RectCircleColliding(Player, Platforms[i])) {
gravity = -1;
hasCollided = true;
} else {
gravity = 1;
}
}
}

关于javascript - Canvas 矩形和球碰撞不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47607492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com