【问题标题】:Java 2D Platformer - Some Logic/Physics QuirksJava 2D Platformer - 一些逻辑/物理怪癖
【发布时间】:2011-11-30 02:12:34
【问题描述】:

我正在制作 Java 2d 平台游戏,并且正在使用线程,到目前为止我有 4 个类:

Main.java - 处理主 JFrame

Board.java - 大部分游戏逻辑在哪里 - 使用每 5 毫秒刷新一次的线程 -KeyListener

Guy.java - 人的实例是在哪里制作的 - 使用 ImageIcon,获取人的图像 -getBounds、getX/Y等其他有用的函数

平台.java - 启动平台实例的位置 -再次,有用的功能

现在,谈谈我的工作:

我能够从一个平台移动到另一个平台,并且能够跳跃。这是我的重力代码,用于检查重力需求,并在需要时执行

if(guy.getGravityState() == true) {
        //check need for gravity
        boolean colliding = false;
        for(int a = 0; a < platform.length; a++) {
            if(guy.getBounds().intersects(platform[a].getBounds())) {
                colliding = true;
                //guy.setY(platform[a].getY()-platform[a].getHeight()+3);
            }
        }

        //if needed, do gravity
        if(colliding == false) {
            guy.setYSpeed(3);
                            //move him down by positive y speed
        } else {
            guy.setYSpeed(0);
        }
}

以下是角色的移动方式:

if(guy.getXSpeed() > 0 && guy.getX() > 500) {
        for(int i = 0; i < platform.length; i++) {
            platform[i].setX(platform[i].getX() - guy.getXSpeed());
        }
    } else if (guy.getXSpeed() < 0 && guy.getX() < 300) {
        for(int i = 0; i < platform.length; i++) {
            platform[i].setX(platform[i].getX() - guy.getXSpeed());
        }
    } else {
        guy.moveX();
    }

    if(guy.getYSpeed() > 0 && guy.getY() > 350) {
        for(int i = 0; i < platform.length; i++) {
            platform[i].setY(platform[i].getY() - guy.getYSpeed());
        }
    } else if  (guy.getYSpeed() < 0 && guy.getY() < 250) {
        for(int i = 0; i < platform.length; i++) {
            platform[i].setY(platform[i].getY() - guy.getYSpeed());
        }
    } else {
        guy.moveY();
    }

很抱歉那里没有 cmets,基本上它会检查是否需要移动那个人或平台。如果它靠近边缘,它会移动平台,如果不是,它会移动。

现在,跳转代码(不确定是否相关):

if(guy.getGravityState() == false) {
        d++;
        if(d == 35) {
            d = 0;
            guy.setGravityState(true);
        }
    }

关闭重力的唯一方法是跳跃,所以如果重力关闭,我使用 setYSpeed(-5);所以角色会向上移动(负数)现在它向上移动直到 d = 35,所以 35 刷新。在此之后,重力恢复正常。

所以现在我希望你能坚持下去,并且可以回答我的问题。看看游戏在运行时的样子:

现在,当我向右移动时,角色会根据需要向下移动,但当我向左移动时,他会穿过平台。如果有东西阻止它,我将如何使它不会移动?例如看这里,这家伙直接通过:

我的第二个问题是,它与第一个有关,当我的角色跳跃并撞到他上方的平台时,我希望它直接向下,而不是穿过平台。

另外,当我从上面的某个东西跳到左/右时,他有时甚至会这样卡住:

这些都是我现在的问题,如果你能帮助我一点,我非常感谢,我知道这可能是一个压倒性的问题,但任何帮助都非常感谢。谢谢。

【问题讨论】:

    标签: java 2d game-physics


    【解决方案1】:

    看起来您正在重力功能中进行碰撞检查以阻止玩家从地面坠落,但在处理玩家的移动(左/右或跳跃向上)时没有发生碰撞检测。这就是你的两个问题的问题。

    移动玩家时,你需要确定他的下一个动作是否会与任何东西发生碰撞。您应该将您当前拥有的碰撞检测移到重力功能之外,并在玩家的移动功能中处理它 - 实际上,只要根据您的实现设置玩家的Y速度,您就会不断移动玩家,您甚至可能不需要让重力循环运行...只要玩家不跳跃时将 Y 速度设置为 3。

    我不会试图向您展示我的意思,因为我看不到足够的代码来说明跳跃的工作原理,但希望这个答案足以让您走上正轨。

    请注意,这只是一个粗略的指南,由于您正在移动平台,您还有其他考虑因素,并且可能需要根据您处理跳跃等的方式进行更改。

    这也没有考虑到这个人可能会尝试向下坠落 3 个像素,但地面距离为 2 个像素——在这种情况下,他会在方块上方悬浮 2 个像素,因为 canExecuteMove 总是会返回假。

    希望这会有所帮助。 :) 如果你遇到困难,你应该阅读一下处理简单碰撞检测的方法。我自己并没有做太多这方面的工作,但我相信其他人可以将您链接到有用的教程。

    编辑: 哎呀,这并不能真正解决你的第二个问题,即让那个人在很好地撞到他的头后摔倒。根据我下面的建议,他会一直坚持到天花板的底部,直到他跳完,然后再次开始下落。显然,您需要确保他在撞到天花板后完成跳跃(导致他立即再次开始下降),但问题是“最好的地方是哪里?”我没时间了,所以我将把它留给你或其他人!

    private void move()
    {
        //....your other code
        if(canExecuteMovement(guy.getBounds(), guy.getXSpeed(), 0))
        {
            guy.moveX();
        }
    
        if(canExecuteMovement(guy.getBounds(), 0, guy.getYSpeed())
        {
            guy.moveY();
        }
    }
    
    
    private boolean canExecuteMovement(Bounds currentBounds, int xChange, int yChange)
    {
        int projectedX = currentBounds.getX() + xChange;
        int projectedY = currentBounds.getY() + yChange;
        Bounds projectedBounds = new Bounds(projectedX, projectedY);
        // ^ Making an assumption about Bounds constructor but you get the idea
    
        for(int i = 0; i < platform.length; i ++)
        {
                if(projectedBounds.intersects(platform[i].getBounds())
                {
                        return false;
                }
        }
    
        return true;
    }
    

    【讨论】:

    • 非常感谢,你给了我比我想象的要多得多,我已经解决了我遇到的问题,当然我也能弄清楚跳跃,并会发表评论当我完善解决方案时。作为记录,它不是“边界”,而是它的“矩形”,即 x、y、宽度和高度。再次感谢。
    • 呃,忘了回来看看。不客气。很高兴听到你让它工作。对不起。边界/矩形混淆;我没有打开我的 IDE,只是对可能返回的对象类型做出假设。 :) 希望你的项目进展顺利。顺便说一句,我也刚刚开始用 Java 制作自己的客户端/服务器 2D 游戏引擎!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多