相信许多同学在学完C/C++后还停留在那黑乎乎的控制台窗口,或许会认为C/C++只能呈现单调乏味的控制台页面。然而事实并非如此!通过运用easyx插件,我们能够实现图形化编程,让我们的程序焕发多彩的魅力!接下来,我将以简单的球球大作战项目为例,向大家介绍easyx插件图形化界面编程的基本操作。
项目所需条件:
1.运行环境:
Windows 11
2.开发软件
Visual Studio 2022
3.使用插件
Easyx图形库
EasyX 是针对 C++ 的图形库,可以帮助 C 语言初学者快速上手图形和游戏编程。
项目开发功能:
1. 玩家可以通过移动来吞食固定的小球。
2. 吞食小球会增加玩家自身的大小。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<easyx.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<math.h>
#define FOOD_NUM 150
#define TWOPointDistance(x1,y1,x2,y2) sqrt( pow(x1-x2,2)+pow(y1-y2,2))
void drawGrid();
void key_down_up();
void move();
void init_FOOD();
void draw_FOOD();
void Transboundary();
void eat_FOOD();
void grow();
struct food_position {
int fx;
int fy;
int color;
int radius = rand()%15;
bool active;
}food[FOOD_NUM];
struct circle_position {
int x = 50;
int y = 50;
int radius = 10;
int speed = 4;
int vx;
int vy;
}cp;
int main()
{
srand((unsigned)time(NULL));
initgraph(880, 680);
cleardevice();
setbkcolor(RGB(230, 238, 229));//设置背景颜色
setlinecolor(RED);
init_FOOD();//初始化食物
int halfH, halfW;
char name[20] = { "小爱同学" };
while (1)
{
BeginBatchDraw();
cleardevice();
drawGrid();//画网格
draw_FOOD();//画食物
solidcircle(cp.x, cp.y, cp.radius);//画自己
setfillcolor(RGB(9, 207, 254));
halfH = textheight(name) / 2;//实现居中写名字
setbkmode(TRANSPARENT);//设置文字背景颜色
halfW = textwidth(name) / 2;
settextcolor(BLACK);
outtextxy(cp.x - halfW, cp.y - halfH, name);
key_down_up();//按键控制移动
move();
eat_FOOD();
Transboundary();//判断是否越界
Sleep(8);
EndBatchDraw();
}
getchar();
closegraph();
} //main在这里
void drawGrid()
{
for (int i = 0; i < 680; i += 10)
{
line(0, i, 880, i);
}
for (int i = 0; i < 880; i += 10)
{
line(i, 0, i, 680);
}
}
void key_down_up() {
ExMessage msg = { 0 };
if (peekmessage(&msg))
{
if (msg.message==WM_KEYDOWN)
{
switch (msg.vkcode)
{
case VK_UP:cp.vy = -1;
break;
case VK_DOWN:cp.vy = 1;
break;
case VK_LEFT:cp.vx = -1;
break;
case VK_RIGHT:cp.vx = 1;
break;
default:
break;
}
}
else if (msg.message == WM_KEYUP)
{
switch (msg.vkcode)
{
case VK_UP:cp.vy = 0;
break;
case VK_DOWN:cp.vy =0;
break;
case VK_LEFT:cp.vx = 0;
break;
case VK_RIGHT:cp.vx =0;
break;
default:
break;
}
}
}
}
void move()
{
cp.x += cp.vx * cp.speed;
cp.y += cp.vy * cp.speed;
}
void init_FOOD()
{
for (int i = 0; i < FOOD_NUM; i++)
{
food[i].fx = rand() % 880;
food[i].fy = rand() % 680;
food[i].color = RGB(rand() % 255, rand() % 255, rand() % 255);
food[i].active = true;
}
}
void draw_FOOD() {
for (int i = 0; i < FOOD_NUM; i++)
{
if (food[i].active==true)
{
fillcircle(food[i].fx, food[i].fy, food[i].radius);
setlinecolor(BLACK);
setfillcolor(food[i].color);
}
}
}
void Transboundary() {
if (cp.x-cp.radius<0)
{
cp.x = cp.radius;
}
if (cp.y-cp.radius<0)
{
cp.y = cp.radius;
}
if (cp.x>getwidth() - cp.radius)
{
cp.x = getwidth() - cp.radius;
}
if (cp.y>getheight() - cp.radius)
{
cp.y = getheight() - cp.radius;
}
}
void eat_FOOD() {
for (int i = 0; i < FOOD_NUM; i++)
{
float distance;
distance = TWOPointDistance(cp.x, cp.y, food[i].fx, food[i].fy);
float r = cp.radius - food[i].radius;
if (distance<r&&cp.radius>food[i].radius && food[i].active == true)
{
food[i].active = false;
cp.radius = cp.radius + 1;
}
}
}
运行结果如下:
关键代码讲解:
1.初始化小球信息
radius为生成的食物半径
struct food_position {
int fx;
int fy;
int color;
int radius = rand()%15;
bool active;
}food[FOOD_NUM];
2.控制小球是否移动
通过easyx插件获取消息结构体变量键盘信息,并控制键盘按下与弹起时小球是否移动
void key_down_up() {
ExMessage msg = { 0 };
if (peekmessage(&msg))
{
if (msg.message==WM_KEYDOWN)
{
switch (msg.vkcode)
{
case VK_UP:cp.vy = -1;
break;
case VK_DOWN:cp.vy = 1;
break;
case VK_LEFT:cp.vx = -1;
break;
case VK_RIGHT:cp.vx = 1;
break;
default:
break;
}
}
else if (msg.message == WM_KEYUP)
{
switch (msg.vkcode)
{
case VK_UP:cp.vy = 0;
break;
case VK_DOWN:cp.vy =0;
break;
case VK_LEFT:cp.vx = 0;
break;
case VK_RIGHT:cp.vx =0;
break;
default:
break;
}
}
}
}
3.移动小球
通过改变小球的坐标来实现小球的移动
void move()
{
cp.x += cp.vx * cp.speed;
cp.y += cp.vy * cp.speed;
}
4.初始化食物坐标并绘制食物
通过rand函数随机在画板上生成食物,冰为每个食物初始化不同的颜色。
void init_FOOD()
{
for (int i = 0; i < FOOD_NUM; i++)
{
food[i].fx = rand() % 880;
food[i].fy = rand() % 680;
food[i].color = RGB(rand() % 255, rand() % 255, rand() % 255);
food[i].active = true;
}
}
void draw_FOOD() {
for (int i = 0; i < FOOD_NUM; i++)
{
if (food[i].active==true)
{
fillcircle(food[i].fx, food[i].fy, food[i].radius);
setlinecolor(BLACK);
setfillcolor(food[i].color);
}
}
}
5.吃食物
当玩家半径大于食物时吞并食物并增加自身半径大小
void eat_FOOD() {
for (int i = 0; i < FOOD_NUM; i++)
{
float distance;
distance = TWOPointDistance(cp.x, cp.y, food[i].fx, food[i].fy);
float r = cp.radius - food[i].radius;
if (distance<r&&cp.radius>food[i].radius && food[i].active == true)
{
food[i].active = false;
cp.radius = cp.radius + 1;
}
}
}