2016-10-04 51 views
0

我正在傍在Java中,現在使用Eclipse。我試圖讓球按照他們擊中帕德爾的位置按比例反彈。如果他們擊中頂部或底部,我希望他們在頂部75度向上或底部向下75度反彈。如果他們碰到中心附近,那麼我希望他們能夠更接近水平地反彈。傍球離開帕德爾

我計算球類的角度這道數學:

double speed = getSpeed() + ballIncrease; 
yPos = Math.abs(yPos); 
double angle = multiplier * yPos; 
double ratio = Math.tan(angle); 
xSpeed = ratio * (speed/(ratio + 1)); 
ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed)); 

我認爲這應該是正確的,但球沒有表現得像我希望他們。我想知道是否有人能幫我解決這個問題。

package Pong; 

/*Place cursor here to start 
* 
*/ 

//Import Libraries 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.Random; 

@SuppressWarnings("serial") 
public class Pong extends JPanel implements KeyListener{ 

//Create random instances 
Random r2 =new Random(); 

public final static int padelStart = 150; 
public final static int padelSpace = 10; 

final static int BOX_WIDTH = 1200; 
public final static int BOX_HEIGHT = 800; 

double ballX = BOX_WIDTH/2; 
double ballY = BOX_HEIGHT/2; 

public static Padel padel1 = new Padel(padelSpace,padelStart,true); 
public static Padel padel2 = new Padel(BOX_WIDTH-padelSpace-padel1.getWidth(),padelStart,false); 

Ball ball1 = new Ball(ballX,ballY); 
Ball ball2 = new Ball(300,300); 

public static int padel1y1; 
public static int padel1y2; 
public static int padel2y1; 
public static int padel2y2; 

//Constants 
public final static int UPDATE_RATE = 200; 

//Main game class 
public Pong() { 

    //Set window size 
    setPreferredSize(new Dimension(BOX_WIDTH,BOX_HEIGHT)); 

    //Start game thread 
    Thread gameThread = new Thread() { 

     public void run(){ 

      while(true){ 

       //Draw objects 

       padel1y1 = padel1.getY(); 
       padel1y2 = padel1.getY() + Padel.padelLength; 
       padel2y1 = padel2.getY(); 
       padel2y2 = padel2.getY() + Padel.padelLength; 

       padel1.update(); 
       padel2.update(); 

       ball1.update(); 
       ball2.update(); 
       repaint(); 

       //Wait 
       try {Thread.sleep(1000/UPDATE_RATE);} 
       catch (InterruptedException ex) {} 

      } 

     } 

    }; 

gameThread.start(); 

} 

@Override 
public void paintComponent(Graphics g) { 

    super.paintComponent(g); 

    g.setColor(Color.white); 
    g.fillRect(0,0,BOX_WIDTH,BOX_HEIGHT); 

    padel1.draw(g); 
    padel2.draw(g); 
    ball1.draw(g); 
    ball2.draw(g); 

} 

public void keyPressed(KeyEvent e){ 

    if(e.getKeyCode() == KeyEvent.VK_UP){padel2.setSpeed(-Padel.padelSpeed);} 
    if(e.getKeyCode() == KeyEvent.VK_DOWN){padel2.setSpeed(Padel.padelSpeed);} 

    if(e.getKeyCode() == KeyEvent.VK_W){padel1.setSpeed(-Padel.padelSpeed);} 
    if(e.getKeyCode() == KeyEvent.VK_S){padel1.setSpeed(Padel.padelSpeed);} 

} 

public void keyReleased(KeyEvent e) { 

    if(e.getKeyCode() == KeyEvent.VK_UP){padel2.setSpeed(0);} 
    if(e.getKeyCode() == KeyEvent.VK_DOWN){padel2.setSpeed(0);} 

    if(e.getKeyCode() == KeyEvent.VK_W){padel1.setSpeed(0);} 
    if(e.getKeyCode() == KeyEvent.VK_S){padel1.setSpeed(0);} 


} 

public void keyTyped(KeyEvent e) {} 

public static void main(String[] args) { 

    javax.swing.SwingUtilities.invokeLater(new Runnable() { 

     public void run() { 

      //Create Frame 
      JFrame frame = new JFrame("PONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONG"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      Pong pong = new Pong(); 
      frame.setContentPane(pong); 
      frame.setSize(BOX_WIDTH,BOX_HEIGHT); 
      frame.pack(); 
      frame.addKeyListener(pong); 
      frame.setVisible(true); 

     } 

    }); 

} 

} 

帕德爾類:

package Pong; 

import java.awt.*; 
import java.util.Random; 

public class Padel { 

public int y; 
public int x; 

public boolean ws; 

public int speed = 0; 

public final static int padelSpeed = 3; 
public final static int padelWidth = 30; 
public final static int padelLength = 200; 

Random rng = new Random(); 

int r = rng.nextInt(256); 
int g = rng.nextInt(256); 
int b = rng.nextInt(256); 

Color color = new Color(r,g,b); 

public Padel(int xPos, int yPos, boolean wands){ 

    y = yPos; 
    x = xPos; 

    ws = wands; 

} 

public void update(){ 

    if(speed > 0 && y + padelLength < Pong.BOX_HEIGHT){ 

     y = y + speed; 

    } 

    if(speed < 0 && y > 0){ 

     y = y + speed; 

    } 

} 

public void draw(Graphics g) { 

    g.setColor(color); 
    g.fillRoundRect(x, y, padelWidth, padelLength, 25, 25); 

} 

public int getX(){ 

    return x; 

} 

public int getY(){ 

    return y; 

} 

public int getWidth(){ 

    return padelWidth; 

} 

public int getLength(){ 

    return padelLength; 

} 

public int getSpeed(){ 

    return speed; 

} 

public void setSpeed(int speed1){ 

    speed = speed1; 


} 

public int getPadelSpeed(){ 

    return padelSpeed; 

} 

} 

Ball類:

package Pong; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.util.Random; 

public class Ball { 

Random rng = new Random(); 

int r = rng.nextInt(256); 
int g = rng.nextInt(256); 
int b = rng.nextInt(256); 

Color color = new Color(r,g,b); 

public final static double ballSpeedMin = -2.0; 
public final static double ballSpeedMax = 2.0; 
public final static double middleSpeedCutoff = 1.0; 

public final static double ballIncrease = .2; 

public final int ballRadiusMin = 10; 
public final int ballRadiusMax = 40; 

double x; 
double y; 

double xSpeed; 
double ySpeed; 

int ballRadius; 

public Ball(double xPos,double yPos){ 

    x = xPos; 
    y = yPos; 

    xSpeed = getRandomSpeed(); 
    ySpeed = getRandomSpeed(); 

    ballRadius = getRandomRadius(); 

} 

public double getRandomSpeed(){ 

    Random r =new Random(); 

    return ballSpeedMin + (ballSpeedMax - ballSpeedMin) * r.nextDouble(); 

} 

public int getRandomRadius(){ 

    Random r = new Random(); 

    return r.nextInt((ballRadiusMax - ballRadiusMin) + 1) + ballRadiusMin; 

} 

public void update(){ 

    x = x + xSpeed; 
    y = y + ySpeed; 

    ySpeed = verticalBounce(); 

    double multiplier = .75; 

    if(getLowX() < Pong.padelSpace + Padel.padelWidth){ 

     if(y>=Pong.padel1y1 && y<=Pong.padel1y2){ 

      double yPos = y - Pong.padel1y1 - (Padel.padelLength/2); 

      if(yPos<0){ 
       double speed = getSpeed() + ballIncrease; 
       yPos = Math.abs(yPos); 
       double angle = multiplier * yPos; 
       double ratio = Math.tan(angle); 
       xSpeed = ratio * (speed/(ratio + 1)); 
       ySpeed = -Math.sqrt((speed * speed) - (xSpeed * xSpeed)); 
      } 

      else if(yPos>0){ 
       double speed = getSpeed() + ballIncrease; 
       yPos = Math.abs(yPos); 
       double angle = multiplier * yPos; 
       double ratio = Math.tan(angle); 
       xSpeed = ratio * (speed/(ratio + 1)); 
       ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed)); 
      } 

      else{ 
       double speed = getSpeed(); 

       xSpeed = speed; 
       ySpeed = 0; 

      } 

     } 

