c语言贪吃蛇怎么让蛇自己动起来啊?

c语言贪吃蛇怎么让蛇自己动起来啊?,第1张

#define N 200
#include <graphicsh>
#include <stdlibh>
#include <dosh>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/得分/
int gamespeed=50000;/游戏速度自己调整/
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;
void Init(void);/图形驱动/
void Close(void);/图形结束/
void DrawK(void);/开始画面/
void GameOver(void);/结束游戏/
void GamePlay(void);/玩游戏具体过程/
void PrScore(void);/输出成绩/
/主函数/
void main(void)
{
Init();/图形驱动/
DrawK();/开始画面/
GamePlay();/玩游戏具体过程/
Close();/图形结束/
}
/图形驱动/
void Init(void)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
/开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙/
void DrawK(void)
{
/setbkcolor(LIGHTGREEN);/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/设置线型/
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);/右边/
}
}
/玩游戏具体过程/
void GamePlay(void)
{
randomize();/随机数发生器/
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(0);/把画面上的食物东西去掉/
rectangle(foodx,foody,foodx+10,foody-10);
snakex[snakenode]=-20;snakey[snakenode]=-20;
/新的一节先放在看不见的位置,下次循环就取前一节的位置/
snakenode++;/蛇的身体长一节/
foodyes=1;/画面上需要出现新的食物/
score+=10;
PrScore();/输出新得分/
}
setcolor(4);/画出蛇/
for(i=0;i<snakenode;i++)
rectangle(snakex[i],snakey[i],snakex[i]+10,
snakey[i]-10);
delay(gamespeed);
setcolor(0);/用黑色去除蛇的的最后一节/
rectangle(snakex[snakenode-1],snakey[snakenode-1],
snakex[snakenode-1]+10,snakey[snakenode-1]-10);
} /endwhile(!kbhit)/
if(snakelife==1)/如果蛇死就跳出循环/
break;
key=bioskey(0);/接收按键/
if(key==ESC)/按ESC键退出/
break;
else
if(key==UP&&snakedirection!=4)
/判断是否往相反的方向移动/
snakedirection=3;
else
if(key==RIGHT&&snakedirection!=2)
snakedirection=1;
else
if(key==LEFT&&snakedirection!=1)
snakedirection=2;
else
if(key==DOWN&&snakedirection!=3)
snakedirection=4;
}/endwhile(1)/
}
/游戏结束/
void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"GAME OVER");
getch();
}
/输出成绩/
void PrScore(void)
{
char str[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);
}
/图形结束/
void Close(void)
{
getch();
closegraph();
}

1、可能是软件问题,可以先把贪吃蛇大作战卸载掉,再去应用商店下载最新版本的贪吃蛇大作战,下载好后,登陆。

2、可能是手机内存问题,可以把手机清除数据,或者升级手机系统。再去应用商店下载最新版本的贪吃蛇大作战,下载好后,登陆。

知识延展:

1、贪吃蛇大作战,休闲益智类游戏,玩家需要控制蛇在屏幕内吃到小豆子,每吃一个身体会发生变化,越到后面难度系数将会越大哦,游戏支持单机,玩家也可以和其家人或朋友进行对战。

2、游戏支持触屏 *** 作,玩家需要2根手指即可完成游戏,具体 *** 作:两个手指分别放在屏幕的左下角和右下角,屏幕左上角控制蛇进行向上和向左移动,右下角控制蛇进行向下和向右移动。

