贪吃蛇C语言
实现了两种模式的双人双蛇对战,界略微花哨,基本功能都有,新手参考练习不错
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>
#pragma comment(lib,"winmm.lib")
using namespace std;
#define 上 1
#define 下 2
#define 左 3
#define 右 4
#define UP 10
#define DOWN 11
#define LEFT 12
#define RIGHT 13
#define MAP_X 30
#define MAP_Y 30
#define 空地 0
#define 食物 1
#define 障碍物 2
#define P1 3
#define P2 4
#define 奖品 5 // 特殊食物
typedef struct _COORDS
{
int x;
int y;
}COORDS;
COORD g_Snake[100]; //第一条蛇的长度数组
COORDS g2_Snake[100]; //第二条蛇的长度数组
int g_nlenth = 4; //第一条蛇的长度
int g2_nlenth = 4; //第二条蛇的长度
int g_Dir = 右; //第一条蛇初始方向 右
int g2_Dir = LEFT; //第二条蛇的初始方向 左
int g_Map[MAP_X][MAP_Y] = {};
int g_FoodExist = 0; //基本食物
int g_Food = -1; //奖励食物
int g_len = 0; //蛇1积分
int g2_len = 0; //蛇2积分
int Speed = 150; //初始速度
int n = 0; //选择判断
int g_hp = 1; //蛇1生命值
int g2_hp = 1; //蛇2生命值
int g_color = 0; //颜色选择
//Windows控制台操作******************************
//播放开场音乐
void psound111()
{
PlaySound("111.WAV", NULL, SND_FILENAME | SND_ASYNC);
}
//播放碰撞声
void psound222()
{
PlaySound("222.WAV", NULL, SND_FILENAME | SND_ASYNC);
}
//播放结束声
void psound333()
{
PlaySound("333.WAV", NULL, SND_FILENAME | SND_ASYNC);
}
//设置控制台长宽
void Swindow()
{
system("mode con cols=100 lines=33");
psound111();
}
//在任何位置输出字符
void WriteChar(int x, int y, char * szInfo, int color = 0) //在任何位置输出字符
{
COORD pos = { x * 2,y };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
SetConsoleTextAttribute(hOut, color);
printf("%s", szInfo);
}
//隐藏光标
void HiddenCursor()
{
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(hOutput, &cci);
}
#define KEY_DOWN(key) GetAsyncKeyState(key)==(SHORT)0x8001?1:0
#define MP mer.dwMousePosition
char ch;
void KeyEventProc(KEY_EVENT_RECORD ker)
{
COORD m = { 0, 0 };
if (ker.bKeyDown)
{
ch = ker.uChar.AsciiChar;
}
}
//鼠标事件处理
void MouseEventProc(MOUSE_EVENT_RECORD mer, int c)
{
if (mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
if (MP.X > 1 && MP.X < 60 && MP.Y>0 && MP.Y < 30)
{
switch (c)
{
case 1:WriteChar(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y, "□", 15);
g_Map[mer.dwMousePosition.X / 2][mer.dwMousePosition.Y] = 2; break;
case 2:WriteChar(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y, "■", 2);
g_Map[mer.dwMousePosition.X / 2][mer.dwMousePosition.Y] = 0; break;
}
}
}
}
int flag = 1;
//消息提示
int MessageLoop()
{
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD stcRecord = { 0 };
DWORD dwRead;
SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
while (flag)
{
ReadConsoleInput(hStdin, &stcRecord, 1, &dwRead);
int c = 1;
switch (ch)
{
case '1':
c = 1; break;
case '2':
c = 2; break;
case '3':
flag = 0; break;
default:
break;
}
if (stcRecord.EventType == KEY_EVENT)
{
KeyEventProc(stcRecord.Event.KeyEvent);
}
else
{
MouseEventProc(stcRecord.Event.MouseEvent, c);
}
if (flag == 0)
{
WriteChar(36, 15, "保存成功!!", 4);
}
}
return 0;
}
//判断此用户是否按键
int waitKey()
{
if (_kbhit()) //判断此用户是否按键,
return _getch(); //接受用户按键,并将按键返回
return 0; //没有按键,返回0
}
//蛇的初始位置***************************
//蛇出生坐标
void InitGame()
{
g_Snake[0].X = 10;
g_Snake[0].Y = 3;
g_Snake[1].X = 10;
g_Snake[1].Y = 4;
g_Snake[2].X = 10;
g_Snake[2].Y = 5;
g_Snake[3].X = 10;
g_Snake[3].Y = 6;
}
//蛇出生坐标
void InitGame2()
{
g2_Snake[0].x = 20;
g2_Snake[0].y = 23;
g2_Snake[1].x = 20;
g2_Snake[1].y = 24;
g2_Snake[2].x = 20;
g2_Snake[2].y = 25;
g2_Snake[3].x = 20;
g2_Snake[3].y = 26;
}
//随机障碍物
void Obstacles()
{
for (int i = 0; i < 20; i++) //生成随机数,产生障碍物
{
int X = rand() % 28 + 1;
int Y = rand() % 28 + 1;
if (g_Map[X][Y] == 空地) //地图上的这一点是不是空地,如果是空地就附为障碍物,画出来
{
g_Map[X][Y] = 障碍物;
WriteChar(X, Y, "□", 15);
}
}
}
//设定初始参数
void Inidial()
{
g_nlenth = 4; //游戏结束或开始恢复初始
g2_nlenth = 4;
g_Dir = 右;
g2_Dir = LEFT;
g_Map[MAP_X][MAP_Y] = {0};
g_FoodExist = 0;
g_Food = -1;
g_len = 0;
g2_len = 0;
Speed = 150;
n = 0;
g_hp = 1;
g2_hp = 1;
g_color = 0;
}
//自定义地图*****************************
//玩家绘制地图
int DrewMap()
{
system("mode con cols=100 lines=33");
g_Map[MAP_X][MAP_Y] = { 0 };
for (int i = 0; i < MAP_X; i++)
{
for (int j = 0; j < MAP_Y; j++)
{
if (i == 0 || j == 0 || i == MAP_X - 1 || j == MAP_Y - 1) //定义的游戏范围
{
g_Map[i][j] = 障碍物;
}
}
}
for (int i = 0; i < MAP_X; i++)
{
for (int j = 0; j < MAP_Y; j++) //打印出地图
{
if (g_Map[i][j] == 障碍物)
{
WriteChar(i, j, "□", 15);
}
else
{
WriteChar(i, j, "■", 2);
}
}
}
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 30; j++)
{
if (i == 0 || j == 0 || i == 50 - 1 || j == 30 - 1) //绘制侧边栏