耗时三小时写了一个图形化的贪吃蛇(第一次使用easyx图形库)算是对学习的小小实战吧

熬夜连干三个小时写了这个小游戏,虽然很简单,我这次只写了无敌模式,你也可以自己继续优化,但是我收获了很多,就来分享一下我遇到的问题和逻辑。

效果(gif没有背景音乐,实际上是有的):

在这里插入图片描述

头文件


三个都是现学的,easyx图形库直接去网上搜下载安装到编译器就🆗,很容易上手,我习惯先去阅读官方文档,有没见过的查阅学习。

#include<stdio.h>//标准io

#include<conio.h>//控制键盘操作

#include<graphics.h>//easyx图形库,创建图形化窗口

#include<stdlib.h>//本次主要用来生成随机数

#include<mmstream.h>//最后这两个,就是花里胡哨,可以播放音乐,升华

#pragma comment(lib ,“winmm.lib”)

1.写出图形化界面


注释都写好了

#include<stdio.h>

#include<graphics.h>//引入图形库

//需要知识:结构体,循环,函数,easyx图形库,结构体数组

int main()

{

initgraph(640,480);//init graph 初始化 图形窗口

while (1)//卡死

{

}

return 0;

}

效果:

在这里插入图片描述

好ok,就是这样,第一步就完成了。加个背景颜色优化一下

//设置背景颜色

setbkcolor(RGB(82,143,22));

//清空绘图设备

cleardevice();

效果:

在这里插入图片描述

🆗,完成


2.绘制🐍


说一下,后来背景颜色我要调了一下,配色白痴。。。。。。浪费了可长时间,然后细节代码里都写注释了。

1,好习惯

2,方便学习和增删改查

#include<stdio.h>

#include<graphics.h>//引入图形库

//需要知识:结构体,循环,函数,easyx图形库,结构体数组

//宏定义🐍的最大节数,宏定义建议大写,好的编码习惯

#define SNAKE_MAX 400

//结构体定义🐍的结构

struct Snake

{

int size;//节数

int speed;//速度

int dir;//方向

//坐标,定义好的结构体(x,y)

POINT coor[SNAKE_MAX];//通过宏定义定义🐍的最大400节,想开挂,直接去修改宏定义

}snake;

//数据初始化,用函数模块化编程思想

void Gameinit()

{

//init graph 初始化 图形窗口

initgraph(640, 480);

//初始化🐍,开始游戏有3节

snake.size = 3;

snake.speed = 10;

snake.dir;

//通过循环初始化出3段🐍

for (int i = snake.size; i >= 0; i–)

{

snake.coor[i].x = 10*i+40;//x坐标慢慢调试,合适位置

snake.coor[i].y = 30;

}

}

//绘制,也单独写一个函数

void Gamedraw()

{

//设置背景颜色

setbkcolor(RGB( 193, 205, 193));

cleardevice();

//循环绘制3段🐍

setfillcolor(GREEN);

for (int i = 0; i < snake.size; i++)

{

solidcircle(snake.coor[i].x, snake.coor[i].y, 5);//三个参数,x坐标,y坐标,半径

}

EndBatchDraw();

}

int main()

{

Gameinit();

Gamedraw();

while (1)//卡死

{

}

return 0;

}

简简单单,无压力。最浪费我时间的就是逻辑判断和码字速度,需要多锻炼。😏

🆗看下效果:

在这里插入图片描述

3.移动🐍


初步效果:

在这里插入图片描述

很简单,只需要循环让三节在x轴++就实现了,但是有很多问题。

//移动🐍

void snakeMove()

{

for (int i = 0; i < snake.size; i++)

{

snake.coor[i].x++;

}

}

用枚举加按键改变方向,这里要引入#include<conio.h>//控制键盘操作这个头文件,这里需要注意_getch()是一个阻塞函数,我们通过函数_kbhit()判断有没有按键来解决,有按键就返回真就移动,这里入坑了,🆗没问题

