Cxxdroid 中文文档 下载 App

游戏循环基础 —— 让方块跟着手指移动

游戏循环的标准结构

SDL2 做游戏的标准循环:

bool running = true;
SDL_Event event;

while (running) {
    // 1. 事件处理(触摸、退出等)
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            running = false;
        }
        // 其他事件...
    }

    // 2. 更新游戏状态
    // 3. 渲染所有物体
    // 4. Present
    SDL_Delay(16);  // 约 60 FPS
}

四步循环:事件 → 状态更新 → 渲染 → 提交。

Android 上的触摸事件

PC 上 SDL2 主要处理键盘和鼠标,Android 上主要是触摸事件:

SDL 事件类型触发时机
SDL_FINGERDOWN手指按下屏幕
SDL_FINGERMOTION手指在屏幕上滑动
SDL_FINGERUP手指抬起离开屏幕

每个触摸事件携带:

坐标转换

触摸事件的 x, y 是归一化坐标(0-1),需要转换成你窗口的像素坐标:

int winW = 320, winH = 480;
float touchX = event.tfinger.x * winW;  // 转成像素
float touchY = event.tfinger.y * winH;

触摸事件处理示例:方块跟着手指

#include <SDL2/SDL.h>

int main() {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *win = SDL_CreateWindow("Touch Demo",
        0, 0, 320, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer *ren = SDL_CreateRenderer(win, -1, 0);

    SDL_Rect box = {120, 200, 80, 80};  // 要跟随的方块
    bool running = true;
    SDL_Event event;

    while (running) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                running = false;
            }
            if (event.type == SDL_FINGERDOWN) {
                box.x = event.tfinger.x * 320 - box.w / 2;
                box.y = event.tfinger.y * 480 - box.h / 2;
            }
            if (event.type == SDL_FINGERMOTION) {
                box.x = event.tfinger.x * 320 - box.w / 2;
                box.y = event.tfinger.y * 480 - box.h / 2;
            }
        }

        // 清屏
        SDL_SetRenderDrawColor(ren, 30, 30, 30, 255);
        SDL_RenderClear(ren);

        // 画方块
        SDL_SetRenderDrawColor(ren, 255, 128, 0, 255);
        SDL_RenderFillRect(ren, &box);

        SDL_RenderPresent(ren);
        SDL_Delay(16);
    }

    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();
    return 0;
}

控制帧率

SDL_Delay(16) 大致等于 60 FPS(1000ms / 60 ≈ 16.7ms)。如果你的游戏逻辑比较简单,60 FPS 完全够。如果游戏逻辑很重,可以:

Uint32 lastTime = SDL_GetTicks();

while (running) {
    Uint32 now = SDL_GetTicks();
    float delta = (now - lastTime) / 1000.0f;
    lastTime = now;

    // 用 delta 做帧率无关的移动:
    // player.x += player.speed * delta;
}

退出方式

Android 上 SDL2 应用的退出方式和 PC 不同——没有传统的窗口关闭按钮。通常的做法:

如果 SDL_QUIT 事件没触发,说明当前版本的 SDL2 在 Android 上还没把系统返回键映射到退出事件,此时需要在代码里自己监听触摸事件中的特定区域作为退出按钮。