Professional Documents
Culture Documents
逆行模拟器配套说明书(局部替换)
逆行模拟器配套说明书(局部替换)
I.游戏主体的实现--------------------------------------------------------------02
A.如何设计数组------------------------------------------------------02
B.如何生成实体------------------------------------------------------02
1)对向小车:move_raceDowntrN----------------------02
2)对向油包:move_fuelDown---------------------------03
C.如何实现对向实体下落-----------------------------------------04
1)对向小车:move_raceDowntrN----------------------04
2)对向油包:move_fuelDown---------------------------04
3)道路标线:relativity_theory--------------------------05
D.如何判断碰撞------------------------------------------------------05
1)对向实体下落导致 collision----------------------------05
2)小车移动导致 collision----------------------------------06
E.如何使小车移动---------------------------------------------------06
1)左右移动:move_carR/L----------------------------------06
2)前后移动:move_carF/B----------------------------------08
F.如何清除实体-------------------------------------------------------09
G.如何重置数据------------------------------------------------------10
II.显示部分(局部更新)的实现------------------------------------------10
III.BGM 与音效的实现---------------------------------------------------------11
A.如何将资源挂载在资源文件中-------------------------------11
B.PlaySound 的播放与停止---------------------------------------13
C.mciSendString 的部署与播放----------------------------------13
IV.其他代码与问题解决--------------------------------------------------------13
A.如何使用 rand 函数------------------------------------------------------13
1
I.游戏主体的实现(配合数组规划表)
此赛车游戏分为设计数组、生成实体、对向实体下落、判断碰撞、实体变道、清除实体与
重置数据。
所有操作都针对数组来进行,最终将数组内容按排版打印出来作为画面。
A.如何设计数组
B.如何生成实体
1)对向小车:move_raceDowntrN
对向小车利用 rowN 记录操作行,passN 记录经过行,sideN 记录各行车
数量(方便判定总数,但每条车道最多一辆车)。
生成前
a)在主函数中判断确定 sideN 总和小于最高生成车数量,再使用 rand
函数确定本次生成小车的赛道 pick_side。
b)判断确定新生成的小车不会造成如下图的围困(数组规划表中
sheet1 围困),造成则离开生成。
2
生成
判定 sideN==1 调用 move_raceDowntrN 函数,函数会在对应操作位置{ [rowN]
[4*N-3], [rowN][4*N-1], [rowN+1][4*N-2], [rowN+2][4*N-3], [rowN+2][4*N-1]
}(如下图)
3
2)对向油包:move_fuelDown
油包利用 fuel_side 记录油包赛道,fuel_set 记录是否生成了油包,
row_fuel 记录油包操作行,fuel_bak 记录上一次吃到油包时的行驶距离。
生成前
a)在主函数中判断确定 fuel_set=0,即没有生成油包,再跟据行驶距离
count 减上次吃到油包时的行驶距离 fuel_bak 得出中间经过路程,路程大于
难度乘 7.5 保证高难度时少生成油包,再使用 rand 函数确定本次生成油包的
赛道 fuel_side。
b)判断确定新生成的油包不与对向小车重叠。
c)设定 fuel_set=1,row_fuel=0
生成
判定 sideN==1 调用 move_raceDowntrN 函数,函数会在对应操作位置
[row_fuel][fuel_side*4+2]处放置‘ ’并使得操作行 row_fuel++,在新的对应操
作位置放置‘F'。
C.如何实现对向实体下落
1)对向小车:move_raceDowntrN
对向小车利用 rowN 记录操作行,passN 记录经过行,sideN 记录各行车
数量(方便判定总数,但每条车道最多一辆车)。
判定 sideN==1 调用 move_raceDowntrN 函数,函数会在对应操作位置{ [rowN]
[4*N-3], [rowN][4*N-1], [rowN+1][4*N-2], [rowN+2][4*N-3], [rowN+2][4*N-1]
}使用’ ’替换’I’(如下图)
使得操作行 rowN++,在新的对应操作位置放置‘I'。
4
2)对向油包:move_fuelDown
油包利用 fuel_side 记录油包赛道,fuel_set 记录是否生成了油包,
row_fuel 记录油包操作行。
判定 sideN==1 调用 move_raceDowntrN 函数,函数会在对应操作位置
[row_fuel][fuel_side*4+2]处放置‘ ’将上一个‘F’抹掉并使得操作行
row_fuel++,在新的对应操作位置放置‘F'。
3)道路标线:relativity_theory
道路标线利用 steps 记录总行进步数。
道路标线在下落中共有 3 种状态,分别标号为 0,1,2。见下图可以看出 0 时 0
为空格其他为|,利用%对 steps 和 row 取余,按照规律分别赋值空格与|。
D.如何判断碰撞
1)对向实体下落导致 collision
先根据小车前进量 car_pos 确定车前位置的坐标[ROW-5-car_pos][4*N-3]
(如图所示红色方框为车前位置)
5
如果车前位置为 I,即有对向来车,则判断碰撞发生,collision =
true。
判断获得加油包与碰撞类似,先获取车中间 0 的操作坐标,再在油包下
落时判断油包是否会将改‘0’覆写,是则获得油包并重置油包状态。
2)小车移动导致 collision
代码已规定在左右有车时不可变动赛道,具体参见 1)左右移动:move_carL/R
,所以小车移动导致 collision 只考虑前后移动情况。
先根据小车前进量 car_pos 确定车位置的坐标[ROW-4-car_pos][4*N-3](左
前轮,见上图)与[ROW-2-car_pos][4*N-3](左后轮,见上图)。
在可前进时判断[ROW-5-car_pos][4*N-3](左前轮上方,见上图)是不
是‘I’,是则判定碰撞。
在可后退时判断[ROW-1-car_pos][4*N-3](左后轮下方,见上图)是不
是‘I’,是则判定碰撞。
判断获得加油包与碰撞类似,先获取车中间 0 的操作坐标,再在前进后
退与左右移动时判断新的操作坐标是否会将‘F’覆写,是则获得油包并重置
油包状态。
E.如何使小车移动
1)左右移动:move_carR/L
小车前进量用 car_pos 储存,最开始时前进量为 0 如下图。
6
移动前
如需要向右变动赛道先判定右侧无车,即下图中红色区域不存在‘I’。
向左移动同理。图中红色区域坐标为 [ROW - 5 - car_pos][10]到[ROW - 1 -
car_pos][10]。
7
如果在中间的‘0’右方第四格有‘F’,则获得加油包并重置加油包状
态。
8
2)前后移动:move_carF/B
小车前进量用 car_pos 储存,最开始时前进量为 0 如下图。
移动前
先判定 car_pos 是否等于 0 或者等于最大值,若等于 0 则无法后退,等于
最大值则无法前进。
移动时
将下图红色区域中的所有‘0’覆写上‘ ’,同时在上/下方写入‘0’。
注意顺序,向前(上)移动时需要从上往下遍历将 0 搬走,向后(下)
移动则相反,即将‘0’搬到已经遍历过的区域而不是接下来即将继续遍历的
区域,否则将不断循环将‘0’搬到最上/下边。
如果在中间的‘0’上/下方有‘F’,则获得加油包并重置加油包状态。
9
F.如何清除实体
10
G.如何重置数据
为了能重复游玩,在重新开始前应当将所有数据重置,重中之重是重置
赛道,可在 clear 函数中预存车道数组备份,在重置时使用嵌套循环将备份赋
值给赛道数组。
在双缓冲显示中,还应当把 Game Over 提示与残留的赛道清理掉,需要
运用 WriteConsoleOutputCharacterA 函数使用填满空格的数组逐行打印在两个缓冲
区上。
II.显示部分(局部更新)的实现
引入 gotoxy 函数,原理为获得系统显示缓冲区的句柄,将光标移至
(0,0),不清屏只替换不同部分减少闪屏。
只需要将 system(“cls”)替换为 gotoxy(0, 0)即可。
III.BGM 与音效的实现
PlaySound 函 数 一 次 只 能 播 放 一 首 曲 子 , SND_NOSTOP 的 实 现 不 理 想 , 所 以 额 外 需 要
mciSendString 来实现播放音效。同时 Playsound 只能播放 wav 格式的音频,mciSendString 只
能播放 mp3 格式的音频。
A.如何将资源挂载在资源文件中
11
选中文件后选择打开,打开后不管提示任何“已打开…………”都选择
确定。若导入 mp3 文件,格式选择或填写 MP3。之后应当会生成一个.rc 文件,
按下面的图打开它并继续确认。
打开后下图红圈处是资源编号,可用 MAKEINTRESOURCE(IDR_WAVE1)形
式供调用。
12
B.PlaySound 的播放与停止
C.mciSendString 的部署与播放
IV.其他代码与问题解决
A.如何使用 rand 函数
13