'定义蛇的运动速度枚举值
Private Enum tpsSpeed
QUICKLY = 0
SLOWLY = 1
End Enum
'定义蛇的运动方向枚举值
Private Enum tpsDirection
D_UP = 38
D_DOWN = 40
D_LEFT = 37
D_RIGHT = 39
End Enum
'定义运动区域4个禁区的枚举值
Private Enum tpsForbiddenZone
FZ_TOP = 30
FZ_BOTTOM = 5330
FZ_LEFT = 30
FZ_RIGHT = 5730
End Enum
'定义蛇头及身体初始化数枚举值
Private Enum tpsSnake
SNAKEONE = 1
SNAKETWO = 2
SNAKETHREE = 3
SNAKEFOUR = 4
End Enum
'定义蛇宽度的常量
Private Const SNAKEWIDTH As Integer = 100
'该过程用于显示游戏信息
Private Sub Form_Load()
MeShow
MelblTitle = "BS贪食蛇 — (版本 " & AppMajor & "" & AppMinor & "" & AppRevision & ")"
MeCaption = MelblTitleCaption
frmSplashShow 1
End Sub
'该过程用于使窗体恢复原始大小
Private Sub Form_Resize()
If MeWindowState <> 1 Then
MeCaption = ""
MeHeight = 6405 '窗体高度为 6405 缇
MeWidth = 8535 '窗体宽度为 8535 缇
MeLeft = (ScreenWidth - Width) \ 2
MeTop = (ScreenHeight - Height) \ 2
End If
End Sub
'该过程用于重新开始开始游戏
Private Sub cmdGameStart_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Beep
msg = MsgBox("您确认要重新开始游戏吗?", 4 + 32, "BS贪食蛇")
If msg = 6 Then Call m_subGameInitialize
End Sub
'该过程用于暂停/运行游戏
Private Sub chkPause_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If MechkPauseCaption = "暂停游戏(&P)" Then
MetmrSnakeMoveEnabled = False
MetmrGameTimeEnabled = False
MepicMoveAreaEnabled = False
MelblPauseLabVisible = True
MechkPauseCaption = "继续游戏(&R)"
Else
MetmrSnakeMoveEnabled = True
MetmrGameTimeEnabled = True
MepicMoveAreaEnabled = True
MelblPauseLabVisible = False
MechkPauseCaption = "暂停游戏(&P)"
End If
End Sub
'该过程用于显示游戏规则
Private Sub cmdGameRules_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Beep
MsgBox " BS贪食蛇:一个规则最简单的趣味游戏,您将用键盘" & Chr(13) & _
"上的4个方向键来控制蛇的运动方向。在运动过程中蛇" & Chr(13) & _
"不能后退,蛇的头部也不能接触到运动区域的边线以外" & Chr(13) & _
"和蛇自己的身体,否则就游戏失败。在吃掉随机出现的" & Chr(13) & _
"果子后,蛇的身体会变长,越长难度越大。祝您好运!!", 0 + 64, "游戏规则"
End Sub
'该过程用于显示游戏开发信息
Private Sub cmdAbout_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Beep
MsgBox "BS贪食蛇" & "(V-" & AppMajor & "" & AppMinor & "版本)" & Chr(13) & Chr(13) & _
"" & Chr(13) & Chr(13) & _
"由PigheadPrince设计制作" & Chr(13) & _
"CopyRight(C)2002,BestSoftTCG", 0, "关于本游戏"
End Sub
'该过程用于退出游戏
Private Sub cmdExit_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Beep
msg = MsgBox("您要退出本游戏吗?", 4 + 32, "BS贪食蛇")
Select Case msg
Case 6
End
Case 7
MechkWindowButton(2)Value = 0
Exit Sub
End Select
End Sub
'该过程用于拖动窗体_(点击图标)
Private Sub imgWindowTop_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
ReleaseCapture
SendMessage Mehwnd, WM_SYSCOMMAND, SC_MOVE, 0
End Sub
'该共用过程用于处理窗体控制按钮组的相关操作_(锁定、最小化、退出)
Private Sub chkWindowButton_MouseUp(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button <> 1 Then Exit Sub
Select Case Index
Case 0 '锁定窗体
If MechkWindowButton(0)Value = 1 Then
MeimgWindowTopBorderStyle = 0
MeimgWindowTopEnabled = False
Else
MeimgWindowTopBorderStyle = 1
MeimgWindowTopEnabled = True
End If
Case 1 '最小化
MeWindowState = 1
MechkWindowButton(1)Value = 0
MeCaption = "BS贪食蛇 — (V-" & AppMajor & "" & AppMinor & "版本)"
Case 2 '退出
Beep
msg = MsgBox("您要退出本游戏吗?", 4 + 32, "BS贪食蛇")
Select Case msg
Case 6
End
Case 7
MechkWindowButton(2)Value = 0
Exit Sub
End Select
End Select
End Sub
'该过程用于设置蛇运动速度的快慢
Private Sub hsbGameSpeed_Change()
MetmrSnakeMoveInterval = MehsbGameSpeedValue
End Sub
'该过程用于通过键盘的方向键改变蛇的运动方向
Private Sub picMoveArea_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case g_intDirection
Case D_UP
If KeyCode = D_DOWN Then Exit Sub
Case D_DOWN
If KeyCode = D_UP Then Exit Sub
Case D_LEFT
If KeyCode = D_RIGHT Then Exit Sub
Case D_RIGHT
If KeyCode = D_LEFT Then Exit Sub
End Select
g_intDirection = KeyCode
End Sub
'该计时循环过程用于计算游戏耗费的秒数并显示
Private Sub tmrGameTime_Timer()
g_lngGameTime = g_lngGameTime + 1
MelblGameTimeCaption = g_lngGameTime & "秒"
End Sub
'该计时循环过程用于控制蛇的行动轨迹
Private Sub tmrSnakeMove_Timer()
Dim lngSnakeX As Long, lngSnakeY As Long, lngSnakeColor As Long
Dim lngPointX As Long, lngPointY As Long, lngPointColor As Long
Randomize
MepicMoveAreaSetFocus
MepicMoveAreaCls
'确认蛇头的运动方向并获取新的位置
Select Case g_intDirection
Case D_UP '向上运动
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_OldX
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_OldY
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_CurY - SNAKEWIDTH
Case D_DOWN '向下运动
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_OldX
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_OldY
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_CurY + SNAKEWIDTH
Case D_LEFT '向左运动
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_OldX
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_CurX - SNAKEWIDTH
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_OldY
Case D_RIGHT '向右运动
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_OldX
g_udtSnake(SNAKEONE)Snake_CurX = g_udtSnake(SNAKEONE)Snake_CurX + SNAKEWIDTH
g_udtSnake(SNAKEONE)Snake_CurY = g_udtSnake(SNAKEONE)Snake_OldY
End Select
'根据新的位置绘制蛇头
lngSnakeX = g_udtSnake(SNAKEONE)Snake_CurX
lngSnakeY = g_udtSnake(SNAKEONE)Snake_CurY
lngSnakeColor = g_udtSnake(SNAKEONE)Snake_Color
MepicMoveAreaPSet (lngSnakeX, lngSnakeY), lngSnakeColor
'移动蛇身体其他部分的位置
For i = 2 To g_intSnakeLength
g_udtSnake(i)Snake_CurX = g_udtSnake(i - 1)Snake_OldX
g_udtSnake(i)Snake_CurY = g_udtSnake(i - 1)Snake_OldY
lngSnakeX = g_udtSnake(i)Snake_CurX
lngSnakeY = g_udtSnake(i)Snake_CurY
lngSnakeColor = g_udtSnake(i)Snake_Color
MepicMoveAreaPSet (lngSnakeX, lngSnakeY), lngSnakeColor
Next i
'更新蛇旧的坐标位置
For j = 1 To g_intSnakeLength
g_udtSnake(j)Snake_OldX = g_udtSnake(j)Snake_CurX
g_udtSnake(j)Snake_OldY = g_udtSnake(j)Snake_CurY
Next j
'判断蛇在移动中是否到了禁区而导致游戏失败
If m_funMoveForbiddenZone(g_udtSnake(SNAKEONE)Snake_CurX, g_udtSnake(SNAKEONE)Snake_CurY) Then
Beep
MsgBox "您的蛇移动到了禁区,游戏失败!", 0 + 16, "BS贪食蛇"
MetmrSnakeMoveEnabled = False
MetmrGameTimeEnabled = False
MepicMoveAreaVisible = False
Exit Sub
End If
'判断蛇在移动中是否碰到了自己的身体而导致游戏失败
If m_funTouchSnakeBody(g_udtSnake(SNAKEONE)Snake_CurX, g_udtSnake(SNAKEONE)Snake_CurY) Then
Beep
MsgBox "您的蛇在移动中碰到了自己的身体,游戏失败!", 0 + 16, "BS贪食蛇"
MetmrSnakeMoveEnabled = False
MetmrGameTimeEnabled = False
MepicMoveAreaVisible = False
Exit Sub
End If
'判断蛇是否吃到了果子
If m_funEatPoint(g_udtSnake(SNAKEONE)Snake_CurX, g_udtSnake(SNAKEONE)Snake_CurY) Then
'累加玩家的得分并刷新得分显示
g_intPlayerScore = g_intPlayerScore + 1
MelblYourScoreCaption = g_intPlayerScore & "分"
Call m_subAddSnake '加长蛇的身体
Call m_subGetPoint '获取下一个果子的位置和颜色
Else
'绘制果子
lngPointX = g_udtPointPoint_X
lngPointY = g_udtPointPoint_Y
lngPointColor = g_udtPointPoint_Color
MepicMoveAreaPSet (lngPointX, lngPointY), lngPointColor
End If
End Sub
'该私有子过程用于初始化游戏
Private Sub m_subGameInitialize()
Erase g_udtSnake '清空蛇的结构数组
g_intPlayerScore = 0 '清空玩家的得分
g_lngGameTime = 0 '清空游戏耗费的秒数
g_intDirection = D_DOWN '设定蛇的初始运动方向为下
g_intSnakeLength = 4 '设定蛇的初始长度
ReDim g_udtSnake(1 To g_intSnakeLength) '重新定义蛇的长度
'定义蛇头部的数据
With g_udtSnake(SNAKEONE)
Snake_OldX = 530
Snake_OldY = 530
Snake_Color = vbBlack
End With
'定义蛇身第2节的数据
With g_udtSnake(SNAKETWO)
Snake_OldX = 530
Snake_OldY = 430
Snake_Color = vbGreen
End With
'定义蛇身第3节的数据
With g_udtSnake(SNAKETHREE)
Snake_OldX = 530
Snake_OldY = 330
Snake_Color = vbYellow
End With
'定义蛇身第4节的数据
With g_udtSnake(SNAKEFOUR)
Snake_OldX = 530
Snake_OldY = 230
Snake_Color = vbRed
End With
MepicMoveAreaVisible = True
MelblYourScoreCaption = g_intPlayerScore & "分"
MelblGameTimeCaption = g_lngGameTime & "秒"
MetmrSnakeMoveInterval = MehsbGameSpeedValue
MetmrSnakeMoveEnabled = True
MetmrGameTimeEnabled = True
Call m_subGetPoint '获取第一个果子的位置和颜色
End Sub
'该私有子过程用于返回获取的果子的位置和颜色信息
Private Sub m_subGetPoint()
Dim lngRedValue As Long, lngGreenValue As Long, lngBlueValue As Long
Dim lngPointX As Long, lngPointY As Long, lngPointColor As Long
'随机获取果子的颜色
lngRedValue = Int((255 - 0 + 1) Rnd + 0)
lngGreenValue = Int((255 - 0 + 1) Rnd + 0)
lngBlueValue = Int((255 - 0 + 1) Rnd + 0)
lngPointColor = RGB(lngRedValue, lngGreenValue, lngBlueValue)
'随机获取果子的位置
lngPointX = Int((FZ_LEFT - FZ_RIGHT + 1) Rnd + FZ_RIGHT)
lngPointY = Int((FZ_TOP - FZ_BOTTOM + 1) Rnd + FZ_BOTTOM)
MePSet (lngPointX, lngPointY), lngPointColor
'设置函数返回值
With g_udtPoint
Point_X = lngPointX
Point_Y = lngPointY
Point_Color = lngPointColor
End With
End Sub
'该私有子过程用于加长蛇的身体
Private Sub m_subAddSnake()
Dim udtSnakeTemp() As Snake
Dim lngSnakeX As Long, lngSnakeY As Long, lngSnakeColor As Long
'备份蛇原先身体的数据并使蛇的身体加长
ReDim udtSnakeTemp(1 To g_intSnakeLength)
For k = 1 To g_intSnakeLength
With udtSnakeTemp(k)
Snake_CurX = g_udtSnake(k)Snake_CurX
Snake_CurY = g_udtSnake(k)Snake_CurY
Snake_OldX = g_udtSnake(k)Snake_OldX
Snake_OldY = g_udtSnake(k)Snake_OldY
Snake_Color = g_udtSnake(k)Snake_Color
End With
Next k
g_intSnakeLength = g_intSnakeLength + 1
ReDim g_udtSnake(g_intSnakeLength)
'将备份蛇身体的数据返回到加长的蛇身数组中
For l = 1 To g_intSnakeLength - 1
With g_udtSnake(l)
Snake_CurX = udtSnakeTemp(l)Snake_CurX
Snake_CurY = udtSnakeTemp(l)Snake_CurY
Snake_OldX = udtSnakeTemp(l)Snake_OldX
Snake_OldY = udtSnakeTemp(l)Snake_OldY
Snake_Color = udtSnakeTemp(l)Snake_Color
End With
Next l
'写入新加入的身体数据
Select Case g_intDirection
Case D_UP
With g_udtSnake(g_intSnakeLength)
Snake_OldX = g_udtSnake(g_intSnakeLength - 1)Snake_CurX + SNAKEWIDTH
Snake_OldY = g_udtSnake(g_intSnakeLength - 1)Snake_CurY
Snake_Color = g_udtPointPoint_Color
End With
Case D_DOWN
With g_udtSnake(g_intSnakeLength)
Snake_OldX = g_udtSnake(g_intSnakeLength - 1)Snake_CurX - SNAKEWIDTH
Snake_OldY = g_udtSnake(g_intSnakeLength - 1)Snake_CurY
Snake_Color = g_udtPointPoint_Color
End With
Case D_LEFT
With g_udtSnake(g_intSnakeLength)
Snake_OldX = g_udtSnake(g_intSnakeLength - 1)Snake_CurX
Snake_OldY = g_udtSnake(g_intSnakeLength - 1)Snake_CurY + SNAKEWIDTH
Snake_Color = g_udtPointPoint_Color
End With
Case D_RIGHT
With g_udtSnake(g_intSnakeLength)
Snake_OldX = g_udtSnake(g_intSnakeLength - 1)Snake_CurX
Snake_OldY = g_udtSnake(g_intSnakeLength - 1)Snake_CurY - SNAKEWIDTH
Snake_Color = g_udtPointPoint_Color
End With
End Select
lngSnakeX = g_udtSnake(g_intSnakeLength)Snake_CurX
lngSnakeY = g_udtSnake(g_intSnakeLength)Snake_CurY
lngSnakeColor = g_udtSnake(g_intSnakeLength)Snake_Color
MepicMoveAreaPSet (lngSnakeX, lngSnakeY), lngSnakeColor
End Sub
'该自定义函数用于返回运动的蛇是否到达禁区而导致游戏失败
Private Function m_funMoveForbiddenZone(SnakeX As Long, SnakeY As Long) As Boolean
If (SnakeX >= FZ_LEFT And SnakeX <= FZ_RIGHT) And (SnakeY >= FZ_TOP And SnakeY <= FZ_BOTTOM) Then
m_funMoveForbiddenZone = False
Else
m_funMoveForbiddenZone = True
End If
End Function
'该自定义函数用于返回运动的蛇是否碰到自己的身体而导致游戏失败
Private Function m_funTouchSnakeBody(SnakeX As Long, SnakeY As Long) As Boolean
For m = 2 To g_intSnakeLength
If SnakeX = g_udtSnake(m)Snake_CurX And SnakeY = g_udtSnake(m)Snake_CurY Then
m_funTouchSnakeBody = True
Exit For
Else
m_funTouchSnakeBody = False
End If
Next m
End Function
'该自定义函数用于返回运动的蛇是否吃到了果子
Private Function m_funEatPoint(SnakeX As Long, SnakeY As Long) As Boolean
If Abs(SnakeX - g_udtPointPoint_X) <= SNAKEWIDTH And Abs(SnakeY - g_udtPointPoint_Y) <= SNAKEWIDTH Then
m_funEatPoint = True
Else
m_funEatPoint = False
End If
End Function
'(API函数调用过程_用以实现无标题窗体的拖动操作)---------------------------------
'RleaseCapture函数用以释放鼠标捕获
Public Declare Function ReleaseCapture Lib "user32" () As Long
'SendMessage函数用作向Windows发送移动窗体的消息
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As _
Long, ByVal wMsg As Long, ByVal wParam As Long, IParam As Any) As Long
Public Const WM_SYSCOMMAND = &H112 '声明向Windows发送消息的常量
Public Const SC_MOVE = &HF012 '声明控制移动窗体常量
'(游戏变量声明部分)-------------------------------------------------------------
'定义蛇的数据类型结构
Public Type Snake
Snake_OldX As Long
Snake_OldY As Long
Snake_CurX As Long
Snake_CurY As Long
Snake_Color As Long
End Type
'定义果子的数据类型结构
Public Type Point
Point_X As Long
Point_Y As Long
Point_Color As Long
End Type
'定义蛇的动态数组
Public g_udtSnake() As Snake
'定义果子
Public g_udtPoint As Point
'定义蛇的长度
Public g_intSnakeLength As Integer
'定义蛇的颜色
Public g_lngSnakeColor As Long
'定义蛇的运动方向
Public g_intDirection As Integer
'定义玩家的得分
Public g_intPlayerScore As Integer
'定义游戏耗费的秒数
Public g_lngGameTime As Long
/
贪吃蛇游戏,由于是C++源码 且 用到Windows API ,是控制台界面不是图形界面,需要用VC++60 或 VC++2010 在windows环境编译运行。如果符合上述条件一定可以编译运行zjlj,2015316
/
#define DEBUG 0 //当程序在调试阶段时 DEBUG为 1
#include<iostream>
#include<windowsh>
#include<timeh>
#include<conioh>
using namespace std;
void readini(FILE fphead, int score, char argv[]) //创建或打开一个和运行文件对应的ini文件,读取最高纪录
{
char filename[200],pfilename;
int flag=-1,i;
strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{
if (''==filename[i])flag=1;
}
if(1==flag)
{
filename[i-1]='i';
filename[i-2]='n';
filename[i-3]='i';
}
else
{
filename[i]='';
filename[i+1]='i';
filename[i+2]='n';
filename[i+3]='i';
filename[i+4]='\0';
}
for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];
if ( (fphead=fopen(pfilename, "rb+"))==NULL)
{
if ( (fphead=fopen(pfilename, "wb+"))==NULL)
{
printf("无法创建或打开\"%s\"文件\n",pfilename);
system("pause");
exit(0);
}
}
else
{
fread(score,sizeof(int),1,fphead);
}
}
void writeini(FILE fphead, int score, char argv[]) //打开一个和运行文件对应的ini文件,写入最高纪录
{
char filename[200],pfilename;
int flag=-1,i;
strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{
if (''==filename[i])flag=1;
}
if(1==flag)
{
filename[i-1]='i';
filename[i-2]='n';
filename[i-3]='i';
}
else
{
filename[i]='';
filename[i+1]='i';
filename[i+2]='n';
filename[i+3]='i';
filename[i+4]='\0';
}
for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];
if ( (fphead=fopen(pfilename, "wb+"))==NULL)
{
printf("无法写入\"%s\"文件,磁盘写保护!\n",pfilename);
system("pause");
exit(0);
}
else
{
rewind(fphead);
fwrite(score,sizeof(int),1,fphead);
fclose(fphead);
}
}
void gotoxy(int x,int y)//光标定位,光标定位函数SetConsoleCursorPosition是左上角位置是0,0然后向左向下延伸
{
COORD pos;
posX=2y;
posY=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void color(int a)//颜色函数
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
void Refresh(int q[][22], int grade, int gamespeed, int length,int score) // 输出贪吃蛇棋盘
{
int i,j;
for(i=0;i<22;i++)
{
for(j=0;j<22;j++)
{
if(q[i][j]==0)//输出棋盘空白
{
gotoxy(i,j);
color(11);
cout<<"■";
}
if(q[i][j]==1||q[i][j]==2)//输出棋盘墙壁
{
gotoxy(i,j);
color(11);
cout<<"□";
}
if(q[i][j]==3)//输出蛇头
{
gotoxy(i,j);
color(14);
cout<<"★";
}
if(q[i][j]==4)//输出蛇身
{
gotoxy(i,j);
color(12);
cout<<"◆";
}
if(q[i][j]==5)//输出果子
{
gotoxy(i,j);
color(12);
cout<<"●";
}
}
if(i==0) cout << "\t";
if(i==1) cout << "\t等级为:" << grade;//显示等级
if(i==3) cout << "\t自动前进时间";
if(i==4) cout << "\t间隔为:" << gamespeed << "ms";//显示时间
if(i==6) cout << "\t历史最高分为:" << score << "分";
if(i==7) cout << "\t你现在得分为:" << (length+(grade-1)8)10 << "分";
if(i==8) cout << "\t";
if(i==9) cout << "\t游戏说明:";
if(i==10) cout << "\t(1)用小键盘方向键控制";
if(i==11) cout << "\t蛇头运动方向;";
if(i==12) cout << "\t(2)蛇每吃一个果子蛇身";
if(i==13) cout << "\t增加一节;";
if(i==14) cout << "\t(3)蛇咬到自己或碰到墙";
if(i==15) cout << "\t壁游戏结束。";
if(i==18) cout << "\t";
if(i==19) cout << "\tC/C++语言作业:";
if(i==20) cout << "\tzjlj,20150316 ";
}
}
int main(int argc, char argv[]){
int tcsQipan[22][22]; // 贪吃蛇棋盘是一个二维数组(如2222,包括墙壁)
int i,j,score,directiontemp;
FILE fpini;//fpini 信息文件
readini(&fpini, &score, argv);//读取ini文件的最高纪录
if (score<0)//最高成绩小于零设置为零,初建文件会是负数
score=0;
while(1)
{
for(i=1;i<=20;i++)
for(j=1;j<=20;j++)
tcsQipan[i][j]=0; //贪吃蛇棋盘相应坐标标上中间空白部分的标志0
for(i=0;i<=21;i++)
tcsQipan[0][i] = tcsQipan[21][i] = 1; //贪吃蛇棋盘相应坐标标上上下墙壁的标志1
for(i=1;i<=20;i++)
tcsQipan[i][0] = tcsQipan[i][21] = 2; //贪吃蛇棋盘相应坐标标上左右墙壁的标志2
int tcsZuobiao[2][500]; //蛇的坐标数组
for(i=0; i<4; i++)
{
tcsZuobiao[0][i] = 1;//蛇身和蛇头的x坐标
tcsZuobiao[1][i] = i + 1;//蛇身和蛇头的y坐标
}
int head = 3,tail = 0;//标示蛇头和蛇尾的数组偏移量
for(i=1;i<=3;i++)
tcsQipan[1][i]=4; //蛇身
tcsQipan[1][4]=3; //蛇头
int x1, y1; // 随机出果子
srand(time(0));//设置随机种子
do
{
x1=rand()%20+1;
y1=rand()%20+1;
}
while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子
tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5
color(12);
cout<<"\n\n\t\t\t\t贪吃蛇游戏即将开始 !"<<endl;//准备开始
long start,starttemp;
int grade = 1, length = 4; //设置初始等级和蛇的初始长度
int gamespeed = 500; //设置初始前进时间间隔
for(i=3;i>=0;i--)
{
start=clock();
while(clock()-start<=1000);
system("cls");
if(i>0)
cout << "\n\n\t\t\t\t进入倒计时:" << i << endl; //倒计时显示
else
Refresh(tcsQipan,grade,gamespeed,length,score); //初始棋盘显示
}
int timeover=1,otherkey=1;//初始化超时时间和按键判断参数
char direction = 77; // 设置初始情况下,向右运动
int x=tcsZuobiao[0][head],y=tcsZuobiao[1][head];//保存蛇头坐标到x,y变量
while(1)//运行一局游戏
{
start = clock();
while((timeover=((starttemp=clock())-start<=gamespeed))&&!kbhit());//如果有键按下或时间超过自动前进时间间隔则终止循环
if(direction==72||direction==80||direction==75 ||direction==77)
directiontemp=direction;//保留上一次方向按键
//starttemp=gamespeed+start-starttemp;//保留停留时间
if(timeover)
{
#if (DEBUG==1)
direction = getch();//调试代码
#else
if((direction =getch())==-32)
direction = getch();
#endif
}
#if (DEBUG==1)//调试代码
start=clock();
while(clock()-start<=2000);
gotoxy(24,4);
cout << "\t按键ASCII代码"<<(int)direction<<" "<<endl;
#endif
if(!(direction==72||direction==80||direction==75 ||direction==77))
{
otherkey=0;// 按键非方向键,otherkey设置为0
}
else
{
otherkey=1;// 按键为方向键,otherkey设置为1
}
if(direction==72 && directiontemp==80)//忽略反方向按键
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
else if(direction==80 && directiontemp==72)
{
direction=32;//设置按键为非方向键
otherkey=0;// 按键为非方向键,otherkey设置为0
// start = clock();
//while(clock()-start<=starttemp);//补偿等待时间
}
else if(direction==75 && directiontemp==77)
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
else if(direction==77 && directiontemp==75)
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
switch(direction)//判断方向键
{
case 72: x= tcsZuobiao[0][head]-1; y= tcsZuobiao[1][head];break; // 向上
case 80: x= tcsZuobiao[0][head]+1; y= tcsZuobiao[1][head];break; // 向下
case 75: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]-1;break; // 向左
case 77: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]+1;break; // 向右
default: break;
}
if(x==0 || x==21 ||y==0 || y==21) // 蛇头碰到墙壁,结束本局游戏
{
gotoxy(22,12);
cout << "\t游戏已结束!" << endl;
if(score>=(length+(grade-1)8)10)//判断是否破记录
{
gotoxy(10,7);
color(12);
cout << "闯关失败 加油耶!" << endl;
fclose(fpini);//关闭ini文件
}
else
{
gotoxy(10,7);
color(12);
cout << "恭喜您打破记录" << endl;
score=(length+(grade-1)8)10;
writeini(&fpini, &score, argv);//写入ini文件的最高纪录
}
gotoxy(23,12);
cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示
break;//退出该局游戏
}
if(tcsQipan[x][y]!=0&&!(x==x1&&y==y1)&&tcsQipan[x][y]!=3) // 蛇头碰到蛇身,结束本局游戏
{
gotoxy(22,12);
cout << "\t游戏已结束!" << endl;
if(score>=(length+(grade-1)8)10)//判断是否破记录
{
gotoxy(10,7);
color(12);
cout << "闯关失败 加油耶!" << endl;
fclose(fpini);//关闭ini文件
}
else
{
gotoxy(10,7);
color(12);
cout << "恭喜您打破记录" << endl;
score=(length+(grade-1)8)10;
writeini(&fpini, &score, argv);//写入ini文件的最高纪录
}
gotoxy(23,12);
cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示
break;//退出该局游戏
}
/
游戏运行时的核心算法开始
/
if(x==x1 && y==y1) // 吃果子,长度加1
{
length ++;
if(length>=8)//长度大于等于8重新计算长度,等级加1
{
length -= 8;//重新计算长度
grade ++;//等级加1
if(gamespeed>50)//控制最快速度为50
gamespeed = 550 - grade 50; // 改变自动前进时间间隔
}
tcsQipan[x][y]= 3;//贪吃蛇棋盘相应坐标现在蛇头标志改为蛇头标志3
tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;//贪吃蛇棋盘相应坐标原来蛇头标志改为蛇身标志4
head = (head+1)%400;//防止数组越界
tcsZuobiao[0][head] = x;//蛇头的x坐标
tcsZuobiao[1][head] = y;//蛇头的y坐标
do//随机出果子
{
x1=rand()%20+1;
y1=rand()%20+1;
}
while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子
tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5
gotoxy(22,12);
cout << "\t游戏进行中!" << endl;
Refresh(tcsQipan,grade,gamespeed,length,score);
}
else // 不吃果子
{
if(otherkey)
{
tcsQipan [tcsZuobiao[0][tail]][tcsZuobiao[1][tail]]=0;
tail=(tail+1)%400;//防止数组越界
tcsQipan [tcsZuobiao[0][head]][tcsZuobiao[1][head]]=4;
head=(head+1)%400;//防止数组越界
tcsZuobiao[0][head]=x;//蛇头的x坐标
tcsZuobiao[1][head]=y;//蛇头的y坐标
tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=3;
gotoxy(22,12);
cout << "\t游戏进行中!" << endl;
Refresh(tcsQipan,grade,gamespeed,length,score);
}
else
{
gotoxy(22,12);
cout << "\t游戏暂停中!" << endl;
}
}
/
游戏运行时的核心算法结束
/
}
while(1)
{
while(!kbhit());
if((direction =getch())==13)//按回车键开始下一局
break;
if(direction ==27)//按ESC退出游戏
exit(0);
}
system("cls");//清除屏幕重新开始
}
return 0;
}
C语言贪吃蛇源代码必须经过相应的C/C++编译器编译成EXE文件后才能运行。
由于我们通常使用的操作系统是Windows系统,而在该系统下最长用的C/C++编译器是VC++编译器,目前在大专院校常用的版本还是VC++60
下面就以VC++60来说明编译过程:
1在VC++60中通过“File”菜单下的 “Open”子菜单打开贪吃蛇代码
2在VC++60中通过“Build”菜单下的 “Compile xxxxxx”子菜单编译贪吃蛇代码
3在VC++60中通过“Build”菜单下的 “Execute xxxxexe”子菜单运行贪吃蛇程序
附:在VC++6环境下可运行的C/C++贪吃蛇源代码(无版权,自己编写,欢迎任意修改拷贝)
/C/C++贪吃蛇游戏,zjlj,2015316
/
#define DEBUG 0 //当程序在调试阶段时 DEBUG为 1
#include<iostream>
#include<windowsh>
#include<timeh>
#include<conioh>
using namespace std;
void readini(FILE fphead, int score, char argv[]) //创建或打开一个和运行文件对应的ini文件,读取最高纪录
{
char filename[200],pfilename;
int flag=-1,i;
strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{
if (''==filename[i])flag=1;
}
if(1==flag)
{
filename[i-1]='i';
filename[i-2]='n';
filename[i-3]='i';
}
else
{
filename[i]='';
filename[i+1]='i';
filename[i+2]='n';
filename[i+3]='i';
filename[i+4]='\0';
}
for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];
if ( (fphead=fopen(pfilename, "rb+"))==NULL)
{
if ( (fphead=fopen(pfilename, "wb+"))==NULL)
{
printf("无法创建或打开\"%s\"文件\n",pfilename);
system("pause");
exit(0);
}
}
else
{
fread(score,sizeof(int),1,fphead);
}
}
void writeini(FILE fphead, int score, char argv[]) //打开一个和运行文件对应的ini文件,写入最高纪录
{
char filename[200],pfilename;
int flag=-1,i;
strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{
if (''==filename[i])flag=1;
}
if(1==flag)
{
filename[i-1]='i';
filename[i-2]='n';
filename[i-3]='i';
}
else
{
filename[i]='';
filename[i+1]='i';
filename[i+2]='n';
filename[i+3]='i';
filename[i+4]='\0';
}
for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];
if ( (fphead=fopen(pfilename, "wb+"))==NULL)
{
printf("无法写入\"%s\"文件,磁盘写保护!\n",pfilename);
system("pause");
exit(0);
}
else
{
rewind(fphead);
fwrite(score,sizeof(int),1,fphead);
fclose(fphead);
}
}
void gotoxy(int x,int y)//光标定位,光标定位函数SetConsoleCursorPosition是左上角位置是0,0然后向左向下延伸
{
COORD pos;
posX=2y;
posY=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void color(int a)//颜色函数
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
void Refresh(int q[][22], int grade, int gamespeed, int length,int score) // 输出贪吃蛇棋盘
{
int i,j;
for(i=0;i<22;i++)
{
for(j=0;j<22;j++)
{
if(q[i][j]==0)//输出棋盘空白
{
gotoxy(i,j);
color(11);
cout<<"■";
}
if(q[i][j]==1||q[i][j]==2)//输出棋盘墙壁
{
gotoxy(i,j);
color(11);
cout<<"□";
}
if(q[i][j]==3)//输出蛇头
{
gotoxy(i,j);
color(14);
cout<<"★";
}
if(q[i][j]==4)//输出蛇身
{
gotoxy(i,j);
color(12);
cout<<"◆";
}
if(q[i][j]==5)//输出果子
{
gotoxy(i,j);
color(12);
cout<<"●";
}
}
if(i==0) cout << "\t";
if(i==1) cout << "\t等级为:" << grade;//显示等级
if(i==3) cout << "\t自动前进时间";
if(i==4) cout << "\t间隔为:" << gamespeed << "ms";//显示时间
if(i==6) cout << "\t历史最高分为:" << score << "分";
if(i==7) cout << "\t你现在得分为:" << (length+(grade-1)8)10 << "分";
if(i==8) cout << "\t";
if(i==9) cout << "\t游戏说明:";
if(i==10) cout << "\t(1)用小键盘方向键控制";
if(i==11) cout << "\t蛇头运动方向;";
if(i==12) cout << "\t(2)蛇每吃一个果子蛇身";
if(i==13) cout << "\t增加一节;";
if(i==14) cout << "\t(3)蛇咬到自己或碰到墙";
if(i==15) cout << "\t壁游戏结束。";
if(i==18) cout << "\t";
if(i==19) cout << "\tC/C++语言作业:";
if(i==20) cout << "\tzjlj,20150316 ";
}
}
int main(int argc, char argv[]){
int tcsQipan[22][22]; // 贪吃蛇棋盘是一个二维数组(如2222,包括墙壁)
int i,j,score,directiontemp;
FILE fpini;//fpini 信息文件
readini(&fpini, &score, argv);//读取ini文件的最高纪录
if (score<0)//最高成绩小于零设置为零,初建文件会是负数
score=0;
while(1)
{
for(i=1;i<=20;i++)
for(j=1;j<=20;j++)
tcsQipan[i][j]=0; //贪吃蛇棋盘相应坐标标上中间空白部分的标志0
for(i=0;i<=21;i++)
tcsQipan[0][i] = tcsQipan[21][i] = 1; //贪吃蛇棋盘相应坐标标上上下墙壁的标志1
for(i=1;i<=20;i++)
tcsQipan[i][0] = tcsQipan[i][21] = 2; //贪吃蛇棋盘相应坐标标上左右墙壁的标志2
int tcsZuobiao[2][500]; //蛇的坐标数组
for(i=0; i<4; i++)
{
tcsZuobiao[0][i] = 1;//蛇身和蛇头的x坐标
tcsZuobiao[1][i] = i + 1;//蛇身和蛇头的y坐标
}
int head = 3,tail = 0;//标示蛇头和蛇尾的数组偏移量
for(i=1;i<=3;i++)
tcsQipan[1][i]=4; //蛇身
tcsQipan[1][4]=3; //蛇头
int x1, y1; // 随机出果子
srand(time(0));//设置随机种子
do
{
x1=rand()%20+1;
y1=rand()%20+1;
}
while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子
tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5
color(12);
cout<<"\n\n\t\t\t\t贪吃蛇游戏即将开始 !"<<endl;//准备开始
long start,starttemp;
int grade = 1, length = 4; //设置初始等级和蛇的初始长度
int gamespeed = 500; //设置初始前进时间间隔
for(i=3;i>=0;i--)
{
start=clock();
while(clock()-start<=1000);
system("cls");
if(i>0)
cout << "\n\n\t\t\t\t进入倒计时:" << i << endl; //倒计时显示
else
Refresh(tcsQipan,grade,gamespeed,length,score); //初始棋盘显示
}
int timeover=1,otherkey=1;//初始化超时时间和按键判断参数
char direction = 77; // 设置初始情况下,向右运动
int x=tcsZuobiao[0][head],y=tcsZuobiao[1][head];//保存蛇头坐标到x,y变量
while(1)//运行一局游戏
{
start = clock();
while((timeover=((starttemp=clock())-start<=gamespeed))&&!kbhit());//如果有键按下或时间超过自动前进时间间隔则终止循环
if(direction==72||direction==80||direction==75 ||direction==77)
directiontemp=direction;//保留上一次方向按键
//starttemp=gamespeed+start-starttemp;//保留停留时间
if(timeover)
{
#if (DEBUG==1)
direction = getch();//调试代码
#else
if((direction =getch())==-32)
direction = getch();
#endif
}
#if (DEBUG==1)//调试代码
start=clock();
while(clock()-start<=2000);
gotoxy(24,4);
cout << "\t按键ASCII代码"<<(int)direction<<" "<<endl;
#endif
if(!(direction==72||direction==80||direction==75 ||direction==77))
{
otherkey=0;// 按键非方向键,otherkey设置为0
}
else
{
otherkey=1;// 按键为方向键,otherkey设置为1
}
if(direction==72 && directiontemp==80)//忽略反方向按键
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
else if(direction==80 && directiontemp==72)
{
direction=32;//设置按键为非方向键
otherkey=0;// 按键为非方向键,otherkey设置为0
// start = clock();
//while(clock()-start<=starttemp);//补偿等待时间
}
else if(direction==75 && directiontemp==77)
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
else if(direction==77 && directiontemp==75)
{
direction=32;
otherkey=0;
//start = clock();
//while(clock()-start<=starttemp);
}
switch(direction)//判断方向键
{
case 72: x= tcsZuobiao[0][head]-1; y= tcsZuobiao[1][head];break; // 向上
case 80: x= tcsZuobiao[0][head]+1; y= tcsZuobiao[1][head];break; // 向下
case 75: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]-1;break; // 向左
case 77: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]+1;break; // 向右
default: break;
}
if(x==0 || x==21 ||y==0 || y==21) // 蛇头碰到墙壁,结束本局游戏
{
gotoxy(22,12);
cout << "\t游戏已结束!" << endl;
if(score>=(length+(grade-1)8)10)//判断是否破记录
{
gotoxy(10,7);
color(12);
cout << "闯关失败 加油耶!" << endl;
fclose(fpini);//关闭ini文件
}
else
{
gotoxy(10,7);
color(12);
cout << "恭喜您打破记录" << endl;
score=(length+(grade-1)8)10;
writeini(&fpini, &score, argv);//写入ini文件的最高纪录
}
gotoxy(23,12);
cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示
break;//退出该局游戏
}
if(tcsQipan[x][y]!=0&&!(x==x1&&y==y1)&&tcsQipan[x][y]!=3) // 蛇头碰到蛇身,结束本局游戏
{
gotoxy(22,12);
cout << "\t游戏已结束!" << endl;
if(score>=(length+(grade-1)8)10)//判断是否破记录
{
gotoxy(10,7);
color(12);
cout << "闯关失败 加油耶!" << endl;
fclose(fpini);//关闭ini文件
}
else
{
gotoxy(10,7);
color(12);
cout << "恭喜您打破记录" << endl;
score=(length+(grade-1)8)10;
writeini(&fpini, &score, argv);//写入ini文件的最高纪录
}
gotoxy(23,12);
cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示
break;//退出该局游戏
}
/
游戏运行时的核心算法开始
/
if(x==x1 && y==y1) // 吃果子,长度加1
{
length ++;
if(length>=8)//长度大于等于8重新计算长度,等级加1
{
length -= 8;//重新计算长度
grade ++;//等级加1
if(gamespeed>50)//控制最快速度为50
gamespeed = 550 - grade 50; // 改变自动前进时间间隔
}
tcsQipan[x][y]= 3;//贪吃蛇棋盘相应坐标现在蛇头标志改为蛇头标志3
tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;//贪吃蛇棋盘相应坐标原来蛇头标志改为蛇身标志4
head = (head+1)%400;//防止数组越界
tcsZuobiao[0][head] = x;//蛇头的x坐标
tcsZuobiao[1][head] = y;//蛇头的y坐标
do//随机出果子
{
x1=rand()%20+1;
y1=rand()%20+1;
}
while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子
tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5
gotoxy(22,12);
cout << "\t游戏进行中!" << endl;
Refresh(tcsQipan,grade,gamespeed,length,score);
}
else // 不吃果子
{
if(otherkey)
{
tcsQipan [tcsZuobiao[0][tail]][tcsZuobiao[1][tail]]=0;
tail=(tail+1)%400;//防止数组越界
tcsQipan [tcsZuobiao[0][head]][tcsZuobiao[1][head]]=4;
head=(head+1)%400;//防止数组越界
tcsZuobiao[0][head]=x;//蛇头的x坐标
tcsZuobiao[1][head]=y;//蛇头的y坐标
tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=3;
gotoxy(22,12);
cout << "\t游戏进行中!" << endl;
Refresh(tcsQipan,grade,gamespeed,length,score);
}
else
{
gotoxy(22,12);
cout << "\t游戏暂停中!" << endl;
}
}
/
游戏运行时的核心算法结束
/
}
while(1)
{
while(!kbhit());
if((direction =getch())==13)//按回车键开始下一局
break;
if(direction ==27)//按ESC退出游戏
exit(0);
}
system("cls");//清除屏幕重新开始
}
return 0;
}
欢迎分享,转载请注明来源:表白网
评论列表(0条)