[英]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.