java - 乒乓球离开帕德尔

标签 java math pong

我现在正在使用 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);

        }

    });

}

}

帕德尔级别:

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

}

}

最佳答案

    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 圈多一点。这真的是你想要的吗?

关于java - 乒乓球离开帕德尔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39854024/

相关文章:

ruby - 对回文产品问题感到困惑

c++ - 如何计算 int64_t 的平均值

Ruby - 数学运算

Python 类对象错误

Android - 为乒乓球游戏创建定时器循环

c# - XNA 模型球体不会与四个壁面网格中的一个或全部发生碰撞

java - 使用maven创建带有xml文件的jar文件

java - Mozilla Rhino 1_7R4 扩展抽象类 ( JS )

java - 不支持使用 JPA 更新查询的 DML 操作

java - 在 netbeans Java DB 数据库或 Sqlite 中拥有图像