今天我们来尝试一下通过easyx窗口创建贪吃蛇小游戏

首先就是引入几个必要的头文件,相信大家都已经不陌生了,因为在之前的小游戏中都有涉及

#include<stdio.h>

#include<stdlib.h>
#include<graphics.h>  //便于引入easyx窗口及其函数
#include<conio.h>     //按键控制 
#include<time.h>     //构建随机函数

接下来就是对各个变量进行编写,我们这里的窗口高度定义为640,宽度为480

首先就是最为关键的坐标属性

struct point //坐标属性
{
    int x;
    int y;
};

然后就是蛇和食物的属性

struct Snake //蛇的属性
{
    int num;       //蛇的节数
    point xy[100]; //蛇最长的节数
    char postion;  //方向
}snake;

struct Food //食物属性
{
    point foodxy; //食物坐标
    int flag;     //食物是否存在
}food;

因为后期在移动小蛇时,我们要对方向进行编写,所以我们在这里不妨先枚举一下各个方向,便于后期编写

enum moveposition{right=77,left=75,down=80,up=72};

此处也可以不枚举,只需要将后面代码中的的方向改为相应的数字即可

接下来我们就要用不同的函数来构建不同的变量,我将不同的变量总结了一下,便于大家观察

void intsnake();//初始化蛇
void drawsnake();//画蛇
void movesnake();//移动蛇
void keysnake();//按键控制
void intfood();//初始化食物
void drawfood();//画食物
void eatfood();//吃食物
int snakedie();//蛇死亡

首先就是初始化蛇了,这里我们将初始化的蛇确定为三节,并且每一节的间距为10,并初始化蛇运动的方向为右

void intsnake()
{
    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.postion = right;
}

然后就是对蛇进行绘画,我们这里用矩形来表示蛇的身体,对于蛇就颜色,大家可以选择自己喜欢的,我这里用随机函数进行绘制,效果奇特 ,哈哈哈哈哈嗝~

void drawsnake()
{
    for (int i = 0; i < snake.num; i++)
    {
        setlinecolor(BLACK);//边框颜色
        setfillcolor(RGB(rand()%255, rand() % 255, rand() % 255));//填充颜色(随机色)
        //画矩形
        fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10);
    }
}

然后就是要考虑蛇移动的问题 ,我们可以这样想,所谓的蛇移动,就是在蛇头移动后,蛇身体的每一个坐标都等于它前面的坐标,这里我们将蛇头记为snake.xy[0],那么第二节的坐标就是蛇头移动前的坐标,第三节的坐标就变成了蛇移动前第二节的坐标。因此这里我们将蛇头与蛇身体分开表示

