我现在正在使用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));
}
}
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次以上。这真的是你想要的吗?