【VC++开源代码栏目提醒】:网学会员,鉴于大家对VC++开源代码十分关注,论文会员在此为大家搜集整理了“88行代码实现俄罗斯方块游戏(含讲解) - 其它资料”一文,供大家参考学习!
88 行
代码实现俄罗斯方块游戏(含讲解)在正式阅读本文之前,请你记得你应该用娱乐的心态来看,本
代码所使用到的技巧,在工作了的人眼里会觉得很纠结,很蛋疼,很不可理喻,很丑,注意,是你蛋疼,不关我的事通常,写一个俄罗斯方块,往往动不动就几百行,甚至上千行,而这里只有 88 行正所谓头脑风暴,打破常规。
这里将使用很多不平常的手段来减少
代码但为了能更通用,一份控制台版本的
代码,同样是 88 行,直接复制到
VC 即可编译:includeincludeincludeincludeincludechar gcText 1LJTSZstruct tetris int _pool1632 pool32 tmap8416 int x y s st tgtvoid trsInit int sp84 3802 3930511456254561993065151-1 int p i j b for p sp0 p 0 p if p 0 p p-2 gt.pool gt._pool4 for j 0 j 7 j for i 0 i 4 i for b 0 b 16 b gt.tmapj1ib spji 1 j 1 spji 1 memsetgt._pool -1 sizeofgt._pool for i 0 i 10 i memsetgt.pooli 0 sizeofint21 return int trsCopyint sp int x int y int c int i cx cy for i 0 i 16 i if spi cx x i 3 cy y i 2 if gt.poolcxcy if c 2 gt.poolcxcy 0 else return 0 if c1 gt.poolcxcy spi return 1int trsScene int x y 0 COORD pos 0 gt.s rand 7 1 gt.st gt.t 0 gt.x 3 gt.y 0 for --gt.t Sleep1 --gt.t int k 0 while kbhit k getch if k 27 return 0 if k A k a if trsCopygt.tmapgt.sgt.st gt.x-1 gt.y 0 --gt.x else if k D k d if trsCopygt.tmapgt.sgt.st gt.x1 gt.y 0 gt.x else if k W k w if trsCopygt.tmapgt.sgt.st1 4 gt.x gt.y 0 gt.st gt.st1 4 if k S k s gt.t 0 if trsCopygt.tmapgt.sgt.st gt.x gt.y1 0gt.ygt.t50 else trsCopygt.tmapgt.sgt.st gt.x gt.y 1 for --y y 0 --y for x 0 gt.poolxy 0 x if gt.poolxy 0 for k y k 0 --k for x 0 gt.poolx0 0 x gt.poolxk gt.poolxk-1 return 1 trsCopygt.tmapgt.sgt.st gt.x gt.y 1 SetConsoleCursorPositionGetStdHandleSTD_OUTPUT_HANDLE pos for y 1 gt.pool0y 0 yputchar10 for x 0 gt.poolx0 0 x putchargcTextgt.poolxy trsCopygt.tmapgt.sgt.st gt.x gt.y 2 int main srandunsignedtimeNULL for trsInit trsScene return 0以下是对
代码的压缩方法进行分析首先,通常我们需要准备 7 种方块,4 个方向的形状表,相当多的俄罗斯方块程序就是在开头写了这样一个很长的数组定义,有的光这个定义就直接超 100 行了,这个程序是怎么实现的呢?其实这个程序,同样是使用一个 7416 的数组来保存这个形状表,但是,它没有直接初始化,见这个数组的定义:int sp84 3802 3930511456254561993065151-1这个莫名其妙的数组的值是什么意思呢?其实很好猜的,我们尝试把这些数化为二进制:15 11114369 1000100010001合理地四位四位拆开,从低位到高位,从左到右,从上到下排列一下:11110000000000001000100010001000你终于发现,这就是长条方块的两个形状后面类似然后你会发现,这个数组并不完整,有的只定义了两个形状,有的是四个形状,没定义的数会默认置 0 的,这个怎么解释?看这个数组定义的下面第二行:for p sp0 p 0 p if p 0 p p-2意思是找出这个数组为 0 的元素,用它前面的元素值填上即p p-2而数组中最后一个元素值-1 起监督头的作用,用于让这个循环跳出虽然可以把这些常数全直接写在数组里,但常数太多显得不太好,就这样写了之后你看到这行
代码:gt.pool gt._pool4为什么定义两个 pool 呢?因为我们需要在原来的 pool 的界外用-1 值填充,以便后面做碰撞检测减少不必要的
代码但如果直接用原来的_pool,那每次访问都要加上一个偏移常数,不美观且显得
代码长,就用另一个指针直接指向开始的位置然后,后面的三重循环就是解开那个位压缩数组以初始化 gt.tmap 数组,这个数组就是记录74 种形状的数组再下面三行,就是初始化 pool,游戏区为 0,界外为-1而其中,i 10 决定了游戏池的宽度为 10,sizeofint21决定了游戏池的高度是 20 (0我们不使用,这一行有特殊作用,后文会讲)用 memset 也是为了免写二重循环而已。
整个初始化流程就到这里了然后,是一个 trsCopy 函数,这个函数综合了碰撞检测,复制到游戏池和反复制,行为由参数 c (是 control 缩写字母)控制c 为 0 就单纯的碰撞检测,c 为 1 是复制,c 为 2 就是反复制,细心分析一下,这个函数功能就清楚了,这里不详细展开好了,到了 trsScene 函数,整个游戏的主逻辑流程就在这里了我们先看第 75 行的那个二重循环,只有那个地方是根据 pool 保存的值来输出所以,这个时候,你应该明白为什么 trsCopy 函数还要复制和反复制了,它把你正在控制的方块,复制到 pool 里,统一输出,这样就不需要另加一个函数来绘画你的控制块了而绘图之前,就是键盘处理等的逻辑控制,这里就没有什么复杂难懂的
代码了,唯一要讲讲的是,if k S k s gt.t 0这一段是判断下落键的按下,和是否到时间强制下落里面 for --y y 0 --y开始是消行计算你可能会奇怪这个 y 没有明显的初始值,直接就来一个 --y,初始从哪里来?其实就在之前讲的输出绘画那个循环里,循环结束后,y 的值一定是最后一行1所以我们只要--y 就得到最底下一行,因为消行计算,从下往上,只要一次就解决了,
代码较少好了,现在解释之前说的,为什么不是从 0,而是从 1 开始消行计算这里,每消除一行,最顶的一行就应该用 0 填充,但如果你因为这个多写一个 for循环就不值得了我们改成从 1 开始,那么把第 0 行的内容复制到第一行,就完成 0 填充了,就可以少写一个 for好了,差不多接近尾声了,最后说说 trsScene 的返回值trsScene 返回值的意思很简单,如果是 1 就继续循环,如果是 0 就退出所以你可以在
代码里看到,当按下 ESC值为 27的时候才返回 0而方块落下一个的时候,返回 1,让主函数重新调用它,就能再次初始化当前控制块的位置和形状了,达到免除状态管理的
代码的作用最后,在主循环除了初始化,只要华丽的一行 for trsInit trsScene 就可以玩这个游戏了看不懂?说明你也是个正常人 看得懂?说明你已经脑残了。
。
。
PS: 成年人不要乱学未成年人的东西。
。
。
以下是 Win-TC 可以成功编译并执行的
代码(
代码保证单行长度不超过 80 字符,如果你是Win7 系统,那请看后文):include graphics.hincludeincludeint gcW 20 gcColor DARKGRAY LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHTMAGENTAMAGENTA YELLOWstruct tetris int _pool1632 pool32 tmap8416 int x y s st tgtvoid trsInit int sp84 3802 3930511456254561993065151-1 int p i j b for p sp0 p 0 p if p 0 p p-2 gt.pool gt._pool4 for j 0 j 7 j for i 0 i 4 i for b 0 b 16 b gt.tmapj1ib spji 1 j 1 spji 1 memsetgt._pool -1 sizeofgt._pool for i 0 i 10 i memsetgt.pooli 0 sizeofint21 return int trsCopyint sp int x int y int c int m 0326496356799 i cx cy for i 0 i 16 i if spi cx x mi 5 cy y mi 31 if gt.poolcxcy if c 2 gt.poolcxcy 0 else return 0 if c1 gt.poolcxcy spi return 1int trsScene int x y 0 gt.s random7 1 gt.st gt.t 0 gt.x 4 gt.y 0 for --gt.t delay10 --gt.t int k 0 while kbhit k getch if k 27 return 0 if k A k a if trsCopygt.tmapgt.sgt.st gt.x-1 gt.y 0 --gt.x else if k D k d if trsCopygt.tmapgt.sgt.st gt.x1 gt.y 0 gt.x else if k W k w if trsCopygt.tmapgt.sgt.st1 4 gt.x gt.y 0 gt.st gt.st1 4 if k S k s gt.t 0 if trsCopygt.tmapgt.sgt.st gt.x gt.y1 0gt.ygt.t50 else trsCopygt.tmapgt.sgt.st gt.x gt.y 1 for --y y 0 --y for x 0 gt.poolxy 0 x if gt.poolxy 0 for k y k 0 --k for x 0 gt.poolx0 0 x gt.poolxk gt.poolxk-1 return 1 trsCopygt.tmapgt.sgt.st gt.x gt.y 1 for x 0 gt.poolx0 0 x for y 1 gt.poolxy 0 y setfillstyle1 gcColorgt.poolxy bar201 xgcW 1 ygcW 200 gcW xgcW gcW ygcW trsCopygt.tmapgt.sgt.st gt.x gt.y 2 int main int g DETECT m 0 initgraphg m randomize trsInit while trsScene return 0如果你没有 Win-TC,或者你是 Win7 系统,可以用这个能用
VC6 编译的工程包:以上是图形界面版本,显示看起来好看一些一样都是 88 行
上一篇:
基于VB的NC代码转换与传送
下一篇:
4种小菜缓解孕妈咪不适