打砖块之双人对战
61010220
李少冉
1、申请题目:打砖块之双人对战
游戏类,两个人操作桌子,防止小球落出游戏区。出界或时间到则游戏结束。
2、课题背景:
n 打砖块是一个非常普遍的游戏,几乎所有人都曾经玩过。但是只有一个人的游戏是无趣的,因此我提出了双人对战的模式。
n 在这个游戏中,可以让你和你的朋友进行对战。游戏中还增加了变化,小球时而加速时而减速,时而屏幕会闪烁,一定会有不一样的体验。
3、项目规划:
n 功能、指标、规模
v 功能:
①开始前时间至初值,玩家计分为0 。点阵板能显示初始界面。有砖块,两个桌子,一个小球。
②按下“2”开始,小球开始运动。按“A”“B”可以移动Player1的桌子,A往左,B往右;按“C”“D”可以移动Player2的桌子C往左,D往右。
③小球碰到障碍物可以自动反弹,若是砖块打碎砖块。期间计分模块为两位玩家计分,时间减小。在不确定的时间点阵板闪烁,小球变速。
④若未碰至桌子或计时结束则游戏结束,显示结束的LED灯亮。
v 指标:
初值正常;启动后小球可以完成运动、反弹;按相应的键可以移动桌子;计时模块减计时;可以对两名玩家计分;结束时,红灯亮起。
v 规模:
中上等,有一定难度。
n 面板(显示)、操作、规则
v 显示:点阵板,数码管,LED灯
v 操作&规则:
①按下“2”开始,小球开始运动。按“A”“B”可以移动Player1的桌子,按“C”“D”可以移动Player2的桌子。
②小球碰到障碍物自动反弹,若是砖块打碎砖块。若属于Player1操作则Player1的计分模块加分。同理Player2操作则Player2的计分模块加分。时间也在随着游戏的运行减小。在不确定的时间点阵板闪烁,小球变速。
③玩家通过“A”“B”“C”“D”操作桌子左右移动用来接小球。
④若未碰至桌子或计时结束则游戏结束,显示结束的LED灯亮。
n 输入、输出接口
v 输入:4×4键盘
v 输出:点阵板,数码管,LED灯
4、实现方案:
n 核心问题
小球的移动、碰撞;桌子的移动
n 解决方案
利用数组,将点阵板上的点编号如图:
0
|
32
|
64
|
96
|
128
|
160
|
192
|
224
|
256
|
288
|
320
|
352
|
384
|
416
|
448
|
480
|
2
|
34
|
66
|
98
|
130
|
162
|
194
|
226
|
258
|
290
|
322
|
354
|
386
|
418
|
450
|
482
|
4
|
36
|
68
|
100
|
132
|
164
|
196
|
228
|
260
|
292
|
324
|
356
|
388
|
420
|
452
|
484
|
6
|
38
|
70
|
102
|
134
|
166
|
198
|
230
|
262
|
294
|
326
|
358
|
390
|
422
|
454
|
486
|
8
|
40
|
72
|
104
|
136
|
168
|
200
|
232
|
264
|
296
|
328
|
360
|
392
|
424
|
456
|
488
|
10
|
42
|
74
|
106
|
138
|
170
|
202
|
234
|
266
|
298
|
330
|
362
|
394
|
426
|
458
|
490
|
12
|
44
|
76
|
108
|
140
|
172
|
204
|
236
|
268
|
300
|
332
|
364
|
396
|
428
|
460
|
492
|
14
|
46
|
78
|
110
|
142
|
174
|
206
|
238
|
270
|
302
|
334
|
366
|
398
|
430
|
462
|
494
|
16
|
48
|
80
|
112
|
144
|
176
|
208
|
240
|
272
|
304
|
336
|
368
|
400
|
432
|
464
|
496
|
18
|
50
|
82
|
114
|
146
|
178
|
210
|
242
|
274
|
306
|
338
|
370
|
402
|
434
|
466
|
498
|
20
|
52
|
84
|
116
|
148
|
180
|
212
|
244
|
276
|
308
|
340
|
372
|
404
|
436
|
468
|
500
|
22
|
54
|
86
|
118
|
150
|
182
|
214
|
246
|
278
|
310
|
342
|
374
|
406
|
438
|
470
|
502
|
24
|
56
|
88
|
120
|
152
|
184
|
216
|
248
|
280
|
312
|
344
|
376
|
408
|
440
|
472
|
504
|
26
|
58
|
90
|
122
|
154
|
186
|
218
|
250
|
282
|
314
|
346
|
378
|
410
|
442
|
474
|
506
|
28
|
60
|
92
|
124
|
156
|
188
|
220
|
252
|
284
|
316
|
348
|
380
|
412
|
444
|
476
|
508
|
30
|
62
|
94
|
126
|
158
|
190
|
222
|
254
|
286
|
318
|
350
|
382
|
414
|
446
|
478
|
510
|
v 小球的移动、碰撞
表征小球运动的go及其运动关系
go
|
小球方向
|
坐标变换(Pos)
|
备注
|
000
|
向上
|
减2
|
go[2]:是否为单向运动
go[1]:0表示向左
1表示向右
go[0]:0表示向上
1表示向下
|
001
|
向下
|
加2
|
|
100
|
向左上
|
减 34
|
|
101
|
向左下
|
减30
|
|
110
|
向右上
|
加30
|
|
111
|
向右下
|
加34
|
根据不同的Go即可改变Pos,从而确定下一步的位置。每次根据Go和Pos查询小球前进方向的“路况”:若有砖块,打碎(即砖块处数组置零);若位于桌面区(pos%32==0||pos%32==30)则说明桌子未接住小球,游戏结束;其他则直接反弹。
处理碰撞:
先判断上下有无障碍物,根据go[0]判断上下方向前进的道路;
如果go[2]为1,说明不是单向运动,需处理左右侧的道路。如果位于墙壁处,即若(pos>=2&&pos<=28)||(pos>=482&&pos<=508),则左右方向直接反向。再根据go[1]判断左右侧向前进的道路。
若都没碰撞,查看是否为对角相碰:
if((q[pos-34]||q[pos-33])&&ggo==3'b100)
begin q[pos-33]=0;q[pos-34]=0;go=3'b111; end
else if((q[pos-30]||q[pos-29])&&ggo==3'b101)
begin q[pos-29]=0;q[pos-30]=0;go=3'b110; end
else if((q[pos+30]||q[pos+31])&&ggo==3'b110)
begin q[pos+31]=0;q[pos+30]=0;go=3'b101; end
else if((q[pos+34]||q[pos+35])&&ggo==3'b111)
begin q[pos+35]=0;q[pos+34]=0;go=3'b100; end
如果位于桌面并且桌面在移动,则坐标也相应变化。
若小球走至特定位置(设定为pos%26==0),则将表示变化的c增加c=c+1;送至外部,使状态变化。如闪烁,小球加减速。
v 桌子的移动
桌子有两个属性,起始位置和长度,所以处理桌面有4个参数:st1,leng1,st2,leng2。初始:st1=222;leng1=6;st2=160;leng2=6;
开始后,若按下相应键,改变st1或st2 。再改变数组内的桌面处的值。只需改q[st]和q[st2+leng1*32]处的值。始终使桌面保持6个单位长度。
5、系统结构:
n 系统框图
n 模块功能描述
fenpin10:10分频器,VHDL编写。用以分频。
keyboard:键盘译码,VHDL编写。输出4位二进制数。
last:核心处理数据模块,Verilog编写,主要有:
cpu:处理碰撞,移动,桌子移动。是整个系统的核心。
lled:管理计分数码管显示,LED灯显示。控制信号全部由cpu产生。
chu:管理改变部分。开始信号由该模块产生。由cpu产生的c[1:0]
改变cpu的工作时钟达到控制小球加减速的功能,也可以达到点阵板的闪烁功能。
decode4_8:共阳极8段LED译码,VHDL编写。
n 模块接口标注(参数、协议)
模块名称
|
Input
|
Output
|
fenpin10
|
clkin
|
clkout
|
keyboard
|
col[3:0];clk
|
row_scan[3:0]:keyoutput[3:0];keydown
|
last
|
clk;s[3:0]
|
heng[15:0];over;zong[31:0];p1[7:0];
p2[7:0];shijian[7:0]
|
decode4_8
|
decodein[3:0]
|
decodeout[7:0]
|
引脚表:
I/O名称
|
引脚号
|
I/O名称
|
引脚号
|
I/O名称
|
引脚号
|
clk
|
PIN_28
|
p2[6]
|
PIN_113
|
zong[11]
|
PIN_18
|
col[0]
|
PIN_124
|
p2[5]
|
PIN_114
|
zong[12]
|
PIN_17
|
col[1]
|
PIN_125
|
p2[4]
|
PIN_115
|
zong[13]
|
PIN_16
|
col[2]
|
PIN_126
|
p2[3]
|
PIN_116
|
zong[14]
|
PIN_15
|
col[3]
|
PIN_131
|
p2[2]
|
PIN_117
|
zong[15]
|
PIN_14
|
row[0]
|
PIN_120
|
p2[1]
|
PIN_118
|
zong[16]
|
PIN_13
|
row[1]
|
PIN_121
|
p2[0]
|
PIN_119
|
zong[17]
|
PIN_12
|
row[2]
|
PIN_122
|
heng[0]
|
PIN_158
|
zong[18]
|
PIN_11
|
row[3]
|
PIN_123
|
heng[1]
|
PIN_159
|
zong[19]
|
PIN_8
|
p1[15]
|
PIN_80
|
heng[2]
|
PIN_160
|
zong[20]
|
PIN_7
|
p1[14]
|
PIN_81
|
heng[3]
|
PIN_161
|
zong[21]
|
PIN_6
|
p1[13]
|
PIN_82
|
heng[4]
|
PIN_162
|
zong[22]
|
PIN_5
|
p1[12]
|
PIN_83
|
heng[5]
|
PIN_163
|
zong[23]
|
PIN_4
|
p1[11]
|
PIN_84
|
heng[6]
|
PIN_164
|
zong[24]
|
PIN_45
|
p1[10]
|
PIN_85
|
heng[7]
|
PIN_165
|
zong[25]
|
PIN_46
|
p1[9]
|
PIN_86
|
heng[8]
|
PIN_166
|
zong[26]
|
PIN_47
|
p1[8]
|
PIN_87
|
heng[9]
|
PIN_167
|
zong[27]
|
PIN_48
|
p1[7]
|
PIN_88
|
heng[10]
|
PIN_168
|
zong[28]
|
PIN_49
|
p1[6]
|
PIN_93
|
heng[11]
|
PIN_169
|
zong[29]
|
PIN_50
|
p1[5]
|
PIN_94
|
heng[12]
|
PIN_170
|
zong[30]
|
PIN_53
|
p1[4]
|
PIN_95
|
heng[13]
|
PIN_173
|
zong[31]
|
PIN_54
|
p1[3]
|
PIN_96
|
heng[14]
|
PIN_174
|
s[0]
|
PIN_221
|
p1[2]
|
PIN_97
|
heng[15]
|
PIN_175
|
s[1]
|
PIN_220
|
p1[1]
|
PIN_98
|
zong[0]
|
PIN_176
|
s[3]
|
PIN_218
|
p1[0]
|
PIN_99
|
zong[1]
|
PIN_177
|
s[2]
|
PIN_219
|
p2[15]
|
PIN_100
|
zong[2]
|
PIN_178
|
s[4]
|
PIN_216
|
p2[14]
|
PIN_101
|
zong[3]
|
PIN_179
|
s[5]
|
PIN_214
|
p2[13]
|
PIN_102
|
zong[4]
|
PIN_180
|
s[6]
|
PIN_208
|
p2[12]
|
PIN_103
|
zong[5]
|
PIN_181
|
s[7]
|
PIN_206
|
p2[11]
|
PIN_104
|
zong[6]
|
PIN_182
|
key[3]
|
PIN_202
|
p2[10]
|
PIN_105
|
zong[7]
|
PIN_184
|
key[2]
|
PIN_200
|
p2[9]
|
PIN_106
|
zong[8]
|
PIN_21
|
key[1]
|
PIN_198
|
p2[8]
|
PIN_107
|
zong[9]
|
PIN_20
|
key[0]
|
PIN_196
|
p2[7]
|
PIN_108
|
zong[10]
|
PIN_19
|
over
|
PIN_222
|
6、状态流程图:
n 系统工作状态流程
CPU流程:
7、各主要模块仿真结果波形
n 各模块的仿真波形,详细注释输入输出功能端口
v last模块
start为按下2时开始信号。kai是为后面模块提供的启动信号,表示游戏开始。gameover是游戏结束信号。clk是输入chu的时钟,fenclk是分出的时钟,为cpu的工作时钟。control是计分计时模块的时钟,由cpu产生。c[1:0]是更改状态的变量,输入chu,改变时钟。s[3:0]是键盘输入。shijian[7:0]是计时,p1[7:0] ,p2[7:0]是两个玩家的计分模块。heng[15:0]是列选,zong[31:0]是行选,二者共同构成了点阵的扫描信号。
v 10分频器,键盘,8段译码
老师提供,此处略。
8、课程设计总结
n 预期的目标与当前实现功能的差异详细注释
①桌面移动
预期为每按下一次键移动一下。由于时间紧,时钟没仔细调节,加上人按下的速度比较慢,导致桌面直接运行到两端。因为此点按下按键移动桌面时发现小球也在移动。需要再接一个分频器和与门即可。
②小球有时会穿透
小球前后左右没砖块而加上对角碰撞后,编译30分钟还未出结果,时间太长。故把这种碰撞删去。
③分值显示
分值显示有二进制转10进制的译码模块,但是加上之后“逻辑门数量不足”,只得去掉。所以显示分为16进制显示。
④暂停功能
第一版是有暂停功能,按“E”暂停,但是验收版没有——逻辑门不足。
n 可以进一步发挥提高的部分
改变桌面长度:改变leng参数,再循环赋桌面的值即可。c[1:0]变为c[2:0],
增加状态。
打砖块方式:原来为触碰打碎(即赋值0),改为触碰砖块的数据加1,。带
来的效果是砖块绿色——红色——橙色——消失。
n 课程设计体会
我用Verilog,学习的很快,原来的计算器1天就搞定。最后的大系统拖到最后是由于思路的错误。一开始总是想着置数读数,就用了RAM。RAM带来的时钟麻烦让我头昏脑乱,非常难处理。就因为处理RAM搞了一个月,最后实在没办法改用数组。不过这次大的思想转变让我牢牢的记住了2种方案的特点
两个方式的编译结果:
RAM法:
数组法:
可以看到RAM方法是用逻辑门少,编译速度较快。但是外部模块多,更大的问题是时钟非常难处理,尤其是本项目需要不停的读数据,写数据,还有点阵的扫描。这也是我最后改为数组的原因。
由于本项目是4色(无色,红色,绿色,橙色)显示,需要数组十分庞大,为512位一维数组。所以每次编译耗时是RAM法的5倍甚至更多。有时候编译20分钟在Fitter时提示错误,实在是浪费时间。除此,数组消耗逻辑门,导致许多状态无法加入,这是一个硬伤。
从编译报告看,FPGA中的存储部分非常多,但逻辑门元件是十分宝贵的。
本次系统设计让我更加清楚了数字系统的特点。虽然最后效果不甚理想,但是自己也付出了许多。我明白以后做一件事要事先想清楚再开始干。就好比我那1个月的RAM调试,白白浪费时间。还有一点,这次数字系统设计我全部自己设计,自己编写。我的参考资料只有一本书里的几页纸。许多人说网上的代码多得是,CSDN是一个“神奇”的地方。我觉得本课程就是让大家学习语言设计的,直接“拿来主义”与课程的目的相悖。这个课拿别人的东西验收糊弄老师非常之简单,也有许多人这么做。虽然这样很省事儿,但是我不想,我不甘心就这么否定自己。我坚信自己能做出来。从某一方面说就是坚持,不抛弃,不放弃。坦白的说,数字系统设计,我问心无愧。
9、参考文献
《EDA技术与Verilog设计》 王金明 冷自强 编著 科学出版社