
程序设计及说明
1
、边墙(
Wall
)
该类规定游戏的范围大小。
2
、蛇类(
Snake
)
用该类生成一个实例蛇
snake
。
3
、移动(
Move
)
该类用于实现对蛇的 *** 作控制,即蛇头方向的上下左右的移动 *** 作。
4
、食物类(
Food
)
该类是游戏过程中食物随机产生的控制和显示。
5
、判断死亡(
Dead
)
该类是对游戏过程中判断玩家 *** 作是否导致蛇的死亡,其中包括蛇头咬食自己身体和蛇头是否触
及游戏“边墙”。
6
、蛇结点(
SnakeNode
)
该类是蛇吃下随机产生的食物从而增加长度的控制类,其中包括蛇长度增加和尾部的变化。
7
、计分统计(
Score
)
该类由于玩家的游戏成绩记录,及游戏结束时的得分输出。
部分函数及说明
1Char menu();
/
用于玩家选择的游戏速度,返回一个
char
值
/
2DELAY(char ch1);
/
用于控制游戏速度
/
3void drawmap();
/
绘制游戏地图函数
4
、
void menu()
/
游戏帮助信息的输出
部分类细节解说
1
、蛇的构建
—
Snake
class Snake{
public:
int x[n]
;
int y[n];
int node;
//
蛇身长度
int direction;//
蛇运动方向
int
life;//
蛇生命,判断死亡
}
2
、随机食物
Food
利用
rand(
)函数进行随机数产生,然后就行坐标定位
void Food(void){
int pos_x = 0;
int pos_y = 0;
pos_x = rand() % length;//x
坐标的确定
pos_y = rand() % (width-1);//y
坐标的确定
}
3
、蛇头方向确定
利用
switch
语句进行方向确定
switch(){
case VK_UP:{
OutChar2Y--;
y--;
break;
}
case VK_LEFT:{
OutChar2Y++;
y++;
break;
}
case VK_DOWN:{
OutChar2X---;
x--;
break;
}
case 'VK_RIGHT:{
OutChar2X++;
x++;
break;
}
}
代码
#include <iostream>
#include <ctime>
#include <conioh>
#include <windowsh>
#include <timeh>
using namespace std;
int score=0,t=300,f=1;//
得分与时间间隔
/ms
(控制贪吃蛇的速度)
double ss=0,tt=0;//
统计时间所用参数
class Node
{
Node(): x(0), y(0), prior(0), next(0) { }
int x;
int y;
Node prior;
Node next;
friend class Snake;
};
class Snake
{
public:
Snake();
~Snake();
void output();
void move();
void change_point(char);
private:
Node head;
Node tail;
enum p{ UP
, RIGHT, DOWN, LEFT }point; //
方向
int food_x, food_y; //
食物的坐标
static const int N = 23;
int game[N][N];
void add_head(int, int); //
添加坐标为
a,b
的结点
void delete_tail(); //
删除最后一个结点
void greate_food(); //
产生食物
void gotoxy(int, int);
};
void menu();
//
游戏 *** 作菜单
int main()
{
system("color a");
//
初始
cmd
窗口颜色为黑(背景)淡绿(文字)
cout<<"\n\n\n\n\n\n
";
for(int i=0;i<23;i++)
{char star[]={"Welcome To Snake Game!"};
cout<<star[i];
Sleep(170);}
cout<<"\n\n
祝你好运!
"<<endl;
Sleep(3000);
if(kbhit()){char kk=getch();if(kk==9)f=5;} //
如果执行,吃一颗星加
5
分
system("cls");
Snake s;
menu();
system("color 1a");
soutput();
while (true)
{
char keydown = getch();
if(keydown==32)getch();
if(keydown==27)return 0;
schange_point(keydown);
while (!kbhit())
{clock_t start,end;start=clock();
smove();
soutput();
Sleep(t);
end=clock();tt=(double)(end-start)/CLOCKS_PER_SEC;ss+=tt;
cout<<"
时间:
"<<(int)ss;
#include <windowsh>
#include <ctime>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#ifndef SNAKE_H
#define SNAKE_H
class Cmp
{
friend class Csnake;
int rSign; //横坐标
int lSign; //竖坐标
public:
// friend bool isDead(const Cmp& cmp);
Cmp(int r,int l){setPoint(r,l);}
Cmp(){}
void setPoint(int r,int l){rSign=r;lSign=l;}
Cmp operator-(const Cmp &m)const
{
return Cmp(rSign-mrSign,lSign-mlSign);
}
Cmp operator+(const Cmp &m)const
{
return Cmp(rSign+mrSign,lSign+mlSign);
}
};
const int maxSize = 5; //初始蛇身长度
class Csnake
{
Cmp firstSign; //蛇头坐标
Cmp secondSign;//蛇颈坐标
Cmp lastSign; //蛇尾坐标
Cmp nextSign; //预备蛇头
int row; //列数
int line; //行数
int count; //蛇身长度
vector<vector<char> > snakeMap;//整个游戏界面
queue<Cmp> snakeBody; //蛇身
public:
int GetDirections()const;
char getSymbol(const Cmp& c)const
//获取指定坐标点上的字符
{
return snakeMap[clSign][crSign];
}
Csnake(int n)
//初始化游戏界面大小
{
if(n<20)line=20+2;
else if(n>30)line=30+2;
else line=n+2;
row=line3+2;
}
bool isDead(const Cmp& cmp)
{
return ( getSymbol(cmp)=='@' || cmprSign == row-1
|| cmprSign== 0 || cmplSign == line-1 ||
cmplSign == 0 );
}
void InitInstance(); //初始化游戏界面
bool UpdataGame(); //更新游戏界面
void ShowGame(); //显示游戏界面
};
#endif // SNAKE_H
using namespace std;
//测试成功
void Csnake::InitInstance()
{
snakeMapresize(line); // snakeMap[竖坐标][横坐标]
for(int i=0;i<line;i++)
{
snakeMap[i]resize(row);
for(int j=0;j<row;j++)
{
snakeMap[i][j]=' ';
}
}
for(int m=1;m<maxSize+1;m++)
{
//初始蛇身
snakeMap[line/2][m]='@';
//将蛇身坐标压入队列
snakeBodypush(Cmp(m,(line/2)));
//snakeBody[横坐标][竖坐标]
}
//链表头尾
firstSign=snakeBodyback();
secondSignsetPoint(maxSize-1,line/2);
}
//测试成功
int Csnake::GetDirections()const
{
if(GetKeyState(VK_UP)<0) return 1; //1表示按下上键
if(GetKeyState(VK_DOWN)<0) return 2; //2表示按下下键
if(GetKeyState(VK_LEFT)<0) return 3; //3表示按下左键
if(GetKeyState(VK_RIGHT)<0)return 4; //4表示按下右键
return 0;
}
bool Csnake::UpdataGame()
{
//-----------------------------------------------
//初始化得分0
static int score=0;
//获取用户按键信息
int choice;
choice=GetDirections();
cout<<"Total score: "<<score<<endl;
//随机产生食物所在坐标
int r,l;
//开始初始已经吃食,产生一个食物
static bool eatFood=true;
//如果吃了一个,才再出现第2个食物
if(eatFood)
{
do
{
//坐标范围限制在(1,1)到(line-2,row-2)对点矩型之间
srand(time(0));
r=(rand()%(row-2))+1; //横坐标
l=(rand()%(line-2))+1;//竖坐标
//如果随机产生的坐标不是蛇身,则可行
//否则重新产生坐标
if(snakeMap[l][r]!='@')
{snakeMap[l][r]='';}
}while (snakeMap[l][r]=='@');
}
switch (choice)
{
case 1://向上
//如果蛇头和社颈的横坐标不相同,执行下面 *** 作
if(firstSignrSign!=secondSignrSign)nextSignsetPoint(firstSignrSign,firstSignlSign-1);
//否则,如下在原本方向上继续移动
else nextSign=firstSign+(firstSign-secondSign);
break;
case 2://向下
if(firstSignrSign!=secondSignrSign)nextSignsetPoint(firstSignrSign,firstSignlSign+1);
else nextSign=firstSign+(firstSign-secondSign);
break;
case 3://向左
if(firstSignlSign!=secondSignlSign)nextSignsetPoint(firstSignrSign-1,firstSignlSign);
else nextSign=firstSign+(firstSign-secondSign);
break;
case 4://向右
if(firstSignlSign!=secondSignlSign)nextSignsetPoint(firstSignrSign+1,firstSignlSign);
else nextSign=firstSign+(firstSign-secondSign);
break;
default:
nextSign=firstSign+(firstSign-secondSign);
}
//----------------------------------------------------------
if(getSymbol(nextSign)!='' && !isDead(nextSign))
//如果没有碰到食物(且没有死亡的情况下),删除蛇尾,压入新的蛇头
{
//删除蛇尾
lastSign=snakeBodyfront();
snakeMap[lastSignlSign][lastSignrSign]=' ';
snakeBodypop();
//更新蛇头
secondSign=firstSign;
//压入蛇头
snakeBodypush(nextSign);
firstSign=snakeBodyback();
snakeMap[firstSignlSign][firstSignrSign]='@';
//没有吃食
eatFood=false;
return true;
}
//-----吃食-----
else if(getSymbol(nextSign)=='' && !isDead(nextSign))
{
secondSign=firstSign;
snakeMap[nextSignlSign][nextSignrSign]='@';
//只压入蛇头
snakeBodypush(nextSign);
firstSign=snakeBodyback();
eatFood=true;
//加分
score+=20;
return true;
}
//-----死亡-----
else {cout<<"Dead"<<endl;cout<<"Your last total score is "<<score<<endl; return false;}
}
void Csnake::ShowGame()
{
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
cout<<snakeMap[i][j];
cout<<endl;
}
Sleep(1);
system("cls");
}
int main()
{
Csnake s(20);
sInitInstance();
//sShowGame();
int noDead;
do
{
sShowGame();
noDead=sUpdataGame();
}while (noDead);
system("pause");
return 0;
}
这个代码可以运行的,记得给分啦
话说,我用c++11和opengl在mac上写过一个贪吃蛇,可以参考一下:>
主要是贪吃蛇本身的核心逻辑才70行左右(偷懒用了STL的list,不用自己实现链表)
当时装逼用英语写的注释,请不要打我!
核心逻辑大概是这样子 每次移动的时候:
1 如果蛇头出界或者碰到自己,game over
2 如果蛇头吃到食物,蛇变长。
3 否则(蛇头什么都没碰到)移动蛇。
用链表存蛇身的各个位置的话,链表尾部当蛇头,那蛇变长的 *** 作很简单:把新的蛇头位置插入链表尾部。
移动蛇的 *** 作也简单:把新的蛇头位置插入链表尾部,删除链表头。
然后,剩下的事情还有两个:
1 拿到蛇身的所有位置,在对应位置画上蛇身
2 获取用户输入,改变蛇的移动方向
那。。。你需要了解的只有:
opengl怎么在指定位置画方块(圆圈)
opengl怎么处理用户输入
没了。
#include<stdioh>
#include<stdlibh>
#include<timeh>
#include<conioh>
typedef struct snake
{
int a;
int b;
struct snake u;
struct snake n;
}snake,snake1;
typedef struct food
{
int a;
int b;
}food;
int main()
{
char c,c0 = 'd';
int i,j,k,n=1,t,at;
snake p,q;
snake dd,dd0,dd1,dd2;
food f;
srand(time(NULL));
pu = NULL;
pn = &q;
pa = 5;pb = 6;qa = 5;qb = 5;
qu = &p;qn = NULL;
dd=dd2= &q;
fa=(rand()%15+1);
fb=(rand()%15+1);
while(1)
{
srand(time(NULL));
system("cls");
for(i = 0;i < 17;i ++)
{
for(j = 0; j < 17;j++)
{
if(i == 0 )
printf("▁");
else if(i == 16)
printf("▔");
else if(j == 0)
printf("▕");
else if(j == 16)
printf("▏");
else if(i == pa && j == pb)
printf("◆");
else if(i == fa && j == fb)
printf("☆");
else
{
t = 0;
dd = dd2;
for(k = 0; k < n ;k++)
{
if(i == dd->a && j == dd->b)
{
printf("¤");
t = 1;
break;
}
dd = dd->u;
}
if(t == 0)
printf(" ");
}
}printf("\n");
}
at = 0;
dd =dd2;
for(i=0;i<n;i++)
{
if(pa == dd->a && pb == dd->b)
{
printf("game over!!\n");
for (int iii=0;iii<1000;iii++) {};
exit(0);
}
dd = dd->u;
}
if(pa == fa && pb == fb)
{
dd = dd2;
at =1;
fa = (rand()%15+1);
fb = (rand()%15+1);
for(i=0;i<n;i++)
{
if(fa == dd->a && fb == dd->b)
{
fa = dd2->a;
fb = dd2->b;
break;
}
}
n++;
}
if(kbhit())
{
c = getch();
dd = dd2;
if(c == 'w' && c0 != 's')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
if(pa == 1)
pa = 15;
else
pa = (pa-1)%15;
}
else if(c == 's' && c0 != 'w')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
pa = (pa%15)+1;
}
else if(c == 'a' && c0 != 'd')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
if(pb == 1)
pb = 15;
else
pb = (pb-1)%15;
}
else if(c == 'd' && c0 != 'a')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
pb = (pb%15)+1;
}
else
{
goto qq;
}
c0 = c;
}
else
{
qq: if(c0 == 'w')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
if(pa == 1)
pa = 15;
else
pa=(pa-1)%15;
}
else if(c0 == 's')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
pa=(pa%15)+1;
}
else if(c0 == 'a')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
if(pb == 1)
pb = 15;
else
pb=(pb-1)%15;
}
else if(c0 == 'd')
{
if(at == 1)
{
dd0 =(snake1)malloc(sizeof(snake));
dd0->a = dd2->a;dd0->b = dd2->b;
dd0->n = NULL;dd0->u = dd2;
dd2=dd0;
}
dd = dd2;
for(i = 0; i<n ; i++)
{
dd1 = dd->u;
dd->b = dd1->b;
dd->a = dd1->a;
dd = dd->u;
}
pb=(pb%15)+1;
}
}
fflush(stdin);
dd = &q;
_sleep(0);
}
}
可以Sleep函数设置延时来控制贪吃蛇的速度。
函数名: Sleep
功 能: 执行挂起一段时间
用 法: void Sleep(DWORD dwMilliseconds);
在VC中使用带上头文件
#include <windowsh>
( Sleep函数存放头文件:WinBaseh)
在gcc编译器中,使用的头文件因gcc版本的不同而不同
#include <unistdh>
Sleep()单位为毫秒,sleep()单位为秒(如果需要更精确可以用usleep单位为微秒)
返回值
若进程/线程挂起到参数所指定的时间则返回0,若有信号中断则返回剩余秒数。
例程:
/ --------------------snakeh --------------------/#ifndef SNAKE_H
#define SNAKE_H
#define LEFT 'a'
#define RIGHT 'd'
#define DOWN 's'
#define UP 'w'
#define ESC 27
#define N 200 /蛇的最大长度/
char key; /控制按键/
struct Food
{
int x; /食物的横坐标/
int y; /食物的纵坐标/
int yes; /判断是否要出现食物的变量/
}food; /食物的结构体/
struct Snake
{
int x[N];
int y[N];
int node; /蛇的节数/
int direction; /蛇移动方向/
int life; / 蛇的生命,0活着,1死亡/
}snake;
#endif
/ --------------------snakec --------------------/
#include <graphicsh>
#include <stdlibh>
#include <conioh>
#include <timeh>
#include <stdioh>
#include "snakeh"
int score = 0;
int gamespeed = 100; //蛇运行速度
static void Init(void); /图形驱动/
static void Close(void); /图形结束/
static void Game_interface(void); /游戏界面/
static void GameOver(void); /结束游戏/
static void GamePlay(void); /游戏过程/
static void PrScore(void); /输出成绩/
/主函数/
int main(void)
{
Init();
Game_interface();
GamePlay();
Close();
return 0;
}
/图形驱动/
static void Init(void)
{
int gd=9,gm=2;
initgraph(&gd,&gm," ");
cleardevice();
}
/ 开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙 /
static void Game_interface(void)
{
int i;
setcolor(LIGHTCYAN); /setbkcolor(LIGHTGREEN);/
setlinestyle(PS_SOLID,0,1); /设置线型/
for(i=50;i<=600;i+=10) /画边框/
{
rectangle(i,40,i+10,49); /上边框/
rectangle(i,451,i+10,460); /下边框/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10); /左边框/
rectangle(601,i,610,i+10); /右边框/
}
}
/ 游戏主函数 /
static void GamePlay(void)
{
int i;
srand(time(NULL)); /随机数发生器/
foodyes = 1; /1表示需要出现新食物,0表示已经存在食物/
snakelife = 0; /活着/
snakedirection = 1; /方向往右/
snakex[0] = 100;
snakey[0] = 100;
snakex[1] = 110;
snakey[1] = 100;
snakenode = 2; /节数/
PrScore(); /输出得分/
while(1) /可以重复玩游戏,压ESC键结束/
{
while( !kbhit() ) /在没有按键的情况下,蛇自己移动/
{
if(foodyes == 1) /需要出现新食物/
{
foodx = rand()%400 + 60;
foody = rand()%350 + 60;
while(foodx%10 != 0) /食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到/
foodx++;
while(foody%10 != 0)
foody++;
foodyes = 0; /画面上有食物了/
}
if(foodyes == 0) /画面上有食物了就要显示/
{
setcolor(GREEN);
rectangle(foodx,foody,foodx + 10,foody - 10);
}
for(i=snakenode-1;i>0;i--) /蛇的每个环节往前移动,也就是贪吃蛇的关键算法/
{
snakex[i] = snakex[i-1];
snakey[i] = snakey[i-1];
}
/1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头/
switch(snakedirection)
{
case 1:
snakex[0] += 10;
break;
case 2:
snakex[0] -= 10;
break;
case 3:
snakey[0] -= 10;
break;
case 4:
snakey[0] += 10;
break;
}
/ 从蛇的第四节开始判断是否撞到自己 /
for(i=3;i<snakenode;i++)
{
if((snakex[i] == snakex[0]) && (snakey[i] == snakey[0]))
{
GameOver(); /显示失败/
snakelife = 1;
break;
}
}
if((snakex[0] < 55) || (snakex[0] > 595) || (snakey[0] < 55) || (snakey[0] > 455)) /蛇是否撞到墙壁/
{
GameOver(); /本次游戏结束/
snakelife = 1; /蛇死/
}
if(snakelife == 1) /以上两种判断以后,如果蛇死就跳出内循环,重新开始/
break;
if((snakex[0] == foodx) && (snakey[0] == foody)) /吃到食物以后/
{
setcolor(BLACK); /把画面上的食物东西去掉/
rectangle(foodx,foody,foodx+10,foody-10);
snakex[snakenode] = -20;
snakey[snakenode] = -20;
/ 新的一节先放在看不见的位置,下次循环就取前一节的位置 /
snakenode++; /蛇的身体长一节/
foodyes = 1; /画面上需要出现新的食物/
score += 10;
PrScore(); /输出新得分/
}
setcolor(RED); /画出蛇/
for(i=0;i<snakenode;i++)
rectangle(snakex[i],snakey[i],snakex[i]+10,snakey[i]-10);
Sleep(gamespeed); /用延迟控制贪吃蛇速度/
setcolor(BLACK); /用黑色去除蛇的的最后一节/
rectangle(snakex[snakenode-1],snakey[snakenode-1],
snakex[snakenode-1]+10,snakey[snakenode-1]-10);
} /endwhile(!kbhit)/
if(snakelife == 1) /如果蛇死就跳出循环/
break;
key=getch(); /接收按键/
if (key == ESC) break; /按ESC键退出/
switch(key)
{
case UP:
if(snakedirection != 4) /判断是否往相反的方向移动/
snakedirection = 3;
break;
case RIGHT:
if(snakedirection != 2)
snakedirection = 1;
break;
case LEFT:
if(snakedirection != 1)
snakedirection = 2;
break;
case DOWN:
if(snakedirection != 3)
snakedirection = 4;
break;
}
}/endwhile(1)/
}
/游戏结束/
static void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
setfont(56,0,"黑体");
outtextxy(200,200,"GAME OVER");
getch();
}
/输出成绩/
static void PrScore(void)
{
char str[10];
setfillstyle(YELLOW);
bar(50,15,220,35);
setcolor(BROWN);
setfont(16,0,"宋体");
sprintf(str,"score:%d",score);
outtextxy(55,16,str);
}
static void Close(void)
{
closegraph();
}
以上就是关于在dos环境下c语言编程编一个贪吃蛇游戏全部的内容,包括:在dos环境下c语言编程编一个贪吃蛇游戏、贪吃蛇游戏的C语言编程、怎样在mac上用C语言写出一个贪吃蛇游戏等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)