2012-09-09 103 views
1

我使用processing java庫來模擬使用牛頓物理學在兩個牆之間彈跳的球;水平速度是一個常數,因爲沒有加速度。我得到了模擬工作,但我想指定地板的高度。然而,在我的方程式中,當球從屏幕底部起10個像素時嘗試改變方向,每次反彈後,球在「地板」下方越來越低。如果我將場地提升到> 20像素,那麼球不會停下來,而是無限期地反彈。以下是相關的代碼: 請注意,處理的座標系從頂部開始,向下和向右延伸。我在這裏先向您的幫助表示感謝。處理中的重力(樓層)

public class Testing extends PApplet { 

boolean inFloor=false; 
float xPosition=500; 
float yPosition=200; 
float xVelocity=25; 
float yVelocity=-80.0f; 
float yAccelleration=+10.0f; 
float elasticity=0.80f; 

public void setup(){ 
    size(displayWidth,displayHeight); 
    noStroke(); 
    ellipseMode(RADIUS); 
    frameRate(35); 
} 
public boolean sketchFullScreen() { 
    return true; 
} 



public void draw(){ 
    background(0); 
    //Changes direction of motion when hitting a wall 
    if(xPosition>=displayWidth||xPosition<0){ 
     xVelocity=-xVelocity; 
    } 
    //supposed to change direction of motion when the ball hits the floor 
    if(yPosition>=displayHeight-20){ 
     yPosition=(displayHeight-20);  
     yVelocity=-(yVelocity)*elasticity; 
     if(yVelocity>=-1 && yVelocity<=0){ 
      xVelocity=xVelocity*elasticity; 
      yVelocity=0; 
      yAccelleration=0; 
     }  
    } 
    else{ 
     yVelocity=yVelocity+yAccelleration; 
    } 

    yPosition=yVelocity+yPosition; 
    xPosition=xPosition+xVelocity; 
    ellipse(xPosition,yPosition,10,10); 
} 

編輯:難道這可能是一個時機的問題?

編輯:謝謝你所有的迴應。不幸的是,我不能對他們中的任何一個都滿意,(只有6個代表)。我結合了@ tobius_k的回答,@ Roberto_Mereghetti的回答以及OpenProcessing.org的一些示例代碼,並解決了這個問題。在下面提供的解決方案中,由於畫布以像素(整數值)爲單位進行度量,因此使用浮點數來指定座標會導致處理中出現圖形故障。所以我實現了一個系統,其中float值被四捨五入,並且將十進制值添加到累加器(「xRounder」和「yRounder」),當-1和1大於-1時,它們被舍入並添加到Ball的當前位置。這給了我一個地板!

終極密碼:

import processing.core.*; 
    //import processing.xml.*; 

    import java.applet.*; 
    import java.awt.Dimension; 
    import java.awt.Frame; 
    import java.awt.event.MouseEvent; 
    import java.awt.event.KeyEvent; 
    import java.awt.event.FocusEvent; 
    import java.awt.Image; 
    import java.io.*; 
    import java.net.*; 
    import java.text.*; 
    import java.util.*; 
    import java.util.zip.*; 
    import java.util.regex.*; 

    public class Testing extends PApplet { 
    int xPosition=500; 
    int yPosition=200; 
    float xRounder=0; 
    float yRounder=0; 
    float xVelocity=25; 
    float yVelocity=-80.0f; 
    float yAccelleration=+10.0f; 
    float elasticity=0.80f; 
    public void setup(){ 
    size(displayWidth,displayHeight); 
    noStroke(); 
    ellipseMode(RADIUS); 
    frameRate(15); 
    } 
    public boolean sketchFullScreen() { 
     return true; 
    } 