void movesnake()
{   //除了第一节(蛇头),后面每一节都是前一节的坐标
    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.postion)
    {
    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 keysnake()
{
    char userkey = 0;
    userkey = _getch();//控制台可以直接读取我按的键
    switch (userkey)
    {
    case 'd':
    case right:
        snake.postion = right;        
        break;
    case left:
    case 'a':
        snake.postion = left;        
        break;
    case down:
    case 's':
        snake.postion = down;    
        break;
    case up:
    case 'w':
        snake.postion = up;
        break;
    default:
        break;
    }
}

蛇我们已经完成,接下来就是对 食物进行编写,这里我们用随机函数rand对食物出现的位置进行定义,确保食物每次出现的位置不同,之所以将640分成64*10,是确保食物尽可能出现在窗口中间,不然数字太小,蛇可能吃不到。这里我们多加一个如果食物出现在蛇身上,是为了防止在一开始的时候食物便出现在蛇身上导致我们没有看见食物。(虽然这样的几率很小很小很小,但我还是想皮一下 ,嘿嘿嘿)

void intfood()
{
    //拆开写,防止蛇吃不到食物
    food.foodxy.x = rand() % 64 * 10;
    food.foodxy.y = rand() % 48 * 10;
    food.flag = 1;//防止反复出现食物
    //如果食物出现在蛇身上
    for(int i = 0; i > snake.num; i++)
    {
        
        if(food.foodxy.x==snake.xy[i].x && food.foodxy.y == snake.xy[i].y)
        {
            food.foodxy.x = rand() % 64 * 10;
            food.foodxy.y = rand() % 48 * 10;
        }
    }
}

接下来就是画食物了,和蛇一样,我们也用矩形绘制食物

void drawfood()
{
    setlinecolor(BLACK);
    setfillcolor(GREEN);
    fillrectangle(food.foodxy.x, food.foodxy.y, food.foodxy.x + 10, food.foodxy.y + 10);
}

食物画完了,接下来就该让小蛇吃食物啦

void eatfood()
{
    if (snake.xy[0].x == food.foodxy.x&&snake.xy[0].y==food.foodxy.y)
    {
        snake.num++;//蛇长度每次加一
        food.flag = 0;//重新显示食物
    }
}

接下来就是蛇的死亡啦,小蛇死亡分为两种,撞墙或者撞自己,因为这里用到了MessageBox,所以我们在开头应该声明一个主窗口

HWND hwnd = NULL;//表示主窗口

int snakedie()
{
    if (snake.xy[0].x > 640 || snake.xy[0].y > 480 || snake.xy[0].x < 0 || snake.xy[0].y < 0)
    {
        MessageBox(hwnd, "游戏结束","撞墙",MB_OK);//弹出一个窗口
        return 1;
    }
    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)
        {            
            MessageBox(hwnd, "游戏结束", "撞自己", MB_OK);//弹出一个窗口
            return 1;
        }
    }
    return 0;
}

接下来就是振奋人心的主函数组合啦,我们这里定义flag为0时表示无食物,此时就对食物进行定义并且绘制,在食物出现后,因为 intfood()中flag为1,所以之后食物就不会再次出现,直到在eatfood()中小蛇吃掉食物,并将flag改为0,则食物才会在while()循环的驱动下再次定义并绘制

这里我们还用到了双缓冲绘图,是为了防止小蛇在移动时一闪一闪,这个在我之前的easyx基础中有涉及

int main()
{
    srand((unsigned int)time(NULL));//生成随机数种子
    hwnd = initgraph(640, 480);//窗口大小,init意思是初始化
    setbkcolor(WHITE);//窗口颜色
    intsnake();
    while (1)//循环执行命令
    {
        cleardevice();//刷新一下,防止窗口颜色不变
        //双缓冲绘图,放在绘图代码之前和之后,防止贪吃蛇界面一闪一闪
        BeginBatchDraw();//开始绘图
        drawsnake();
        movesnake();
        drawfood();
        EndBatchDraw();// 结束绘图
        if (food.flag == 0)
        {
            intfood();
        }
        eatfood();
        if (snakedie())
        {
            break;
        }
        while (_kbhit())//判断是否有按键,防止出现屏幕不动的情况
        {
            keysnake();
        }
        Sleep(50);//放慢速度
    }
    getchar();//防止闪屏
    closegraph();//关闭窗口
    return 0;
}

