重构一个贪吃蛇游戏(linux c++)
2010-08-31 18:37 BAsil 阅读(2463) 评论(2) 编辑 收藏 举报最近读dave_cn的[原创]分享自己写的一个贪吃蛇的游戏(Linux) ,C程序写的,就想着用C++重写一下,把面向对象的思想也引入进来。
这里感谢dave_cn,重构后应该有40%的代码是重用的,省了不少功夫。
程序继续采用了ncurses.h库,关于ncurses猛击这里。不知道在window下有没有类似的库(查了一下,可以用conio.h在类dos窗口下实现,有空实现一个window版)。
第一次在linux下用c++写东西,碰到的问题比较多,好歹都解决了,这里也一并做记号。
需求比较简单,直接上UML图
Screen 类 主要负责定时刷新
Snake类 footprintx,footprinty 由于蛇移动实际就是重绘窗口,所以需要把它走过的痕迹擦掉(用空字符代替*即可),只记录一步痕迹
list 蛇的身体,采用了双链表,关于双链表猛击这里,代码中调用 dlinkedList.h
bodyReshape() 每一步移动时,其实就是蛇身体各部位坐标的移动,bodyReshape修改各部位坐标
eraseFootPrint() 擦除痕迹
isClapseArea() 是否走到边界
isSpiralDead() 是否头部碰到身体
lifeProbing() 生命迹象探测,就是看看是不是还活着
move() 移动,在移动的过程会做一些工作,详见时序图
receivingNavi() 接受键盘控制蛇头移动方向
selfGeneration() 吃到Block后,身体张长
LivingArea类 蛇的活动区域
Block 障碍物,由于一次只有一个障碍,所以LivingArea和Block是1对1的
blockChecking() 检测障碍物
isEattingPhase() 是否是吃Block的时刻,当蛇头和Block的坐标相同,即认为是isEattingPhase=true
isDigestPhase() 未用
eraseBlock() 将isBlockExisted置为false
generateBlock() 生成Block
再看一下时序图
关于蛇的身体,原c程序采用的是一个倒置的首尾相连的链表,head->front指向snake的尾部
如: [a]<-[b]<-[c]<-[d] a为head
| ^ snake移动的时候,只用head指向d,
`-------------- ' 并且修改d的(y,x)为snake头移动到的位置.
这样的好处是在移动时(身体不增长时),只需要把不用的节点(即上面提到的痕迹)设为头节点,修改其坐标为头的坐标
重构的时候为了简单,用了双链表的源代码,简单的删除痕迹节点,增加新节点,效率不高,简单粗暴。
原c代码
void movesnake(struct TSnake *psnake) { int hy = psnake->head->y; int hx = psnake->head->x; psnake->head = GetSnakeTail(psnake); switch (psnake->dir) { case DIR_UP: psnake->head->y = hy - 1; psnake->head->x = hx; break; case DIR_DOWN: psnake->head->y = hy + 1; psnake->head->x = hx; break; case DIR_LEFT: psnake->head->y = hy; psnake->head->x = hx - 1; break; case DIR_RIGHT: psnake->head->y = hy; psnake->head->x = hx + 1; break; default: break; } }
void Snake::bodyReshape() { SnakeNode t; list.pop_back(t); footprinty=t.y; footprintx=t.x; list.retrieve(0,t); switch (dir) { case DIR_UP: t.y = t.y - 1; t.x = t.x; break; case DIR_DOWN: t.y = t.y + 1; t.x = t.x; break; case DIR_LEFT: t.y = t.y; t.x = t.x - 1; break; case DIR_RIGHT: t.y = t.y; t.x = t.x + 1; break; default: break; } list.insert(0,t); }
编译:
sudo g++ -o mySnake mySnake.cpp Screen.cpp LivingArea.cpp Snake.cpp SnakeNode.cpp Block.cpp –lncurses