2010-07-18 2 views
1

캔버스에 작은 사각형을 표시하는 간단한 Javascript 프로그램이 있습니다. 사각형이 마우스 위치쪽으로 이동합니다. 그것이 방향을 바꿀 때, 그것은 날카로운 모서리를 가지고 그렇게한다. 마찬가지로, 직사각형 뒤에 선이 남아있는 경우 마우스를 원으로 움직이면 직사각형이 기울어 진 정사각형을 그립니다.개체의 방향을 부드럽게 변경하려면 어떻게해야합니까?

내가 원하는 것은 원을 그리는 것입니다. 날카로운 모서리가 없습니다.

function changeDir() 
{ 
if(mouseXCoord-5<x && x<mouseXCoord+5) 
{ 
    xDirection = 0;//stop moving if close to mouse 
} 
else if(x>mouseXCoord) 
{ 
    xDirection = -1; 
} 
else if(x<mouseXCoord) 
{ 
    xDirection = 1; 
} 

if(mouseYCoord-5<y && y<mouseYCoord+5) 
{ 
    yDirection = 0;//stop moving if close to mouse 
} 
else if(y>mouseYCoord) 
{ 
    yDirection = -1; 
} 
else if(y<mouseYCoord) 
{ 
    yDirection = 1; 
} 
} 

추첨 기능 : : 그래서

function draw() 
{ 
    context2D.clearRect(0, 0, canvas.width, canvas.height); 
    fillwith = context2D.fillStyle='red'; 
    context2D.fillRect(x,y,10,10); 
    changeDir(); 
    x = x + (thrust * xDirection); 
    y = y + (thrust * yDirection); 
    console.log(x,y,xDirection, yDirection,mouseXCoord,mouseYCoord); 
} 

, 내가 그걸 어떻게해야합니까

여기에서 방향을 변경 내가 사용하고있는 코드는?

업데이트 : 기울임 사각형의 모서리가 둥글게되도록 changeDir() 함수를 변경했습니다.

function changeDir() 
{ 
    if(mouseXCoord-5<x && x<mouseXCoord+5) 
    { 
     xstop = true;//stop moving if close to mouse 
    } 
    else if(x>mouseXCoord) 
    { 
     if(Math.abs(xthrust)==mainThrust) 
     { 
      xthrust = -1*mainThrust; 
     } 
     else 
     { 
      xthrust--; 
     } 
     xstop = false;//make sure it moves 
    } 
    else if(x<mouseXCoord) 
    { 
     if(xthrust==mainThrust) 
     { 
      xthrust = mainThrust; 
     } 
     else 
     { 
      xthrust++; 
     } 
     xstop = false;//make sure it moves 
    } 

    if(mouseYCoord-5<y && y<mouseYCoord+5) 
    { 
     ystop = true;//stop moving if close to mouse 
    } 
    else if(y>mouseYCoord) 
    { 
     if(Math.abs(ythrust)==mainThrust) 
     { 
      ythrust = -1*mainThrust; 
     } 
     else 
     { 
      ythrust--; 
     } 
     ystop = false;//make sure it moves 
    } 
    else if(y<mouseYCoord) 
    { 
     if(ythrust==mainThrust) 
     { 
      ythrust = mainThrust; 
     } 
     else 
     { 
      ythrust++; 
     } 
     ystop = false;//make sure it moves 
    } 
    } 

다음은 변수 I 선언입니다 :

const FPS = 5; 
var x = 300; 
var y = 200; 
var xDirection = 1; 
var yDirection = 1; 
var image = new Image(); 
var canvas = null; 
var context2D = null; 
var mouseXCoord = 0; 
var mouseYCoord = 0; 
var mainThrust = 5; 
var xthrust = mainThrust; 
var ythrust = mainThrust; 
var xstop = false; 
var ystop = false; 

는 actualy 이동 장소 :

