【问题标题】:Pong Ball Leaving Padel乒乓球离开Padel
【发布时间】:2016-10-04 22:52:14
【问题描述】:

我现在正在使用 Eclipse 在 Java 中制作 Pong。我试图让球从板子上反弹,与它们击中板子的位置成比例。如果它们击中顶部或底部,我希望它们在顶部向上 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);

        }

    });

}

}

Padel 类:

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;

}

}

球类:

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

}

}

【问题讨论】:

  • 你好 Liam,不用看太多你的代码,我可以推荐一些东西来让控球更容易。例如,尝试在每次更新时使用角度来确定球的 x 和 y 速度,就像在这个答案中一样:stackoverflow.com/questions/11720293/… 然后您可以使用球在碰撞时的迎角来确定退出角度。
  • 您希望他们做什么?他们表现如何?我建议找到一个物理引擎来正确执行此操作。

标签: java math pong


【解决方案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 次以上。这真的是你想要的吗?

【讨论】:

  • 非常感谢!我的游戏现在运行良好,我只是不知道它在弧度上运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2014-09-26
相关资源
最近更新 更多