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

Java 2D马里奥类游戏角色跳跃功能实现技术求助

2D马里奥风格游戏角色跳跃功能问题求助

我正在用Java开发一款类似马里奥的2D游戏,整体进度良好,但在实现角色跳跃功能时遇到了瓶颈。

尝试过的无效方案

  • 用worldY -= velY实现跳跃,角色会瞬移到高处后无法下落
  • 尝试以下while循环,依然没有效果:
while(jumpVelocity > 0 ) {
    worldY--;
    jumpVelocity--;
}

Player类代码

package game.entity;

import game.CollisionManager;
import game.GamePanel;
import game.KeyManager;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class Player extends Entity {

    GamePanel gamePanel;
    KeyManager keyManager;
    CollisionManager collisionManager;
    public int screenX;
    public int screenY;
    public int maxHeight;

    public Player(GamePanel gamePanel, KeyManager keyManager) {
        this.gamePanel = gamePanel;
        this.keyManager = keyManager;
        this.collisionManager = new CollisionManager(gamePanel);

        screenX = gamePanel.screenWidth / 2 - (gamePanel.tileSize / 2);
        screenY = gamePanel.screenHeight / 2 - (gamePanel.tileSize / 2);

        solidArea = new Rectangle(20, 0, 15, gamePanel.tileSize);

        setDefaultValue();
        getPlayerImage();
    }

    public Player() {
    }


    public void setDefaultValue() {
        worldX = gamePanel.tileSize;
        worldY = gamePanel.tileSize * 7;
        maxHeight = (int) worldY;

        velY = 0;
        velX = 0;
        jumpVelocity = 50;
        speed = 3;
        direction = "idle";
    }

    public void getPlayerImage() {
        //TODO: Get player image
        try {
            up = ImageIO.read(getClass().getResourceAsStream("/game/textures/idle.png"));
            left1 = ImageIO.read(getClass().getResourceAsStream("/game/textures/left1.png"));
            left2 = ImageIO.read(getClass().getResourceAsStream("/game/textures/left2.png"));
            right1 = ImageIO.read(getClass().getResourceAsStream("/game/textures/right1.png"));
            right2 = ImageIO.read(getClass().getResourceAsStream("/game/textures/right2.png"));
            down = ImageIO.read(getClass().getResourceAsStream("/game/textures/down.png"));
            idle = ImageIO.read(getClass().getResourceAsStream("/game/textures/idle.png"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void update() {
        if (keyManager.jumpPressed || keyManager.downPressed || keyManager.leftPressed || keyManager.rightPressed) {
            velX = 3;
            velY = 2;
            if (keyManager.jumpPressed && isOnPlatform()) {

                worldY-=velY;


            }
            if (keyManager.downPressed) {
                direction = "down";
            }
            if (keyManager.leftPressed) {
                direction = "left";
            }
            if (keyManager.rightPressed) {

                direction = "right";
            }
        }else {
            velX = 0;
        }

        //Check collision
        collisionOn = false;
        gamePanel.collisionManager.checkTile(this);
        if (!collisionOn) {
            switch (direction) {
                case "left":
                    worldX -= velX;
                    break;
                case "right":
                    worldX += velX;
                    break;
                case "down":
                    worldY += speed;
                    break;
            }
        }

        // Animation changer
        spriteCounter++;
        if (spriteCounter > 15) {
            spriteNumber = (spriteNumber == 1) ? 2 : 1;
            spriteCounter = 0;
        }
    }


    public void draw(Graphics2D g2) {
        //g2.setColor(Color.WHITE);
        //g2.fillRect(x, y, gamePanel.tileSize, gamePanel.tileSize);
        BufferedImage image = null;
        switch (direction) {
            case "space":
                image = idle;
                break;
            case "down":
                image = down;
                break;
            case "left":
                if (spriteNumber == 1)
                    image = left1;
                if (spriteNumber == 2)
                    image = left2;
                break;
            case "right":
                if (spriteNumber == 1)
                    image = right1;
                if (spriteNumber == 2)
                    image = right2;
                break;

            case "idle":
                image = idle;
        }

        g2.drawImage(image, screenX, screenY, gamePanel.tileSize, gamePanel.tileSize, null);
    }

    void jump() {
        if (!jumping) {
            jumping = true;
            gravity -= 0.1;
            setVelY(-gravity);
            worldY -= gravity;
            System.out.println(jumping);
        }
        if (gravity <= 0) {
            System.out.println(jumping);
            jumping = false;
            falling = true;
            worldY += gravity;
        }
    }

    @Override
    public boolean isOnPlatform() {
        gamePanel.collisionManager.entityBottomRow = (gamePanel.collisionManager.entityBottomWorldY + speed) / gamePanel.tileSize;
        gamePanel.collisionManager.tileNum1 = gamePanel.tileManager.mapTileNum[gamePanel.collisionManager.entityLeftCol][gamePanel.collisionManager.entityBottomRow];
        gamePanel.collisionManager.tileNum2 = gamePanel.tileManager.mapTileNum[gamePanel.collisionManager.entityRightCol][gamePanel.collisionManager.entityBottomRow];
        if ((gamePanel.tileManager.tiles[gamePanel.collisionManager.tileNum1].collision || gamePanel.tileManager.tiles[gamePanel.collisionManager.tileNum2].collision)) {
            onPlatform = true;
        } else {
            onPlatform = false;
        }

        return onPlatform;
    }


}

KeyManager类代码

package game;

import game.entity.Entity;
import game.entity.Player;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyManager implements KeyListener {

    public boolean jumpPressed,downPressed,leftPressed,rightPressed;
    public Player player= new Player();



    @Override
    public void keyTyped(KeyEvent e) {
        //Nothing
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();

        if(code == KeyEvent.VK_SPACE || code == KeyEvent.VK_W){
            //player.setJumping(true);
            jumpPressed = true;
        } else if(code == KeyEvent.VK_A){
            leftPressed = true;
        } else if (code == KeyEvent.VK_D) {
            rightPressed = true;
        } else if (code == KeyEvent.VK_S){
            downPressed = true;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();

        if(code == KeyEvent.VK_W || code == KeyEvent.VK_SPACE){
            jumpPressed = false;
        }
        if(code == KeyEvent.VK_A){
            leftPressed = false;
        }
        if(code == KeyEvent.VK_S){
            downPressed = false;
        }
        if(code == KeyEvent.VK_D){
            rightPressed = false;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:54:53