You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言SDL2环境下实现可切换的回合制战斗游戏循环

SDL RPG 实时探索切换回合制战斗的实现方案

核心实现思路

用有限状态机拆分游戏运行逻辑,完全复用现有主循环,不要在logic内新增嵌套循环阻塞主流程。

具体实现步骤

1. 定义状态枚举

首先新增全局/场景级的状态变量,区分探索、战斗两大模式,同时为战斗模式拆分行动子状态:

// 全局游戏状态
typedef enum {
    GAME_STATE_EXPLORE,
    GAME_STATE_BATTLE
} GameState;

// 战斗子状态
typedef enum {
    BATTLE_TURN_WAIT_PLAYER_INPUT, // 等待玩家操作
    BATTLE_TURN_EXECUTE_NPC_ACTION, // NPC行动中
    BATTLE_TURN_NEXT // 切换下一个行动实体
} BattleSubState;

// 全局变量,也可以封装到场景结构体中
GameState current_game_state = GAME_STATE_EXPLORE;
BattleSubState battle_state;
Entity* current_acting_entity; // 当前轮到行动的实体
uint8_t player_action_confirmed = 0; // 玩家操作完成标记

2. 适配输入处理函数

根据当前游戏状态分发输入事件,只有战斗模式下轮到玩家行动时,才响应战斗操作输入:

void input(){ 
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
        case SDL_QUIT:
            exit(0);
            break;
        case SDL_KEYDOWN:
            if (current_game_state == GAME_STATE_EXPLORE) {
                // 原有探索输入逻辑:移动、交互等
                if (event.key.keysym.sym == SDLK_c) {
                    // 触发战斗初始化
                    init_battle(); // 内部实现先攻值计算、实体排序、生成行动链表
                    current_game_state = GAME_STATE_BATTLE;
                    battle_state = BATTLE_TURN_NEXT;
                }
            } else if (current_game_state == GAME_STATE_BATTLE) {
                // 只有等待玩家操作时才响应战斗输入
                if (battle_state == BATTLE_TURN_WAIT_PLAYER_INPUT) {
                    switch(event.key.keysym.sym) {
                        case SDLK_a: // 按A选择攻击
                            selected_action = ACTION_ATTACK;
                            player_action_confirmed = 1;
                            break;
                        case SDLK_s: // 按S选择技能
                            selected_action = ACTION_SKILL;
                            player_action_confirmed = 1;
                            break;
                        // 其他战斗操作逻辑
                    }
                }
            }
            break;
        case SDL_KEYUP:
            // 原有按键抬起逻辑
            break;
        }
    }
}

3. 适配逻辑处理函数

分状态执行对应逻辑,战斗模式下通过子状态控制行动流程,轮到玩家时进入等待输入的空转状态,不会主动向下执行:

void logic() {
    if (current_game_state == GAME_STATE_EXPLORE) {
        // 原有探索逻辑:实体移动、碰撞检测、交互判定等
    } else if (current_game_state == GAME_STATE_BATTLE) {
        switch(battle_state) {
            case BATTLE_TURN_NEXT:
                // 从行动链表取下个要行动的实体
                current_acting_entity = get_next_turn_entity();
                if (current_acting_entity == NULL) {
                    // 本回合所有实体行动完成,重置行动链表
                    reset_turn_list();
                    current_acting_entity = get_next_turn_entity();
                }
                // 根据实体类型切换对应子状态
                if (current_acting_entity->type == ENTITY_PLAYER) {
                    battle_state = BATTLE_TURN_WAIT_PLAYER_INPUT;
                } else {
                    battle_state = BATTLE_TURN_EXECUTE_NPC_ACTION;
                }
                break;
            case BATTLE_TURN_WAIT_PLAYER_INPUT:
                // 等待玩家操作完成标记,无操作时直接跳过不执行后续逻辑
                if (player_action_confirmed) {
                    execute_player_action(selected_action); // 执行玩家选择的操作
                    player_action_confirmed = 0;
                    battle_state = BATTLE_TURN_NEXT;
                }
                break;
            case BATTLE_TURN_EXECUTE_NPC_ACTION:
                execute_npc_action(current_acting_entity); // 自动执行NPC逻辑
                battle_state = BATTLE_TURN_NEXT;
                break;
        }
    }
}

4. 适配渲染函数

根据当前状态渲染对应内容:探索模式渲染地图、实体,战斗模式渲染战斗场景、操作菜单、血条等信息。

方案优势

  • 完全不阻塞原主循环,SDL事件处理、渲染流程全程正常运行,不会出现窗口未响应问题
  • 扩展灵活,后续要加战斗动画、技能演出、回合倒计时等功能,只需要新增对应战斗子状态即可
  • 逻辑拆分清晰,探索和战斗代码完全隔离,后续调试修改成本低

内容的提问来源于stack exchange,提问作者lancen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 22:54:05