     else{ 

      System.exit(0); 

     } 

    } 

    if(getHighX() > Pong.BOX_WIDTH - Pong.padelSpace - Padel.padelWidth){ 

     if(y>Pong.padel2y1 && y<Pong.padel2y2){ 

      double yPos = y - Pong.padel2y1 - (Padel.padelLength/2); 

      if(yPos<0){ 
       double speed = getSpeed() + ballIncrease; 
       yPos = Math.abs(yPos); 
       double angle = multiplier * yPos; 
       double ratio = Math.tan(angle); 
       xSpeed = - ratio * (speed/(ratio + 1)); 
       ySpeed = -Math.sqrt((speed * speed) - (xSpeed * xSpeed)); 
      } 

      else if(yPos>0){ 
       double speed = getSpeed() + ballIncrease; 
       yPos = Math.abs(yPos); 
       double angle = multiplier * yPos; 
       double ratio = Math.tan(angle); 
       xSpeed = - ratio * (speed/(ratio + 1)); 
       ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed)); 
      } 

      else{ 
       double speed = getSpeed(); 

       xSpeed = -speed; 
       ySpeed = 0; 

      } 

     } 

     else{ 

      System.exit(0); 

     } 

    } 

} 

public void draw(Graphics g) { 

    g.setColor(color); 

    int xPos = (int) Math.round(x) - ballRadius; 
    int yPos = (int) Math.round(y) - ballRadius; 

    g.fillOval(xPos,yPos,ballRadius*2,ballRadius*2); 

} 

