我的实现步骤:
(1)构造小蛇和边界
(2)实现小蛇的移动
(3)玩家控制小蛇移动
(4)判断游戏失败
(5)吃食物增加长度
实现贪吃蛇游戏关键的几点就在于:
(1)蛇的运动以及吃到食物后蛇的长度变化:可谓是牵一发而动全身,因为只要蛇头朝向一个方向移动,所有蛇身的坐标都会变化;同样吃到食物后蛇长增加,需要在尾部添加一个元素。我们从蛇头到蛇尾(假设N个元素),蛇头用1表示,依次到蛇尾用N表示,然后每次移动一个单位都对蛇的所有元素加1,如果蛇吃到了食物,那么只需要根据移动方向把蛇头找到赋值为1,如果没吃到还要把+1后尾部赋值为0。
(2)还有几个点就是规则的实现:比如游戏失败的条件是蛇头撞到边界或者蛇身,食物的随机生成。这些加一些判断以及利用rand()函数即可。
代码中也有详细的注释
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
using namespace std;
#define High 20 // 游戏画面尺寸
#define Width 50
// 全局变量
int canvas[High][Width]={0}; //记录每个元素对应位置,0为空格,1为蛇头@,大于1为蛇身*(从2到snake_len),-2为食物$,-1为围墙#
int pos_header_X,pos_header_Y;//蛇头位置
int snake_len;//蛇长度
int direction;//蛇移动方向:1向左,2向右,3向上,4向下
int score;//吃到食物的个数
int food_X,food_Y; //食物的位置
void gotoxy(int x,int y) //光标移动到(x,y)位置
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
}
void snakerun()//控制蛇的运动 (关键)
{
int i,j;
int tail_X,tail_Y,max=0;//尾巴的位置
//得到移动后的蛇
for(i=1;i<High-1;i++){
for(j=1;j<Width-1;j++){
if(canvas[i][j]>=1){
canvas[i][j]++;
}
}
}
//得到尾巴的位置
for(i=1;i<High-1;i++){
for(j=1;j<Width-1;j++){
if(canvas[i][j]>max){
max=canvas[i][j];
tail_Y=i;
tail_X=j;
}
if(canvas[i][j]==2){//得到蛇头位置 (因为前面都++了所以是2)
pos_header_Y=i;
pos_header_X=j;
}
}
}
int new_head_X=pos_header_X,new_head__Y=pos_header_Y;//移动后头的位置
//根据当前移动方向找到新的蛇头位置
for(i=0;i<snake_len;i++){
if(direction==1){
new_head_X=pos_header_X-1;
}else if(direction==2){
new_head_X=pos_header_X+1;
}else if(direction==3){
new_head__Y=pos_header_Y-1;
}else if(direction==4){
new_head__Y=pos_header_Y+1;
}
}
//判断是否吃到食物
if(new_head__Y==food_Y&&new_head_X==food_X){
canvas[food_Y][food_X]=0;
food_Y=rand()%(High-2)+2;
food_X=rand()%(Width-2)+2;
canvas[food_Y][food_X]=-2;
}else{
canvas[tail_Y][tail_X]=0;
}
//检查是否碰壁或碰自己身体 (一定在更新之后判断才方便!!!)
if(canvas[new_head__Y][new_head_X]==-1||canvas[new_head__Y][new_head_X]>0){
cout<<"游戏失败"<<"\n";
Sleep(1000);
system("pause");
exit(0);
}else{
canvas[new_head__Y][new_head_X]=1;
}
}
void startup() // 数据初始化
{
int i,j;
pos_header_Y=High/2;
pos_header_X=Width/2;
snake_len=5; //初始蛇长为5
direction=2;//初始向右运动
canvas[pos_header_Y][pos_header_X]=1;//1为蛇头
score=0;
//随机产生食物
food_Y=rand()%(High-5)+2;
food_X=rand()%(Width-5)+2;
canvas[food_Y][food_X]=-2;
for(i=1;i<snake_len;i++)
canvas[pos_header_Y][pos_header_X-i]=i+1;//大于1为蛇身
//上下左右的围墙
for(j=0;j<Width;j++){
canvas[0][j]=-1;
canvas[High-1][j]=-1;
}
for(i=0;i<High;i++){
canvas[i][0]=-1;
canvas[i][Width-1]=-1;
}
}
void show() // 显示画面
{
gotoxy(0,0); // 光标移动到原点位置,以下重画清屏
int i,j;
for(i=0;i<High;i++){
for(j=0;j<Width;j++){
if(canvas[i][j]==0){//输出空格
cout<<" ";
}else if(canvas[i][j]==-1){//输出边界
cout<<"#";
}else if(canvas[i][j]==1){//输出蛇头
cout<<"@";
}else if(canvas[i][j]>1){//输出蛇身
cout<<"*";
}else if(canvas[i][j]==-2){//输出食物
cout<<"$";
}
}
cout<<"\n";
}
cout<<"score:"<<score<<"\n";
Sleep(100);
}
void updateWithoutInput() // 与用户输入无关的更新
{
int i,j;
snakerun();
}
void updateWithInput() // 与用户输入有关的更新
{
char input;
if(kbhit()){
input=getch();
//蛇移动方向:1向左,2向右,3向上,4向下
if(input=='a')
direction=1;
snakerun();
if(input=='d')
direction=2;
snakerun();
if(input=='w')
direction=3;
snakerun();
if(input=='s')
direction=4;
snakerun();
}
}
int main()
{
startup(); // 数据初始化
while (1) // 游戏循环执行
{
show(); // 显示画面
updateWithoutInput(); // 与用户输入无关的更新
updateWithInput(); // 与用户输入有关的更新
}
return 0;
}