|
蛇头,蛇身,拐角,蛇尾,这些都是一个东西,用一个统一的类来管理就可以。
我的思路是,贪吃蛇就两个东西,蛇身和蛇头。身体的每一块是一个节点,蛇头也是一个节点,一串节点构成一条蛇。每一个节点中最核心的两个东西:(此节点的上一个位置坐标;指向前一个节点的指针。)。这样封装出来算法比较清晰,每一次移动,所有的节点都移动到前一个节点的上一个位置,你只需要控制蛇头。(假如蛇在向上运动,这时你按下键盘←改变蛇的方向,蛇头向左移动一个单位,第二个节点,就会移动到蛇头之前的位置,以后的节点都往前这么移动一格。然后蛇头再左走了一个单位,第二个节点走到前一个节点的上一个位置,就是蛇头之前刚向左移了一格的那个位置,后面的节点以此类推,就是贪吃蛇的行进方式,不用去算每一个节点,封装好他的移动函数,你每次只移动蛇头,然后让之后所有的节点move一次就好)。关于添加,那就是新创建一个节点,放在最后一个节点的位置。在上一个节点移动走以后,你新添加的节点就会跟上之前的蛇尾走成为新的蛇尾。
前阵子刚写了一个极简版的,300行不到就可以完成。上面啰嗦那么多也不知道讲清楚没有。下面是我关于类封装结构的伪代码,你看这个思路能理解不。
Widget {
Snake *snake;
void timerEvent();//没过interval毫秒,蛇向前移动一个身位
void createFood();//随机生成一个食物,如果与蛇重合,就重新生成
void keyPressEvent();//检测到对应按键,改变蛇的方向
SnakeBody *food;
int timer_id;
bool is_timer_start;
void eatOrDeath();//检测坐标重合
}
Snake {
enum DIRECTION{UP,DOWN,LEFT,RIGHT};
SnakeBody *snake_head;//蛇头
SnakeBody *snake_body;//蛇身
QVector<SnakeBody *> snake_list;//整条蛇
DIRECTION direction;//前进方向
void goAhead();//前进
void changeDirection(DIRECTION dir);//改变前进方向
void addLength();
SnakeBody * getHead();
SnakeBody * getBody(int index);
SnakeBody * getLast();
}
SnakeBody {
SnakeBody(QWidget* parent = 0);
SnakeBody(SnakeBody * pre_body,QWidget *parent = 0);
QPoint old_pos;
QPoint oldPos();
SnakeBody * previous_body;
SnakeBody * previousBody();
void setPreviousBody(SnakeBody * pre_body);
void bodyMove(int x,int y);
void moveTo();//移动到前节点的旧坐标
}
定时器:
{
每隔interval毫秒,蛇向当前方向移动一次
}
移动 :
{
头结点往direction的方向移动一个身位
只移动头结点,后面的节点移动到前一个节点的前一个位置
}
方向 : 上下左右
{
获取按键信息,改变蛇的方向属性
}
吃点(吃食物)
{ ---随机生成(避开蛇身)
食物和蛇头坐标重合,蛇加一个身长,
消除现有食物,创建新食物
}
加长 : 加一个身长
{
后一个body存放前一个body的指针
}
碰壁:
{
蛇头坐标超出窗体
}
**:
{
蛇头坐标与蛇身重合
}
|
|