前言:C语言初学者都是在控制台上开发一些小游戏什么,由于没有界面(比如图片、音乐,不能做出拥有自己风格的程序)学起来比较乏味,很难坚持下去。所以我在这里就教大家使用简单的图形化工具——easyx图形界面库,开发贪吃蛇小游戏,让初学者也能感受界面的魅力。做的不是很完善,希望大家可以自己动手完善它!
我们开始说思路。
1,我们需要一张地图,图形库初始化的窗口是自带坐标的(左上角为0,0)。
2,我们需要一条蛇,这条蛇由蛇头和蛇身组成(这里我们初始化三节蛇)。
3,我们需要食物,并且在蛇吃掉食物之后将蛇的身体变长,而且重新生成一个食物。
4,蛇需要移动,这应该是最难实现的(实现蛇身坐标的传值,除蛇头以外,每一节蛇的坐标都是上节蛇的上一次运动之前的坐标,有点绕~)。
5,蛇撞到墙或者撞到自己的身体就会死亡(判断坐标是否重合就可以)。
6,我们需要能用键盘控制蛇的运动方向,这个会和蛇的移动有一些联系。
下面我们来写代码。
首先是头文件snake.h部分,我们把一些函数的申明,和结构体的定义放在头文件中:
#define _CRT_SECURE_NO_WARNINGS #ifndef __SNAKE_H_ #define __SNAKE_H_ #define MAX 500 #pragma message("我的贪吃蛇!") #include<stdio.h> #include<conio.h> #include<time.h> //初始化蛇 void insnake(); //绘制蛇 void inisnake(); //蛇的移动 void way(); //蛇的方向 void snakemove(); //蛇的食物 void foodxy(); //食物绘制 void inifood(); //判断蛇是否吃掉食物 void eatfood(); //判断蛇是否吃挂掉 void snakedie(); //游戏过程中,按 空格 可以对游戏进行暂停、开始 void again(); //存储蛇的坐标的结构体 typedef struct coor { int x; int y; }coor; //蛇的基本属性 struct snake { int num;//蛇的总节数 coor xy[MAX];//存储蛇的坐标的结构体数组 char way; }snake; //食物的基本属性 struct food { coor fdxy; int flag=0; int eatgrade = 0; }food; //方向枚举 enum way { right=72, left=75, down=77, up=80 }; #endif
OK,头文件部分完毕,接下来进入snake.cpp代码编写环节。
(图形库需要在xxx.CPP下编写,在xxx.C可能会出错)
#include"snake.h" #include<graphics.h>//easyx图形库头文件 #define Azure 0xA4D3EE//自己定义的一个颜色 忘记了... int main() { srand((unsigned int)time(NULL));//随机数种子,后面随机产生蛇的食物要用到 insnake(); while (1) { cleardevice(); if (food.flag == 0) { foodxy(); } inifood(); inisnake(); snakedie(); eatfood(); way(); Sleep(100); while (_kbhit())//这里是按上下左右键控制蛇的移动 { again(); snakemove(); } } while (1); closegraph(); return 0; } //初始化蛇 void insnake(){ initgraph(640, 480); setbkcolor(Azure); snake.xy[2].x = 0; snake.xy[2].y = 0; snake.xy[1].x = 10; snake.xy[1].y = 0; snake.xy[0].x = 20; snake.xy[0].y = 0; snake.num = 3; snake.way = right; food.flag = 0; } //绘制蛇 void inisnake() { for (int i = 0; i < snake.num; i++) { setlinecolor(BLUE); setfillcolor(YELLOW); fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10); } } //蛇的移动 void way() { //除了第一节蛇,后面每节都是前面一节蛇的前一次坐标 for (int i = snake.num-1; i >0; i--) { snake.xy[i].x = snake.xy[i-1].x; snake.xy[i].y = snake.xy[i-1].y; } switch (snake.way) { case right: snake.xy[0].x += 10; break; case left: snake.xy[0].x -= 10; break; case down: snake.xy[0].y += 10; break; case up: snake.xy[0].y -= 10; break; default: break; } } //蛇的方向控制 void snakemove() { char ch = 0; ch = _getch(); switch (ch) { case 72: if (snake.way != down) snake.way = up; break; case 75: if (snake.way != right) snake.way = left; break; case 77: if (snake.way != left) snake.way = right; break; case 80: if (snake.way != up) snake.way = down; break; default: break; } } //食物坐标获取 void foodxy() { //蛇坐标 0 10 20 30 n*10 //食物 如果 rand() % 650 那么坐标0 1 2 3 4 蛇将吃不到食物 坐标重合低 food.fdxy.x = rand() % 65 * 10; food.fdxy.y = rand() % 48 * 10; food.flag = 1; for (int i = 0; i > snake.num; i++) { if (food.fdxy.x == snake.xy[i].x && food.fdxy.y == snake.xy[i].y) { food.fdxy.x = rand() % 65 * 10; food.fdxy.y = rand() % 48 * 10; } } } //绘制食物 void inifood() { fillrectangle(food.fdxy.x, food.fdxy.y, food.fdxy.x + 10, food.fdxy.y + 10); } //吃食物的判断 void eatfood() { if (snake.xy[0].x == food.fdxy.x && snake.xy[0].y == food.fdxy.y) { snake.num++; food.eatgrade += 10; food.flag = 0; } } //判断蛇是否死亡 void snakedie() { { //分数 char grade[100] = { 0 }; sprintf(grade, "%d", food.eatgrade); setbkmode(0);//文字背景透明 outtextxy(570, 20, "分数:"); outtextxy(610, 20, grade); } if (snake.xy[0].x > 640 || snake.xy[0].x < 0 || snake.xy[0].y > 480 || snake.xy[0].y<0) { outtextxy(240, 320, "撞墙了,游戏结束!加C/C++学习交流Qun:231662552"); MessageBox(0, "撞墙了!游戏结束!加C/C++学习交流Qun:231662552", "暴力提示!", 0); getchar(); } for (int i = 1; i < snake.num; i++) { if (snake.xy[0].x == snake.xy[i].x &&snake.xy[0].y == snake.xy[i].y) { outtextxy(240, 320, "你咬死了自己,游戏结束!加C/C++学习交流Qun:231662552"); getchar(); } } } void again() { if (_getch() == 32) { while (getch() != 32); } }
好了贪吃蛇代码写完了,我们来看一下效果:
蛇开始是一直向右运动的!我们按下下方向键:
看见没有,我顺便完了两下,吃了食物蛇是不是变长了!
来,我们去撞下墙【皮~】:
哎呀,我去,本来是撞墙的,结果自己咬死了自己!
好了,还没看过瘾的,赶快自己去编写实现吧!有问题或要图形库的可以加上面图片里的交流qun!拜拜!