# 游戏循环(game loop)

您现在知道了如何显示精灵,但是如何使它们移动?这很简单:使用Pixi的ticker创建一个循环函数,这被称为游戏循环(game loop)。你放入游戏循环的任何代码,每秒都会被执行60次。例如下面的代码,执行都会使猫(cat)精灵以每帧1像素的速度向右移动。

function setup() {

  //Start the game loop by adding the `gameLoop` function to
  //Pixi's `ticker` and providing it with a `delta` argument.
  app.ticker.add(delta => gameLoop(delta));
}

function gameLoop(delta){

  //Move the cat 1 pixel 
  cat.x += 1;
}
1
2
3
4
5
6
7
8
9
10
11
12

运行这段代码,您将看到精灵逐渐移动到舞台的右侧。

那是因为每次gameLoop运行时,它都会向猫的x位置加1。

cat.x += 1;
1

加入到ticker的函数都,每秒被调用60次。ticker函数提供了一个参数delta,可这是啥?

delta值表示帧之间的延迟分量。您可以选择将它添加到猫的位置,使猫的动画独立于帧速率。

注意

此处翻译可能有误

注意,这里是译者的理解,未做验证

delta = (当前帧的时间 - 上一帧的时间) / (1000 / 60); 其中1000是指1000ms,即1秒, 60是1秒种执行60次。 (1000 / 60)就是每秒钟执行60次,帧与帧之前的平均时间间隔。

cat.x += 1 + delta;
1

您是否选择添加这个delta值在很大程度上是一个美学上的选择。这种效果只有在你的动画很难达到每秒60帧的显示速度时才会被注意到(这可能会发生,例如,如果它在一个很慢的设备上运行)。本教程中的其他示例不会使用这个delta值,但是如果您愿意,可以在自己的工作中使用它。

注意

译者对上段的理解,如果你的设备能够做到60帧/秒,帧与帧之间的间隔相差不大,就不用考虑delta。 若是你的设备运行较慢(代码计算量较大,也可能导致这种情况),不能满足60帧/秒,或者帧间隔相差较大,才会考虑delta,纠正显示效果。

除了用Pixi的ticker去创造一个游戏循环,你还可以使用requestAnimationFrame,就像这样:

function gameLoop() {

  //Call this `gameLoop` function on the next screen refresh
  //(which happens 60 times per second)
  requestAnimationFrame(gameLoop);

  //Move the cat
  cat.x += 1;
}

//Start the loop
gameLoop();
1
2
3
4
5
6
7
8
9
10
11
12

到底使用哪种方法,取决于你。

只需在循环内以较小的增量更改任何sprite属性,它们就会随着时间变化进行动画处理。 如果你想让精灵朝相反的方向移动(向左),只要给它一个负值,比如-1

您可以在movingSprites.html文件中找到此代码:

//Aliases
let Application = PIXI.Application,
    Container = PIXI.Container,
    loader = PIXI.loader,
    resources = PIXI.loader.resources,
    TextureCache = PIXI.utils.TextureCache,
    Sprite = PIXI.Sprite,
    Rectangle = PIXI.Rectangle;

//Create a Pixi Application
let app = new Application({ 
    width: 256, 
    height: 256,                       
    antialias: true, 
    transparent: false, 
    resolution: 1
  }
);

//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);

loader
  .add("images/cat.png")
  .load(setup);

//Define any variables that are used in more than one function
let cat;

function setup() {

  //Create the `cat` sprite 
  cat = new Sprite(resources["images/cat.png"].texture);
  cat.y = 96; 
  app.stage.addChild(cat);
 
  //Start the game loop 
  app.ticker.add(delta => gameLoop(delta));
}

function gameLoop(delta){

  //Move the cat 1 pixel 
  cat.x += 1;
  
  //Optionally use the `delta` value
  //cat.x += 1 + delta;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

(注意,cat变量需要在setupgameLoop函数外部定义,以便您可以在这两个函数内部访问它。

您可以为精灵的比例,旋转或大小设置动画。后面您会看到更多给精灵设置动画的示例。

# 使用速度属性

使用两个速度属性vxvy)来控制精灵的移动速度,会比上面更灵活。vx用于设置精灵在x轴上(水平)的速度和方向。 vy用于在y轴上(垂直)设置精灵的速度和方向。 无需直接更改精灵的x和y值,只需更新速度变量,然后给精灵设置这些速度值。

第一步是在sprite上创建vxvy属性,并给它们一个初始值。

vxvy设置为0表示精灵不移动。

接下来,在游戏循环中,更新精灵的移动速度vxvy。然后让精灵的xy属性增加vxvy。下面的代码表示的是,猫精灵每帧向下和右移动一个像素:

function setup() {

  //Create the `cat` sprite 
  cat = new Sprite(resources["images/cat.png"].texture);
  cat.y = 96; 
  cat.vx = 0;
  cat.vy = 0;
  app.stage.addChild(cat);
 
  //Start the game loop
  app.ticker.add(delta => gameLoop(delta));
}

function gameLoop(delta){

  //Update the cat's velocity
  cat.vx = 1;
  cat.vy = 1;

  //Apply the velocity values to the cat's 
  //position to make it move
  cat.x += cat.vx;
  cat.y += cat.vy;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

当您运行此代码时,猫将以每帧向下和向右移动一个像素:

如果要使猫向不同的方向移动怎么办? 要使猫向左移动,请将其vx值设为-1。 要使其向上移动,请将猫的vy值设为-1。 要使猫更快地移动,请为其设置更大的vxvy值,例如35-2-4

lastUpdate: 2/3/2023, 2:34:54 AM