(一)开始新游戏
11 获取并应用各个参数(当前级别,控制键等),初始化随机数(Randomize)。
12 清除地图上的所有物品,各个统计数值置零。
13 初始化地图:布置食物,炸d,蛇身位置以及蛇头的移动方向——在PictureBox上绘画图像 并修改对应的地图格属性值(MapProperty()数组)。
14 启动Timer定时器,游戏开始。
(二)游戏 *** 作
21 暂停\恢复——
修改表示游戏状态的Boolean型变量值;
显示\隐藏 表示游戏状态的Label;
暂停\恢复 Timer定时器。
22 控制方向(根据Nokia贪吃蛇的 *** 作方式)——
由于蛇头只能朝上下左右4个方向移动,但是方向键有8个,所以“斜线方向”的控制键和水平,垂直方向的控制键编码上有点不同
221 斜线方向键(以“右上”方向键为例)——
如果当前蛇头朝着左边(水平方向)运动,则将水平方向的分量变为0,再将垂直方向的分量变为-1(向上运动);
如果当前蛇头朝着上方(垂直方向)运动,则将垂直方向的分量变为0,再将水平方向的分量变为 1(向右运动)。
其余“左上,左下,右下”的方向键编码与上述雷同。
222“水平,垂直”方向键——
当蛇以 水平 方向移动时,“左”和“右”的按键无效;(即不处理按键事件)
当蛇以 垂直 方向移动时,“上”和“下”的按键无效。
(三)移动蛇身
31 根据运动方向,找出蛇头的新坐标;
32 判断蛇头新坐标下的 地图属性——
(1)如果蛇头的新坐标 和当前 蛇尾 的坐标重合,那不算GameOver--因为随着蛇头的移动,蛇身各个节点都会向前跟进,使得当前 蛇尾 坐标下的网格在移动之后会变成 空白地。
(2)如果当前蛇头位置的地图属性是“食物”——增加蛇身长度,统计玩家吃进的食物数量,增加分数,补充地图上的食物,记录(累加)当前吃进的物品,如果吃进的物品(curEatCount) 达到一定数量(EatCountPerShowPrize)就在地图上显示奖品。
(3)如果当前蛇头位置的地图属性是“炸d“(陷阱)——统计玩家吃进的炸d数量,扣分(如果分数小于0,就GameOver),补充地图上的炸d,记录(累加)当前吃进的物品,如果吃进的物品达到一定数量就显示奖品。
(4)如果当前蛇头位置的地图属性是“奖品”——加分,重新累计 吃进的物品数(curEatCount = 0)
33 刷新蛇身坐标,更新 地图网格属性 以及画面
(1)在更新蛇身坐标之前,保存原来的 蛇尾坐标;
(2)先在地图上 擦除旧的的蛇头,然后在地图上 绘画出新的蛇头;
(3)修改变量值,标记蛇头新坐标下的地图格属性为:蛇身;
(4)要先更新 蛇身除了蛇头外其余部分的坐标;
(5)之后才更新 蛇头的坐标;
(6)判断是否需要 增加蛇身长度——如果要增加长度:旧蛇尾的坐标不变,蛇身长度 + 1;
否则(无需增加蛇身长度):如果蛇头的新坐标与旧蛇尾的坐标重合,就不用在旧蛇尾的坐标下 绘画空白地的图案(因为该网格属性已经是 蛇头,而不是空白地)
(7)在地图上擦除旧蛇尾,绘画空白地;
(8)在地图上把 旧蛇尾坐标 下的地图格的属性设置为 空白地;
《标准模块 Module1 代码》——
Option Explicit
'全局 常量
Public Enum MAP_PROPERTY '地图属性
MAP_EMPTY = 0 '空白地
MAP_FOOD '食物
MAP_BOMB '炸d,陷阱
MAP_PRIZE '加分奖品
MAP_SNAKE '蛇身
End Enum
Public Const MAP_SCALE As Integer = 15 '地图放大倍数
'地图网格数(Index值,首值为0)
Public Const MAX_COL_INDEX As Integer = 19
Public Const MAX_ROW_INDEX As Integer = 10
Public Const START_SNAKE_LENGTH As Integer = 8 '蛇身初始长度
Public Const SPEED_LV1 As Integer = 200 '第一级(最慢)的速度(TimerInterval,最快第9级=40)
Public Const SPEED_CHANGE As Integer = 20 '前后2个等级之间的 Interval差值(毫秒)
'定义控制键
Public Const KEY_PAUSE As Integer = vbKeyNumpad5
Public Const KEY_UP As Integer = vbKeyNumpad8
Public Const KEY_DN As Integer = vbKeyNumpad2
Public Const KEY_LF As Integer = vbKeyNumpad4
Public Const KEY_RT As Integer = vbKeyNumpad6
Public Const KEY_LFUP As Integer = vbKeyNumpad7
Public Const KEY_LFDN As Integer = vbKeyNumpad1
Public Const KEY_RTUP As Integer = vbKeyNumpad9
Public Const KEY_RTDN As Integer = vbKeyNumpad3
'定义填充色
Public Const HEAD_COLOR As Long = &H80FF '蛇头颜色
Public Const BODY_COLOR As Long = vbGreen '蛇身颜色
Public Const EMPTY_COLOR As Long = &HE0E0E0 '空白地颜色
Public Const FOOD_COLOR As Long = vbBlue '食物颜色
Public Const BOMB_COLOR As Long = vbRed '炸d颜色
Public Const FULL_COLOR As Long = 255 ^ 3
Public Const RECORD_FILE_NAME As String = "\recorddat" '记录得分榜的 文件名
Public Const MAX_PRIZE As Integer = 50 '起始 奖励分数的 上限
Public Const MIN_PRIZE As Integer = 20 '起始 奖励分数的 下限
'全局 变量
'记录玩家的相关信息和设置值:
Public Type thePlayerInfo
Score As Integer '记录得分
HeadColor As Long '蛇头填充色
BodyColor As Long '蛇身填充色
Food As Integer '记录吃进的 食物数量
Bomb As Integer '记录吃进的 炸d数量
blnGameOver As Boolean '标记该玩家是否已经game over
' SnakeColor As Long '绘画蛇身使用的填充色……暂时省略……
SnakeLength As Integer '蛇身长度
'蛇头移动方向(值为 -1,0,1)
X_Way As Integer
Y_Way As Integer
'控制键(8个)……暂时省略(采用默认控制键)
End Type
'记录 玩家的得分和名字
Type theRecord
Name As String 15
Score As Integer
End Type
'用于表示二维坐标值
Public Type thePosition
X As Integer
Y As Integer
End Type
Public FoodCount_AtOneTime As Integer '地图上同时出现的 食物数量
Public BombCount_AtOneTime As Integer '地图上同时出现的 炸d数量
Public PrizeRemain As Integer '当前剩余的 奖励分数
Public EatCountPerShowPrize '记录 蛇每吃进多少物品(包括食物和炸d,奖品不计)才显示一次奖品
Public AddScorePerFood As Integer '每吃进一个 食物,所增加的分数
Public AddScorePerBomb As Integer '每吃进一个 炸d,所扣掉的分数
Sub Main()
frmPlayShow
frmScoreListShow '第一次运行时先显示得分榜
End Sub
Private blnStartGame As Boolean '标记是否已经开始 新游戏(T=游戏已经开始)
Private blnPause As Boolean '标记当前是否处于暂停状态(T=暂停)
Private blnThroughWall As Boolean '标记是否为穿墙模式(T=可以穿墙)
Private blnOnKeyEvents As Boolean '标记是否能够 接收键盘事件(T=可以接收),此变量可防止 Form_KeyDown()事件重复执行
Private Map_Width As Integer '地图宽度(象素)
Private Map_Height As Integer '地图高度(象素)
Private Map_Empty_Color '地图-空白地颜色
Private Map_Bomb_Color '地图-炸d颜色
Private Map_Food_Color '地图-食物颜色
Private MapProperty() As Integer '记录地图各个网格的属性
Private curEatCount As Integer '记录 每次出现奖品之前,一共吃进多少物品(包括食物和炸d,奖品不计),当奖品出现后,此变量值变为 零"0",然后进入下一次统计
Private curLevel As Integer '当前级别
Private P1 As thePlayerInfo '记录Player1 的信息
Private Snake_P1() As thePosition '记录蛇身坐标
Private PrizePos As thePosition '记录奖品的坐标
Private Record(9) As theRecord '存放前十名的 得分记录信息
Option Explicit
Private Sub cmdHelp_Click()
If blnPause = False Then Call Form_KeyDown(KEY_PAUSE, 0) '如果游戏正在进行,则发送“暂停”按键事件,暂停游戏
frmHelpShow

