raylib U3 - 对开始按钮的封装
这一篇实现的效果还是开始按钮,但是在代码上做了大量的封装。
在实现复杂功能的时候,把重复的代码封装起来,是编程必须掌握的技能。
后面我们会再用class类来做一次封装。
主要的修改:
- 把按钮相关的功能都用结构体封装了,尽量让main函数里的代码更简洁。
- 使用raylib自带的碰撞检测。
上代码:
#include <raylib.h>
#include<bits/stdc++.h>
using namespace std;
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
struct Ball{
Texture t;
int x,y;
int speedx,speedy;
};
//创建一个枚举类型,表示按钮的状态。
enum startState{
normal,
hover,
pressed
};
struct Button{
Texture normal;
Texture hover;
Texture pressed;
Rectangle frame;
startState cstate;//当前状态
void unload(){
UnloadTexture(normal);
UnloadTexture(hover);
UnloadTexture(pressed);
}
void setframe(int x,int y,int width,int height){
frame.x = x;
frame.y = y;
frame.width=width;
frame.height=height;
}
//下面是三个按钮的图片
void setNormalImage(const char *filename){
Image startimg=LoadImage(filename);
normal = LoadTextureFromImage(startimg);
UnloadImage(startimg);
}
void setHoverImage(const char *filename){
Image startimg=LoadImage(filename);
hover = LoadTextureFromImage(startimg);
UnloadImage(startimg);
}
void setPressedImage(const char *filename){
Image startimg=LoadImage(filename);
pressed = LoadTextureFromImage(startimg);
UnloadImage(startimg);
}
};
//创建一个变量,用来管理程序状态
int state=0;
int main() {
InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT,"Test");
SetTargetFPS(60);
//用结构体实例实现开始按钮 ,main函数里的代码越少,我们实现复杂的功能就可以更清晰
Button startbtn;
startbtn.cstate = normal;
startbtn.setframe((WINDOW_WIDTH-200)/2,(WINDOW_HEIGHT-200)/2,200,200);
startbtn.setNormalImage("start_normal.png");
startbtn.setHoverImage("start_hover.png");
startbtn.setPressedImage("start_pressed.png");
Ball ballarray[5];
for(int i=0;i<5;++i){
Image img=GenImageColor(40,40,BLANK);
ImageDrawCircle(&img,20,20,19,RED);
ballarray[i].t = LoadTextureFromImage(img);
UnloadImage(img);
ballarray[i].x=0;
ballarray[i].y=0;
ballarray[i].speedx=(6-i);
ballarray[i].speedy=(6+i);
}
while (!WindowShouldClose()) {
if(state==0){
//开始菜单,如果点击了,把state改成1就行了
Vector2 mp = GetMousePosition();
if(IsMouseButtonUp(MOUSE_BUTTON_LEFT)){
startbtn.cstate=normal;
//判断鼠标是否在按钮的区域
if(CheckCollisionPointRec(mp,startbtn.frame)){
startbtn.cstate = hover;
}
}
if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)){
startbtn.cstate=normal;
//判断鼠标是否在按钮的区域
if(CheckCollisionPointRec(mp,startbtn.frame)){
startbtn.cstate = pressed;
}
}
if(IsMouseButtonReleased(MOUSE_BUTTON_LEFT)){
if(CheckCollisionPointRec(mp,startbtn.frame)){
state=1;
}
}
}
else if(state==1){
//游戏进行
for(int i=0;i<5;++i){
//判断本次运动后,是否碰到了边界
if(ballarray[i].x+ballarray[i].speedx>=WINDOW_WIDTH-40 || ballarray[i].x+ballarray[i].speedx<=0){
ballarray[i].speedx*=-1;
}
if(ballarray[i].y+ballarray[i].speedy>=WINDOW_HEIGHT-40 || ballarray[i].y+ballarray[i].speedy<=0){
ballarray[i].speedy*=-1;
}
ballarray[i].x+=ballarray[i].speedx;
ballarray[i].y+=ballarray[i].speedy;
}
}
else if(state==2){
//游戏结束
}
BeginDrawing();
ClearBackground(WHITE);
if(state==0){
//开始菜单
if(startbtn.cstate == normal)
DrawTexture(startbtn.normal,startbtn.frame.x,startbtn.frame.y,WHITE);
else if(startbtn.cstate == hover)
DrawTexture(startbtn.hover,startbtn.frame.x,startbtn.frame.y,WHITE);
else if(startbtn.cstate == pressed)
DrawTexture(startbtn.pressed,startbtn.frame.x,startbtn.frame.y,WHITE);
}
else if(state==1){
//游戏进行
for(int i=0;i<5;++i){
DrawTexture(ballarray[i].t,ballarray[i].x,ballarray[i].y,WHITE);
}
}
else if(state==2){
//游戏结束
}
EndDrawing();//结束绘制
}
//释放texture对象
for(int i=0;i<5;++i){
UnloadTexture(ballarray[i].t);
}
//调用结构体的释放函数
startbtn.unload();
//关闭窗口
CloseWindow();
return 0;
}

浙公网安备 33010602011771号