总体代码就是这样,如果大家发现bug或者有更好的方法 ,欢迎大家一起来讨论呀

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<graphics.h>
#include<conio.h>
struct point //坐标属性
{int x;int y;
};
struct Snake //蛇的属性
{int num;       //蛇的节数point xy[100]; //蛇最长的节数char postion;  //方向
}snake;
struct Food //食物属性
{point foodxy; //食物坐标int flag;     //食物是否存在
}food;
HWND hwnd = NULL;//表示主窗口
enum moveposition{right=77,left=75,down=80,up=72};
//void intsnake();//初始化蛇
//void drawsnake();//画蛇
//void movesnake();//移动蛇
//void keysnake();//按键控制
//void intfood();//初始化食物
//void drawfood();//画食物
//void eatfood();//吃食物
//int snakedie();//蛇死亡void intsnake()
{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.postion = right;
}
void drawsnake()
{for (int i = 0; i < snake.num; i++){setlinecolor(BLACK);//边框颜色setfillcolor(RGB(rand()%255, rand() % 255, rand() % 255));//填充颜色(随机色)//画矩形fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10);}
}
void movesnake()
{   //除了第一节(蛇头),后面每一节都是前一节的坐标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.postion){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 keysnake()
{char userkey = 0;userkey = _getch();//控制台可以直接读取我按的键switch (userkey){case 'd':case right:snake.postion = right;        break;case left:case 'a':snake.postion = left;       break;case down:case 's':snake.postion = down;   break;case up:case 'w':snake.postion = up;break;default:break;}
}
void intfood()
{//拆开写,防止蛇吃不到食物food.foodxy.x = rand() % 64 * 10;food.foodxy.y = rand() % 48 * 10;food.flag = 1;//如果食物出现在蛇身上for(int i = 0; i > snake.num; i++){if(food.foodxy.x==snake.xy[i].x && food.foodxy.y == snake.xy[i].y){food.foodxy.x = rand() % 64 * 10;food.foodxy.y = rand() % 48 * 10;}}
}
void drawfood()
{setlinecolor(BLACK);setfillcolor(GREEN);fillrectangle(food.foodxy.x, food.foodxy.y, food.foodxy.x + 10, food.foodxy.y + 10);
}
void eatfood()
{if (snake.xy[0].x == food.foodxy.x&&snake.xy[0].y==food.foodxy.y){snake.num++;//蛇长度每次加一food.flag = 0;//重新显示食物}
}
int snakedie()
{if (snake.xy[0].x > 640 || snake.xy[0].y > 480 || snake.xy[0].x < 0 || snake.xy[0].y < 0){MessageBox(hwnd, "游戏结束","撞墙",MB_OK);//弹出一个窗口return 1;}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){          MessageBox(hwnd, "游戏结束", "撞自己", MB_OK);//弹出一个窗口return 1;}}return 0;
}
int main()
{srand((unsigned int)time(NULL));//生成随机数种子hwnd = initgraph(640, 480);//窗口大小,init意思是初始化setbkcolor(WHITE);//窗口颜色intsnake();while (1){cleardevice();//刷新一下,防止窗口颜色不变//双缓冲绘图,放在绘图代码之前和之后,防止贪吃蛇界面一闪一闪BeginBatchDraw();//开始绘图drawsnake();movesnake();drawfood();EndBatchDraw();// 结束绘图if (food.flag == 0){intfood();}eatfood();if (snakedie()){break;}while (_kbhit()){keysnake();}Sleep(50);//放慢速度}getchar();//防止闪屏closegraph();//关闭窗口return 0;
}

大家一起加油

通过easyx窗口实现贪吃蛇相关推荐

  1. c语言制作贪吃小白入门,小白入门——easyx界面版“贪吃蛇”的C语言实现(详细)...

    小白入门--easyx界面版"贪吃蛇"的C语言实现(详细) 作者:顽石 前言:C语言初学者都是在控制台上开发一些小游戏什么,由于没有界面(比如图片.音乐,不能做出拥有自己风格的程序 ...

  2. 基于easyx的c++贪吃蛇

    本代码来自于easyx讨论群的分享 先上效果图,其实也只是画了简单的圈圈代表蛇和食物,背景就是黑色的. #include "stdafx.h" #include <iostr ...

  3. 用C/C++实现简单游戏开发:easyx实现幻彩贪吃蛇

    效果: 标题 实现代码(粗略实现,有待优化): #include<iostream> #include<graphics.h> #include<vector> # ...

  4. easyx写登入界面_小白入门——easyx界面版“贪吃蛇”的C语言实现(详细)

    #include"snake.h"#include//easyx图形库头文件 #define Azure 0xA4D3EE//自己定义的一个颜色 忘记了... intmain() ...

  5. EasyX实现简易贪吃蛇

  6. [C语言] 自制的贪吃蛇游戏

    使用C语言自带的游戏图新库开发贪吃蛇 我看网上好多制作贪吃蛇的帖子都是对刚学习C语言的同学们很不友好,制作的都是控制台,黑窗口的贪吃蛇游戏,能做出来但是感觉很无趣,不太像正常的游戏,接下来我将制作完全 ...

  7. C语言游戏项目——贪吃蛇游戏

    贪吃蛇游戏所需要运用到的知识 贪吃蛇游戏创建界面 贪吃蛇游戏框架基本函数 贪吃蛇游戏总代码 因为本人在编写贪吃蛇的时候会用到easyX,所以建议读者可以先了解一些EasyX,这样能够帮助你对本篇文章的 ...

  8. 自己动手写贪吃蛇AI——附源码和程序

    从第一次构想写贪吃蛇AI,到现在两个学期才落实下来.其实之前用手机C4droid控制台写过一次,不是很理想,这次把这个坑填了吧,非要问有什么意义的话,自娱自乐罢了. 再来回顾一下这张动图,非常的流畅, ...

  9. C++ 开发贪吃蛇游戏总结

    一.思考贪吃蛇的思路: 1.在一个窗口绘制贪吃蛇,肯定少不了绘制的API,所以必不可少需要引入graphics.h这个图形界面库(里面封装了WIN 32大部分绘制API,如果没有的话,可以用GDI). ...

  10. C语言实战 - 贪吃蛇(图形界面)

    由于本人精力有限,暂时先把素材和代码放上,等以后有空再补教程. 目录 效果预览 准备工作 EasyX图形库 音频素材 代码编写 Transfer.h文件 game.cpp文件 main.c文件 效果预 ...

最新文章

  1. centos 删除crontab_centos crontab(定时任务) 使用
  2. 图解Istio原理和实践--云平台技术栈18
  3. 禁止UDP端口引起DNS错误导致邮局无法外发的故障
  4. hdu 5720(贪心)
  5. 虚拟机安装windows ghost版本系统记录完整过程
  6. 快速数论变换(NTT)
  7. 易用性软件测试用例,软件性能测试规定——易用性测试规定
  8. 单片机---HLK-W801图形框架LVGL下开发(四)
  9. 【从零开始学架构-李运华】06|复杂地来源:可扩展性
  10. 初学者入门——NOI题库1.3
  11. 配置Jenkins及下载相关插件
  12. Go语言 —— 前景
  13. Windows2016 L2TP配置(证书模式)
  14. 《数字信号处理》正弦信号的波形及频谱的求解
  15. python使用pypandoc将html转换成word文档
  16. 操作系统为什么需要驱动? 驱动程序是什么?为什么有的硬件“免驱”?
  17. 闲置电脑挂机赚钱-Traffmonetizer,支持windows,linux,Android,MacOS多平台
  18. LOAM论文和程序代码的解读
  19. Echarts世界地图的国家名称中文化
  20. 安卓虚拟键盘_0202年了,苹果IOS和安卓系统的差距还大吗?

热门文章

  1. 随便谈谈我的实习经历
  2. 戴尔笔记本无线网络无法连接
  3. 构建 Web 应用之 Service Worker 初探
  4. 前端学习之路, 记录前端小白成长历程, 学习总结, 工具汇总, 打造开箱即用的学习体验
  5. 群晖docker容器内配置ubuntu远程桌面访问
  6. pinctrl学习笔记---描述/获得引脚
  7. Rasa中文聊天机器人开发指南(2):NLU篇
  8. 笔记本没有Insert键怎么办
  9. 常用邮箱大全,申请邮箱收费吗?邮箱活动有哪些?
  10. 基于NIOS II的1553B总线开发板