我有虚幻的世界:
var worldSize = [10000, 10000]; //width, height
Run Code Online (Sandbox Code Playgroud)
接下来我有球员的位置:
var currentPlayerPosition = [5000, 5000]; //center on the map
Run Code Online (Sandbox Code Playgroud)
现在我需要每10ms检查当前鼠标位置,并计算鼠标的方向,并更新currentPlayerPosition到方向结果-1px(如果鼠标在播放器下,则更新+ 1px ...).与右/左侧相同.
编辑:我不需要代码,我需要mathematica来计算方向,然后减去/添加像素到玩家位置的数组[5000,5000]
编辑2
我的意思是:
如果currentPlayerPosition是[5000,5000]和mousePosition是[4500,4800]那么我必须从数学currentPlayerPosition每10ms,如果我想移动玩家的鼠标位置?
currentPlayerPosition[0] = currentPlayerPosition[0]-(what_number_here)
currentPlayerPosition[1] = currentPlayerPosition[1]-(what_number_here)
Run Code Online (Sandbox Code Playgroud)
要么
currentPlayerPosition[0] = currentPlayerPosition[0]+(what_number_here)
currentPlayerPosition[1] = currentPlayerPosition[1]+(what_number_here)
Run Code Online (Sandbox Code Playgroud)
编辑3
我想让这个问题更好,所以我在这里写下我的(坏)想法:
我先尝试计算距离X和Y:
var fullWidth = 5000;
var playerPositionX = 2500;
var mousePositionX = 2700;
var distanceBetweenX = mousePositionX-playerPositionX; //200
Run Code Online (Sandbox Code Playgroud)
接下来,我尝试的相同代码计算Y距离.我得到了这样的结果:
distanceBetweenX = 200;
distanceBetweenY = 150;
Run Code Online (Sandbox Code Playgroud)
现在我尝试从X和Y两侧每1000ms扣除-1px.但这不能解决我的问题,因为150小于200,所以与此相符就好
这很糟糕.
我认为现在这个问题很好,我相信我的禁令将被删除.感谢你们.
忘记线的等式,斜率和截距在游戏开发中不会给你太多.使用矢量!
所以,你有两点
player: (700, 250)
mouse: (800, 100)
Run Code Online (Sandbox Code Playgroud)
而且你想要矢量从一个到另一个.这是不同的:
Difference: player - mouse
=>
Difference: (700, 250) - (800, 100)
=>
Difference: (700 - 800, 250 - 100)
=>
Difference: (-100, 150)
Run Code Online (Sandbox Code Playgroud)
勘误:因为你将使用代码(而不是鼠标)移动播放器,我们需要从播放器到鼠标的距离,因此请计算mouse - player.这是因为我们稍后会将(操纵的)差异向量添加到玩家向量中.
对于抽象,接下来要做的是计算范数和单位向量.然后 - 可能 - 使用缩放单位向量来获得要添加到位置的高级向量.
好的,现在,那个载体有多长?这是矢量的标准:
Distance: Norm(Difference)
=>
Distance: Norm((-100, 150))
=>
Distance: sqrt((-100 * -100) + (150 * 150))
=>
Distance: 180.277563...
Run Code Online (Sandbox Code Playgroud)
注意:这是欧几里德距离(又名毕达哥拉斯定理,推广超过2D,但我们仍然在2D中).
它的方向是什么?嗯,水平方向为负100,垂直方向为150 ......所以,它位于象限2上.
我们可以将方向表示为差异的单位向量(即相同方向和长度为1的向量):
Direction: Difference/Distance
=>
Direction: (-100, 150)/180.277563...
=>
Direction: (-100 / 180.277563..., 150 / 180.277563...)
=>
Direction: (-0.554700..., 0.832050...)
Run Code Online (Sandbox Code Playgroud)
理解单位向量的值可能更难.请记住,单位矢量保持相同的方向.
单位向量有用的原因是因为您可以将其缩放到您需要的任何距离.例如,如果要移动10个距离单位,则将单位向量缩放 10,这是您必须添加到位置的值.
因此,提前向量将是单位向量乘以您想要前进的距离.
为了便于理解,我会谈一下斜率,你要做的计算斜率如下:
Slope: Y/X
=>
Slope: 150/-100
=>
Slope: -1.5
Run Code Online (Sandbox Code Playgroud)
你可以看到的斜率是Y在X上的变化率(也就是说,每个X单位的Y变化多少).所以-1.5表示对于每个单位,你在X轴上前进,你在Y轴上移动-1.5个单位......这就是方向.
你可能更喜欢一个角度:
Angle: Atan(Slope)
=>
Angle: Atan(-1.5)
=>
Angle: -0.982794...
Run Code Online (Sandbox Code Playgroud)
注1:该值以弧度表示.如果你愿意,你可以把它转换成度数.
实现时如果在您的语言的标准库中可用,请使用Atan2.它将采用X和Y值,并将解决以0为单位计算斜率的除法.编辑:此外,如果你使用阿坦,角度将在第一或第四象限.要理解这一点,请考虑-1/2和1/-2是相同的斜率,但是(2,-1)和(-2,1)不是相同的向量(它们也不是同一个方向) .
所以,改用Atan2:
Angle: Atan2(Difference)
=>
Angle: Atan2(Y, X)
=>
Angle: Atan2(150, -100)
=>
Angle: 2.158798...
Run Code Online (Sandbox Code Playgroud)
相比:
-0.982794 radian = -56.3099° (degrees) [Quadrant 4]
2.158798 radian = 123.69° (degrees) [Quadrant 2]
Run Code Online (Sandbox Code Playgroud)
实际上,这个角度在实现中并没有多大用处.如上所述,您将发现自己使用单位向量.
曼哈顿几何(又名出租车几何)是一种几何形状,其中物体只沿轴移动.所以你没有真正的对角线或不同的角度.只是向上,向下,向左和向右(2D,即).
如果您在曼哈顿几何中工作,则按如下方式计算范数:
Distance: Norm(Difference)
=>
Distance: Norm((-100, 150))
=>
Distance: abs(-100) + abs(150)
=>
Distance: 250
Run Code Online (Sandbox Code Playgroud)
即通过沿每个轴添加矢量长度的绝对值.原因是物体必须在一个轴上移动,然后在另一个轴上移动.
现在,在曼哈顿几何体中实现游戏时很少使用单位矢量.相反,你可能会采取绝对值来决定首先移动哪个轴.向量具有更多绝对值的轴应首先移动(或最后移动,具体取决于您的需要).
或者,您可以先在同一轴上移动,然后在另一个轴上移动.测试何时在单个轴上到达目的地是比较棘手的,它需要独立地检查每个轴的距离 - 并且将遇到下面描述的振荡问题,以及比较浮点数的问题.
因此,提前向量将是您想要移动的距离(带有差异向量的符号)在您决定先移动的轴上,而在另一个轴上移动0.
您正在以固定的间隔检查位置 - 尽管测量从上次检查所经过的时间是值得的,因为计算机性能可能会有所不同 - 这意味着您有时间.
比如说,如果你想每单位时间移动10个距离单位,那么通过的时间实际上是3个单位.然后距离是3*10 = 30个单位.这就是你用来缩放高级向量的东西.
无论如何,当你更新位置时,实际发生的是物体从一个位置跳到另一个位置.这可能会产生意想不到的后果:物体将不可避免地超调.它将超出目标点,然后尝试返回然后再次超越,来回摆动...为了防止这种情况,你将检查距离矢量的范数是否小于你前进的距离,如果它更少......只需将对象放在目的地.
请注意,如果您需要flock行为,碰撞检测,加速等等.这部分代码需要更新.
屏幕坐标说明:由于历史原因,计算机将坐标原点放在左上角.因此,当水平轴上有正值时,它会向右移动.垂直轴上的正值,它是向下的.除非你是在一个变换的坐标系下工作......在这种情况下,无论变形说什么,有疑问,都要做实验.
var time = (new Date()).getTime(); // time in milliseconds
var player_element = document.getElementById('player');
player_element.style.left = 0;
player_element.style.top = 0;
var mouse = [0, 0]; // pixels
var player = [0, 0]; // pixels
var speed = 100.0; // pixels per second
// get the mouse pointer position
jQuery(document).ready(function(){
$(document).on('mousemove', function(e){
// update mouse
mouse[0] = e.pageX;
mouse[1] = e.pageY;
});
});
function update()
{
// calculate the difference
let diff = [mouse[0] - player[0], mouse[1] - player[1]];
// calculate the norm
let norm = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]);
if (norm == 0)
{
// already at target or not yet initilized
return;
}
// calculate the unit vector
let unit = [diff[0] / norm, diff[1] / norm];
// get elapsed time from last iteration
// divided by 1000 to get seconds
let new_time = (new Date()).getTime();
let elapsed = (new_time - time) / 1000.0;
// calculate advance by scaling unit vector
let advance = [unit[0] * elapsed * speed, unit[1] * elapsed * speed];
// calculate the norm of the advance vector
let advance_norm = Math.sqrt(advance[0] * advance[0] + advance[1] * advance[1]);
// check if we are about to overshoot
if (advance_norm > norm)
{
// we are too close to target
// just set the position to the target
player[0] = mouse[0];
player[1] = mouse[1];
}
else
{
// there is still room to go
// advance
player[0] += advance[0];
player[1] += advance[1];
}
// update player and time
player_element.style.left = (player[0]) + "px";
player_element.style.top = (player[1]) + "px";
time = new_time;
}
setInterval(update, 40);Run Code Online (Sandbox Code Playgroud)
#player
{
position:absolute;
display:block;
background: green;
width:10px;
height:10px;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="player"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
272 次 |
| 最近记录: |