当前位置:网站首页>用C语言开发NES游戏(CC65)10、游戏循环
用C语言开发NES游戏(CC65)10、游戏循环
2022-07-28 11:26:00 【firseve】
粘贴到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
现在把这个变成游戏已经很简单了,但是横向移动需要写很复杂的代码,我会把示例写的尽可能简单。
边栏推荐
- Unity encountered a pitfall and the AB package failed to unload
- The reflect mechanism obtains the attribute and method information of class
- LyScript 获取上一条与下一条指令
- 游戏流程与底层实现 逐步完成
- Image filter from the perspective of convolution
- 2022.07.06 summer training personal qualifying (I)
- 分布式定时器
- PHP date time application: add or subtract the number of days of a specific date
- 【Try to Hack】AT、SC、PS命令提权
- "Weilai Cup" 2022 Niuke summer multi school training camp 2
猜你喜欢

IDEA复制模块

Unity中使用UnityWebRequest进行网络和本地图片加载

Unity one key replacement of objects in the scene

LyScript 获取上一条与下一条指令

分布式定时器

Several ways to bind controls --butterknife/viewbinding/databinding

“蔚来杯“2022牛客暑期多校训练营2

ViewPager2+Fragment

Zhou Hongyi talks about Internet thinking: users, not customers

Interpretation of the paper: attention mechanism in medical images
随机推荐
瑞吉外卖——Day01
PHP获取本周所有日期或者最近七天所有日期
[diary of supplementary questions] [2022 Niuke summer multi school 2] l-link with level editor I
华为发布HarmonyOS 3及全场景新品,智慧体验更进一步
tolua之wrap文件的原理与使用
[geek challenge 2019] babysql-1 | SQL injection
[leetcode] 7. valid anagram · effective letter ectopic words
"Weilai Cup" 2022 Niuke summer multi school training camp 2
QT writing IOT management platform 42 data query export print
IDEA复制模块
Hcip day 6 (OSPF related knowledge)
What if the instruction set umi2 is missing? PTK installation cannot be carried out
Lua makes a deep copy of table
Laravel之缓存
Opencv notes sorting [Hough transform]
Lua 中 __index、__newindex、rawget、rawset的理解
Google Earth engine (GEE) -- problems in the use of coordinate projection and reduceresolution functions in image downscaling
2022.07.12 summer training personal qualifying (VII)
LyScript 获取上一条与下一条指令
The reflect mechanism obtains the attribute and method information of class