easyx保姆级教程——从游戏玩家到游戏制作者

简介: 📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的📖作者主页:热爱编程的小K📖专栏链接:C🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾————————————————版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_72157449/a

0d48cccd75af42b390be6ed1391f98ec.png

b655bb9c9aaf4ad6a1b805acd1e172fc.png

请点击这里:https://live.csdn.net/v/268327?spm=1001.2014.3001.5501

目录

一、头文件

二、窗口

1.初始化绘制窗口

2.设置窗口的背景颜色

3.用设置的背景颜色填充整个窗口—>清屏

4.窗口的坐标体系

三、绘制

1.点

2.线

3.正矩形

4.圆角矩形

5.圆形

6.椭圆

四、文字

1.绘制文字

2.设置文字大小

3.设置颜色

4.设置背景模式

5.练习

6.文字居中显示在指定的区域

五、消息处理—–>鼠标消息

六、消息处理——->按钮

七、消息处理——>按键消息

八、图片加载输出

1.定义图片变量

2.加载路径

3.输出图片

九、图片透明贴图

十、单帧多图动画

十一、精灵表动画

十二、句柄操作

十三、音乐播放

一、头文件

一个是新版头文件,另外一个是旧版本

#include<easyx.h>    //这个是只包含最新的API(函数接口)

#include<graphics.h> //这个头文件包含了上面的,还包含了已经不推荐使用的函数

二、窗口

1.初始化绘制窗口

下方代码中有详细的注释

initgraph(width,height,flag);   //窗口宽度,高度,样式

//窗口样式

//1.在绘图窗口支持鼠标双击事件

EX_DBLCKS

//2.禁用绘图窗口的关闭按钮

EX_NOCLOSE

//3.禁用绘图窗口的最小化按钮

EX_NOMINIMIZE

//4.显示控制台窗口

EX_SHOWCONSOLE

注:窗口事件可以通过按位或( | )连接使用

2.设置窗口的背景颜色

setbkcolor();//可以用RGB(),也可以使用英文大写

3.用设置的背景颜色填充整个窗口—>清屏

cleardevice();

4.窗口的坐标体系

窗口的左上角是坐标原点,x轴向右增大,y轴向下增大,不包括标题栏

三、绘制

1.点

putpixel(x,y,color);

2.线

line(x1,y1,x2,y2); //起始坐标,终止坐标

//可以使用getwidth() gethight()

//获取窗口的宽度和高度

//设置线条颜色

setlinecplor();

//样式

setlinestyle(样式,宽度);

样式

e357a76fa61040979b597c8097660297.png

3.正矩形

rectangle(x1,y1,x2,y2);   //左上角坐标,右下角坐标---->无填充矩形

fillrectangle();          //填充矩形

solidrectangle();         //无边框填充矩形

setfillcolor();           //颜色填充

4.圆角矩形

roundrect(x1,y1,x2,y2,宽度,高度);

//也有

fillroundrect()和solidroundrect()

宽度、高度讲解129512c9a1194003b5334f9511cfd6c1.png

5.圆形

circle(x,y,r);  //圆心坐标和半径

//当然也有

fillcircle()和solidcircle()

6.椭圆

ellipse(x1,y1,x2,y2);         //矩形左上角和右下角坐标,椭圆就是该矩形的内切

//也有

fillellipse()和solidellipse()

四、文字

1.绘制文字

outtextxy(x,y,文字);

文字乱码、不显示问题:

1. 原因:编码格式不同

2. 三种解决方案:

  • 在字符串前面加上L进行转换(强制转换)
  • 用带参宏(_T() 或者 _TEXT())把字符串包起来,自适应转换
  • 设置:菜单栏 – 属性 – 高级 – 字符集 – Unicode改为多字节

2.设置文字大小

settextstyle(高度,宽度,字体);     //宽度为0表示自适应

3.设置颜色

settextcolor();

4.设置背景模式

setbkmode(TRANSPARENT);  //透明

//如果不设置,那么文字会带有背景颜色

5.练习

题目:现有一个int类型的分数,需要输出到图形界面上

int score=88;

char str[50]="";

sprintf(str,"%d",score);

outtextxy(x,y,str);

//必须要把score格式化到str中,否则输出的讲是score的ASCII码值

6.文字居中显示在指定的区域

int rx = 300, ry = 200, rw = 50, rh = 50;

rectangle(300, 200, 350, 250);

settextcolor(YELLOW);

char str[] = "Center Text!";

int hSpace = (rw - textwidth(str)) / 2;

int vSpace = (rh - textheight(str)) / 2;

outtextxy(rx + hSpace, ry + vSpace, str);

思路就是把大矩形中间放一个小矩形,然后求出大矩形边到小矩形边的距离,得出小矩形坐标,把文字写在小矩形位置,来个图例解释:cddda06e91cc4f9ca1131ab41eb0cb18.png

五、消息处理—–>鼠标消息

#include<stdio.h>

#include<easyx.h>

int main()

{

initgraph(800, 800, EX_SHOWCONSOLE | EX_DBLCLKS);  

   //如果要使用双击事件,必须加上EX_DBLCLKS

 

//定义消息结构体变量

ExMessage msg = { 0 };

while (true)

{

 //获取消息

 if (peekmessage(&msg, EX_MOUSE))        //返回bool类型

 {

  switch (msg.message)

  {

  case WM_LBUTTONDOWN:               //左键按下

   printf("%d %d左键按下!\n",msg.x,msg.y);   //获取坐标

   break;

  case WM_RBUTTONDOWN:               //右键按下

   printf("右键按下!\n");

   break;

  case WM_MBUTTONDOWN:               //中键按下

   printf("中键按下\n");

   break;  

  case WM_MOUSEWHEEL:                //滚轮滑动

   printf("%d滚轮滑动\n",msg.wheel);    

                //获取滚轮滑动方向,正朝屏幕,负朝自己

   break;

  case WM_LBUTTONDBLCLK:            //左键双击

   printf("左键双击\n");

   break;

  case WM_MOUSEMOVE:                //鼠标移动

   printf("鼠标移动\n");

   break;

  }

 }

}

return 0;

}

六、消息处理——->按钮

#include<stdio.h>

#include<easyx.h>

bool inArea(int mx, int my, int x, int y, int w, int h);

bool button(int x, int y, int w, int h, const char* text);

ExMessage msg = { 0 };

int main()

{

initgraph(640, 640, EX_SHOWCONSOLE);

setbkcolor(RED);

cleardevice();

while (true)

{

 //获取消息

 if(peekmessage(&msg,EX_MOUSE)){}

 //双缓冲绘图:所有的绘图代码必须放在begin和end之间

 BeginBatchDraw();

 cleardevice();

 if(button(20,20,150,35,"Start Game"))

 {

  printf("Start Game!\n");

 }

 if (button(300, 20, 150, 35, "End Game"))  

 {

  printf("End Game!\n");

 }

 EndBatchDraw();

       //一轮循环消息需要为零,否则点一次出现多次效果

 msg.message = 0;

}

return 0;

}

//判断鼠标是否在按钮区域内

bool inArea(int mx, int my, int x, int y, int w, int h)

{

if (mx > x && mx<x + w && my>y && my < y + h)  

{

 return true;

}

return false;

}

bool button(int x, int y, int w, int h, const char* text)

{

   //鼠标在按钮区域内按钮变色

if (inArea(msg.x, msg.y, x, y, w, h))

{

 setfillcolor(RGB(210, 226, 128));

}

else

{

 setfillcolor(RGB(255, 255, 255));

}

 

//绘制按钮

fillroundrect(x, y, x + w, y + h, 5, 5);

 

//绘制按钮文本

int hSpace = (w - textwidth(text)) / 2;

int vSpace = (h - textheight(text)) / 2;

settextcolor(BLACK);

setbkmode(TRANSPARENT);

outtextxy(x + hSpace, y + vSpace, text);

 

//判断按钮是否被点击

if (msg.message == WM_LBUTTONDOWN && inArea(msg.x, msg.y, x, y, w, h))

{

 return true;

}

return false;

}

七、消息处理——>按键消息

下面以小球移动为案例讲解

#include<stdio.h>

#include<easyx.h>

#include<time.h>

int main()

{

initgraph(800, 640, EX_SHOWCONSOLE);

setbkcolor(RGB(209, 226, 122));

cleardevice();

ExMessage msg = { 0 };

int x = 80, y = 80, vx = 0, vy = 0, speed = 5; //vx,vy代表方向

clock_t Fps = 1000 / 60;              //1s/60f=16.6每一帧应该花费的时间

int startTime = 0;

int freamTime = 0;

while (true)

{

 startTime = clock();    //开始时间

 BeginBatchDraw();

 cleardevice();

 setfillcolor(RED);

 fillcircle(x, y, 25);

 EndBatchDraw();

 if(peekmessage(&msg,EX_MOUSE|EX_KEY)){}  //EX_KEY获取按键消息

 if (msg.message == WM_KEYDOWN)  

 {

  switch (msg.vkcode)

  {

  case VK_UP:

   vy = -1;

   break;

  case VK_DOWN:

   vy = 1;

   break;

  case VK_LEFT:

   vx = -1;

   break;

  case VK_RIGHT:

   vx = 1;

   break;

  }

 }

 else if(msg.message==WM_KEYUP)

 {

  switch (msg.vkcode)

  {

  case VK_UP:

   vy = 0;

   break;

  case VK_DOWN:

   vy = 0;

   break;

  case VK_LEFT:

   vx = 0;

   break;

  case VK_RIGHT:

   vx = 0;

   break;

  }

 }

 x += vx * speed;                   //坐标变化

 y += vy * speed;

 freamTime = clock() - startTime;    //运行时间

 if (freamTime < 16)

 {

  Sleep(Fps - freamTime);

 }

 msg.message = 0;

}

return 0;

}

八、图片加载输出

1.定义图片变量

IMAGE img_king;

2.加载路径

图片路径有两种:

1.绝对路径:带盘符的路径

2.相对路径:该文件位置下的图片

loadimage(&img_king,"图片路径",nwidth,nheight);

//后面两个参数为把图片缩放的宽度高度

3.输出图片

putimage(x,y,&img_king);

九、图片透明贴图

IMGAGE img_king[2];

loadimage(img_king+0,"");

loadimage(img_king+1,"");

putimage(20,20,img_king+0,NOTSRCERASE);   //先绘制掩码图,必须加上最后一个参数

putimage(20,20,img_king+1,SRCINVERT);     //再绘制原图,最后一个参数必须加上

//PNG图片为透明---->没有背景颜色,但是eaxyz不支持

十、单帧多图动画

#include<stdio.h>

#include<easyx.h>

#include<time.h>

#include"tools.hpp"

int main()

{

initgraph(700, 700, EX_SHOWCONSOLE);

setbkcolor(RGB(208, 225, 123));

IMAGE img_king[4];

char path[100] = { 0 };

for (int i = 0; i < 4; i++)

{

 sprintf(path, "./asset/king%d.jpeg", i + 1);

 loadimage(img_king + i, path,700,700);

}

const int frameDelay = 1000 / 60;

int frameStart = 0, frameTime = 0, index = 0, speed = 1000;

while (true)

{

 frameStart = clock();

 BeginBatchDraw();

 cleardevice();

 drawImg(0, 0, img_king + index);

 EndBatchDraw();

 index = (clock() / speed) % 4;

 frameTime = clock() - frameStart;

 if (frameTime<16)

 {

  Sleep(frameDelay - frameTime);

 }

}

return 0;

}

十一、精灵表动画

所谓精灵表动化就是把一张图中的小图片当成动画播放,以下面这张图为例子讲解:

841f231d0f56479ba20629b2b6d9620b.png

#include<stdio.h>

#include<easyx.h>

#include<time.h>

#include"tools.hpp"

int main()

{

initgraph(900, 700, EX_SHOWCONSOLE);

setbkcolor(RGB(208, 225, 123));

IMAGE img_king;

loadimage(&img_king, "./asset/king0.jpeg");

int imgwSize = 240, imghSize = 190;  ///小图片尺寸

const int frameDelay = 1000 / 60;

int frameStart = 0, frameTime = 0, index = 0, speed = 1000;

int i = 0;

while (true)

{

 frameStart = clock();

 BeginBatchDraw();

 cleardevice();

 drawImg(50,50,imgwSize,imghSize,&img_king,index*imgwSize,i);

       //后面两个参数为小图片相对于大图片的横纵坐标

 EndBatchDraw();

 if (index*imgwSize>=720)

 {

  i = 190;

 }

 if (index == 5)  

 {

  i = 0;

 }

 index = (clock() / speed) % 6;

 frameTime = clock() - frameStart;

 if (frameTime < 16)

 {

  Sleep(frameDelay - frameTime);

 }

}

return 0;

}

十二、句柄操作

#include<easyx.h>

#include<stdio.h>

void change();

int main()

{

initgraph(640, 640, EX_SHOWCONSOLE);

setbkcolor(RGB(209, 226, 124));

cleardevice();

change();

getchar();

}

void change()

{

//获取窗口句柄

HWND hnd = GetHWnd();

//设置窗口标题

SetWindowText(hnd, "king");

//弹出窗口提示用户操作

int isok = MessageBox(hnd, "恭喜你中奖500w", "提示", MB_OKCANCEL);  

   //第一个参数设置为hnd,则必须先点击弹出窗口,设置为NULL时都可以点击

   //提示为弹出窗口标题

if(isok==IDOK)

{

 printf("ok\n");

}

else if(isok==IDCANCEL)

{

 printf("取消\n");

}

}

效果图:

3d3748977e6e4169a177e8343cb7bc15.png

十三、音乐播放

#include<stdio.h>

#include<Windows.h>    

#include<mmsystem.h>               //多媒体头文件

#pragma comment(lib,"winmm.lib")   //连接库

void juddge_Error(int ret,const char str[]);

void playBackgroundMusic(const char* music, bool repeat = false, int volume = -1);

int main()

{

playBackgroundMusic("asset/pyghlkn.mp3", false, 500);

//专门用来播放音效----->wav

//PlaySound("asset/CDImage.wav", NULL, SND_FILENAME | SND_ASYNC);

//最后一个参数为异步,防音乐同时播放的卡顿

getchar();

}

void juddge_Error(int ret,const char str[])

{

if (ret != 0)

{

 char err[100] = { 0 };

 mciGetErrorString(ret, err, 100);

 printf("[%s]:%s\n", str,err);

}

}

void playBackgroundMusic(const char* music, bool repeat, int volume)

{

static int i = 0;

char cmd[100] = { 0 };

sprintf(cmd, "open %s alias bgm%d", music, i);

MCIERROR ret = mciSendString(cmd, NULL, 0, NULL);    

//如果失败返回非零值,成功返回零

 

juddge_Error(ret, "open");

sprintf(cmd, "play bgm%d %s", i, repeat ? "repeat" : "");

ret = mciSendString(cmd, NULL, 0, NULL);

juddge_Error(ret, "play");

if (volume != -1)  

{

 sprintf(cmd, "setaudio bgm%d volume to %d", i, volume);      

 //音效范围[0,1000]

 ret = mciSendString(cmd, NULL, 0, NULL);

 juddge_Error(ret, "volume");

}

i++;

}

————————————————

版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_72157449/article/details/128575615

相关文章
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
54 2
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
36 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
36 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版4(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版4(附带项目源码)
17 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版1(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版1(附带项目源码)
53 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版7(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版7(附带项目源码)
18 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版5(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版5(附带项目源码)
16 0
|
3月前
泡泡龙游戏开发实战教程(1):泡泡龙游戏的布局
泡泡龙游戏开发实战教程(1):泡泡龙游戏的布局
57 0
|
3月前
|
存储
扫雷游戏的实现以及具体分析(保姆级教学)
扫雷游戏的分析和设计、扫雷游戏的文字描述、开始前的准备---多文件的创建、开始实操、扫雷游戏的扩展
|
定位技术 开发者
如何做一个俄罗斯方块游戏(一)
从今天开始,我将开启一个新的游戏,并且顺带着会写一个新的系列教程,这个游戏就是人人都知道的——俄罗斯方块。 我一直都在做消除类型的游戏,在所有消除类型的游戏里,俄罗斯方块可以称得上是“鼻祖”了,所以,不论怎样这个系列里都不能少的了它。
126 0