public double verticalBounce(){ 

    if(y - ballRadius<0 || y + ballRadius > Pong.BOX_HEIGHT){ 

     return -ySpeed; 

    } 

    else{ 

     return ySpeed; 

    } 
} 

public double getY(){ 

    return y; 

} 

public double getX(){ 

    return x; 

} 

public double getYSpeed(){ 

    return ySpeed; 

} 

public double getXSpeed(){ 

    return xSpeed; 

} 

public void setYSpeed(double y){ 

    ySpeed = y; 

} 

public void setXSpeed(double x){ 

    xSpeed = x; 

} 

public double getLowX(){ 

    return x - ballRadius; 

} 

public double getLowY(){ 

    return y - ballRadius; 

} 

public double getHighX(){ 

    return x + ballRadius; 

} 

public double getHighY(){ 

    return y + ballRadius; 

} 

public double getSpeed(){ 

    return Math.sqrt((xSpeed*xSpeed)+(ySpeed*ySpeed)); 

} 

} 
+0

您好利亞姆,不看你太多的代碼,有很多事情我可以推薦,使控制球輕鬆了許多。例如,嘗試使用角度來確定每次更新時球的x和y速度,就像在這個答案中一樣:http://stackoverflow.com/questions/11720293/need-better-way-of-making-the-ball-角的乒乓遊戲?RQ = 1 然後,您可以在碰撞時用球的攻角,以確定出口角度。 –

+0

你期望他們做什麼?他們的表現如何?我建議找一個物理引擎來正確地做到這一點。 – duffymo

回答

1
double multiplier = .75; 
    //... 

      double yPos = y - Pong.padel1y1 - (Padel.padelLength/2); 
      //... 
      double angle = multiplier * yPos; 

你知道,你在三角函數通過角弧度表示?
假設你的槳長度爲20,與yPos之間[-10, 10]您的角度將[-7.5, 7.5]之間變化而變化。用弧度翻譯它,你會看到你的angle圍繞圓圈旋轉了2次以上。這真的是你想要的嗎?

+0

非常感謝!我的遊戲現在完美運行,我只是不知道它是以弧度運行的。 –