熬夜连干三个小时写了这个小游戏,虽然很简单,我这次只写了无敌模式,你也可以自己继续优化,但是我收获了很多,就来分享一下我遇到的问题和逻辑。
效果(gif没有背景音乐,实际上是有的):
三个都是现学的,easyx图形库直接去网上搜下载安装到编译器就🆗,很容易上手,我习惯先去阅读官方文档,有没见过的查阅学习。
#include<stdio.h>//标准io
#include<conio.h>//控制键盘操作
#include<graphics.h>//easyx图形库,创建图形化窗口
#include<stdlib.h>//本次主要用来生成随机数
#include<mmstream.h>//最后这两个,就是花里胡哨,可以播放音乐,升华
#pragma comment(lib ,“winmm.lib”)
注释都写好了
#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();
效果:
🆗,完成
说一下,后来背景颜色我要调了一下,配色白痴。。。。。。浪费了可长时间,然后细节代码里都写注释了。
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;
}
简简单单,无压力。最浪费我时间的就是逻辑判断和码字速度,需要多锻炼。😏
🆗看下效果:
初步效果:
很简单,只需要循环让三节在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;
}
首先定义食物的结构体
//结构体定义食物的结构
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);
}
好,🆗
//判断吃食物
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等面试解析及知识点整理
Java分布式高级面试问题解析文档
其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!
互联网Java程序员面试必备问题解析及文档学习笔记
Java架构进阶视频解析合集
w,size_16,color_FFFFFF,t_70)
//判断吃食物
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架构进阶视频解析合集