c++ sdl 根据鼠标位置绘制动态矩形
c++ sdl draw dynamic rect based on mouse position
这对很多人来说似乎是显而易见的,但我被困住了,找不到任何对我有帮助的教程,所以如果能在这里找到答案就太好了。
我尝试制作一个矩形,就像您在 RTS 游戏中那样,可以说是一个动态 select 框,但它无法正常工作。
如果有人列出创建这样一个盒子的每个步骤的要点就足够了
(不要奇怪我真的是 c++ 的新手)
Mouse.h :
#ifndef MOUSE_H_
#define MOUSE_H_
class Mouse {
public:
bool leftButtonDown = false;
bool mouseMoves = false;
struct MouseCoords {
int x = -1;
int y = -1;
};
MouseCoords start_coords;
MouseCoords move_coords;
Mouse(){}
void setState(Uint32 eventType, SDL_Event event){
if ( eventType == SDL_MOUSEBUTTONDOWN) {
this->leftButtonDown = true;
SDL_GetMouseState( &this->start_coords.x, &this->start_coords.y );
}
if ( eventType == SDL_MOUSEBUTTONUP ) {
this->leftButtonDown = false;
}
if ( eventType == SDL_MOUSEMOTION ) {
this->mouseMoves = true;
this->move_coords.x = event.motion.x;
this->move_coords.y = event.motion.y;
} else {
this->mouseMoves = false;
}
}
/**
* Provides coordinates when mousebutton down
*/
MouseCoords getCoordinates(){
return move_coords;
}
/**
* Refresh the coordinates. MUST be called after Mouse::clearCoordinates();
*/
void clearCoordinates(){
this->move_coords.x = -1;
this->move_coords.y = -1;
}
/**
* Creates selector rect, call this in the render loop
*/
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
Block rect(
this->start_coords.x,
this->move_coords.y,
this->start_coords.y -this->move_coords.y ,
this->move_coords.x - this->start_coords.x
);
rect.draw( renderer );
this->clearCoordinates();
}
}
};
#endif
Block.h
#ifndef BLOCK_H_
#define BLOCK_H_
/**
* Standard Class which can be used to build a player, enemy, or something similar
*/
class Block{
SDL_Rect rect;
public:
Block(int x=10, int y=10, int w=10, int h=10, int filled=true){
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
}
/**
* draw with the given rendererer
*/
void draw(SDL_Renderer *renderer){
SDL_SetRenderDrawColor( renderer , 200 , 155 , 255 , 255);
SDL_RenderDrawRect( renderer, &rect );
SDL_RenderPresent( renderer );
}
bool framed(){
return 0;
}
};
#endif
然后在我的main.cpp
SDL_Window *window;
SDL_Renderer *renderer;
Mouse mouse;
Block rect;
void renderWindow(){
window = SDL_CreateWindow("commanding rects", 100, 100, 700, 600, 0);
renderer = SDL_CreateRenderer(window, -1, 0);
}
void renderGame(Mouse mouse){
SDL_RenderSetLogicalSize( renderer, 400, 300 );
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 0);
SDL_RenderClear( renderer );
SDL_RenderPresent( renderer );
mouse.createSelectBox( renderer );
}
void gameLoop(){
bool game_run = true;
while (game_run) {
SDL_Event event;
while( SDL_PollEvent(&event)){
if ( event.type == SDL_QUIT ) {
game_run = false;
}
mouse.setState(event.type, event);
}
renderGame(mouse);
SDL_Delay( 15 );
}
}
int main(){
renderWindow();
gameLoop();
return 0;
}
我在这里发现了一个问题:
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
Block rect(this->mousedown_coords.x,
this->mousemove_coords.y,
this->mousedown_coords.y - this->mousemove_coords.y,
this->mousemove_coords.x - this->mousedown_coords.x);
在这段代码中,无论鼠标坐标值是多少,您都将矩形的宽度和高度设置为 0。由于您正在绘制边界框,我想您想要存储两组 x,y 坐标,一组用于按下鼠标按钮时,一组用于释放鼠标按钮时。
我终于发现我做错了什么了。
我检索到绘制矩形的错误起点。
当触发 mousedown 我必须得到 event.button.x
而不是 GetMouseState
这是更新后的 Mouse.h
#ifndef MOUSE_H_
#define MOUSE_H_
class Mouse {
public:
bool leftButtonDown = false;
bool mouseMoves = false;
struct MouseCoords {
int x = -1;
int y = -1;
};
MouseCoords start_coords;
MouseCoords move_coords;
Mouse(){}
void setState(Uint32 eventType, SDL_Event event){
if ( eventType == SDL_MOUSEBUTTONDOWN) {
this->leftButtonDown = true;
this->start_coords.x = event.button.x;
this->start_coords.y = event.button.y;
}
if ( eventType == SDL_MOUSEBUTTONUP ) {
this->leftButtonDown = false;
}
if ( eventType == SDL_MOUSEMOTION ) {
this->move_coords.x = event.motion.x;
this->move_coords.y = event.motion.y;
}
}
/**
* Provides coordinates when mousebutton down
*/
MouseCoords getCoordinates(){
return move_coords;
}
/**
* Creates selector rect, call this in the render loop
*/
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
float width = this->move_coords.x - this->start_coords.x;
float height = this->start_coords.y - this->move_coords.y;
float x = this->start_coords.x ;
float y = this->move_coords.y;
Block rect(x, y,width, height);
rect.draw( renderer );
}
}
};
#endif
这对很多人来说似乎是显而易见的,但我被困住了,找不到任何对我有帮助的教程,所以如果能在这里找到答案就太好了。
我尝试制作一个矩形,就像您在 RTS 游戏中那样,可以说是一个动态 select 框,但它无法正常工作。 如果有人列出创建这样一个盒子的每个步骤的要点就足够了
(不要奇怪我真的是 c++ 的新手)
Mouse.h :
#ifndef MOUSE_H_
#define MOUSE_H_
class Mouse {
public:
bool leftButtonDown = false;
bool mouseMoves = false;
struct MouseCoords {
int x = -1;
int y = -1;
};
MouseCoords start_coords;
MouseCoords move_coords;
Mouse(){}
void setState(Uint32 eventType, SDL_Event event){
if ( eventType == SDL_MOUSEBUTTONDOWN) {
this->leftButtonDown = true;
SDL_GetMouseState( &this->start_coords.x, &this->start_coords.y );
}
if ( eventType == SDL_MOUSEBUTTONUP ) {
this->leftButtonDown = false;
}
if ( eventType == SDL_MOUSEMOTION ) {
this->mouseMoves = true;
this->move_coords.x = event.motion.x;
this->move_coords.y = event.motion.y;
} else {
this->mouseMoves = false;
}
}
/**
* Provides coordinates when mousebutton down
*/
MouseCoords getCoordinates(){
return move_coords;
}
/**
* Refresh the coordinates. MUST be called after Mouse::clearCoordinates();
*/
void clearCoordinates(){
this->move_coords.x = -1;
this->move_coords.y = -1;
}
/**
* Creates selector rect, call this in the render loop
*/
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
Block rect(
this->start_coords.x,
this->move_coords.y,
this->start_coords.y -this->move_coords.y ,
this->move_coords.x - this->start_coords.x
);
rect.draw( renderer );
this->clearCoordinates();
}
}
};
#endif
Block.h
#ifndef BLOCK_H_
#define BLOCK_H_
/**
* Standard Class which can be used to build a player, enemy, or something similar
*/
class Block{
SDL_Rect rect;
public:
Block(int x=10, int y=10, int w=10, int h=10, int filled=true){
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
}
/**
* draw with the given rendererer
*/
void draw(SDL_Renderer *renderer){
SDL_SetRenderDrawColor( renderer , 200 , 155 , 255 , 255);
SDL_RenderDrawRect( renderer, &rect );
SDL_RenderPresent( renderer );
}
bool framed(){
return 0;
}
};
#endif
然后在我的main.cpp
SDL_Window *window;
SDL_Renderer *renderer;
Mouse mouse;
Block rect;
void renderWindow(){
window = SDL_CreateWindow("commanding rects", 100, 100, 700, 600, 0);
renderer = SDL_CreateRenderer(window, -1, 0);
}
void renderGame(Mouse mouse){
SDL_RenderSetLogicalSize( renderer, 400, 300 );
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 0);
SDL_RenderClear( renderer );
SDL_RenderPresent( renderer );
mouse.createSelectBox( renderer );
}
void gameLoop(){
bool game_run = true;
while (game_run) {
SDL_Event event;
while( SDL_PollEvent(&event)){
if ( event.type == SDL_QUIT ) {
game_run = false;
}
mouse.setState(event.type, event);
}
renderGame(mouse);
SDL_Delay( 15 );
}
}
int main(){
renderWindow();
gameLoop();
return 0;
}
我在这里发现了一个问题:
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
Block rect(this->mousedown_coords.x,
this->mousemove_coords.y,
this->mousedown_coords.y - this->mousemove_coords.y,
this->mousemove_coords.x - this->mousedown_coords.x);
在这段代码中,无论鼠标坐标值是多少,您都将矩形的宽度和高度设置为 0。由于您正在绘制边界框,我想您想要存储两组 x,y 坐标,一组用于按下鼠标按钮时,一组用于释放鼠标按钮时。
我终于发现我做错了什么了。
我检索到绘制矩形的错误起点。
当触发 mousedown 我必须得到 event.button.x
而不是 GetMouseState
这是更新后的 Mouse.h
#ifndef MOUSE_H_
#define MOUSE_H_
class Mouse {
public:
bool leftButtonDown = false;
bool mouseMoves = false;
struct MouseCoords {
int x = -1;
int y = -1;
};
MouseCoords start_coords;
MouseCoords move_coords;
Mouse(){}
void setState(Uint32 eventType, SDL_Event event){
if ( eventType == SDL_MOUSEBUTTONDOWN) {
this->leftButtonDown = true;
this->start_coords.x = event.button.x;
this->start_coords.y = event.button.y;
}
if ( eventType == SDL_MOUSEBUTTONUP ) {
this->leftButtonDown = false;
}
if ( eventType == SDL_MOUSEMOTION ) {
this->move_coords.x = event.motion.x;
this->move_coords.y = event.motion.y;
}
}
/**
* Provides coordinates when mousebutton down
*/
MouseCoords getCoordinates(){
return move_coords;
}
/**
* Creates selector rect, call this in the render loop
*/
void createSelectBox(SDL_Renderer *renderer){
if(this->leftButtonDown) {
float width = this->move_coords.x - this->start_coords.x;
float height = this->start_coords.y - this->move_coords.y;
float x = this->start_coords.x ;
float y = this->move_coords.y;
Block rect(x, y,width, height);
rect.draw( renderer );
}
}
};
#endif