【发布时间】:2023-04-10 05:35:01
【问题描述】:
我今天想知道如何使画布元素平滑地跟随另一个画布元素。例如,我正在尝试制作一个画布元素连续跟随玩家(可以使用 W、A、S 和 D 移动)平滑的游戏。我有一个想法,使用勾股定理来检查从 A 点(画布元素)移动到 B 点(玩家)的最接近和最快的方式。但是,我没有物理方法可以做到这一点。有没有人对我如何使画布元素尽可能流畅地不断跟随玩家以最快速度到达玩家有任何想法或答案?
这里我有一个非常糟糕的跟随方式的例子:
<!DOCTYPE html>
<html>
<head>
<title>Target Following Test</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<center>
<canvas id="canvas" width="800" height="500"></canvas>
</center>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var circle = function(x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
var drawRect = function(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, 20, 20)
}
//Moving Obstacle
var Obstacle = function(x, y) {
this.x = x;
this.y = y;
this.vSpeed = 0;
this.hSpeed = 0;
}
Obstacle.prototype.drawOb = function(color) {
drawRect(this.x, this.y, "Red")
}
Obstacle.prototype.follow = function() {
this.y += this.vSpeed
this.x += this.hSpeed
if (this.x < ball.x - 9) {
this.hSpeed = 1;
}
if (this.x > ball.x - 10) {
this.hSpeed = -1;
}
if (this.y > ball.y - 10) {
this.vSpeed = -1;
}
if (this.y < ball.y - 9) {
this.vSpeed = 1;
}
}
Obstacle.prototype.checkCollision = function(direction) {
return (ball.x - ball.radius < this.x + 20) &&
(ball.x + ball.radius > this.x) &&
(ball.y - ball.radius < this.y + 20) &&
(ball.y + ball.radius > this.y);
}
// The Ball constructor
var Ball = function() {
this.x = 20
this.y = 20
this.xSpeed = 0;
this.ySpeed = 0;
this.radius = 10;
};
// Draw the ball at its current position
Ball.prototype.draw = function() {
circle(this.x, this.y, 10, true, "Black");
};
Ball.prototype.reposition = function(reX, reY) {
this.x = reX;
this.y = reY;
}
// Update the ball's position based on its speed
Ball.prototype.move = function() {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 11) {
this.x = 11;
} else if (this.x > width - 11) {
this.x = width - 11;
} else if (this.y < 11) {
this.y = 11;
} else if (this.y > height - 11) {
this.y = height - 11;
}
};
// Set the ball's direction based on a string
Ball.prototype.setDirection = function(direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -2;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 2;
} else if (direction === "left") {
this.xSpeed = -2;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 2;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
function simulate() {
var prev_ball_x = ball.x;
var prev_ball_y = ball.y;
var prev_fol_x = follower.x;
var prev_fol_y = follower.y;
ball.move();
follower.follow()
if (follower.checkCollision()) {
ball.setDirection('stop');
follower.vSpeed = 0;
follower.hSpeed = 0;
follower.x = prev_fol_x;
follower.y = prev_fol_y;
ball.x = prev_ball_x;
ball.y = prev_ball_y;
}
}
function draw() {
ctx.clearRect(0, 0, width, height);
ball.draw();
follower.drawOb();
ctx.strokeRect(0, 0, width, height);
}
// An object to convert keycodes into action names
var keyActions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
// The keydown handler that will be called for every keypress
$("body").keydown(function(event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
$("body").keyup(function(event) {
ball.setDirection('stop');
})
setInterval(function() {
// separate drawing and simulating phases
simulate();
draw();
}, 10);
// Create all the Objects!
var ball = new Ball();
var follower = new Obstacle(400, 100);
</script>
</body>
</html>
【问题讨论】:
-
A 和 B 之间的最短距离是一条线。请参阅重复的 [Q&A}(stackoverflow.com/questions/27561041/…) 了解如何使用线性插值。
-
@markE:这个问题的两个欺骗目标之一似乎已被删除。作为金徽章持有者,您能否编辑重复列表以解决此问题?或者更好的是,重新关闭这个例如作为 stackoverflow.com/questions/13849185/… 的骗子。
标签: javascript html canvas