#include<stdio.h>

#include<conio.h>//控制键盘操作

#include<graphics.h>//引入图形界面的头文件

//需要知识:结构体,循环,函数,easyx图形库,结构体数组

//宏定义🐍的最大节数,宏定义建议大写,好的编码习惯

#define SNAKE_MAX 400

//🐍的方向通过枚举实现

enum DIR

{

UP,

DOWN,

LEFT,

RIGHT,

};

//结构体定义🐍的结构

struct Snake

{

int size;//节数

int speed;//速度

int dir;//方向

//坐标,定义好的结构体(x,y)

POINT coor[SNAKE_MAX];//通过宏定义定义🐍的最大400节,想开挂,直接去修改宏定义

}snake;

//数据初始化,用函数模块化编程思想

void Gameinit()

{

//init graph 初始化 图形窗口

initgraph(640, 480);

//初始化🐍,开始游戏有3节

snake.size = 3;

snake.speed = 10;

//默认往右走

snake.dir=RIGHT;

//通过循环初始化出3段🐍

for (int i = snake.size; i >= 0; i–)

{

snake.coor[i].x = 10*i+40;//x坐标慢慢调试,合适位置

snake.coor[i].y = 30;

}

}

//绘制,也单独写一个函数

void Gamedraw()

{

//设置背景颜色

setbkcolor(RGB(193, 205, 193));

cleardevice();

//循环绘制3段🐍

setfillcolor(GREEN);

for (int i = 0; i < snake.size; i++)

{

solidcircle(snake.coor[i].x, snake.coor[i].y, 5);//三个参数,x坐标,y坐标,半径

}

EndBatchDraw();

}

//移动🐍

void snakeMove()

{

for (int i = 0; i < snake.size; i++)

{

switch (snake.dir)

{

case UP:

snake.coor[i].y-=snake.speed;

break;

case DOWN:

snake.coor[i].y+=snake.speed;

break;

case LEFT:

snake.coor[i].x-=snake.speed;

break;

case RIGHT:

snake.coor[i].x+=snake.speed;

break;

}

}

}

//通过按键改变蛇的方向(上下左右),需要头文件#include<conio.h>//控制键盘操作

//72 80 75 77上下左右键对应的数字,可以通过这些数字确定键

//_getch()是一个阻塞函数,我们通过函数_kbhit()判断有没有按键来解决,有按键就返回真,就移动

void keyControl()

{

if (_kbhit())

{

switch (_getch())

{

case ‘W’:

case’w’:

case 72:

//移动上面已经写好了,在这就直接用

snake.dir = UP;

break;

case ‘S’:

case’s’:

case 80:

snake.dir = DOWN;

break;

case ‘a’:

case’A’:

case 75:

snake.dir = LEFT;

break;

case ‘D’:

case’d’:

case 77:

snake.dir = RIGHT;

break;

}

}

}

int main()

{

Gameinit();

while (1)//卡死

{

Gamedraw();

snakeMove();

keyControl();

Sleep(10);

}

return 0;

}


实现效果:

在这里插入图片描述

可以看到这……遇到Bug了。

分析了一下,你看它能左右能上下,什么怪物,所以,先让身体跟着头移动

//移动🐍

void snakeMove()

{

//-1防止数组越界

for (int i = snake.size-1; i > 0; i–)

{

//身体连接到头上

snake.coor[i] = snake.coor[i - 1];

}

switch (snake.dir)

{

case UP:

snake.coor[0].y-= snake.speed;

break;

case DOWN:

snake.coor[0].y+= snake.speed;

break;

case LEFT:

snake.coor[0].x-= snake.speed;

break;

case RIGHT:

snake.coor[0].x+= snake.speed;

break;

}

}

在这里插入图片描述

果然,现在还有问题,发现它是没有头的开了挂的🐍,向上直接能变成向下,左右也是

这时候再用 if 判断语句轻松实现上了不能下,左了不能右,试一下:

//如果不👇那就👆,乖乖听话

if (snake.dir != DOWN)

{

snake.dir = UP;

}

break;

case ‘S’:

case’s’:

case 80:

//如果不👆那就👇,乖乖听话

if (snake.dir != UP)

{

snake.dir = DOWN;

}

break;

case ‘a’:

case’A’:

case 75:

//如果不👉那就👈,乖乖听话

if (snake.dir != RIGHT)

{

snake.dir = LEFT;

}

break;

case ‘D’:

case’d’:

case 77:

//如果不👈那就👉,乖乖听话

if (snake.dir != LEFT)

{

snake.dir = RIGHT;

}

break;

}

好,🆗啊,简简单单。看下效果:

在这里插入图片描述

Good,好像有点样了

但是这个一出墙就不见了,我技术菜,我想让它无敌,上边进下边出,坐进又出。怎么实现?思考一下……


对移动部分的部分的函数做以下判断即可

  • 普通模式: 如果蛇头在y轴坐标小于等于0,就说明已经碰到墙,可以直接结束游戏(不适合我)

  • 开挂模式:如果撞墙把它坐标修改一下就实现了(适合我)

switch (snake.dir)

{

case UP:

snake.coor[0].y-= snake.speed;

//蛇头在y轴<等你0了,说明撞到墙了

if (snake.coor[0].y -5 <= 0)

{

snake.coor[0].y = 480;

}

break;

case DOWN:

snake.coor[0].y+= snake.speed;

if (snake.coor[0].y +5>= 480)

{

snake.coor[0].y = 0;

}

break;

case LEFT:

snake.coor[0].x-= snake.speed;

if (snake.coor[0].x +5 <=0)

{

snake.coor[0].x = 640;

}

break;

case RIGHT:

snake.coor[0].x+= snake.speed;

if (snake.coor[0].x-5>= 640)

{

snake.coor[0].x = 0;

}

break;

}

在这里插入图片描述


4.绘制球球


首先定义食物的结构体

//结构体定义食物的结构

struct food

{

int x;//食物坐标x

int y;//食物坐标y

int r;//食物半径r

bool flag; //布尔类型,1没有吃 0吃了

DWORD color; //color

}food;

然后进行初始化(随机数终于派上用场了😎)

//food初始化(用到随机函数)虚拟随机(如果没有随机数种子则产生的一样)

//设置种子需要头文件stdlib.h

food.x = rand() % 640;//初始化x

food.y = rand() % 480;//初始化y

food.color = RGB(rand() % 256, rand() % 256, rand() % 256);//分别初始化rgb的三个元素

food.r = rand() % 10 + 2;//半径随机

food.flag = true;//开局就生成食物

然后绘制,很简单,只需要判断是1就画

//绘制食物

if (food.flag)

{

solidcircle(food.x, food.y, food.r);

}

好,🆗

在这里插入图片描述

在这里插入图片描述


5.🐍吃球球


//判断吃食物

void eat()

{

if (food.flag && snake.coor[0].x >= food.x - food.r && snake.coor[0].x <= food.x + food.r && snake.coor[0].y >= food.y - food.r && snake.coor[0].y <= food.y + food.r)

{

food.flag = false;

snake.size++;

}

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

image

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

image

互联网Java程序员面试必备问题解析及文档学习笔记

image

Java架构进阶视频解析合集

w,size_16,color_FFFFFF,t_70)

在这里插入图片描述


5.🐍吃球球


//判断吃食物

void eat()

{

if (food.flag && snake.coor[0].x >= food.x - food.r && snake.coor[0].x <= food.x + food.r && snake.coor[0].y >= food.y - food.r && snake.coor[0].y <= food.y + food.r)

{

food.flag = false;

snake.size++;

}

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

[外链图片转存中…(img-ijzHlJiY-1714787864192)]

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

[外链图片转存中…(img-n5uOGA6t-1714787864193)]

互联网Java程序员面试必备问题解析及文档学习笔记

[外链图片转存中…(img-TPkxXzWX-1714787864193)]

Java架构进阶视频解析合集

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 28
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用 EasyX 图形实现的贪吃游戏的示例代码: ```c++ #include <graphics.h> #include <conio.h> #include <time.h> const int WIDTH = 600; // 游戏窗口宽度 const int HEIGHT = 600; // 游戏窗口高度 const int CELL_SIZE = 20; // 每个身格子的大小 const int ROWS = HEIGHT / CELL_SIZE - 1; // 游戏窗口中行数 const int COLS = WIDTH / CELL_SIZE - 1; // 游戏窗口中列数 struct Snake { int x, y; struct Snake *next; }; enum Direction { UP, DOWN, LEFT, RIGHT }; Direction direction = RIGHT; // 的初始方向 Snake *head = NULL; // 头指针 int score = 0; // 得分 void initSnake() { head = new Snake; head->x = 5; head->y = 5; head->next = NULL; } void drawSnake() { setfillcolor(YELLOW); for (Snake *p = head; p; p = p->next) { solidrectangle(p->x * CELL_SIZE, p->y * CELL_SIZE, (p->x + 1) * CELL_SIZE, (p->y + 1) * CELL_SIZE); } } void moveSnake() { int x = head->x, y = head->y; switch (direction) { case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } Snake *p = new Snake; p->x = x; p->y = y; p->next = head; head = p; if (x < 0 || x > COLS || y < 0 || y > ROWS) { // 撞墙 closegraph(); printf("Game Over!\n"); exit(0); } for (Snake *p = head->next; p; p = p->next) { // 撞自己 if (p->x == head->x && p->y == head->y) { closegraph(); printf("Game Over!\n"); exit(0); } } if (x == food_x && y == food_y) { // 吃到食物 score += 10; food_x = rand() % COLS; food_y = rand() % ROWS; } else { Snake *p = head; while (p->next->next) { p = p->next; } delete p->next; p->next = NULL; } } void drawFood() { setfillcolor(RED); solidcircle(food_x * CELL_SIZE + CELL_SIZE / 2, food_y * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE / 2); } void updateScore() { setbkmode(TRANSPARENT); settextcolor(WHITE); char buf[32]; sprintf(buf, "Score: %d", score); outtextxy(10, 10, buf); } int food_x, food_y; int main() { initgraph(WIDTH, HEIGHT); setbkcolor(DARKGRAY); initSnake(); food_x = rand() % COLS; food_y = rand() % ROWS; while (true) { cleardevice(); drawSnake(); drawFood(); updateScore(); moveSnake(); Sleep(100); if (_kbhit()) { switch (_getch()) { case 'W': case 'w': if (direction != DOWN) direction = UP; break; case 'S': case 's': if (direction != UP) direction = DOWN; break; case 'A': case 'a': if (direction != RIGHT) direction = LEFT; break; case 'D': case 'd': if (direction != LEFT) direction = RIGHT; break; } } } return 0; } ``` 在这个示例代码中,我们使用EasyX 图形来实现游戏窗口和绘制图形。我们使用 Snake 结构体来表示身,其中的 next 指针指向下一个身。当移动时,我们将一个新的 Snake 节点插入到头位置,然后删除尾节点,从而实现的移动。当头碰到墙壁或者自己的身体时,游戏结束。当头碰到食物时,得分加 10 分,并在随机位置生成一个新的食物。 在游戏循环中,我们使用 cleardevice() 函数清空屏幕,然后分别绘制身、食物和得分。我们使用 Sleep(100) 函数控制游戏的帧率,从而实现动画效果。我们使用 _kbhit() 和 _getch() 函数来读取键盘输入,从而控制的方向。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值