简体   繁体   中英

Moving sprite image to selected position

Currently I'm working on a fish animation. My fish sprite is animated and able to move freely on the canvas. Secondly I wanted to add food to feed the fishes on the canvas. But currently I'm stuck and couldn't get the fishes to swim towards the food when it's draw on the canvas.

Here is how my fish sprite is moving randomly:

Fish.prototype.changeDirection = function () {
    var me = this;
    var speedXSign = Math.random() < 0.5 ? 1 : -1;
    var speedYSign = Math.random() < 0.5 ? 1 : -1;
    this.speedX = speedXSign * (1 + Math.random() * 1.6);
    this.speedY = speedYSign * (1 + Math.random() * 1.6);
    var time = 1000 + 2000*Math.random();
    setTimeout(function() {me.changeDirection()}, time);
};

Fish.prototype.move = function () {
    this.animIndex++;
    if ( this.animIndex == animFrames.length) this.animIndex = 0;

    this.xPos += this.speedX;
    if ((this.xPos + this.frameWidth * this.frameScale / 1.8) >= canvas.width && this.speedX > 0 || 
    (this.xPos - this.frameWidth * this.frameScale / 1.8) <= 0 && this.speedX <= 0) {
        this.speedX = -this.speedX;
    }

    this.yPos += this.speedY;
    if ((this.yPos + this.frameHeight * this.frameScale / 1.8) >= canvas.height && this.speedY > 0 || 
    (this.yPos - this.frameHeight * this.frameScale / 1.8) <= 0 && this.speedY <= 0) {
        this.speedY = -this.speedY;
    }
};

And now when I Onclick on the canvas, the food will appear and together with the X and Y Offsets.

function addFood(foodArray){
    var iiimage = new Image();
    iiimage.src = 'Images/redFood.png';
    for(var m = 0 ; m<foodArray.length;m++){
        var x = foodArray[m].x;
        var y = foodArray[m].y;
        context.drawImage(iiimage,x,y,50,50);
    }
}

function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
}

canvas.onmousedown = function(e){
    foodX = getMousePos(canvas,e).x;
    foodY = getMousePos(canvas,e).y;
    food = {x:foodX,y:foodY};
    foodArray.push(food);
    console.log('('+foodX+','+foodY+')');
    console.log(food);
    console.log(foodArray.length);
}

Is it possible to make the fish sprite change it's direction to the nearest food available and then back to it's random movement after the fish sprite has made contact with the food.

Here is my fiddle: http://jsfiddle.net/Bernard_9/bV4r6/

Here is my updated fiddle , and now I'll explain the changes I made.

  1. Add variables for the width and height of food:

     ... var foodArray = []; var foodWidth = 50; var foodHeight = 50; var food; ... 
  2. Update draw function to use those variables:

     function addFood(foodArray) { ... var x = foodArray[m].x; var y = foodArray[m].y; context.drawImage(iiimage, x, y, foodWidth, foodHeight); ... } 
  3. Add function to find the closest piece of food:

     Fish.prototype.closestFood = function () { var closestFoodIndex = -1; var shortestDistance = Infinity; for (var i = 0; i < foodArray.length; i++) { var distance = Math.max(Math.abs(this.xPos - foodArray[i].x), Math.abs(this.yPos - foodArray[i].y)); if (distance < shortestDistance) { shortestDistance = distance; closestFoodIndex = i; } } return closestFoodIndex; }; 
  4. Add function to change direction toward that 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); } }; 
  5. Add variable to keep track of when a fish is chasing food:

     function Fish(xPos, yPos, speedX, speedY, imgFish, frameWidth, frameHeight) { ... this.chasingFood = false; ... } 
  6. Add a function to eat any food that is under a fish:

     Fish.prototype.eatFood = function() { var foodX, foodY; var halfWidth = this.frameWidth * this.frameScale / 2; var halfHeight = this.frameHeight * this.frameScale / 2; // Loop backward because we are removing elements. for (var i = foodArray.length-1; i >= 0; i--) { foodX = foodArray[i].x + foodWidth / 2; foodY = foodArray[i].y + foodHeight / 2; if (foodX > this.xPos - halfWidth && foodX < this.xPos + halfWidth && foodY > this.yPos - halfHeight&& foodY < this.yPos + halfHeight) { foodArray.splice(i, 1); } } }; 
  7. Update the move function to eat food, look for food and chase it:

     Fish.prototype.move = function () { ... this.eatFood(); var closestFoodIndex = this.closestFood(); if (closestFoodIndex >= 0) { this.chasingFood = true; this.chaseFood(closestFoodIndex); } else { this.chaseingFood = false; } ... }; 
  8. Update the change direction function to only change direction when not chasing food:

     Fish.prototype.changeDirection = function () { var me = this; if (!this.chasingFood) { var speedXSign = Math.random() < 0.5 ? 1 : -1; var speedYSign = Math.random() < 0.5 ? 1 : -1; this.speedX = speedXSign * (1 + Math.random() * 1.6); this.speedY = speedYSign * (1 + Math.random() * 1.6); } var time = 1000 + 2000 * Math.random(); setTimeout(function () { me.changeDirection(); }, time); }; 

This will only make the fish change x and y direction, not speeds. The chaseFood function could be modified to make them speed up, or maybe go straight for the food (although that might make the animations look strange).

Leave a comment if you need more explanation on any of the new code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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