End Sub
'开始新游戏
Private Sub cmdNewGame_Click()
Dim i As Integer

Randomize '重新生成随机数列

blnStartGame = Not blnStartGame
If blnStartGame Then
cmdNewGameCaption = "停止"
Else
cmdNewGameCaption = "新游戏"
End If
'中止游戏
If blnStartGame = False Then
'如果上一次的奖品还没有消失(以 PrizeRemain > 0 为标志),就先清除旧的奖品,然后才显示新的奖品
If PrizeRemain > 0 Then Call ShowPrize(False)
picDisplayCls

P1Score = 0 '玩家的初始分数
P1Food = 0
P1Bomb = 0
curEatCount = 0
PrizeRemain = 0
blnPause = False
lblPauseVisible = False
lblScoreCaption = P1Score
lblFoodCountCaption = P1Food
lblBombCountCaption = P1Bomb
P1blnGameOver = True
HscrLevelEnabled = True
tmrMoveEnabled = False
Exit Sub
End If

blnThroughWall = True '穿墙模式
blnOnKeyEvents = True

'暂时使用默认填充色
Map_Bomb_Color = BOMB_COLOR
Map_Empty_Color = EMPTY_COLOR
Map_Food_Color = FOOD_COLOR
P1BodyColor = BODY_COLOR
P1HeadColor = HEAD_COLOR

