简体   繁体   English

使精灵运动向对象移动时使其平滑

[英]Making sprite movement smooth when it's move towards an object

I'm working on a fish sprite animation. 我正在制作鱼精灵动画。 Currently when I add a piece of food then the sprite animation will move forward to eat it. 目前,当我添加食物时,子画面动画将向前移动以食用它。 But I am not able to make it swim smoothly toward the food. 但是我无法使其顺着食物游动。 Sometimes the sprite animation will move up and down till it reach the food. 有时,精灵动画会上下移动,直到到达食物为止。

Here is how the sprite animation is moving towards the food: 这是精灵动画向食物移动的方式:

Fish.prototype.chaseFood = function(index) {
    if (this.xPos > foodArray[index].x + foodWidth) {
        this.speedX = -1 * Math.abs(this.speedX);
    } else if (this.xPos < foodArray[index].x) {
        this.speedX = Math.abs(this.speedX);
    }
    if (this.yPos > foodArray[index].y + foodHeight) {
        this.speedY = -1 * Math.abs(this.speedY);
    } else if (this.yPos < foodArray[index].y) {
        this.speedY = Math.abs(this.speedY);
    }
};

Is there anyway to make it swim more smoothly towards the food and not moving up and down towards it. 无论如何,有没有使它朝着食物更顺畅地游动而不朝着食物上下移动的方法。

I'd calculate angle between the fish and the food and make the fish move towards that angle. 我会计算出鱼和食物之间的角度,并使鱼向该角度移动。

Here are some helper functions to get you going: 以下是一些帮助功能,可助您一臂之力:

function distanceBetweenPoints(a, b)
{
    return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}

function angleBetweenPoints(a, b)
{
    return Math.atan2(b.y-a.y,b.x-a.x)*180/Math.PI;
}

Usage: 用法:

var angle = angleBetweenPoints({ x: fish.x, y: fish.y }, { x: food.x, y: food.y });

Then you can do something like: 然后,您可以执行以下操作:

fish.x += Math.sin(angle * Math.PI / 180) * 10;
fish.y += Math.cos(angle * Math.PI / 180) * 10;

I think you want your sprite to move in a direct line from one set of coordinates (it's location) to another set of coordinates (the food's location). 我想您想让精灵沿一条直线从一组坐标(它的位置)移动到另一组坐标(食物的位置)。
http://coolmath.com/algebra/08-lines/06-finding-slope-line-given-two-points-01.htm

So if your if your x coordinates are a difference of 6 pixels and your y coordinates are a difference of 4, we want to keep the ratio of 6 to 4 when we increase our x and y offset for our happy little fish. 因此,如果您的x坐标相差6个像素,而您的y坐标相差4,则当我们增加快乐小鱼的x和y偏移量时,我们希望保持6与4的比率。

In this case, we could change the program to move x by 1 pixel at a time and then move y by 4/6 pixel at a time and thus go on a path straight towards the goal. 在这种情况下,我们可以将程序更改为一次将x移动1个像素,然后一次将y移动4/6像素,从而沿着直接朝向目标的道路前进。 If we were to increase the y by a full pixel, it would arrive directly below the target and then go straight up. 如果我们将y增加一个完整像素,它将直接到达目标下方,然后直线上升。 This would be an indirect path and less realistic looking. 这将是一条间接的路径,而且看起来不太现实。

Actually I think it would arrive to the left of the goal and then go directly right in the old version if you use the 1 to 1 ratio, but I think you knew what I meant. 实际上,如果您使用1:1的比例,它会到达目标的左侧,然后直接在旧版本中向右移动,但是我想您知道我的意思。

I'll try to adapt an example I have to your code: 我将尝试为您的代码改编一个示例:

int fishSpeed = 2;
float xOffset = fishSpeed;
float yOffset = fishSpeed;
float xDis = abs(this.xPos-(foodArray[index].x + foodWidth));
float yDis = abs(this.yPos-(foodArray[index].y + foodWidth));
//each offset changes depending on how far it is from goal
xOffset = xOffset * (xDis / (xDis + yDis));
yOffset = yOffset * (yDis / (xDis + yDis));

if(this.xPos > foodArray[index].x) this.xPos+=xOffset;
if(this.yPos > foodArray[index].y) this.yPos+=yOffset;
if(this.xPos < foodArray[index].x) this.xPos-=xOffset;
if(this.yPos < foodArray[index].y) this.yPos-=yOffset;

