如何在GameMaker回滚游戏中实现相机跟随玩家
一、回滚游戏中相机跟随玩家的适配方案
回滚游戏的核心是仅同步游戏状态数据,相机属于本地渲染逻辑,不能纳入回滚快照,也不需要在客户端间同步。你原来的代码是为单人双玩家设计的,在回滚网络环境下需要调整为「每个客户端仅渲染本地玩家的视角」:
- 创建一个仅本地实例化的控制器对象(比如
obj_local_camera),不要让这个对象参与回滚同步。 - 在该对象的Step事件中处理相机逻辑,确保仅跟随当前客户端的本地玩家:
// obj_local_camera 的 Step 事件 // 先获取本地玩家实例(根据你的网络逻辑标记,比如玩家对象的is_local变量) var local_player = instance_find(obj_player, 0); if (!local_player || !local_player.is_local) exit; // 初始化相机(仅执行一次) if (!variable_instance_exists(id, "cam") || !camera_exists(cam)) { cam = camera_create_view(0, 0, 1366, 768); view_camera[0] = cam; view_enabled[0] = true; } // 更新相机跟随逻辑 camera_set_view_target(cam, local_player); camera_set_view_speed(cam, 5, 5); camera_set_view_border(cam, 64, 64);
关键注意点:
- 相机逻辑必须放在本地专属对象中,不能放在玩家对象(会被回滚重置状态)。
- 只对本地玩家实例应用相机跟随,忽略远程玩家。
二、让部分输入仅本地生效的实现方法
回滚游戏中,只有影响游戏状态的输入(比如移动、攻击)需要同步,本地操作(比如相机调整、菜单、音效触发)完全不需要同步到对方,实现方式如下:
1. 输入分类处理
在输入检测时,明确区分「游戏性输入」和「本地输入」,仅将前者加入同步队列:
// 输入处理事件(建议放在本地输入控制器中) // 游戏性输入(需要同步,加入回滚输入队列) if (keyboard_check_pressed(vk_left)) { // 加入输入队列,用于同步给对方 network_input_add("move_left", global.current_frame); // 本地预执行(回滚时会根据同步数据修正) local_player.x -= 4; } // 本地输入(无需同步,仅本地执行) if (keyboard_check_pressed(vk_up)) { // 仅本地调整相机速度,不同步 camera_set_view_speed(cam, 10, 10); }
2. 排除本地变量的回滚快照
在生成回滚快照时,不要包含本地操作相关的变量(比如相机参数、UI状态),仅同步影响游戏进程的数据(玩家位置、血量、技能CD等):
// 生成游戏状态快照的函数(仅同步核心游戏数据) function create_game_snapshot() { var snapshot = { player_x: local_player.x, player_y: local_player.y, player_hp: local_player.hp, // 只包含需要同步的变量,排除相机、UI等本地数据 }; return snapshot; }
关键原则
- 所有会改变游戏世界状态的操作必须同步,仅影响本地表现的操作完全由客户端自行处理。
- 回滚逻辑只处理游戏状态的修正,不干预本地渲染、输入的非游戏性操作。
内容的提问来源于stack exchange,提问作者Sejow
相关产品推荐
相关产品推荐

