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

如何实现Gravity Guys游戏中敌人延迟3秒复制玩家动作?

实现敌方延迟3秒复制玩家动作的解决方案

问题分析

你当前的代码逻辑存在核心问题:在keyPressed事件中处理敌人的延迟动作完全行不通——该事件仅在玩家按下按键时触发一次,不会持续检查时间是否达到延迟要求。敌人的动作执行逻辑必须放在游戏的持续更新循环(如每帧执行的tick方法)中,才能定时检测并执行延迟动作。

解决方案步骤

  • 记录玩家的动作历史:用队列存储玩家的每一次操作及其时间戳,保证敌人能按顺序延迟执行。
  • 玩家触发动作时记录到队列:修改输入处理类,仅处理玩家动作并将动作信息存入队列,不再在按键事件中处理敌人逻辑。
  • 在敌人的更新逻辑中执行延迟动作:在敌人每帧更新的tick方法中,检查动作队列,当动作的时间戳与当前时间差达到3秒时,执行对应动作。

具体代码修改

1. 定义动作存储类

用于记录玩家的动作类型和触发时间:

class PlayerAction {
    public String action;
    public long timestamp;

    public PlayerAction(String action, long timestamp) {
        this.action = action;
        this.timestamp = timestamp;
    }
}

2. 在Handler中添加动作队列

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Handler {
    public List<GameObject> object = new ArrayList<>();
    // 存储玩家动作的队列
    public Queue<PlayerAction> playerActions = new LinkedList<>();
}

3. 修改KeyInput类,仅处理玩家动作并记录

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class KeyInput extends KeyAdapter{
    Handler handler;

    public KeyInput(Handler handler){
        this.handler=handler;
    }

    public void keyPressed(KeyEvent e){
        int key=e.getKeyCode();

        for(int i =0 ; i<handler.object.size(); i++){
            GameObject tempObject= handler.object.get(i);

            if (tempObject.getId() == ObjectId.Player) {
                if (key == KeyEvent.VK_SPACE && ((Player) tempObject).canSwitchGravity ) {
                    // 执行玩家的重力切换
                    tempObject.setGravityInverted(!tempObject.isGravityInverted());
                    ((Player) tempObject).canSwitchGravity = false;
                    // 将动作记录到队列
                    handler.playerActions.add(new PlayerAction("switch_gravity", System.currentTimeMillis()));
                }
            }

            if(key== KeyEvent.VK_ESCAPE){
                System.exit(1);
            }
        }
    }
}

4. 在Enemy类的tick方法中处理延迟动作

public class Enemy extends GameObject {
    private Handler handler;
    public boolean canSwitchGravity;

    public Enemy(float x, float y, ObjectId id, Handler handler) {
        super(x, y, id);
        this.handler = handler;
    }

    public void tick() {
        // 保留原有的敌人移动、碰撞检测等逻辑...

        // 处理延迟动作
        long currentTime = System.currentTimeMillis();
        // 遍历动作队列,检查是否有达到延迟时间的动作
        while (!handler.playerActions.isEmpty()) {
            PlayerAction action = handler.playerActions.peek();
            if (currentTime - action.timestamp >= 3000) {
                // 延迟3秒后执行对应动作
                if (action.action.equals("switch_gravity") && this.canSwitchGravity) {
                    this.setGravityInverted(!this.isGravityInverted());
                    this.canSwitchGravity = false;
                }
                // 执行完成后移除该动作
                handler.playerActions.poll();
            } else {
                // 队列按时间顺序存储,前面的动作未到延迟时间,后面的无需再检查
                break;
            }
        }
    }

    // 保留原有的render等方法...
}

注意事项

  • 线程安全:如果游戏采用多线程架构(输入线程与更新线程分离),请使用ConcurrentLinkedQueue替代LinkedList,避免并发修改问题。
  • 动作顺序:队列会按玩家操作的先后顺序存储动作,敌人会依次延迟执行,完全复刻玩家的操作节奏。
  • 状态一致性:确保Enemy的canSwitchGravity逻辑与Player完全一致(仅接触地面时为true),避免敌人在无效状态下执行动作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:05:55