Sorry I couldn't make it work using your example. 抱歉,使用您的示例无法正常工作。 I don't know if it will help, but here is a complete .htm file that has a bunny wabbit that is controlled by the mouse and one that is chased directly by another wabbit. 我不知道它是否会有所帮助,但这是一个完整的.htm文件,其中包含由鼠标控制的兔子wabbit和由另一个wabbit直接追赶的兔子wabbit。 The wabbit will go directly for its goal. 兔子将直接实现其目标。 The file needs processing.js in the same directory. 该文件需要在同一目录中的processing.js。

<!DOCTYPE html>
<html>
<body bgcolor="lightblue"   style="margin:0;">
<center>
<script src="processing.js"></script>
<script type="application/processing">

void setup(){
    size(screen.width*.9,screen.height*.9);
    blueWabbit = new wabbit(600,600,105);
    pinkWabbit = new wabbit(100,100,100);
    blueWabbit.blue = 255;
    blueWabbit.red = 128;
    blueWabbit.green = 128;

    wabbitSpeed = 5;
    }

void draw() { 

    float xOffset = wabbitSpeed;
    float yOffset = wabbitSpeed;
    float xDis = abs(pinkWabbit.xpos-blueWabbit.xpos);
    float yDis = abs(pinkWabbit.ypos-blueWabbit.ypos);
    xOffset = xOffset * (xDis / (xDis + yDis));
    yOffset = yOffset * (yDis / (xDis + yDis));

    if(pinkWabbit.xpos > blueWabbit.xpos) blueWabbit.xpos+=xOffset;
    if(pinkWabbit.ypos > blueWabbit.ypos) blueWabbit.ypos+=yOffset;
    if(pinkWabbit.xpos < blueWabbit.xpos) blueWabbit.xpos-=xOffset;
    if(pinkWabbit.ypos < blueWabbit.ypos) blueWabbit.ypos-=yOffset;

    if (xDis+yDis<wabbitSpeed){
        for(int a =0;a<20; a++)babyWabbit();
    }
    else background(0,0,0,0);

    pinkWabbit.show();
    blueWabbit.show();
    pinkWabbit.xpos = mouseX;
    pinkWabbit.ypos = mouseY;


    /*
    fill(0);
    text("blue x = "+(int)blueWabbit.xpos,10,10);
    text("blue y = "+(int)blueWabbit.ypos,10,20);
    text("pink x = "+pinkWabbit.xpos,10,30);
    text("pink y = "+pinkWabbit.ypos,10,40);
    text("xOffset = "+xOffset,10,50);
    text("yOffset = "+yOffset,10,60);
    text("xDis = "+(int)xDis,10,70);
    text("yDis = "+(int)yDis,10,80);
    */
    } 


class wabbit { 
    //declare the properties that will be used as variables for the object
    float xpos, ypos, diameter; 
    int red, blue, green;
    //define the parameters for the creation of a new class
    wabbit (float x, float y, float wSize) {  
        xpos = x;
        ypos = y; 
        diameter = wSize;
        //radius = .5 * diameter;
        //make it pink if user did not define colors
        if (!(0>red>256)) red = 255;
        if (!(0>green>256))green = 200;
        if (!(0>blue>256)) blue = 200;
        } 
  void show() { 
    noStroke();
    for(a = diameter; a > 0; a-=5){
        fill(red-a,green-a,blue-a);
        //belly and head
        ellipse(xpos, ypos, a, a); 
        ellipse(xpos, ypos-diameter*.7, a*.7,a*.7);
        //feets
        ellipse(xpos-.2*diameter, ypos+diameter*.4, a*.4,a*.4);
        ellipse(xpos+.2*diameter, ypos+diameter*.4, a*.4,a*.4);
        //ears
        ellipse(xpos-.2*diameter, ypos-diameter, a*.2,a*.8);
        ellipse(xpos+.2*diameter, ypos-diameter, a*.2,a*.8);
        }
  } 
}

void babyWabbit(){
 noStroke();
var red=random(1,255);
var green=random(1,255);
var blue=random(1,255);
var xpos=random(1,width);
var ypos=random(1,height);
var diameter = random(20,80);
    for(var a = diameter; a > 0; a-=5){
        fill(red-a,green-a,blue-a);
        //belly and head
        ellipse(xpos, ypos, a, a); 
        ellipse(xpos, ypos-diameter*.7, a*.7,a*.7);
        //feets
        ellipse(xpos-.2*diameter, ypos+diameter*.4, a*.4,a*.4);
        ellipse(xpos+.2*diameter, ypos+diameter*.4, a*.4,a*.4);
        //ears
        ellipse(xpos-.2*diameter, ypos-diameter, a*.2,a*.8);
        ellipse(xpos+.2*diameter, ypos-diameter, a*.2,a*.8);
        }
}

</script><canvas></canvas> 
</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM