C语言彩色版贪吃蛇——图形界面Easyx的简单使用

大一上大概12月份学完了C语言,基本语法与知识已经基本具备,可以用C语言写出基本的贪吃蛇游戏,但是基础C语言的可视化与交互功能实在是太弱了,为了写出有色彩的游戏,需要在网上安装一个Easyx的插件,具体Easyx如何使用参见https://zhuanlan.zhihu.com/p/24826034点击打开链接

然后编程软件我用的是VS 2017(因为Dev C++不支持Easyx) VS安装入口:点击打开链接

程序实现了用户登陆与注册,用户数据保存到文件,高分榜等较为简单的功能,整个代码不算注释大概三百五十行。

游戏效果大概是这样:

介绍一下游戏思路:先想清楚完成贪食蛇这个游戏需要哪些元素,游戏需要满足哪些功能,再敲代码把它们逐渐实现。
首先我们需要基础元素:地图(墙),然后是食物,一条蛇。 然后是功能:1.移动蛇   2.蛇的长大(吃果子)  3.蛇的死活(撞墙或者自食) 具体代码见下(有详细注释)。
然后是图像的处理:1.注意Eaxyx的点是像素点,与控制台的点不一样,用的时候要记得乘个系数转化
2.你可以选择用Easyx的函数画地图(就像我的代码一样,很随便而简陋),也可以选择去网上找图然后贴上去(可以做的很精美,想在同学面前秀一秀的注意了)
3.用户登陆与注册的部分界面用Easyx的InputBox,然后用文件读入读出的方式,把用户数据存入单独的文件中,更方便的办法是弄一个二进制文件,把用户账号和密码弄成结构存进去。
4.高分榜的实现:每次用户结束游戏后,把榜上分数从文件中读下来然后与用户本次分数比较,排序然后再重新写入文件中。
//代码如下:
#include <graphics.h>      // 引用图形库头文件
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include<stdlib.h>