changeDir(); 
if(!xstop) 
x = x + (xthrust); 
if(!ystop) 
y = y + (ythrust); 

좋아, 여기 cape1232 내 새로운 코드 덕분입니다. 나는 사실 전적으로 시작했다. 나는 부드럽게 선회하지만 블록의 속도는 변화에 따라 움직입니다. 에서 데모 : 당신은 당신의 x 방향과 y 방향을 원하지 않는 http://develzone.davidreagan.net/jsMoveTesting/index.html

var gameVars = { 
    fps: 30 
} 

var object = { 
    name: 'default', 
    xpos: 200, 
    ypos: 200, 
    xVect: 1, 
    yVect: 1, 
    thrust: 15 
} 
ctx = null; 
canvas = null; 
xMousePos = 0; 
yMousePos = 0; 
runGame = null; 


function init() 
{ 
    canvas = document.getElementById('canvas'); 
    ctx = canvas.getContext('2d'); 
    $('#canvas').mousemove(getMousePos); 
    $('#canvas').click(stop); 

    //setTimeout('clearInterval(runGame);',30000); 
} 
function start() 
{ 
    runGame = setInterval('run();',1000/gameVars.fps); 
} 
function run() 
{ 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    moveBlock(); 
    //ctx.translate(object.xpos,object.ypos); 
    drawBlock(); 
    showMousePos = 'X: ' + xMousePos + ' Y: ' + yMousePos; 
    ctx.fillText(showMousePos, 215,50); 
} 
function stop() 
{ 
    //alert('hit stop'); 
    console.log('clicked'); 
    //if(e.keyCode == 113) 
    if(runGame) 
    { 
     clearInterval(runGame); 
     runGame = false; 
     //console.log('stop true'); 
    } 
    else 
     start(); 
} 
function drawBlock() 
{ 
    ctx.fillRect(object.xpos,object.ypos,10,10); 
} 

function moveBlock() 
{ 

    xDiff = xMousePos - object.xpos; 
    yDiff = yMousePos - object.ypos; 
    minDiff = Math.max(Math.min(xDiff, yDiff), 1); 
    deltaX = xDiff/minDiff; 
    deltaY = yDiff/minDiff; 
    // Scale the deltas to limit the largest to mainThrust 
    maxDelta = Math.max(Math.max(deltaX, deltaY), 1) 
    if (maxDelta>object.thrust) 
    { 
     deltaX = deltaX * object.thrust/maxDelta; 
     deltaY = deltaY * object.thrust/maxDelta; 
    } 


    if(object.xpos >= canvas.width) 
    { 
     object.xpos = 0;   
    } 
    else 
    { 
     object.xpos += deltaX; 
     //console.log('moveBlock xpos else: '+object.xpos); 
    } 
    if(object.ypos >= canvas.height) 
    { 
     object.ypos = 0; 
    } 
    else 
    { 
     object.ypos += deltaY; 
     //console.log('moveBlock ypos else: '+object.ypos); 
    } 
    console.log('xpos: '+object.xpos); 
    console.log('ypos: '+object.ypos); 
    console.log('xMousePos: '+xMousePos); 
    console.log('yMousePos: '+yMousePos); 
    console.log('xDiff: '+xDiff); 
    console.log('yDiff: '+yDiff); 
    console.log('minDiff: '+minDiff); 
    console.log('deltaX: '+xDiff+'/'+minDiff+ ' = '+ deltaX); 
    console.log('deltaY: '+yDiff+'/'+minDiff+ ' = '+ deltaY); 
    console.log('maxDelta: '+maxDelta); 
} 

function getMousePos(e) 
{ 
    xMousePos = e.pageX; 
    yMousePos = e.pageY; 
    //console.log('Mouse Moved'); 
} 
window.onload = init; 
+0

현재 글로벌 변수를 사용하고 있지 않습니까? 공유 변수 (예 : xDirection, yDirection)는 클래스 멤버 변수입니다. 맞습니까? – cape1232

