Как сделать так, чтобы объект плавно менял направление? - PullRequest
1 голос
/ 18 июля 2010

У меня есть простая программа 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
    }
    }

Вот переменные, которые я объявляю:

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;

Куда это действительно движется:

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

Хорошо, вот мой новый код благодаря cape1232.Я фактически начал все сначала.Я получаю плавный поворот, но скорость движения блока меняется.Демо в: 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;

Ответы [ 2 ]

2 голосов
/ 18 июля 2010

Вы не хотите, чтобы ваши xDirection и yDirection были только 1 или -1.Они должны быть пропорциональны разнице между мышью и положением прямоугольника.

Отредактировано для учета комментариев.

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 голосов
/ 18 июля 2010

Вместо того, чтобы xDirection и yDirection (на самом деле синус и косинус вашего направления) были четко определены как 0, 1 или -1, вам нужно более точно определить направление, в котором вы должны в конечном счете, направляйтесь внутрь и вспомните, в каком направлении вы в последний раз двигались и сколько «угловых шагов» вы проделали, изменив направление с того, что должно было быть.

Сколько таких угловых шагов вы хотите предпринять для изменения направления, и должен ли каждый шаг быть одинакового размера или зависеть от того, насколько быстро вы двигаетесь и / или как резко вы поворачиваете,и т. д., это то, что вы должны адаптировать методом проб и ошибок, так как кажется, что вы в основном добиваетесь того, чтобы все «выглядело» правильно, поэтому трудно дать точное предписание (то, что вам кажется правильным ; -.)

...