#define frame_height 30 //define map size
#define frame_width 30
#define UP 'w' //define operate key
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
#define SIZE 16
#define N 4
FILE *fp;
int i, j, k, m, n, s[N];
char s1[5], s2[5];
char ch = UP; //initial direction
int grow = 0; //flag: if snake grow
struct Food {
 int x;
 int y;
}food;
struct Snake {
 int x[50];
 int y[50];
 int len;
 int speed;
}snake; //snake[0] is head
typedef struct The_users //用于储存用户账号密码
{
 char id[11];//ID
 char pwd[20];//password
}users;
users a, b;//成员变量,用来登陆与注册
void init_map(void);
void update_food(void);
void move_snake(void);
int is_alive(void);
void get_speed(void);
void gotoxy(int x, int y);
void redraw_map(void);
void menu();
void registers();
void Login();
//void Create_File();
void score();
int compInc(const void *a, const void *b);
int compDec(const void *a, const void *b);
int main()
{
 initgraph(640, 480);//创建绘图窗口
 menu();
 score();
 return 0;
}
void redraw_map(void)
{
 //initial bar
 for (j = 0; j<frame_width; j++)
 {
  moveto(j*SIZE, 0);
  setfillcolor(BLUE);
  fillrectangle(j*SIZE, 0, j*SIZE + SIZE, SIZE);
  moveto(j*SIZE, (frame_height - 1)*SIZE);
  setfillcolor(BLUE);
  fillrectangle(j*SIZE, (frame_height - 1)*SIZE, j*SIZE + SIZE, (frame_height - 1)*SIZE + SIZE);
 }
 for (i = 1; i<frame_height - 1;)
 {
  moveto(0, i*SIZE);
  setfillcolor(BLUE);
  fillrectangle(0, i*SIZE, 0 + SIZE, i*SIZE + SIZE);
  moveto((frame_width - 1)*SIZE, i*SIZE);
  setfillcolor(BLUE);
  fillrectangle((frame_width - 1)*SIZE, i*SIZE, (frame_width - 1)*SIZE + SIZE, i*SIZE + SIZE);
  i = i + 1;
 }
}
void init_map(void)
{
 //initial food
 srand((unsigned int)time(NULL));
 food.x = rand() % (frame_height - 2) + 1;
 food.y = rand() % (frame_width - 2) + 1;
 moveto(food.y*SIZE, food.x*SIZE);
 setfillcolor(RED);
 fillcircle(food.y *SIZE + SIZE / 2, food.x*SIZE + SIZE / 2, SIZE / 2);
 //initial snake
 snake.x[0] = (frame_height) / 2;
 snake.y[0] = (frame_width) / 2;
 moveto(snake.y[0] * SIZE, snake.x[0] * SIZE);
 setfillcolor(GREEN);
 fillcircle(snake.y[0] * SIZE + SIZE / 2, snake.x[0] * SIZE + SIZE / 2, SIZE / 2);
 snake.len = 3;
 snake.speed = 200;
 for (k = 1; k<snake.len; k++)
 {
  snake.x[k] = snake.x[k - 1] + 1;
  snake.y[k] = snake.y[k - 1];
  moveto(snake.y[k] * SIZE, snake.x[k] * SIZE);
  setfillcolor(GREEN);
  fillcircle(snake.y[k] * SIZE + SIZE / 2, snake.x[k] * SIZE + SIZE / 2, SIZE / 2);
 }
 //initial bar
 for (j = 0; j<frame_width; j++)
 {
  moveto(j*SIZE, 0);
  setfillcolor(BLUE);
  fillrectangle(j*SIZE, 0, j*SIZE + SIZE, SIZE);
  moveto(j*SIZE, (frame_height - 1)*SIZE);
  setfillcolor(BLUE);
  fillrectangle(j*SIZE, (frame_height - 1)*SIZE, j*SIZE + SIZE, (frame_height - 1)*SIZE + SIZE);
 }
 for (i = 1; i<frame_height - 1;)
 {
  moveto(0, i*SIZE);
  setfillcolor(BLUE);
  fillrectangle(0, i*SIZE, 0 + SIZE, i*SIZE + SIZE);
  moveto((frame_width - 1)*SIZE, i*SIZE);
  setfillcolor(BLUE);
  fillrectangle((frame_width - 1)*SIZE, i*SIZE, (frame_width - 1)*SIZE + SIZE, i*SIZE + SIZE);
  i = i + 1;
 }
}
//generate food
void update_food()
{
 if (snake.x[0] == food.x&&snake.y[0] == food.y)
 {
  food.x = rand() % (frame_height - 2) + 1;
  food.y = rand() % (frame_width - 2) + 1;
  for (k = 1; k<snake.len; k++)
  {
   if (snake.x[k] == food.x&&snake.y[k] == food.y)
   {
    food.x = rand() % (frame_height - 2) + 1;
    food.y = rand() % (frame_width - 2) + 1;
   }
  }
  moveto(food.y*SIZE, food.x*SIZE);
  setfillcolor(RED);
  fillcircle(food.y*SIZE + SIZE / 2, food.x*SIZE + SIZE / 2, SIZE / 2);
  snake.len++;
  grow = 1;
 }
}
//move snake
void move_snake()
{
 if (_kbhit())
  ch = _getch();
 if (!grow)
 {
  moveto(snake.y[snake.len - 1] * SIZE, snake.x[snake.len - 1] * SIZE);
  setfillcolor(BLACK);
  solidrectangle(snake.y[snake.len - 1] * SIZE, snake.x[snake.len - 1] * SIZE, snake.y[snake.len - 1] * SIZE + SIZE, snake.x[snake.len - 1] * SIZE + SIZE);
 }
 for (k = snake.len - 1; k>0; k--)
 {
  snake.x[k] = snake.x[k - 1];
  snake.y[k] = snake.y[k - 1];
 }
 switch (ch)
 {
 case UP:  snake.x[0]--; break;
 case DOWN: snake.x[0]++; break;
 case LEFT:  snake.y[0]--; break;
 case RIGHT:  snake.y[0]++; break;
 default:  break;
 }
 moveto(snake.y[0] * SIZE, snake.x[0] * SIZE);
 setfillcolor(GREEN);
 fillcircle(snake.y[0] * SIZE + SIZE / 2, snake.x[0] * SIZE + SIZE / 2, SIZE / 2);
 grow = 0;
}
//is alive
int is_alive(void)
{
 if (snake.x[0] == 0 || snake.x[0] == frame_height - 1 || snake.y[0] == frame_width - 1 || snake.y[0] == 0)
  return 0;
 for (k = 1; k<snake.len; k++)
  if (snake.x[k] == snake.x[0] && snake.y[k] == snake.y[0])
   return 0;
 return 1;
}
//speed up
void get_speed(void)
{
 if (snake.len <= 6)
  snake.speed = 200;
 else if (snake.len <= 10)
  snake.speed = 100;
 else if (snake.len <= 20)
  snake.speed = 50;
 else if (snake.len <= 30)
  snake.speed = 30;
 else snake.speed = 20;
}
//move cursor
void gotoxy(int x, int y)
{
 HANDLE hout;
 COORD cor;
 hout = GetStdHandle(STD_OUTPUT_HANDLE);
 cor.X = y;
 cor.Y = x;
 SetConsoleCursorPosition(hout, cor);
}
void menu()
{
 InputBox(s1, 5, "请输入数字:1.开始游戏2.高分榜3.退出游戏");
 int x, y[3];
 sscanf_s(s1, "%d", &x);//将用户输入转化为数字
 if (x == 1)
 {
  InputBox(s2, 5, "请输入数字:1.注册2.登陆");
  sscanf_s(s2, "%d", &x);
  if (x == 1) {
   registers();
   Login();
  }
  else if (x == 2) {
   Login();
  }
  init_map(); //初始化地图
  while (1)
  {
   update_food();
   //是否产生食物
   get_speed();  //获取速度
   move_snake();  //移动蛇身
   redraw_map();//重绘地图
   Sleep(snake.speed);
   //移动速度
   if (!(is_alive()))
    //蛇的死活(撞墙或自食)
    break;
  }
  closegraph();//关闭绘图窗口
  printf("Game Over!\n");
  printf("你的得分:%d", snake.len - 3);
  _getch();
 }
 else if (x == 2)
 {
  closegraph();
  printf("                    排行榜\n");
  fopen_s(&fp, "scores.txt", "r");
  for (x = 0; x < N - 1; x++) {
   fscanf_s(fp, "%d", &y[x]);
   printf("%d\n", y[x]);
  }
  fclose(fp);
  _getch();
  
 }
 else
 {
  closegraph();
 }
}
void registers()//注册账号密码
{
 fopen_s(&fp, "Users1.txt", "r");
 fscanf_s(fp, "%s%s", b.id, sizeof(b.id), b.pwd, sizeof(b.pwd));
 InputBox(a.id, 11, "请输入账号");
 while (1)
 {
  if (strcmp(a.id, b.id) != 0)//如果两串字符串不相等
  {
   if (!feof(fp))//如果未至文件末尾
   {
    fscanf_s(fp, "%s%s", b.id, sizeof(b.id), b.pwd, sizeof(b.pwd));
   }
   else break;
  }
  else
  {
   outtextxy(220, 200, "此用户名已被注册");
   fclose(fp);
   _getch();
   exit(0);
  }
 }
 fclose(fp);
 InputBox(a.pwd, 10, "请输入密码");
 fopen_s(&fp, "Users1.txt", "a");
 fprintf_s(fp, "%s %s\n", a.id, a.pwd);
 outtextxy(220, 200, "账号注册成功!");
 fclose(fp);
}
void Login()//登陆账号密码
{
 fopen_s(&fp, "Users1.txt", "r");
 fscanf_s(fp, "%s%s", b.id, sizeof(b.id), b.pwd, sizeof(b.pwd));
 InputBox(a.id, 11, "请输入账号");
 while (1)
 {
  if (strcmp(a.id, b.id) == 0) break;//如果找到了这个用户名
  else
  {
   if (!feof(fp))//如果文件未读完
    fscanf_s(fp, "%s%s", b.id, sizeof(b.id), b.pwd, sizeof(b.pwd));
   else
   {
    outtextxy(220, 200, "此用户名不存在!");
    fclose(fp);
    _getch();
    exit(0);
   }
  }
 }
 InputBox(a.pwd, 20, "请输入密码");
 if (strcmp(a.pwd, b.pwd) == 0)//如果密码匹配
 {
  fclose(fp);
  outtextxy(250, 200, "登陆成功!");
  initgraph(640, 480);
 }
 else
 {
  outtextxy(220, 200, "密码不正确");
  _getch();
  exit(0);
 }
}
void score()
{
 fopen_s(&fp, "scores.txt", "r");
 for (n = 0; n < N - 1; n++)
 {
  fscanf_s(fp, "%d", &m);
  s[n] = m;
 }
 s[N - 1] = snake.len - 3;
 qsort(s, N, sizeof(s[0]), compDec);
 fclose(fp);
 fopen_s(&fp, "scores.txt", "w");
 for (n = 0; n < N - 1; n++)
 {
  fprintf_s(fp, "%d\n", s[n]);
 }
 fclose(fp);
}
int compInc(const void *a, const void *b)
{
 return *(int *)a - *(int *)b;
}//升序排序
int compDec(const void *a, const void *b) {
 return *(int *)b - *(int *)a;
}//降序排序



猜你喜欢

转载自blog.csdn.net/csustudent007/article/details/79162449