+0

예, 전역 변수를 사용하고 있습니다. 나는 물건을 알아 내고 있기 때문에, 가장 쉬운 일과 함께 가고 있습니다. –

+0

내 게시물에서 이전 코드를 삭제해야합니까? 이 사이트에서 괜찮습니까? –

답변

2

가되게합니다에만 1 또는 -1. 마우스와 사각형 위치의 차이에 비례해야합니다.

의견을 고려하여 수정되었습니다. 당신이 결국 해야 급격히 0, 1, -1로 정의 (실제로는 사인과 방향 코사인) 대신 xDirectionyDirection을 갖는

function changeDir() 
{ 
    xDiff = mouseXCoord - x; 
    yDiff = mouseYCoord - y; 
    // Scale the smallest diff to be 1 (or less) 
    minDiff = max(min(xDiff, yDiff), 1); 
    deltaX = xDiff/minDiff; 
    deltaY = yDiff/minDiff; 
    // Scale the deltas to limit the largest to mainThrust 
    maxDelta = max(max(deltaX, deltaY), 1) 
    if (maxDelta>mainThrust) 
    { 
    deltaX = deltaX * mainThrust/maxDelta; 
    deltaY = deltaY * mainThrust/maxDelta; 
    } 

    if(mouseXCoord-5<x && x<mouseXCoord+5) 
    { 
    xDirection = 0;//stop moving if close to mouse 
    } 
    else 
    { 
    xDirection = deltaX; 
    } 

    if(mouseYCoord-5<y && y<mouseYCoord+5) 
    { 
    yDirection = 0;//stop moving if close to mouse 
    } 
    else 
    { 
    yDirection = deltaY; 
    } 
} 
+0

@Alex Martelli. 현재 방향을 너무 갑자기 변경하지 않는 것이 중요합니다.내 솔루션에서, 마우스를 충분히 자주 추적하지 않으면, 마우스가 "여기"를 넘어서고 갑자기 "거기"를 넘어 서던 방식으로 갑작스러운 방향 변경이 발생합니다. 항상 이동하려고하기 때문에 마우스를 똑바로. 나는 그것을 밖으로 부드럽게하는 해킹을 생각할 수 있지만 (예 : 현재 방향과 새 방향의 가중치 합계 사용) 실제 해결책은 내가 전문가가 아닌 제어 이론 문제입니다. 나는 PID 컨트롤러가 작동한다고 생각하지만, 나는 단지 짐작하고있다. – cape1232

+0

PID 컨트롤러는 다음과 같이 보입니다. http://en.wikipedia.org/wiki/PID_controller – cape1232

+0

시도해보십시오. 직사각형이 캔버스에서 튕겨 나와 내 마우스 위치를 완전히 무시했습니다. 자바 스크립트에서 수레를 선언 할 수 없습니다. 그래서 나는 그 부분을 꺼내야 만했다. –

0

, 당신은 더 정확하게 방향을 정의해야 당신이 마지막으로 어떤 방향으로 나아 갔는지, 그리고 무엇이되어야하는지에 이르기까지 당신이 방향을 바꾸는 데 얼마나 많은 "각 단계"를했는지를 떠올려보십시오.

방향을 바꾸기 위해 걸리는 각 각도 스텝 수와 각 스텝이 같은 크기 여야하는지, 얼마나 빨리 움직이는 지 및/또는 얼마나 잔인하게 움직이는 지에 따라 달라지는 각도 스텝 수는 무엇입니까? 당신이 가장 많이 겪고있는 일은 "모양"이 올바른 것 같아 정확한 처방을 내리기가 어렵 기 때문에 시행 착오로 적응해야 할 대상입니다. ( ;-)로 바뀌 었습니다.

+0

나는 그런 것을 시도했다. 업데이트 된 코드를 참조하십시오. –

관련 문제