如何在MFC对话框中使用SDL2

2025-11-11 08:44:58

1、新建MFC应用程序,工程名称为MFCSDL

如何在MFC对话框中使用SDL2

2、本例使用基于对话框的程序,注意勾选“基于对话框”

如何在MFC对话框中使用SDL2

3、在MFCSDLDlg.h中添加SDL library 头文件和库文件应用,并定义所需变量。

#include "../SDL2-2.0.3/include/sdl.h"

#pragma comment(lib, "../SDL2-2.0.3/lib/x86/SDL2.lib")

#define WINDOW_W    640

#define WINDOW_H    480

#define NUM_SPRITES 100

#define MAX_SPEED   1

static SDL_Window* window;

static SDL_Renderer *renderer;

static SDL_Texture * sprite;

static int window_w, window_h;

static int sprite_w, sprite_h;

static SDL_Rect *positions, *velocities;

4、添加WM_KICKIDLE消息,该消息为微软保留消息,不公开,用它可以避免自己再重载实现消息循环。

具体过程如下:

1. 在 MFCSDLdlg.h文件加入

afx_msg LRESULT OnKickIdle(WPARAM wParam, LPARAM lParam);

2. 在MFCSDLDlg.cpp中加入消息映射

BEGIN_MESSAGE_MAP(CMFCSDLDlg, CDialogEx)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_MESSAGE(WM_KICKIDLE,OnKickIdle)

ON_WM_CLOSE()

END_MESSAGE_MAP()

3.添加OnKickIdle消息实现。

LRESULT CMFCSDLDlg::OnKickIdle(WPARAM wParam, LPARAM lParam)

{

SDL_Event event;

int done = 0;

    while (!done)

{

        /* Check for events */

        while (SDL_PollEvent(&event)) {

            switch (event.type) {

            case SDL_WINDOWEVENT:

                switch (event.window.event) {

                case SDL_WINDOWEVENT_EXPOSED:

                    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);

                    SDL_RenderClear(renderer);

                    break;

                }

                break;

            case SDL_QUIT:

                done = 1;

                break;

            default:

                break;

            }

        }

        MoveSprites(renderer, sprite);

    }

return 0;   //一定要返回0

}

5、在OnInitDialog函数中加入初始化代码。

BOOL CMFCSDLDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

// 設定此對話方塊的圖示。當應用程式的主視窗不是對話方塊時,

// 框架會自動從事此作業

SetIcon(m_hIcon, TRUE); // 設定大圖示

SetIcon(m_hIcon, FALSE); // 設定小圖示

// TODO: 在此加入額外的初始設定

window = SDL_CreateWindowFrom(m_hWnd);

SDL_SetWindowTitle(window, "SDL Native Window Test");

renderer = SDL_CreateRenderer(window, -1, 0);

SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);   

SDL_RenderClear(renderer);

sprite = LoadSprite(renderer, "icon.bmp");

SDL_GetWindowSize(window, &window_w, &window_h);

    SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);

    positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));

    velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));

    if (!positions || !velocities) {

        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");

       // quit(2);

    }

    srand(time(NULL));

    for (int i = 0; i < NUM_SPRITES; ++i) {

        positions[i].x = rand() % (window_w - sprite_w);

        positions[i].y = rand() % (window_h - sprite_h);

        positions[i].w = sprite_w;

        positions[i].h = sprite_h;

        velocities[i].x = 0;

        velocities[i].y = 0;

        while (!velocities[i].x && !velocities[i].y) {

            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;

            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;

        }

    }

return TRUE;  // 傳回 TRUE,除非您對控制項設定焦點

}

6、在MFCSDLDlg.cpp中,添加LoadSprite函数,注意是static 全局函数,放在所有函数最上方。其作用是加载一个图片精灵,本例使用一个笑脸图片。

static SDL_Texture *

LoadSprite(SDL_Renderer *renderer, char *file)

{

    SDL_Surface *temp;

    SDL_Texture *sprite;

    /* Load the sprite image */

    temp = SDL_LoadBMP(file);

    if (temp == NULL) {

        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());

        return 0;

    }

    /* Set transparent pixel as the pixel at (0,0) */

    if (temp->format->palette) {

        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);

    }

    /* Create textures from the image */

    sprite = SDL_CreateTextureFromSurface(renderer, temp);

    if (!sprite) {

        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());

        SDL_FreeSurface(temp);

        return 0;

    }

    SDL_FreeSurface(temp);

    /* We're ready to roll. :) */

    return sprite;

}

7、在LoadSprite后添加MoveSprites函数,其作用是将精灵循环移动,实现动态效果。

static void

MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)

{

if(renderer==NULL||sprite==NULL)

return;

    int sprite_w, sprite_h;

    int i;

    SDL_Rect viewport;

    SDL_Rect *position, *velocity;

    /* Query the sizes */

    SDL_RenderGetViewport(renderer, &viewport);

    SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);

    /* Draw a gray background */

    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);

    SDL_RenderClear(renderer);

    /* Move the sprite, bounce at the wall, and draw */

    for (i = 0; i < NUM_SPRITES; ++i) {

        position = &positions[i];

        velocity = &velocities[i];

        position->x += velocity->x;

        if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) {

            velocity->x = -velocity->x;

            position->x += velocity->x;

        }

        position->y += velocity->y;

        if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) {

            velocity->y = -velocity->y;

            position->y += velocity->y;

        }

        /* Blit the sprite onto the screen */

        SDL_RenderCopy(renderer, sprite, NULL, position);

    }

    /* Update the screen! */

    SDL_RenderPresent(renderer);

}

8、以上完成,按F7编译,将icon.bmp文件拷贝到程序执行文件加下,运行程序,可看到如图效果。

如果对读者有所帮助,请投一篇,thanks.

如何在MFC对话框中使用SDL2

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