我創建了一個算法來對角地移動一個粒子,它使用一個角度很好地工作。基本上,這是我所做的:如何對角線和曲折移動物體?
this.x += this.speed * Math.cos(this.angle * Math.PI/180);
this.y += this.speed * Math.sin(this.angle * Math.PI/180);
this.draw();
我該如何將它與鋸齒形運動相結合?
我創建了一個算法來對角地移動一個粒子,它使用一個角度很好地工作。基本上,這是我所做的:如何對角線和曲折移動物體?
this.x += this.speed * Math.cos(this.angle * Math.PI/180);
this.y += this.speed * Math.sin(this.angle * Math.PI/180);
this.draw();
我該如何將它與鋸齒形運動相結合?
因此,假設您正在朝this.angle
方向移動,並且您想沿該方向以該方向從該方向移動到±45°的方向進行鋸齒形。所有您需要做的是有一個像var zigzag = 45;
這樣的變量,並在計算新職位時將zigzag
加到this.angle
。爲了使它成爲之字形,你需要像這樣往往否定它zigzag *= -1;
。如果你想停止之字形,請設置zigzag = 0;
。
技巧是知道什麼時候在±45°之間交替。也許你可以讓開關計時,並保留上次使用Date.now();
開關時的參考。您可以檢查當前時間和記錄時間之間的差異,然後在您超過特定毫秒數時否定zigzag
。請記住記錄最後一次切換的新時間。你也可以跟蹤旅行的距離,並使用相同的方法,無論爲你工作。
我推薦計算從正常路徑或由
// Triangle wave at position t with period p:
function amplitude(t, p) {
t %= p;
return t > p * 0.25 ? t < p * 0.75 ? p * 0.5 - t : t - p : t;
}
其中t
將被設定爲行進路徑的長度,並p
給出的橫向偏差amplitude
是「鋸齒狀」的週期三角波狀圖案。
var amplitude = amplitude(distance, p) - this.amplitude(previous_distance, p);
this.x += amplitude * Math.sin(this.angle * Math.PI/180);
this.y -= amplitude * Math.cos(this.angle * Math.PI/180);
一個完整的例子有:
考慮幅度和以前的位置,我們現在可以很容易地向前邁進,通過你原來的代碼來描述,然後加入橫向偏離我們的位置計算下一個位置兩個可移動的對象,一個移動 '正常' 和一個下面的一個 '之字形' 圖形:
function Movable(x, y, speed, angle, period) {
this.x = x;
this.y = y;
this.speed = speed;
this.angle = angle;
this.period = period;
this.distance = 0;
}
Movable.prototype.moveDiagonal = function() {
this.distance += this.speed;
this.x += this.speed * Math.cos(this.angle * Math.PI/180);
this.y += this.speed * Math.sin(this.angle * Math.PI/180);
}
Movable.prototype.amplitudeZigZag = function() {
var p = this.period, d = this.distance % p;
return d > p * 0.25 ? d < p * 0.75 ? p * 0.5 - d : d - p : d;
}
Movable.prototype.moveZigZag = function() {
var amplitude1 = this.amplitudeZigZag();
this.moveDiagonal();
var amplitude2 = this.amplitudeZigZag();
var amplitude = amplitude2 - amplitude1;
this.x -= amplitude * Math.sin(this.angle * Math.PI/180);
this.y += amplitude * Math.cos(this.angle * Math.PI/180);
}
Movable.prototype.draw = function(context) {
context.beginPath();
context.arc(this.x, this.y, 1, 0, 2 * Math.PI);
context.stroke();
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var m1 = new Movable(0, 0, 2, 0, 50);
var m2 = new Movable(0, 0, 2, 0, 50);
for (var i = 0; i < 1000; ++i) {
m1.angle += Math.cos(i * Math.PI/180);
m2.angle += Math.cos(i * Math.PI/180);
m1.moveDiagonal();
m2.moveZigZag();
m1.draw(context);
m2.draw(context);
}
<canvas id="canvas" width="600" height="200"></canvas>
尼斯解決方案..! – markE
好的解決方案。您可能想要使用三角波函數f(t)= abs(4 *(t-floor(t + 1/2))) - 1,其中t =時間,頻率爲1,幅度範圍爲 - 1到1.還有一點非常小,與2D API相比,轉換函數是顛倒的。匹配它的'x - = sin(a)* d; y + = cos(a)* d',因此將與'ctx.rotate(a); ctx.translate(0,d);一致; – Blindman67
你可以嘗試使用'Math.sin(Date.now())'或類似的東西改變角度。 –
@SeanLeBlanc這使得角度發生變化,但隨着時間的推移,我無法讓它變得越來越小。這只是突然改變每一個新的繪製 –