我制作了一个有3个物体的小游戏
玩家:可以使用WASD移动
子弹:由点击
的事件监听器移动敌人:像僵尸一样跟随玩家。
如何制作僵尸的角度是他移动的方向,而不是总是面对玩家对象?
tick: function() {
enemy.angle = Math.atan2(player.y - enemy.y, player.x - enemy.x);// * (180 / Math.PI);
},
以上是我用来让敌人面对玩家的代码
答案 0 :(得分:0)
我理解你想要问的是什么,但实际上,现在僵尸总是直接进入玩家,所以如果它看起来像其他方式它实际上会很奇怪。你需要做的是让僵尸慢慢转身并在它上面行走,而不仅仅是减少它与玩家之间的欧氏距离。
第一个干,我将为你做的一个是计算旋转。我们不得不立即转向正确的角度,而是慢慢转动每一个嘀嗒声:
tick: function() {
// 1 degree per tick
const rotationSpeed = (1/180)*Math.PI;
// the angle we want - facing the player
const desiredAngle = Math.atan2(player.y - enemy.y, player.x - enemy.x)
// transition angle will be explained below
enemy.angle = transitionAngle(enemy.angle, desiredAngle,rotationSpeed );
},
这并不像听起来那么容易,因为你需要计算它是否能够更快地左转或右转再次面对玩家。幸运的是,一旦你知道你需要什么,这很容易谷歌。我的功能基于this answer:
function transitionAngle(fromAngle, toAngle, speed) {
// normalize the angles to 0-360 range
const rad360 = 2*Math.PI;
fromAngle = fromAngle % rad360;
toAngle = toAngle % rad360;
if (fromAngle < toAngle) {
if (Math.abs(fromAngle - toAngle) < Math.PI)
fromAngle += speed;
else fromAngle -= speed;
}
else {
if (Math.abs(fromAngle - toAngle) < Math.PI)
fromAngle -= speed;
else fromAngle += speed;
}
return fromAngle;
}
有了这个,僵尸慢慢减速,看起来已经好一点了。
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var bounds = canvas.getBoundingClientRect();
var mouseX = 0.0;
var mouseY = 0.0;
var pressingDown = false;
var pressingUp = false;
var pressingLeft = false;
var pressingRight = false;
var player = {
x: 210,
y: 250,
radius: 17.5,
angle: 0.0,
tick: function() {
this.angle = Math.atan2(mouseY - this.y, mouseX - this.x);
},
draw: function() {
context.fillStyle = "darkred";
context.strokeStyle = "black";
context.translate(this.x, this.y);
context.rotate(this.angle);
context.beginPath();
context.moveTo(this.radius, 0.0);
context.lineTo(-0.5 * this.radius, 0.5 * this.radius);
context.lineTo(-0.5 * this.radius, -0.5 * this.radius);
context.lineTo(this.radius, 0.0);
context.fill();
context.stroke();
context.rotate(-this.angle);
context.translate(-this.x, -this.y);
},
updatePlayerPosition: function() {
if (pressingRight)
player.x += 1;
if (pressingLeft)
player.x -= 1;
if (pressingDown)
player.y += 1;
if (pressingUp)
player.y -= 1;
}
}
var bullet = {
x: player.x,
y: player.y,
dx: 0.0,
dy: 0.0,
radius: 5.0,
tick: function() {
this.x += this.dx;
this.y += this.dy;
if (this.x + this.radius < 0.0 || this.x - this.radius > canvas.width || this.y + this.radius < 0.0 || this.y - this.radius > canvas.height) {
this.dx = 0.0;
this.dy = 0.0;
}
},
render: function() {
context.fillStyle = "darkcyan";
context.strokeStyle = "white";
context.beginPath();
context.arc(this.x, this.y, this.radius, 0.0, 2.0 * Math.PI, false);
context.fill();
context.stroke();
}
};
var enemy = {
x: 200,
y: 300,
radius: 17.5,
angle: 0.0,
tick: function() {
// 1 degree per tick
const rotationSpeed = (1/180)*Math.PI;
const desiredAngle = Math.atan2(player.y - enemy.y, player.x - enemy.x)
enemy.angle = transitionAngle(enemy.angle, desiredAngle,rotationSpeed );
},
draw: function() {
context.fillStyle = "Green";
context.strokeStyle = "darkgreen";
context.translate(this.x, this.y);
context.rotate(this.angle);
context.beginPath();
context.moveTo(this.radius, 0.0);
context.lineTo(-0.5 * this.radius, 0.5 * this.radius);
context.lineTo(-0.5 * this.radius, -0.5 * this.radius);
context.lineTo(this.radius, 0.0);
context.fill();
context.stroke();
context.rotate(-this.angle);
context.translate(-this.x, -this.y);
},
drawEnemy: function(something){
var diffX = player.x - something.x;
var diffY = player.y - something.y
if (diffX > 0)
something.x += .3
else
something.x -= .3;
if (diffY > 0)
something.y += .3
else
something.y -= .3;
}
}
function Refresh() {
context.clearRect(0, 0, canvas.width, canvas.height);
bullet.render();
bullet.tick();
player.draw();
player.tick();
player.updatePlayerPosition();
enemy.draw();
enemy.tick();
enemy.drawEnemy(enemy);
}
setInterval(Refresh, 0)
window.onmousemove = function(e) {
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
}
document.onkeydown = function(event) {
if (event.keyCode === 83) //s
pressingDown = true;
else if (event.keyCode === 87) //w
pressingUp = true;
else if (event.keyCode === 65) //a
pressingLeft = true;
else if (event.keyCode === 68) //d
pressingRight = true;
}
document.onkeyup = function(event) {
if (event.keyCode === 83) //s
pressingDown = false;
else if (event.keyCode === 87) //w
pressingUp = false;
else if (event.keyCode === 65) //a
pressingLeft = false;
else if (event.keyCode === 68) //d
pressingRight = false;
}
window.onmousedown = function(e) {
// The mouse pos - the player pos gives a vector
// that points from the player toward the mouse
var x = mouseX - player.x;
var y = mouseY - player.y;
// Using pythagoras' theorm to find the distance (the length of the vector)
var l = Math.sqrt(x * x + y * y);
// Dividing by the distance gives a normalized vector whose length is 1
x = x / l;
y = y / l;
// Reset bullet position
bullet.x = player.x;
bullet.y = player.y;
// Get the bullet to travel towards the mouse pos with a new speed of 10.0 (you can change this)
bullet.dx = x * 10.0;
bullet.dy = y * 10.0;
}
function transitionAngle(fromAngle, toAngle, speed) {
// normalize the angles to 0-360 range
const rad360 = 2*Math.PI;
fromAngle = fromAngle % rad360;
toAngle = toAngle % rad360;
if (fromAngle < toAngle) {
if (Math.abs(fromAngle - toAngle) < Math.PI)
fromAngle += speed;
else fromAngle -= speed;
}
else {
if (Math.abs(fromAngle - toAngle) < Math.PI)
fromAngle -= speed;
else fromAngle += speed;
}
return fromAngle;
}
&#13;
<canvas id="canvas" style="border:2px solid darkred" width="700" height="500"></canvas>
&#13;
这份工作的第二部分 - 我将这一部分留给你 - 就是让僵尸实际上走向它所面对的方向。为此,请为其指定步行速度,然后使用僵尸角度的sin
和cos
乘以速度来获得X和Y偏移。同样,谷歌是你的朋友,只需键入&#34; 按速度和角度移动javascript &#34;。