canvas 左右的精灵无限循环

infinite loop of sprite left right in canvas

我正在尝试制作一个无限循环,以便在我儿子的 canvas 游戏中左右移动精灵。当精灵到达所需的 x 时,我将精灵的框架更改为左侧,但我不知道如何再次向左移动..我已经尝试了一个 bucle for,等等..没有结果。任何帮助都会非常感激。提前致谢

function loop(){         
     if (game.coin.x < 400){game.coin.row=1; game.coin.x++; }
     if (game.coin.x == 400){game.coin.row=3;game.coin.frames=1;}
     };   loop();

现在以这种方式工作


function myStartFunction() {
  myVar = setTimeout(function(){ game.azul.x+=1; }, 2000);
 if(game.azul.x > 200){myStopFunction();myStartFunctions(); };
}   
function myStartFunctions() {
  myVar = setTimeout(function(){ game.azul.x-=1; }, 2000);
 if(game.azul.x < 30){myStopFunction();};
}
function myStopFunction() {
  clearTimeout(myVar);
}
 myStartFunction(); 

这是一个非常简单的例子:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var speed = 1
var pos = {x: 100, y: 20}

function draw() {  
  ctx.beginPath()
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  ctx.arc(pos.x, pos.y, 10, 0, 10);
  ctx.fill();
  
  pos.x += speed
  if (pos.x > 200 || pos.x < 50)
    speed *= -1
}

setInterval(draw, 50);
<canvas id="canvas" width=500></canvas>

当我们的对象到达边界时:
if (pos.x > 200 || pos.x < 50)
我们只是"flip"速度speed *= -1


这里有一个稍微复杂一点的例子:

  • 使用 class 定义我们的对象
  • 两个对象分别画了一个红蓝圈
  • 点击canvas会停止蓝色,再次点击会重启

class Item {
  constructor(pos, speed, bounds, color) {
    this.pos = pos
    this.color = color;
    this.speed = speed;
    this.bounds = bounds
    this.stopped = false
  }

  draw() {
    this.update()
    ctx.beginPath()
    ctx.fillStyle = this.color;
    ctx.arc(this.pos.x, this.pos.y, 10, 0, 10);
    ctx.fill();
  }

  update() {
    if (!this.stopped) {
      this.pos.x += this.speed
      if (this.pos.x > this.bounds[0] || this.pos.x < this.bounds[1])
        this.speed *= -1
    }
  }
  
  stop() {
    this.stopped = !this.stopped
  }
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  azul.draw();
  rojo.draw();
}

function stop() {
  azul.stop();
}


var canvas = document.getElementById("canvas");
canvas.onclick = stop
var ctx = canvas.getContext("2d");

var azul = new Item({x: 100,  y: 20}, 1, [200, 50], "blue");
var rojo = new Item({x: 80,  y: 100}, 2, [180, 70], "red");


setInterval(draw, 50);
<canvas id="canvas" width=500></canvas>

            class Sprite {
              constructor(options) {
                this.context = options.context;
                this.src = options.src; // Path to image sprite sheet
                this.x = options.x; // Coordinates on canvas
                this.y = options.y;
                this.width = options.width; // Size of sprite frame
                this.height = options.height;
                this.frames = options.frames; // Number of frames in a row
                this.frameIndex = options.frameIndex; // Current frame
                this.row = options.row;
                this.ticksPerFrame = options.ticksPerFrame; // Speed of animation
                this.tickCount = options.tickCount; // How much time has passed
                this.visible= options.visible;
                this.daño= options.daño;

              }

              update() {
                this.tickCount += 1;
                if (this.tickCount > this.ticksPerFrame) {
                  this.tickCount = 0;
                  if (this.frameIndex < this.frames - 1) {
                    this.frameIndex += 1;
                  } else {
                    this.frameIndex = 0;
                  }
                }
              }

              render() {
                const image = new Image();
                image.src = this.src;
                this.context.drawImage(
                  image,
                  this.frameIndex * this.width, // The x-axis coordinate of the top left corner
                  this.row * this.height, // The y-axis coordinate of the top left corner
                  this.width, // The width of the sub-rectangle
                  this.height, // The height of the sub-rectangle
                  this.x, // The x coordinate
                  this.y,// The y coordinate
                  this.width, // The width to draw the image
                  this.height,
                  this.daño, 
                  this.frames // The width to draw the image
                );
              } 
            }
            class Coin extends Sprite {
              constructor(x, y, context) {
                super({
                  context: context,
                  src: 'images/mio.png',
                  x: x,
                  y: y,
                  width: 102,
                  height: 109,
                  frameIndex: 0,
                  row: 0,
                  tickCount: 0,
                  ticksPerFrame: 13,
                  frames: 2
                });
              }
            }

                const game = {
                  isRunning: true,

                  init() {

                    game.canvas = document.getElementById("gamecanvas");
                    game.context = game.canvas.getContext("2d");
                    this.azul = new Coin(5, 5, game.context);
                    var posicion;
                    // Start game
                    game.drawingLoop();
                  },

                  drawingLoop() {

                    // Clear canvas
                       game.context.clearRect(0, 0, game.canvas.width, game.canvas.height);
                    // Draw and update frame index
                      game.azul.src="https://www.pinclipart.com/picdir/middle/423-4236123_link-zelda-i-sprites-hd-clipart.png";
                      game.azul.render();
                      game.azul.update();


            var myVar;

            function myStartFunction() {game.azul.row=6;
              myVar = setTimeout(function(){game.azul.row=6;game.azul.frames=2; game.azul.x+=1; }, 2000);
             if(game.azul.x > 200){myStopFunction();myStartFunctions(); };
            } 
            function myStartFunctions() {game.azul.row=7;
              myVar = setTimeout(function(){ game.azul.row=7;game.azul.frames=2;game.azul.x-=1; }, 2000);
             if(game.azul.x < 30){myStopFunction();};
            }
            function myStopFunction() {
              clearTimeout(myVar);
            }
             myStartFunction(); 

            /*///*/
                    if (game.isRunning) {


                      requestAnimationFrame(game.drawingLoop);
                    }
                  },
                };



                window.addEventListener("load", () => {
                  game.init();
                });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="gamecanvas" width="600px" height="600px"></canvas>