    /* (non-Javadoc) 
    * @see processing.core.PApplet#draw() 
    */ 
    public void draw(){ 
    background(0); 

    yPosition=round(yVelocity)+yPosition; 
    yRounder+=(yVelocity-round(yVelocity)); 
    xPosition=round(xVelocity)+xPosition; 
    xRounder+=(xVelocity-round(xVelocity)); 

    if(xRounder>=1||xRounder<=-1){ 
     xPosition=xPosition+round(xRounder); 
     xRounder=xRounder-round(xRounder); 
    } 
    if(yRounder>=1||yRounder<=-1){ 
     yPosition+=round(yRounder); 
     yRounder=yRounder-round(yRounder); 
    } 

    if(yPosition>displayHeight-50 && yVelocity>0){ 
     yPosition=displayHeight-50; 
     yVelocity=-(yVelocity)*elasticity; 
     xVelocity=xVelocity*elasticity; 


    } 

    if(xPosition>=displayWidth||xPosition<0){ 
    xVelocity=-xVelocity; 
    } 
    yVelocity=yVelocity+yAccelleration; 




    ellipse(xPosition,yPosition,10,10); 


    } 

     static public void main(String args[]) { 
      PApplet.main(new String[] { "--bgcolor=#ECE9D8", "Testing" }); 
    //  new Testing().setVisible(true); 
     } 
    } 
+0

'yVelocity> = - 1 && yVelocity <= 0'可能不會發生,具體取決於加速度......它實際上可能只是變成了'yVelocity <-1' – oldrinb

回答

0

我不是100%肯定,但我認爲,當它真正來臨的幾個像素下面底線球重置底線你到底彈性係數補償,讓球無限期地反彈。

嘗試刪除行yPosition=(displayHeight-20);,那麼它應該會更好。

這樣,球最終會休息,但這仍然是不正確的,因爲球落在地面的時間根本不計算在內。

更新好吧,我想我已經明白了。以下是相關位:

// first update position, then update velocity 
yPosition=yVelocity+yPosition; 
if (yPosition >= floor) { 
    // invert velocity and position w/ elasticity applied 
    yVelocity = -yVelocity * elasticity; 
    yPosition = floor - (yPosition - floor) * elasticity; 
} 
if(Math.abs(yVelocity) <= 2 && Math.abs(yPosition - floor) <= 2){ 
    // stop everything when close to rest 
    yPosition=floor; 
    yVelocity=0; 
} else { 
    // otherwise accelerate, even after bounce 
    yVelocity=yVelocity+yAccelleration; 
} 

所以主要變化w.r.t.您的代碼是:

  1. 第一更新的位置,然後將速度的
  2. 代替球復位到地板上,恢復它通過地板下降量,並且也將所述的彈性係數,以該
  3. 始終以加快球,即使反彈的地板

這裏,它的樣子(地板是500)。不完美,但接近。

enter image description here

更新2:剛發現this Processing example,這實際上是非常接近你的原代碼,用他們總是應用加速的區別,而且他們這樣做的前碰撞的檢查。似乎只有這一招才能做到。

+0

我不是故意刪除if-check,而是刪除下面的行。 (所以,基本上和羅伯託所說的一樣;沒有看到他編輯了他的答案)。但是,不要刪除這條線,而是倒置掉落並將其與因子相乘......在這方面做得更好。 –

+0

謝謝:D三個豎起大拇指 – RabtFt

0

這是我的解決方案。 的問題是在這條線:

if(yVelocity>=-yAccelleration && yVelocity<=yAccelleration){ 

這是每yAcceleration值阻止皮球的唯一途徑。

public void draw(){ 
    background(0); 
    if(xPosition>=displayWidth||xPosition<0){ 
     xVelocity=-xVelocity; 
    } 

    if((yPosition>=displayHeight-40.0) && yVelocity>0){ 
     yPosition=(displayHeight-20);  
     yVelocity=-yVelocity*elasticity; 
     if(yVelocity>=-yAccelleration && yVelocity<=yAccelleration){ 
      xVelocity=xVelocity*elasticity; 
      yVelocity=0; 
      yAccelleration=0; 
     }  
    } 
    else{ 
     yVelocity=yVelocity+yAccelleration; 
    } 
    yPosition=yVelocity+yPosition; 
    xPosition=xPosition+xVelocity; 
    ellipse(xPosition,yPosition,10,10); 
} 
+0

這並沒有提供問題的答案。要批評或要求作者澄清,在他們的帖子下留下評論 - 你可以隨時評論你自己的帖子,一旦你有足夠的[聲譽](http://stackoverflow.com/faq#reputation),你將能夠[評論任何帖子](http://stackoverflow.com/privileges/comment)。 –

+0

已編輯,請看看它是否正確 –