javascript - 画布中矩形形状的随机移动和旋转
问题描述
我正在尝试在 html 画布上创建一个游戏,在那里我可以控制一辆汽车。还有其他一些由计算机控制的汽车。我可以用四个箭头键(上、下、左、右)来控制我的车。它工作正常。我在生成其他对手汽车时遇到了一些困难,这些汽车将在画布区域内随机移动并像我用四个箭头键控制的汽车一样急转弯。
我已经做了一些代码来使随机生成的汽车移动。但这些都不能正常工作。运动不顺畅,随机,汽车不能正确右转或左转。
最初我显示的是一个矩形而不是汽车。绿色矩形是计算机控制的汽车,蓝色矩形是由用户控制的。
任何人有任何想法来解决这个问题?我完全被困在这里。提前致谢。
我的 js 文件如下所示。
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 500;
const canvasW = canvas.width;
const canvasH = canvas.height;
let upPressed = false,
downPressed = false,
rightPressed = false,
leftPressed = false;
let enemies = [];
class PlayerCar {
constructor(carX, carY, carWidth, carHeight) {
this.carX = carX;
this.carY = carY;
this.carWidth = carWidth;
this.carHeight = carHeight;
this.angle = 0;
this.rot = 0.1; //control how fast it turns
}
draw() {
ctx.fillStyle = "blue";
ctx.save();
ctx.beginPath();
ctx.translate(this.carX, this.carY);
ctx.rotate(this.angle);
ctx.rect(
-this.carWidth / 2,
-this.carHeight / 2,
this.carWidth,
this.carHeight
);
ctx.fill();
ctx.closePath();
ctx.restore();
}
update() {
if (rightPressed) {
this.angle += this.rot;
} else if (leftPressed) {
this.angle -= this.rot;
}
if (upPressed) {
this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
}
if (downPressed) {
this.carX += Math.cos(this.angle + toRadians(90)) * 5;
this.carY += Math.sin(this.angle + toRadians(90)) * 5;
}
}
}
class EnemyCar {
constructor(carX, carY, carWidth, carHeight) {
this.carX = carX;
this.carY = carY;
this.carWidth = carWidth;
this.carHeight = carHeight;
this.angle = 0;
this.rot = 0.1;
}
draw() {
ctx.fillStyle = "green";
ctx.save();
ctx.beginPath();
ctx.rect(this.carX, this.carY, this.carWidth, this.carHeight);
ctx.fill();
ctx.closePath();
ctx.restore();
}
update() {
if (this.carX < 0) this.carX = 0;
if (this.carX > canvasW - this.carWidth)
this.carX = canvasW - this.carWidth;
if (this.carY < 0) {
this.carY = 0;
}
if (this.carY > canvasH - this.carHeight) {
this.carY = canvasH - this.carHeight;
}
let test = Math.random() * 30;
if (test < 5) {
this.angle += this.rot;
} else if (test > 5 && test < 10) {
this.angle -= this.rot;
}
if (test > 10 && test < 20) {
this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
}
if (test > 20 && test < 30) {
this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
}
}
}
function toRadians(deg) {
return (deg * Math.PI) / 180;
}
const playerCar = new PlayerCar(200, 100, 40, 60);
playerCar.draw();
function navigation() {
const handleKeyDown = (e) => {
if (e.key === "ArrowUp") {
upPressed = true;
}
if (e.key === "ArrowDown") {
downPressed = true;
}
if (e.key === "ArrowRight") {
rightPressed = true;
}
if (e.key === "ArrowLeft") {
leftPressed = true;
}
};
const handleKeyUp = (e) => {
if (e.key === "ArrowUp") {
upPressed = false;
}
if (e.key === "ArrowDown") {
downPressed = false;
}
if (e.key === "ArrowRight") {
rightPressed = false;
}
if (e.key === "ArrowLeft") {
leftPressed = false;
}
};
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
}
function spawnEnemy() {
enemies.push(new EnemyCar(Math.floor(canvasW / 4), 400, 40, 60));
enemies.push(new EnemyCar(Math.floor(canvasW / 2), 400, 40, 60));
enemies.push(new EnemyCar(Math.floor(canvasW / 1.33), 400, 40, 60));
}
spawnEnemy();
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvasW, canvasH);
if (playerCar.carX < 0) playerCar.carX = 0;
if (playerCar.carX > canvasW - playerCar.carWidth)
playerCar.carX = canvasW - playerCar.carWidth;
if (playerCar.carY < 0) {
playerCar.carY = 0;
}
if (playerCar.carY > canvasH) {
playerCar.carY = canvasH;
}
enemies.forEach((enemy) => {
enemy.draw();
enemy.update();
});
playerCar.draw();
playerCar.update();
}
function startGame() {
animate();
}
function drawCC() {
ctx.beginPath();
ctx.arc(100, 200, 50, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
}
startGame();
navigation();
解决方案
推荐阅读
- javascript - 按 RowClick 展开列
- python - 为多项式朴素贝叶斯准备数据并运行算法 - ValueError:发现输入变量的样本数不一致
- pine-script - Pine Script 在条的右侧绘制一条水平线
- php - PHP 警告:mysqli_num_rows() 期望参数 1 为 mysqli_result,给定对象
- reactjs - 对多个复选框做出反应验证
- python - 如何改进使用 Python 抓取 reddit 的代码
- typescript - 类型 '{ uid: string; 上不存在属性 'uid' 令牌:DecodedIdToken;} | 不明确的'
- reactjs - ReactJs 中是否有一些版本控制,当在 index.html 中设置时会自动使浏览器再次获取应用程序?
- react-native - 从嵌套导航容器返回的 React-native 不起作用
- c# - SQL SELECT查询中ASP.NET TextBox的使用值