所以我创造了一个破砖机游戏,我需要一些帮助找到一个角度。
游戏几乎包含了一些块,当它们被击中时,会导致你失去1点生命值。游戏的目的是在击球之前用球击打它们以打破它们。如果球击中墙壁或街区,其轨迹将反转。
我希望用户能够在html画布中点击某人。然后,从画布底部的屏幕中心开始的球将遵循该角度。换句话说,用户将点击并且球将移动到该位置然后继续直到它击中某些东西。
我在这里有一些代码,但它可能不会对如何实现这个角度有所帮助。
function animate(callback) {
window.requestAnimationFrame(function() {
window.setTimeout(callback, 1000/60);
});
}
// canvas
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// variables
var ballList = [];
var maxBalls = 1;
var checkAmount = 0;
var interval;
// onload/refresh/update/render
window.onload = function() {
refresh();
}
function refresh() {
update();
render();
animate(refresh);
}
function update() {
document.addEventListener("click", spawn);
for(var i = 0; i < ballList.length; i++) {
ballList[i].move();
}
}
function render() {
context.fillStyle = '#000';
context.fillRect(0, 0, canvas.width, canvas.height);
for(var i = 0; i < ballList.length; i++) {
ballList[i].show();
}
}
// ball
function Ball() {
this.x = canvas.width / 2;
this.y = canvas.height - 50;
this.width = 10;
this.height = 10;
this.xVel = 5;
this.yVel = -10;
this.show = function() {
context.fillStyle = '#fff';
context.fillRect(this.x, this.y, this.width, this.height);
}
this.move = function() {
this.x += this.xVel;
this.y += this.yVel;
if(this.x >= canvas.width || this.x <= 0) {
this.xVel *= -1;
}
if(this.y >= canvas.height || this.y <= 0) {
this.yVel *= -1;
}
}
}
function spawn(event) {
var xVel = (event.clientX - canvas.width / 2) / 90;
if(ballList.length < maxBalls) {
if(checkAmount < maxBalls) {
interval = setInterval(function() {
ballList.push(new Ball((event.clientX)));
checkAmount++;
if(checkAmount > maxBalls) {
clearInterval(interval);
checkAmount = 0;
}
}, 10);
}
}
}
提前致谢。
答案 0 :(得分:3)
要将对象从一个点移动到另一个点,请使用向量。向量只是表示方向和速度的两个数字。它可以是极性的,因为一个数字是一个角度,另一个是距离,或者说是向量的笛卡尔,即x和y的变化量。
为此您可以使用其中任何一种,但我更喜欢笛卡尔向量和一种称为单位向量的特定类型。单位矢量长1个单位。在计算机图形学中,单元通常是像素。
所以我们有一个重点从
开始var startX = ?
var startY = ?
我们想要走向
var targetX = ?
var targetY = ?
我们希望单位矢量从开始到目标,
var vectorX = targetX - startX;
var vectorY = targetY - startY;
矢量的长度是两点之间的距离。这不是那么方便,所以我们将x和y除以长度
将其转换为单位向量var length = Math.sqrt(vectorX * vectorX + vectorY * vectorY);
var unitVectX = vectorX / length;
var unitVectY = vectorY / length;
现在我们有一个像素长的单位向量。
球将在开始时开始
var ballX = startX
var ballY = startY
并将以每秒200像素的速度移动(假设为60fps)
var ballSpeed = 200 / 60;
现在移动球只需加速单位矢量乘以速度就可以了。直到下一帧。
ballX += unitVectX * ballSpeed;
ballY += unitVectY * ballSpeed;
使用笛卡儿可以很容易地从与x或y轴对齐的墙壁上反弹。
if(ballX + ballRadius > canvas.width){
ballX = canvas.width - ballRadius;
unitVectX = - unitVectX;
}
您也可以使用极坐标。当我们使用单位向量时,极性单位向量只需要方向。你使用trig函数atan2
// get the direction in radians
var polarDirection = Math.atan2(targetY - startY, targetX - startX);
方向是弧度,许多人不喜欢弧度并转换为度数,但只要它朝着正确的方向,就没有必要知道它的走向。记住弧度很容易。 360度是2弧度180是1兰迪90是0.5。使用的实际单位是PI(很少有人知道pi的许多数字但你不需要)。所以270度是1.5弧度或数字1.5 * Math.PI。
角度从3点钟位置开始(指向屏幕右侧)为0弧度或0度,然后顺时针90度为6点钟位置为0.5弧度,而6点位置为180度1弧度,因此上。
要使用polarDirection移动球,您需要使用更多的trig。
// do this once a frame
ballX += Math.cos(polarDirection) * ballSpeed;
ballY += Math.sin(polarDirection) * ballSpeed;
// note that the cos and sin actually generate the cartesian unit vector
答案 1 :(得分:1)
/**
* @param {number} x1 - x coordinate of the first point
* @param {number} y1 - y coordinate of the first point
* @param {number} x2 - x coordinate of the second point
* @param {number} y2 - y coordinate of the second point
* @return {number} - the angle (between 0 and 360)
*/
function getDirection(x1, y1, x2, y2) {
// might be negative:
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
// correct, positive angle:
return (angle + 360) % 360;
}
我为了类似的目的编写了这个函数。不要忘记你可能不得不否定x。
在下图中,第一个点位于中心,第二个点位于圆圈的某个位置: