接触编程有段时间了,一直想学习怎么去写个游戏来练练手。在看了B站上的教学终于可以自己试试怎么实现贪吃蛇这个游戏了。好了,废话不多说,我们来看看如何用EasyX库来实现贪吃蛇。

一、准备

  • 工具vc++6.0
  • 安装库文件
    • EasyX库安装链接
    • 可以安装任意版本,本人安装的是2018春分版
    • 这是一个简单易学的一个图形库,相信对于大家学习来说应该不成问题
  • 准备工作做好后接下来就得弄清楚游戏工作机制了

二、基本介绍

在这里我们需要明白EasyX库的基本知识,其次我们还有了解游戏的工作原理,不能盲目的直接写代码,需要一步步的思考,比如蛇是如何绘制、移动的;食物是怎么产生的;蛇吃了食物会怎样;死亡机制等等

EasyX库介绍

  1. 首先我们来讲讲EasyX库的坐标概念

    • 物理坐标

      • 简单来说,物理坐标就是以窗口的左上角为原点,以水平向右为x轴,竖直向下为y轴,以像素为单位
    • 逻辑坐标
      • 逻辑坐标和物理坐标是一一对应的,不过逻辑坐标是以点为单位
  2. 颜色概念
  • EasyX库的预定义颜色常量如下:
常量 颜色
BLACK 0
BULE 0xAA0000
GREEN 0x00AA00 绿
CYAN 0xAAAA00
RED 0x0000AA
MAGENTA 0xAA00AA
BROWN 0x0055AA 棕色
LIGHTGRAY 0xAAAAAA 浅灰
DARKGRAY 0x555555 深灰
LIGHTBULE 0xFF5555 亮蓝
LIGHTGREEN 0x55FF55 亮绿
LIGHTCYAN 0xFFFF55 亮青
LIGHTRED 0x5555FF 亮红
LIGHTMAGENTA 0xFF55FF 亮紫
YELLOW 0x55FFFF
WHITE 0xFFFFFF

3.基本函数介绍

  • initgraph(int width,int height,int flag=NULL):初始化绘图环境

    • width:绘图环境的宽度
    • height:绘图环境的高度
    • flag:绘图环境的样式,默认为NULL
  • cleardevice():用于清除屏幕内容
  • setbkcolor(COLORREF color):设置背景颜色
  • setfillcolor(COLORREF color):设置填充颜色
  • setlinecolor(COLORREF color):设置当前画线颜色
  • outtextxy(int x,int y,TCHAR c):用于在指定位置输出字符串
    • x,y表示输出字符串的坐标值
    • c表示待输出的字符
  • fillroundrect(int left,int top,int right,int bottom,int ellipsewidth,int ellipseheight):绘制圆角矩形
    • left:圆角矩形左部 x 坐标
    • top:圆角矩形上部 y 坐标
    • right:圆角矩形右部 x 坐标
    • bottom:圆角矩形下部 y 坐标
    • ellipsewidth:构成圆角矩形的圆角的椭圆的宽度
    • ellipseheight:构成圆角矩形的圆角的椭圆的高度

工作原理

  • 必须先包含头文件,才能运行
#include<graphics.h>
#include<time.h>
#include<stdlib.h>
#include<conio.h>
  • 我们要有窗口才能绘制蛇和食物,因此可以用initgraph()函数来实现
  • 其次我们要弄清楚如何来描述窗口位置,这里我们可以设置一个结构体Coor
struct Coor{
int x;
int y;
};
  • 方向
enum Ch{  //枚举类型表示上下左右键的键值
up=72,
down=80,
left=75,
right=77
};
  • 蛇也是有自己属性的结构体
struct Snake{
//蛇的属性
int n; //蛇当前节数,一节为一个正方形,n个正方形
struct Coor szb[500]; //snake的坐标,存放蛇的坐标,这里设置500,表示蛇能达到的最大长度为500
Ch ch; //蛇的方向
}snake; //变量
  • 食物的结构体
struct Food{
struct Coor fzb; //食物坐标
int flag; //是否被吃
}food;

有了以上的结构体的定义,我们就可以设置函数来完成贪吃蛇的绘制、移动、食物的绘制以及死亡机制等等

  • 函数内容如下

    • InitSnake():包含窗口的初始化,初始化随机种子,初始化蛇的起始坐标
    • DrawSnake():绘制蛇的每个节点
    • MoveSnake():蛇的移动
    • ChangeSnakeCh():通过键盘改变蛇的方向
    • CoorFood():随机生成食物的坐标
    • DrawFood():绘制食物样式
    • EatFood():蛇吃掉食物后的变化
    • KnockWall():撞墙死亡
    • EatSelf():吃到自己死亡
void InitSnake(){
//初始化窗口
srand((unsigned int)time(NULL)); //产生随机种子
initgraph(200,200); //初始化200*200像素的绘图窗口
setbkcolor(GREEN); //设置背景颜色 //初始化蛇
//开始时蛇的节数为1,方向向右
snake.n=1;
snake.ch=right;
snake.szb[0].x=0;
snake.szb[0].y=0;
} //绘制蛇,n节蛇
void DrawSnake(){
setlinecolor(GREEN); //设置蛇边缘的线条颜色
setfillcolor(RED); //设置蛇身的颜色
//遍历数组
for(int i=0;i<snake.n;i++){
fillrectangle(snake.szb[i].x,snake.szb[i].y,snake.szb[i].x+10,snake.szb[i].y+10); //根据蛇的当前长度,创建蛇身,这里设置一节蛇的大小为10*10个像素
}
}
  • 关于蛇的移动其实很简单,只要将前面的节点坐标传递给后面的节点坐标,就能起到移动的效果
//蛇的移动
void MoveSnake(){
for(int i=snake.n-1;i>0;i--){
snake.szb[i].x=snake.szb[i-1].x;
snake.szb[i].y=snake.szb[i-1].y;
}
switch(snake.ch){
case up:
snake.szb[0].y-=10;
break;
case down:
snake.szb[0].y+=10;
break;
case left:
snake.szb[0].x-=10;
break;
case right:
snake.szb[0].x+=10;
break;
}
}
  • 这里需要注意的是:蛇移动时的方向改变规则是在蛇向左/右移动时,蛇只能向上/下移动,同理对于蛇在向上/下移动的情况
//通过键盘控制
void ChangeSnakeCh(){
int move;
move=getch(); //获取键盘传递的字符
switch(move){
case right:
if(snake.ch!=left)
snake.ch=right;
break;
case left:
if(snake.ch!=right)
snake.ch=left;
break;
case up:
if(snake.ch!=down)
snake.ch=up;
break;
case down:
if(snake.ch!=up)
snake.ch=down;
break;
}
}
  • 食物的产生与绘制
void CoorFood(){
food.fzb.x=rand()%20*10; //根据窗口像素来产生食物坐标
food.fzb.y=rand()%20*10;
food.flag=1; 1表示食物没被吃的状态,0表示已吃的状态
}
//绘制食物
void DrawFood(){
//绘制圆角矩形
setfillcolor(YELLOW);
fillroundrect(food.fzb.x,food.fzb.y,food.fzb.x+10,food.fzb.y+10,10,10); }
//蛇吃食物
void EatFood(){
//判断蛇头和食物是否重合
if(snake.szb[0].x==food.fzb.x&&snake.szb[0].y==food.fzb.y){
snake.n++; //蛇身长度加1 food.flag=0; 食物标记为0表示已吃
}
}
  • 死亡机制
//撞墙
int KnockWall(){
for(int i=0;i<snake.n;i++){
if(snake.szb[i].x>200||snake.szb[i].x<0||snake.szb[i].y>200||snake.szb[i].y<0){
//如果蛇头的坐标值超出窗口的坐标值,就返回错误
return 0;
}
}
}
//咬到自己
int EatSelf(){
for(int i=1;i<snake.n;i++){
if(snake.szb[0].x==snake.szb[i].x&&snake.szb[0].y==snake.szb[i].y){
//循环判断蛇头坐标是否与蛇身某部分重合,若重合则放回错误
return 0;
}
}
}
  • 主函数
int main(){
InitSnake(); //初始化
while(1){
while(!kbhit()){ //未改变蛇的方向之前
if(food.flag==0){
CoorFood();
}
cleardevice(); //先清屏,才能保证之前绘制的蛇身不会显示出来
MoveSnake(); //先移动蛇的各个坐标
DrawFood(); //绘制食物
DrawSnake(); //再绘制蛇身
if(!KnockWall()||!EatSelf()) //死亡机制
break;
EatFood(); //吃掉食物后,蛇和食物的变化
Sleep(150); //设置蛇的移动速度
}
while(!KnockWall()||!EatSelf()){
outtextxy(100,100,"YOU DIED!"); //如果蛇吃到自己或撞墙则在窗口显示YOU DIED!
} ChangeSnakeCh(); //通过键盘上下左右键来移动蛇
} return 0;
}

基于EasyX库的贪吃蛇游戏——C语言实现的更多相关文章

  1. 贪吃蛇游戏——C语言双向链表实现

    采用了双向链表结点来模拟蛇身结点: 通过C语言光标控制函数来打印地图.蛇身和食物: /************************** *************************** 贪吃 ...

  2. easyx图形库做贪吃蛇游戏

    编程总是对着一个黑窗口,可以说是非常乏味了,于是喵喵就翻出来了以前用easyx图形库做图形界面的贪吃蛇游戏. 不过大家只是当做提高编程的乐趣来学习吧,想进一步做的话可以学习QT,还有其他的框架. 这是 ...

  3. 贪吃蛇游戏C语言源代码学习

    源代码下载地址为:www.clang.cc 阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读. 程序可在VS2013下编译运行. #include< ...

  4. 基于React的贪吃蛇游戏的设计与实现

    代码地址如下:http://www.demodashi.com/demo/11818.html 贪吃蛇小游戏(第二版) 一年半前层用react写过贪吃蛇小游戏https://github.com/ca ...

  5. Qt 学习之路 2(34):贪吃蛇游戏(4)

    Qt 学习之路 2(34):贪吃蛇游戏(4) 豆子 2012年12月30日 Qt 学习之路 2 73条评论 这将是我们这个稍大一些的示例程序的最后一部分.在本章中,我们将完成GameControlle ...

  6. WebGL实现HTML5的3D贪吃蛇游戏

    js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...

  7. 100行JS实现HTML5的3D贪吃蛇游戏

    js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...

  8. Qt 学习之路 2(31):贪吃蛇游戏(1)

    Qt 学习之路 2(31):贪吃蛇游戏(1) 豆子 2012年12月18日 Qt 学习之路 2 41条评论 经过前面一段时间的学习,我们已经了解到有关 Qt 相当多的知识.现在,我们将把前面所讲过的知 ...

  9. Linux平台下贪吃蛇游戏的运行

    1.参考资料说明: 这是一个在Linux系统下实现的简单的贪吃蛇游戏,同学找帮忙,我就直接在Red Hat中调试了一下,参考的是百度文库中"maosuhan"仁兄的文章,结合自己的 ...

随机推荐

  1. jQuery 小案例

    用jquery实现  百度换肤的模式; <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  2. Python学习---JSONP学习180130

    同源策略机制      同源:协议://IP:端口[协议,域名,端口相同]      跨域:知道对方接口,同时对方返回的数据也必须是Jsonp格式的 问题描述:Ajax跨域请求数据的时候,实际浏览器已 ...

  3. Linux 下Shell的学习2

    0. 查看帮助(比如内置功能)    man bash    -->变量处理大全 1.-计算变量长度的不同方法及不同方法的耗时对比    尽可能的用内置的命令处理,速度快        time ...

  4. 进程&多道技术

    进程 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都 ...

  5. OC文件操作2

    1.对文件本身的操作 NSManager 2.对文件内容的操作 NSHandle 文件句柄 NSFileHandle * fh = [NSFileHandle fileHandleForReading ...

  6. 团队作业—预则立&&他山之石(人月神教)

    1.团队任务 GitHub issues 1.2 团队计划 2.访谈任务 2.1采访对象 采访团队:龙威零式 采访时间:2017.10.23 采访形式:微信群 2.2采访内容 问:你们选题的时候有哪些 ...

  7. Win8.1下运行环境/配置问题解决方案总结

    目录 1.运行 adb shell 时报错" adb server version (26) doesn't match this client (39); killing... " ...

  8. 高性能 Socket 组件 HP-Socket v3.2.1-RC3 公布

    HP-Socket 是一套通用的高性能 TCP/UDP Socket 组件,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统.提供 C/C+ ...

  9. ZooKeeper学习之路 (五)ZooKeeper API的简单使用 增删改查

    zookeeper文件系统的增删改查 public class ZKDemo1 { private static final String CONNECT_STRING = "hadoop1 ...

  10. 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...