我正在简单的游戏中尝试运动机制,并且发现了非常不错的文章,并举例说明了如何通过速度和摩擦(使其非常流行的方法)使其“逼真”。因此,对象开始缓慢移动,加速到上限,一旦释放键,它就会开始释放速度直到0。
关键部分添加了“油门”:
if(keys[38]) {
spaceship.ax = Math.cos(spaceship.r) * 0.05;
spaceship.ay = Math.sin(spaceship.r) * 0.05;
} else {
spaceship.ax = spaceship.ay = 0;
}
并利用该油门来提高受摩擦限制的速度
var friction = 0.97;
function updatePosition(obj) {
//update velocity
obj.vx += obj.ax;
obj.vy += obj.ay;
//apply friction
obj.vx *= friction;
obj.vy *= friction;
//update position
obj.x += obj.vx;
obj.y += obj.vy;
}
尽管它看起来非常漂亮并且感觉不错,但它打破了我关于基于时间移动的逻辑。它是强制性的,因此玩家可以看到每秒的速度,因为它可以进行计划的升级,计划的行程和燃油消耗。
所以当前的实现如下:
this.now = undefined;
this.delta = undefined;
this.then = Date.now();
this.setMoveDelta = function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
};
this.speed = 100; // 100 pixels per second
this.move = function() {
this.setMoveDelta();
var partialDistance = this.speed * this.delta;
this.x += Math.cos(this.rad) * partialDistance;
this.y += Math.sin(this.rad) * partialDistance;
}
现在,当您运行附带的演示时,可以注意到由于摩擦力帽而有某种“最大”速度。问题是可以通过某种方式将此上限设置为this.speed * this.delta
吗?还是使用其他方法以声明的参数(例如每秒100像素)使船舶以最大速度行驶?
这个想法是让加速和减速保持原样,但是一旦船达到最大速度,它将是声明的速度(并显示给用户)。然后,该速度用于计算从点A到点B所需的时间以及将使用多少燃料。目前感觉随机。
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
w = 400,
h = 400;
canvas.width = w;
canvas.height = h;
document.body.appendChild(canvas);
var spaceship = {
x: w / 2, y: h / 2,
vx: 0, vy: 0,
ax: 0, ay: 0,
r: 0,
draw: function(){
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.r);
ctx.fillStyle = 'white';
ctx.fillRect(-10, -5, 20, 10);
ctx.restore();
}
};
var friction = 0.97;
function updatePosition(obj) {
//update velocity
obj.vx += obj.ax;
obj.vy += obj.ay;
applyFriction(obj);
//update position
obj.x += obj.vx;
obj.y += obj.vy;
}
//user interactivity
var keys = [];
document.addEventListener('keydown', function(e){
keys[e.which] = true;
});
document.addEventListener('keyup', function(e){
keys[e.which] = false;
});
function applyFriction(obj){
obj.vx *= friction;
obj.vy *= friction;
}
(function animloop(){
requestAnimationFrame(animloop, canvas);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
//rotation
if(keys[37]) spaceship.r -= 0.05;
if(keys[39]) spaceship.r += 0.05;
//thrust
if(keys[38]){
spaceship.ax = Math.cos(spaceship.r) * 0.05;
spaceship.ay = Math.sin(spaceship.r) * 0.05;
}else{
spaceship.ax = spaceship.ay = 0;
}
updatePosition(spaceship);
spaceship.draw();
})();
-----编辑
我实现了建议的解决方案,但是即使使用此公式,最大速度也要比声明的速度稍低一些,从而导致其他对象以每秒实际100px的速度移动,从长远来看,速度更快。这是新的演示:
this.now = undefined;
this.delta = undefined;
this.then = Date.now();
this.setMoveDelta = function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
};
this.speed = 100; // 100 pixels per second
var secondObj = {
x: 0,
y: 250,
r: 0,
active: false,
draw: function(){
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.r);
ctx.fillStyle = 'white';
ctx.fillRect(-10, -5, 20, 10);
ctx.restore();
}
};
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
w = 1200,
h = 400;
canvas.width = w;
canvas.height = h;
document.body.appendChild(canvas);
var spaceship = {
x: 0, y: 200,
vx: 0, vy: 0,
ax: 0, ay: 0,
r: 0,
draw: function(){
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.r);
ctx.fillStyle = 'white';
ctx.fillRect(-10, -5, 20, 10);
ctx.restore();
}
};
var friction = 0.97;
function updatePosition(obj) {
//update velocity
obj.vx += obj.ax;
obj.vy += obj.ay;
applyFriction(obj);
//update position
obj.x += obj.vx;
obj.y += obj.vy;
}
//user interactivity
var keys = [];
document.addEventListener('keydown', function(e){
keys[e.which] = true;
setTimeout(function() {
secondObj.active = true;
}, 600);
});
document.addEventListener('keyup', function(e){
keys[e.which] = false;
});
function applyFriction(obj){
obj.vx *= friction;
obj.vy *= friction;
}
var is = function(c, num) {
if(parseInt(c) < num + 1 || parseInt(c) > num - 1) {
return true;
}
return false;
};
(function animloop(){
requestAnimationFrame(animloop, canvas);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
//rotation
if(keys[37]) spaceship.r -= 0.05;
if(keys[39]) spaceship.r += 0.05;
//thrust
this.setMoveDelta();
if(keys[38]){
spaceship.ax = Math.cos(spaceship.r) * (this.speed * this.delta * (1-0.97));
spaceship.ay = Math.sin(spaceship.r) * (this.speed * this.delta * (1-0.97));
}else{
spaceship.ax = spaceship.ay = 0;
}
updatePosition(spaceship);
spaceship.draw();
if(secondObj.active) {
secondObj.x += Math.cos(0) * ( this.speed * this.delta );
}
secondObj.draw();
})();
答案 0 :(得分:1)
现在速度为root_of(obj.vx ^ 2 + obj.vy ^ 2)/this.delta,最大速度为0.05 /(1-0.97)/this.delta。 vx和vy之后的第一个在每个时间增量中都在移动。后者由于速度的增加0.05与速度的减少*(1-0.97)平衡。
答案是可以通过调整加速度常数0.05或摩擦常数0.97来设置速度上限。让我们使用加速度一:
加速度常数= max_speed * this.delta *(1-0.97)