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

基于LWJGL与JOML的平台跳跃游戏:跳跃与重力实现问题

平台跳跃游戏改造方案(AD移动+W跳跃+重力机制)

以下是改造后的完整代码,同时加入了重力、跳跃和地面检测逻辑:

package entity;

import org.joml.Vector2f;
import org.joml.Vector3f;
import org.lwjgl.glfw.GLFW;

import io.Window;
import render.Animation;
import render.Camera;
import world.World;

public class Player extends Entity{
    public static final int ANIM_IDLE = 0;
    public static final int ANIM_WALK = 1;
    public static final int ANIM_SIZE = 2;
    
    // 物理常量
    private static final float GRAVITY = -98.0f; // 重力值(向下为负)
    private static final float JUMP_FORCE = 30.0f; // 跳跃初始力
    private static final float MOVE_SPEED = 15.0f; // 水平移动速度
    
    // 物理状态变量
    private Vector2f velocity; // 玩家当前速度
    private boolean isOnGround; // 是否处于地面
    
    public Player(Transform transform) {
        super(ANIM_SIZE, transform);
        setAnimation(ANIM_IDLE, new Animation(1, 2, "player/idle"));
        setAnimation(ANIM_WALK, new Animation(2, 5, "player/walking"));
        
        velocity = new Vector2f();
        isOnGround = false;
    }
    
    @Override
    public void update(float delta, Window window, Camera camera, World world) {
        // 1. 检测是否在地面
        isOnGround = checkOnGround(world);
        
        // 2. 处理水平输入(AD键)
        velocity.x = 0; // 先重置水平速度
        if(window.getInput().isKeyDown(GLFW.GLFW_KEY_A)) {
            velocity.x = -MOVE_SPEED * delta;
        }
        if(window.getInput().isKeyDown(GLFW.GLFW_KEY_D)) {
            velocity.x = MOVE_SPEED * delta;
        }
        
        // 3. 处理跳跃输入(W键,仅地面可跳)
        if(window.getInput().isKeyDown(GLFW.GLFW_KEY_W) && isOnGround) {
            velocity.y = JUMP_FORCE * delta;
            isOnGround = false; // 跳跃后离开地面
        }
        
        // 4. 应用重力
        velocity.y += GRAVITY * delta;
        
        // 5. 应用速度更新位置
        move(velocity);
        
        // 6. 地面碰撞修正:如果落到地面,重置Y速度并固定位置
        if(isOnGround) {
            // 这里需要根据地面高度调整玩家Y坐标,避免穿模
            // 示例:transform.pos.y = 地面高度 + 玩家碰撞盒半高;
            velocity.y = 0; // 地面上Y速度为0
        }
        
        // 7. 更新动画:仅水平移动时播放走路动画
        if(velocity.x != 0) {
            useAnimation(ANIM_WALK);
        } else {
            useAnimation(ANIM_IDLE);
        }
        
        camera.getPosition().lerp(transform.pos.mul(-world.getScale(), new Vector3f()), 0.1f);
    }
    
    // 实现地面检测逻辑
    private boolean checkOnGround(World world) {
        // 这里需要根据你的World实现来检测玩家是否接触地面
        // 示例逻辑:检测玩家碰撞盒底部是否与地面tile重叠
        // 临时示例:假设玩家Y坐标小于等于0时视为在地面
        return transform.pos.y <= 0.0f;
    }
}

关键改动说明

  • 新增物理变量:添加velocity记录当前速度、isOnGround标记地面状态,以及重力、跳跃力等常量,让物理逻辑可调节。
  • 重构输入逻辑:移除S键向下移动,W键仅在玩家站在地面时触发跳跃,AD键控制水平速度而非直接位移。
  • 重力与速度整合:每次更新时将重力叠加到Y轴速度,再通过速度更新玩家位置,符合真实物理规律。
  • 地面检测修正:实现checkOnGround方法判断落地状态,落地后重置Y轴速度,防止持续下落或穿模。
  • 动画逻辑优化:仅水平移动时播放走路动画,跳跃或静止时切换回 idle 动画,更贴合游戏表现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:21:14