'地图初始化
ReDim MapProperty(MAX_COL_INDEX, MAX_ROW_INDEX)
Map_Width = (MAX_COL_INDEX + 1) MAP_SCALE
Map_Height = (MAX_ROW_INDEX + 1) MAP_SCALE
picDisplayCls
picDisplayWidth = Map_Width + 2
picDisplayHeight = Map_Height + 2
picDisplayLine (0, 0)-Step(Map_Width, Map_Height), Map_Empty_Color, BF

FoodCount_AtOneTime = 2 '地图上同时存在的 食物数量
BombCount_AtOneTime = 1 '地图上同时存在的 炸d数量

EatCountPerShowPrize = 5 '设置 蛇每吃进多少物品(包括食物和炸d,奖品不计)才显示一次奖品

curLevel = HscrLevelValue
AddScorePerFood = curLevel '每吃进一个 食物,所增加的分数=当前的级别值
AddScorePerBomb = -curLevel 2 '每吃进一个 炸d,所扣掉的分数

P1Score = Abs(AddScorePerBomb) + 1 '玩家的初始分数='每吃进一个 炸d,所扣掉的分数+1
P1Food = 0
P1Bomb = 0
PrizeRemain = 0
P1blnGameOver = False
lblScoreCaption = P1Score
lblFoodCountCaption = P1Food
lblBombCountCaption = P1Bomb

'初始化P1蛇身
ReDim Snake_P1(START_SNAKE_LENGTH)
For i = 0 To UBound(Snake_P1)
'设定蛇身各段的起始位置
Snake_P1(i)X = MAX_COL_INDEX - UBound(Snake_P1) + i
Snake_P1(i)Y = MAX_ROW_INDEX
'初始化移动方向
P1X_Way = -1
P1Y_Way = 0
MapProperty(Snake_P1(i)X, Snake_P1(i)Y) = MAP_SNAKE
picDisplayLine (Snake_P1(i)X MAP_SCALE, Snake_P1(i)Y MAP_SCALE)-Step(MAP_SCALE, MAP_SCALE), BODY_COLOR, BF
Next
'使用蛇头颜色 重新绘画蛇头
picDisplayLine (Snake_P1(0)X MAP_SCALE, Snake_P1(0)Y MAP_SCALE)-Step(MAP_SCALE, MAP_SCALE), HEAD_COLOR, BF
'放置食物
For i = 1 To FoodCount_AtOneTime
Call AddFood
Next

