Java 2D平台游戏 - 一些逻辑/物理怪癖

时间:2011-11-30 02:12:35

标签: java 2d game-physics

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

Main.java      - 处理主JFrame

Board.java      - 大多数游戏逻辑都是      - 使用每5毫秒刷新一次的线程     -KeyListener

Guy.java      - 在哪个人的实例      - 使用ImageIcon,获取家伙的形象     其他东西,如getBounds,getX / Y等有用的功能

Platform.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();
    }

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

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

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

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

所以现在我希望你坚持下去,并且可以继续我的问题。看一下游戏在运行时的表现:

enter image description here

现在,当我向右移动时,角色向下移动,但是当我向左移动时,他会穿过平台。如果有什么东西阻止它,我怎么能这样做呢?例如,看看这个人,直接通过:

enter image description here

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

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

enter image description here

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

1 个答案:

答案 0 :(得分:1)

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

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

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

请注意,这只是一个粗略的指南,您将有其他注意事项,因为您正在移动平台,并且可能必须根据您处理跳跃等方式进行更改。

这也没有考虑到这个家伙可能会尝试下降3个像素的事实,但地面距离是2个像素 - 在这种情况下,他会悬浮在块上方2个像素,因为canExecuteMove总是会返回false。

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

修改 哎呀,这不会真正解决你的第二个问题,让这个家伙在撞到他的头后非常好地倒下。根据我的建议,他将坚持到天花板的底部,直到他完成跳跃,然后再次开始下降。显然你需要确保他在与天花板发生碰撞后完成跳跃(导致他立即再次开始下降),但问题是“最好的位置在哪里?”我没时间了,所以我会把它留给你或其他人!

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;
}