如何使用javascript创建移动赛道?
问题描述:
我一直在尝试使用JavaScript和画布创建经典赛车游戏。如何使用javascript创建移动赛道?
这是JavaScript部分(car_race.js) 我能够创建一个正在移动的轨道,但它没有那么现实,因为它应该是。现在写出发生的事情是,如果一个边界条完全消失,那么只有它出现在画布的顶部。我想要做的是,当一个边界条从顶部到底部通过完整的画布时,我希望它从顶部恢复,并从画布的底部消失。任何人都可以帮我解决这个问题。
var carRaceTrack = document.getElementById('carraceCanvas');
var carRaceTrackContext = carRaceTrack.getContext('2d');
var boundryWidth = 10;
var boundryHeight = 80;
var boundryTopOffSet = 5;
var boundryLeftOffSet = 402;
var boundryPadding = 8;
setInterval(draw, 0.5);
var leftBoundry = [];
var rightBoundry = [];
for (x = 0; x < 6; x++) {
leftBoundry[x] = {
OffSet: 0,
topOffSet: 0,
width: 0,
height: 0
};
}
for (x = 0; x < 6; x++) {
rightBoundry[x] = {
OffSet: 0,
topOffSet: 0,
width: 0,
height: 0
};
}
var x = 5;
function draw() {
drawCanvas(400, 0, carRaceTrack.width, carRaceTrack.height, 'black');
x++;
if (x > carRaceTrack.height) {
x = boundryTopOffSet;
}
//drawBoundryandCanvas(boundryLeftOffSet, x, boundryWidth, boundryHeight, 'white');
//drawBoundryandCanvas(boundryLeftOffSet, y, boundryWidth, boundryHeight, 'white');
for (i = 0; i < leftBoundry.length; i++) {
leftBoundry[i].OffSet = boundryLeftOffSet;
leftBoundry[i].width = boundryWidth;
leftBoundry[i].height = boundryHeight;
if (i == 0) {
leftBoundry[i].topOffSet = x;
} else {
leftBoundry[i].topOffSet = leftBoundry[i - 1].topOffSet + boundryHeight + boundryPadding;
}
if (leftBoundry[i].topOffSet > carRaceTrack.height) {
leftBoundry[i].topOffSet = boundryTopOffSet;
}
//console.log(boundry[i].topOffSet);
drawBoundry(leftBoundry[i], 'white');
}
for (i = 0; i < rightBoundry.length; i++) {
rightBoundry[i].OffSet = boundryLeftOffSet - 4 + 440;
rightBoundry[i].width = boundryWidth;
rightBoundry[i].height = boundryHeight;
if (i == 0) {
rightBoundry[i].topOffSet = x;
} else {
rightBoundry[i].topOffSet = rightBoundry[i - 1].topOffSet + boundryHeight + boundryPadding;
}
if (rightBoundry[i].topOffSet > carRaceTrack.height) {
rightBoundry[i].topOffSet = boundryTopOffSet;
}
//console.log(boundry[i].topOffSet);
drawBoundry(rightBoundry[i], 'white');
}
}
function drawBoundry(x, elementColor) {
carRaceTrackContext.fillStyle = elementColor;
carRaceTrackContext.fillRect(x.OffSet, x.topOffSet, x.width, x.height);
}
function drawCanvas(posX, posY, width, height, elementColor) {
carRaceTrackContext.fillStyle = elementColor;
carRaceTrackContext.fillRect(posX, posY, width, height);
}
This is the html part. Here i am creating canvas and using car_race.js file i am accessing canvas object.
<html>
<canvas id="carraceCanvas" width="850" height="550"></canvas>
<script type="text/javascript" src="car_race.js"></script>
</html>
答
需要双方(8,而不是6)更多的矩形,并允许顶一个具有负Y坐标,所以这是(部分)隐藏。
然后,当您将这些矩形向下移动时,检测您何时移动了一个这样的矩形的距离(加上填充):这意味着您已经可以返回到初始状态并重复。使用requestAnimationFrame
而不是setInterval
(毫秒数太小)。
这里是你的适应代码(我不能帮助解决拼写错误,使属性名称开始一个微不足道的):
var carRaceTrack = document.getElementById('carraceCanvas');
var carRaceTrackContext = carRaceTrack.getContext('2d');
var boundaryWidth = 10;
var boundaryHeight = 80;
var boundaryTopOffset = 5;
var boundaryLeftOffset = 2; // for snippet purpose I reduced this. Original = 402
var boundaryPadding = 8;
window.requestAnimationFrame(draw); // better use this for animations
var leftBoundary = [];
var rightBoundary = [];
for (x = 0; x < 8; x++) { // We need two more
leftBoundary[x] = {
offset: boundaryLeftOffset,
topOffset: 0,
width: boundaryWidth,
height: boundaryHeight
};
}
for (x = 0; x < 8; x++) {
rightBoundary[x] = {
offset: boundaryLeftOffset - 4 + 440,
topOffset: 0,
width: boundaryWidth,
height: boundaryHeight
};
}
var cycle = 0,
totalCycle = boundaryHeight + boundaryPadding;
function draw() {
drawCanvas(boundaryLeftOffset-2, 0, carRaceTrack.width, carRaceTrack.height, 'black');
// Use modulo operator for resetting to 0 when cycle is complete:
cycle = (cycle + 1) % totalCycle;
// Avoid code repetition: loop over the two boundary arrays:
for (boundary of [leftBoundary, rightBoundary]) {
for (i = 0; i < boundary.length; i++) {
// Note that we put the first one at a negative coordinate!
boundary[i].topOffset = cycle + (i-1) * totalCycle;
drawBoundary(boundary[i], 'white');
}
}
// Repeat
window.requestAnimationFrame(draw);
}
function drawBoundary(x, elementColor) {
carRaceTrackContext.fillStyle = elementColor;
carRaceTrackContext.fillRect(x.offset, x.topOffset, x.width, x.height);
}
function drawCanvas(posX, posY, width, height, elementColor) {
carRaceTrackContext.fillStyle = elementColor;
carRaceTrackContext.fillRect(posX, posY, width, height);
}
<canvas id="carraceCanvas" width="450" height="550"></canvas>
注意,我适应左偏移量,所以它更适合这个片段。
@Kaiido,最后一个确实很快就消失了。将数量从7增加到8来解决这个问题。我将离开'setInterval',因为OP对此毫无疑问。如果一个像素的移动速度如此之慢,那么使用'window.requestAnimationFrame()'并不能真正增加好处。 – trincot
啊是的,我完全忽略了小数。替换为'window.requestAnimationFrame()',这是更好的选择。感谢您强调这一点! – trincot
感谢帮助trincot –