[英]Java 2D Platformer - Some Logic/Physics Quirks
我正在制作Java 2d平台程序,并且正在使用线程,到目前为止,我有4个类:
Main.java-处理主JFrame
Board.java-大多数游戏逻辑是-使用每5毫秒刷新一次的线程-KeyListener
Guy.java-在何处创建了Guy的实例-使用ImageIcon,获取Guy的图像-其他诸如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刷新。 此后,重力将恢复正常。
所以现在我希望你能坚持下去,并继续回答我的问题。 看一下游戏在运行时的外观:
现在,当我向右移动时,角色会根据需要向下移动,但是当我向左移动时,他会穿过平台。 我将如何制造它,以便在有东西停止时它不会移动? 例如看这里,那个家伙会正确地通过:
我的第二个问题是,与第一个问题有关,当我的角色跳跃并撞到他上方的平台时,我希望它直接向下而不是通过平台。
另外,当我从上方跳到左/右时,他有时甚至会被卡住:
这些都是我现在所有的问题,如果您能帮助我,我将非常感激,我知道这可能是一个压倒性的问题,但是对您的任何帮助都是值得的。 谢谢。
看起来您正在重力功能中进行碰撞检查,以阻止玩家跌落地面,但是在处理玩家的运动(向左/向右或从跳跃向上移动)时,没有发生碰撞检测。 这就是你们两个问题的问题。
移动播放器时,您需要确定下一个动作是否会与任何东西发生碰撞。 您应该将当前具有的碰撞检测移动到重力功能之外,并通过播放器的移动功能来处理它-实际上,只要根据您的实现设置了他的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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.