'放置炸d
For i = 1 To BombCount_AtOneTime
Call AddBomb
Next

lblPauseVisible = False
lblScoreCaption = P1Score
lblFoodCountCaption = P1Food
lblBombCountCaption = P1Bomb

P1blnGameOver = False
HscrLevelEnabled = False '游戏进行期间不能改变级别
tmrMoveEnabled = True
End Sub
'显示得分榜
Private Sub cmdShowScoreList_Click()
If blnPause = False Then Call Form_KeyDown(KEY_PAUSE, 0) '如果游戏正在进行,则发送“暂停”按键事件,暂停游戏
frmScoreListShow

End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

If P1blnGameOver Or blnStartGame = False Or blnOnKeyEvents = False Then Exit Sub '以下情况(游戏结束、游戏还没有开始、禁用击键事件)不接收按键 *** 作。

'按“Numpad 5”键--暂停/继续
If KeyCode = KEY_PAUSE Then
blnPause = Not blnPause
lblPauseVisible = blnPause
tmrMoveEnabled = Not blnPause
Exit Sub
End If

If blnPause Then Exit Sub '在暂停状态下不接受“ESC”外的其它按键

Select Case KeyCode
Case KEY_LFUP
blnOnKeyEvents = False
If P1X_Way <> 0 Then
P1X_Way = 0
P1Y_Way = -1
ElseIf P1Y_Way <> 0 Then
P1X_Way = -1
P1Y_Way = 0
End If
Case KEY_LFDN
blnOnKeyEvents = False
If P1X_Way <> 0 Then
P1X_Way = 0
P1Y_Way = 1
ElseIf P1Y_Way <> 0 Then
P1X_Way = -1
P1Y_Way = 0
End If

Case KEY_RTUP
blnOnKeyEvents = False
If P1X_Way <> 0 Then
P1X_Way = 0
P1Y_Way = -1
ElseIf P1Y_Way <> 0 Then
P1X_Way = 1
P1Y_Way = 0
End If
Case KEY_RTDN
blnOnKeyEvents = False
If P1X_Way <> 0 Then
P1X_Way = 0
P1Y_Way = 1
ElseIf P1Y_Way <> 0 Then
P1X_Way = 1
P1Y_Way = 0
End If

'当蛇以 水平 方向移动时,LF 和 RT 按键无效
Case KEY_LF
blnOnKeyEvents = False
If P1X_Way = 0 Then
P1X_Way = -1
P1Y_Way = 0
End If
Case KEY_RT
blnOnKeyEvents = False
If P1X_Way = 0 Then
P1X_Way = 1
P1Y_Way = 0
End If

'当蛇以 垂直 方向移动时,UP 和 DN 按键无效
Case KEY_UP
blnOnKeyEvents = False
If P1Y_Way = 0 Then
P1X_Way = 0
P1Y_Way = -1
End If
Case KEY_DN
blnOnKeyEvents = False
If P1Y_Way = 0 Then
P1X_Way = 0
P1Y_Way = 1
End If

Case Else
Exit Sub
End Select

tmrMoveEnabled = False '暂停Timer事件,等到本次移动 *** 作全部完成后(即sub RefreshSnake()过程执行完毕),再启动Timer

Call PlayerMove

End Sub


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10462475.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-08
下一篇2023-05-08

发表评论

登录后才能评论

评论列表(0条)

    保存