【问题标题】:c++ sdl draw dynamic rect based on mouse positionc++ sdl根据鼠标位置绘制动态矩形
【发布时间】:2015-04-19 20:14:50
【问题描述】:

这对很多人来说似乎很明显,但我被困住了,我找不到任何对我有帮助的教程,所以在这里找到答案会很棒。

我尝试制作一个类似于 RTS 游戏中的矩形,可以说是动态选择框,但它无法正常工作。 有人列出创建这样一个框的每个步骤的要点就足够了

(不要怀疑我真的是 C++ 新手)

鼠标.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

块.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;
}

【问题讨论】:

  • 你得到了什么?什么错误?
  • 我并没有真正收到错误,但我的盒子没有正确绘制

标签: c++ logic sdl selection rectangles


【解决方案1】:

我在这里发现了一个问题:

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 坐标,一组用于按下鼠标按钮时,另一组用于释放鼠标按钮时。

【讨论】:

  • 我更新了 mouse.h 代码,使其更清晰,因为变量名称不明显。我对宽度和高度所做的是从当前移动位置中减去起始位置。所以我不确定,但我认为这不是真正的问题?
【解决方案2】:

我终于发现自己做错了什么。

我为绘制矩形检索了错误的起点。 触发 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    相关资源
    最近更新 更多