当前位置:网站首页>用C语言开发NES游戏(CC65)08、背景 碰撞
用C语言开发NES游戏(CC65)08、背景 碰撞
2022-07-28 11:26:00 【firseve】
背景和精灵有些区别,我们无法读取PPU中的字节。
我们先搞个地图,每个块大小是 16x16,填充整个背景需要 240字节的数组。X从0-15,Y从0-14。我们把数组放到RAM中,以防止被修改。
后面演示运行情况,先看下数组结构。
const unsigned char c2 [] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,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,1,0,0,0,0,0,0,1,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,0,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
};
1表示游戏中的块

要检测碰撞,你只需要将X和Y的低字节去掉,然后拼到一起,后面解释方法
X>>4 将X向右挪4位,Y & 0xF0 将Y的低4位变成0,用他和数组中的值逐个对比,1碰撞,0没有
我会检测精灵的4个方向,并在碰撞的时候修改U D L R 4个属性值(就是精灵的上下左右方向是否有碰撞)
我先进行X移动,检查是否碰撞,如果碰撞了则跳,再移动Y,检测是否碰撞,如果碰撞则跳过,也就是不执行移动的动作。具体看函数bg_collision()
这段代码应该精简,因为每一帧都会有XY的变动,我会修改代码实现变速。每帧1个像素太慢了,会造成很差的游戏体验。
我习惯使用 Tiled Map 制作游戏关卡,他使用非常简单,并且可以导出csv文件,这样可以方便制作C的数组。但是这个工具无法导入NES格式的.chr文件,所以我不得不重做所有类型的地图块。这很简单,我们只需要2个种,空白块和普通的地图块。
我先用NES Screen Tool制作图块,然后绘制2x2的块。看起来这样的做法有点蠢,但是当你的游戏里有几十种图块的时候,这样做起来就会很happy了
因为没有办法导出nametable的图片,所以我截图然后在GIMP编辑,另存为metatile.png
以tileset的方式导入 Tiled Map地图编辑器中。因为nes屏幕工具会使像素加倍,所以每个图片的尺寸都是32x32
(翻译备注:意思就是编辑器截图图像比较大,不是8x8的,而是32x32的,所以才会有上面这种情况)
编辑完关卡地图,导出csv文件。

SV文件转换为C数组是件小事儿,但是我还是做了个python3的脚本来实现。我将C数组导入我的代码,然后使用一个指针的数组指向前面的数组。
#include “CSV/c1.c”
#include “CSV/c2.c”
#include “CSV/c3.c”
#include “CSV/c4.c”
const unsigned char * const All_Collision_Maps[] = {c1,c2,c3,c4};
现在,我编写了一些代码,将一个2×2块的块打印到屏幕上,使用了一个大的循环,里面用了vram_put()方法。
使用vram_put()前需要先关闭屏幕,写入PPU是以从左到右,然后下一行开始从左到右。这样你可以很简单的就写完整个屏幕。
Start按键可以切换下一个地图显示
当你按右的时候,X的位置会+1,然后检测4个碰撞点,如果发生碰撞则会结束向右移动(X会-1)
(翻译备注:作者用 坐标变换后的点去检测碰撞,发生碰撞就退回变化,如果没有碰撞,精灵就会按照变化后的点移动--也就是重新绘制精灵新的位置)
测试:按方向撞墙,碰撞可以生效。按Start按钮,背景变化,碰撞依旧有效,因为RAM加载了一个新的地图碰撞检测。
注意:我使用屏幕滚动的方式将整个背景向下移动了1个像素。Y scroll=ff(-1),因为精灵总是会向下移动一个像素,所以必须将背景整体下移1个像素。
https://github.com/nesdoug/09_BG_Collide/blob/master/collide.c
https://github.com/nesdoug/09_BG_Collide
地图加载部分的代码写的不是很好,因为只能绘制一种贴图块,而且属性表不会修改,稍后我会介绍一个更好的加载方式(11、Metatiles),在此之前我先说一下滚动。
边栏推荐
- Detailed explanation of boost official website search engine project
- 本地化、低时延、绿色低碳:阿里云正式启用福州数据中心
- 数字经济时代的开源数据库创新 | 2022 开放原子全球开源峰会数据库分论坛圆满召开
- QT writing IOT management platform 42 data query export print
- [diary of supplementary questions] [2022 Niuke summer multi school 2] i-let fat tension
- 2022.07.11 summer training personal qualifying (VI)
- 2022.07.07 summer training personal qualifying (II)
- Distributed system (III) construction of distributed transaction service
- 产学研用 共建开源人才生态 | 2022 开放原子全球开源峰会教育分论坛圆满召开
- Lua对table进行深拷贝
猜你喜欢

Develop your own NPM package from 0

Matlab sets the size of graphics window and image and the position of legend

Gecko competition 2.0 is new! Come and show your flexible operation skills!

Lua对table进行深拷贝

The principle and use of the wrap file of tolua

The game process and the underlying implementation are gradually completed

REST风格

顶级“Redis笔记”,缓存雪崩+击穿+穿透+集群+分布式锁,NB了

14. User web layer services (II)

Laravel form data validation
随机推荐
Interpretable ml of Li Hongyi's machine learning model
Lua makes a deep copy of table
QT writing IOT management platform 42 data query export print
2022.07.12 summer training personal qualifying (VII)
用C语言开发NES游戏(CC65)07、控制器
Untiy controls the playback speed of animation
[diary of supplementary questions] [2022 Niuke summer school 2] h-take the elevator
金九银十 再不卷就来不及了
Several ways to bind controls --butterknife/viewbinding/databinding
Live: never believe that suffering is worth it. Suffering is suffering
Laravel之缓存
Image filter from the perspective of convolution
Alexnet - paper analysis and reproduction
Unity 一键替换场景中的物体
配置Jupyter远程服务器
China business CDP white paper | love Analysis Report
Use Baidu PaddlePaddle easydl to complete garbage classification
用C语言开发NES游戏(CC65)09、滚动
PHP gets all the dates of this week or the last seven days
Hcip (condition matching and OSPF packet related knowledge)