用C语言开发NES游戏(CC65)10、游戏循环

粘贴到CSDN格式没调,想看格式好的点下面

https://happysoul.github.io/nes/nesdoug/

 

我们来谈谈游戏循环

游戏需要循环,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

 

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值