您的位置:首页 > 运维架构 > Linux

重构一个贪吃蛇游戏(linux c++)

2010-08-31 18:37 453 查看
最近读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;
}
}


重构后c++代码

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

源代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: