10、游戏循环

我们来谈谈游戏循环

游戏需要循环,while(1){}

循环里的第一项是ppu_wait_nmi(),他会等待新一帧的开始触发nmi,每秒60帧(欧版是50帧)

但是,如果游戏的逻辑太过复杂将会耗费更多的时间,并且超过了nmi触发的开始,那么等到了ppu_wait_nmi()之后,他会等待下一帧,这样会让游戏变得很慢。

好在现在还没发生过这种情况,因为我们的代码太短了,但是后面做的游戏中就不那么简单了,所以还是要注意代码的简洁。

控制器使用了

pad_poll(0)

get_pad_new(0)

然后要说的是clear_vram_buffer(),这些代码对我来说是对一无二的。由于nmi的作用,我们需要重写他,以便让他能实现更多功能

score_lives_draw() 使用one_vram_buffer() 重新显示屏幕顶端的计分板。

这些类似vram_put(),但他们将被放在缓冲区中,并且nmi代码将在v-blank期间自动将它们推送到ppu。

然后是游戏的逻辑,移动球拍,移动球,检查是否有碰撞。

移动手柄

if(pad1 & PAD_LEFT){

Paddle.X -= 2;

if(Paddle.X < PADDLE_MIN) Paddle.X = PADDLE_MIN;

}

if(pad1 & PAD_RIGHT){

Paddle.X += 2;

if(Paddle.X > PADDLE_MAX) Paddle.X = PADDLE_MAX;

}

移动球,如果他是移动的

if(ball_direction == GOING_UP){

Ball.Y -= 3;

if(Ball.Y < MAX_UP){

ball_direction = GOING_DOWN;

}

}

else { // going down

Ball.Y += 3;

if(Ball.Y > MAX_DOWN){

--lives01;

ball_state = BALL_OFF;

}

}

然后到了绘制精灵,首先先要清除旧的,然后重新绘制所有活动的精灵。

如果一个块被球命中,hit_block(),从碰撞图中删除这个块,用一个空白块填充这个区域。

同样,我使用vram缓冲区暂时存储它,并在v-blank期间自动将其发送到PPU。

通常情况下,我会使用很多个

game_states:比如标题,游戏,暂停,结束。

我使用不同的 ball_states:飞出屏幕BALL_OFF,准备发射球BALL_STUCK (卡在平板边缘),球在移动BALL_ACTIVE

我使用NES Screen Tool制作背景,在c1.csv中定义了可以破坏的图块。我没用Tiled工具,因为他显示容易,但是如果有修改对应的可破坏的图块布局也需要跟着修改(也就是前面的c1.csv)

const unsigned char c1 [] = {

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

};

使用灰色的砖块在NES Screen Tool中画图,然后压缩导出RLE文件。

我在NES Screen Tool中预先更改了属性表,然后保存背景。这就是瓷砖的颜色,它们是不同的调色板。但他们都使用相同的瓷砖。这是属性检查器视图(按“A”)。

每帧都会更新记分牌,请注意我将得分的每个数字都保存为单独的变量(等级为0-9)

score10是10位数,score01是个位数。由于6502处理器缺少内置数学运算,因此除法和模数对NES的操作非常慢,因此保持每个数字分开可加快代码速度。

https://github.com/nesdoug/12_Break

现在把这个变成游戏已经很简单了,但是横向移动需要写很复杂的代码,我会把示例写的尽可能简单。