环境:
Visual Studio 2022
装有<easxy.h>库
介绍:
建议按"w"上、"s"下、"a"左、"d"右。无延误
按‘e’加速
此代码会在桌面生成一个叫"score.txt"的文件保存最高分
可在208行到216行加for循环以增加加速后的速度
按Esc键回到控制台
源码:
#include<iostream>
#include<graphics.h>
#include<easyx.h>
#include<conio.h>
using namespace std;
//生成食物的函数
void setfood();
//判断蛇的死活
void nakeAlive();
//显示玩家的分数
void getScore();
//显示玩家已经死亡
void dead();
//开始的界面
void be();
//生成新的蛇的方法每次的移动都是蛇的刷新与生成
void createsnake(int direction);
//分数文件的读取
int readScore();
//分数文件的写入
void writeScore();
struct snake {
int x = 1;
int y = 1;
snake* next = NULL;
}*p;
//对于这个数据当前的坐标为横56,宽24,这个数据中边界地部分是不可以使用地
const int JFramx = 1400, JFramy = 600, length = 20, interval = 5, sum = length + interval;
int snakespeed = 100;//蛇的移动速度
int foodx=8, foody=8;//生成食物的坐标
//int lastx=2, lasty=2;//在尾部添加蛇身而准备的参数
int score ;//统计玩家的得分
int level = '1';//地基关卡//实际数据大小应该为(1-9)字符型
bool snakearr[60][30];//判断蛇是否死亡的bool数组
string fileName = "C:/Users/Administrator/Desktop/score.txt";
class Main {
public:
//默认的蛇的生成
snake a = { 10,10,NULL };
snake* head = &a;
snake* p = &a;
int snakeLength = 3;
//生成地图的构造参数(默认地图的构造函数)
Main(int levelNumber) {
score = 0;
//先生成上部的方块
for (int i = 0; i < JFramx / (length + interval); i++) {
//首先声明颜色,否则第一个格子怪怪的
setfillcolor(BLUE);
setcolor(BLUE);
fillrectangle(i * (length + interval), 0, i * (length + interval) + length, length);
snakearr[i][0]=1;
Sleep(30);
}
//对中间的方块·的操作决定了关卡的不同的说
if (levelNumber=='2') {
for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
snakearr[0][i]=1;
if (i!=11&&i!=10&&i!=12) {
fillrectangle(37*sum,i*sum,37*sum+length,i*sum+length);
snakearr[37][i] = 1;
}
if (i!=7&&i!=8&&i!=14&&i!=15) {
fillrectangle(17 * sum, i * sum, 17 * sum + length, i * sum + length);
snakearr[17][i] = 1;
}
fillrectangle((JFramx / (length + interval) - 1) *sum, i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i] = 1;
Sleep(30);
}
}
else if (levelNumber=='3') {
for (int i = 1; i <= JFramy / sum - 2;i++) {
fillrectangle(0,i*sum,length,i*sum+length);
snakearr[0][i]=1;
for (int i2 = 5; i2 < 9;i2++) {
for (int i1 = 12; i1 < 16;i1++) {
snakearr[i1][i2] = 1;
}
for (int i1 = 37; i1 < 41;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 7; i2 < 10;i2++) {
for (int i1 = 24; i1 < 27;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 13; i2 < 16;i2++) {
for (int i1 = 24; i1 < 27;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 17; i2 < 21; i2++) {
for (int i1 = 12; i1 < 16; i1++) {
snakearr[i1][i2] = 1;
}
for (int i1 = 37; i1 < 41; i1++) {
snakearr[i1][i2] = 1;
}
}
if (i==5||i==6) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i==8||i==7) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 24; i1 < 27;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i==9||i==13||i==14||i==15) {
for (int i1 = 24; i1 < 27;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i == 17 || i == 18 || i == 19||i==20) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41; i1++) {
fillrectangle(i1 * sum, i * sum, i1 * sum + length, i * sum + length);
Sleep(30);
}
}
fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i]=1;
Sleep(30);
}
}
else {
//玩家不存在选关的操作时
level = '1';//令关卡的变量为零
for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
snakearr[0][i]=1;
fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i]=1;
Sleep(30);
}
}
//底部的生成
for (int i = 0; i < JFramx / (length + interval); i++) {
fillrectangle(i * (length + interval), (JFramy / (length + interval) - 1) * (length + interval), i * (length + interval) + length, JFramy - interval);
snakearr[i][JFramy / (length + interval) - 1]=1;
Sleep(30);
}
Main('s');
}
int temp_key = 's';//接受键盘输入的事件的暂时量,为了使蛇的身体不会实现倒退的情况
//蛇的加入构造,其中还有蛇的移动方法
Main(char numebr) {
while (1) {//接受键盘的事件
snakespeed = 100;//加速重置
int ch;//接受键盘上的事件的得到的数据
Sleep(5);
if (_kbhit()) {
ch = _getch();
if (ch == 27) { closegraph(); break; }
else if ((ch == 'd' || ch == 77) && temp_key != 'a') {//向右移动//新加入了判断蛇回退的判断
temp_key = 'd';
}
else if ((ch == 'w' || ch == 72) && temp_key != 's') { //向上移动
temp_key = 'w';
}
else if ((ch == 's' || ch == 80) && temp_key != 'w') { //向下移动
temp_key = 's';
}
else if ((ch == 'a' || ch == 75) && temp_key != 'd') { //向左移动
temp_key = 'a';
}
else if (ch == 'e') {//加速
snakespeed = 50;
if (temp_key == 'd') {
createsnake(1);
}if (temp_key == 'w') {
createsnake(2);
}if (temp_key == 's') {
createsnake(4);
}if (temp_key == 'a') {
createsnake(3);
}
}
else if (ch == 'p') {
pauseGame();
}
}
//这里是蛇身移动的方法,在没有输入的时候的情况//已经减少了代码的冗余
if (temp_key == 'd') {
createsnake(1);
}if (temp_key == 'w') {
createsnake(2);
}if (temp_key == 's') {
createsnake(4);
}if (temp_key == 'a') {
createsnake(3);
}
}
}
//生成新的蛇的方法每次的移动都是蛇的刷新与生成
void createsnake(int direction) {
//直接在生成蛇的时候就直接判断蛇的死亡
getScore();
setfood();
if (head->x==foodx&&head->y==foody) {
snake* endsnake=new snake;
endsnake->x = head->x;
endsnake->y = head->y;
endsnake->next = head;
snake* s = new snake;
head=endsnake;
}
for (p = head; p; p = p->next) {
clearrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
int tempy = head->y;
int tempx = head->x;
int tempx02;
int tempy02;
if (direction == 1) { head->x++; }
else if (direction == 2) { head->y--; }
else if (direction == 3) { head->x--; }
else if (direction == 4) { head->y++; }
for (p = head; p; p = p->next) {
if (p == head) {
setcolor(RED);
setfillcolor(LIGHTRED);
}
else {
setcolor(GREEN);
setfillcolor(GREEN);
}
if (p == head) {
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
else {
tempx02 = p->x;
tempy02 = p->y;
p->x = tempx;
p->y = tempy;
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
tempx = tempx02;
tempy = tempy02;
}
}
Sleep(snakespeed);
snakeAlive(level);
}
//生成食物的函数
void setfood() {
if (head->x == foodx&&head->y==foody) {
score++;//分数的增加
addSnake();
unsigned seed=(time(0));
srand(seed);
foody = rand() % 22 + 1;
if (level=='1') {
foodx = rand() % 54 + 1;
}
else if (level=='2') {
if (head->x<17) {
foodx = rand()%17+20;
}
else if (head->x<37) {
foodx = rand()%17+38;
}
else if (head->x<55) {
foodx = rand() % 16 + 1;
}
}
else if (level=='3') {
if (head->x<12) {
foodx = rand()%7+16;
}
else if (head->x<24) {
foodx = rand() % 10+27;
}
else if (head->x<37) {
foodx = rand() % 14 + 41;
}
else if (head->x<54) {
foodx = rand() % 12 + 1;
}
}
setfillcolor(LIGHTMAGENTA);
fillrectangle(foodx*sum,foody*sum,foodx*sum+length,foody*sum+length);
}
else {
setcolor(LIGHTMAGENTA);
setfillcolor(LIGHTMAGENTA);
fillrectangle(foodx * sum, foody * sum, foodx * sum + length, foody * sum + length);
}
}
//判断蛇是否死亡
void snakeAlive(int level) {
for (p = head; p;p=p->next) {
if (head->x==p->x&&head->y==p->y&&p!=head) {
dead();
closegraph();
}
}
if (snakearr[head->x][head->y]==1) {
dead();
closegraph();
}
}
//使地图显示分数
void getScore() {
int r = 0;
settextcolor(GREEN);
outtextxy(r,625,_T("分数:"));
int p = score,a[100]={0}, top = 0;
do
{
a[top] = p % 10;
p /= 10;
top++;
} while (p>0);
r = 125;
top--;
for (top; top >= 0; top--) {
int g = a[top];
outtextxy(r, 625, 48 + g);
r+=20;
}
}
//届几个在类外实现了
void addSnake();
void dead();
void pauseGame();//游戏的暂停方法
};
void Main::pauseGame() {
bool temp = 1;
while (temp) {
if (_kbhit()) {
temp = 0;
}
}
}
void getScore() {
int r = 0,a[100],top=-1,p=score;
outtextxy(r,550,_T("分数:"));
do
{
top++;
a[top] = p % 10;
p /= 10;
} while (p>0);
r = 200;
for (; top >= 0; top--) {
outtextxy(r, 550, 48 + a[top]);
r += 25;
}
}
void Main::addSnake() {
snake* endsnake=head,*q=new snake;
while (endsnake ->next!=NULL) {
endsnake = endsnake -> next;
}
q->x = endsnake->x;
q->y = endsnake->y;
endsnake->next = q;
}
int readScore() {
FILE* a;
int b;
a = fopen("C:\\Users\\Administrator\\Desktop\\score.txt", "r");
fscanf(a, "%d", &b);
fclose(a);
return b;
}
void writeScore(int score) {
FILE* a;
int b = 0;
a = fopen("C:\\Users\\Administrator\\Desktop\\score.txt", "w+");
fprintf(a, "%d", score);
fclose(a);
}
//死亡的动画
void Main::dead() {
cleardevice();
for (int i = 0; i < 5;i++) {
for (p = head; p;p=p->next) {
clearrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
}
Sleep(200);
for (p = head; p;p=p->next) {
if (p->x==head->x&&p->y==head->y) {
setfillcolor(GREEN);
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
else {
setfillcolor(GREEN);
fillrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
}
}
Sleep(30);
}
if (score>=readScore()) {//如果本次得分比上一次的高就保存在本地文件
writeScore(score);
}
cleardevice();
clearcliprgn();
getScore();
settextcolor(BLUE);
settextstyle(100, 0, _T("宋体"));
for (int i = 0; i < 3; i++) {
clearcliprgn();
Sleep(700);
outtextxy(250, 300, _T("时间停止了,你..死了"));
Sleep(700);
}
outtextxy(250, 300, _T(" "));
settextcolor(GREEN);
cleardevice();
settextstyle(100, 0, _T("宋体"));
outtextxy(250, 300, _T("马上就会回到初始界面"));
Sleep(1000);
clearcliprgn();
be();
}
void be() {
memset(snakearr, 0, sizeof(snakearr));//bool数组的赋值
initgraph(JFramx, 700);
settextstyle(50, 0, _T("宋体"));
outtextxy(620, 50, _T("》贪吃蛇《"));
settextstyle(20, 0, _T("宋体"));
outtextxy(500, 180, _T("提示:"));
outtextxy(500, 230, _T("·使用WASD控制蛇的移动,箭头也行"));
outtextxy(500, 280, _T("·撞墙而死.按p暂停"));
outtextxy(500, 330, _T("·游戏界面可以显示你的分数"));
outtextxy(500, 380, _T("·键盘输入数字可以选关(1-3)"));
settextstyle(50, 0, _T("宋体"));
outtextxy(450, 500, _T(" 点击任意键继续"));
int r = 450, a[100], top = -1, p = readScore();
outtextxy(r, 550, _T(" 最高分数:"));
do
{
top++;
a[top] = p % 10;
p /= 10;
} while (p > 0);
r += 290;
for (; top >= 0; top--) {
outtextxy(r, 550, 48 + a[top]);
r += 25;
}
while (1) {
if (_kbhit()) {
level =_getch();//再键盘上得到的字符类型,从零开始计数的话,0的ASCll的值为48
if (level==27) {//在初始的界面中所加上的一个退出的的选项
closegraph();
}
break;
}
}
clearcliprgn();
new Main(level);//这里传值
}
int main() {
be();
while (1);
return 0;
}