Reputation: 23
I have been trying to create a classic car race game using JavaScript and canvas.
This is the JavaScript part(car_race.js) i am able to create a track that is moving but it is not that much realistic as it should be. Write now what's happening is if one boundary bar gets completely disappeared then only it appears at the top of the canvas. what i want to do is when one boundary bar goes through the complete canvas from top to bottom i want it to resume back from top with the amount of body it gets disappeared from bottom part of canvas. Can anyone help me with this part.
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>
Upvotes: 0
Views: 1401
Reputation: 350202
You need more rectangles on both sides (8 instead of 6), and allow the top one to have a negative Y-coordinate, so that it is (partly) hidden.
Then when you shift those rectangles down, detect when you have moved the distance of one such rectangle (plus the padding): this means you can already return to the initial situation and repeat.
Instead of setInterval
(with a number of milliseconds that is too small anyway), use requestAnimationFrame
.
Here is your adapted code (I couldn't help to fix a spelling mistake, and make property names start with a minuscule):
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>
Note that I adapted the left offset, so it better fits in this snippet.
Upvotes: 2