2017-10-10 3 views
0

나는 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>

답변

2

당신은 양쪽 (대신 6 8)에 대한 자세한 사각형이 필요하고 (부분적으로) 숨겨진되도록, 상단 하나 Y 좌표 부정적인를 할 수 있습니다.

그런 직사각형을 아래로 이동하면 그러한 직사각형과 패딩의 거리를 이동할 때이를 감지합니다. 즉, 이미 초기 상황으로 돌아가서 반복 할 수 있습니다.

setInterval (밀리 초가 너무 작음) 대신 requestAnimationFrame을 사용하십시오.

다음

당신의 적응 코드 (I는 맞춤법 실수를 해결하는 데 도움이, 그리고 속성 이름은 소문자로 시작 만들 수 없습니다) : 나는 왼쪽 적응

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>

주 오프셋을 사용하면이 스 니펫에 더 잘 맞습니다.

+0

@Kaiido, 마지막 하나는 실제로 너무 빨리 사라졌습니다. 이 문제를 해결하기 위해 숫자를 7에서 8로 늘립니다. OP는 그것에 대해 의문의 여지가 없으므로'setInterval'을 그대로 두겠습니다. 느린 속도로 움직이는 한 픽셀로 window.requestAnimationFrame()을 사용하면 실제로 이점이 추가되지 않습니다. – trincot

+0

아, 저는 분수를 완전히 간과했습니다. 'window.requestAnimationFrame()'으로 대체되었으므로 더 나은 옵션입니다. 이것을 강조해 주셔서 감사합니다! – trincot

+0

도움말 trincot에 감사드립니다. –

관련 문제