Foro sobre Java SE > usar los ifs para aplicar esta formula
Hola dr4.
Encontre algo que hice alguna vez para probar algo similar a lo que planteas.
Se trata basicamente de un rectangulo que rebota dentro de una ventana. Espero que te sirva.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class PruebasGraphics extends JPanel implements ActionListener {
private final JFrame frame; //Ventana
private final Timer t; //Timer para el tiempo de animacion.
int xPos = 0, velX = 5; //Posicion x de la figura / Velocidad sobre el eje x (incremento de x).
int yPos = 0, velY = 1; //Posicion y de la figura / Velocidad sobre el eje y (incremento de y).
public PruebasGraphics() throws IOException {
super();
t = new Timer(5, this); //Inicializa el timer con 5ms de time-out.
frame = new JFrame("Pruebas Graphics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1280, 720)); //dimension interna de la ventana.
frame.add(this);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws IOException {
new PruebasGraphics();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red); //Selecciona el color de la figura
g.fillRect(xPos, yPos, 300, 169); //Dibuja la figura.
t.start();//Reinicia el timer.
}
@Override
public void actionPerformed(ActionEvent ae) {
//Llega aca con cada desborde del timer.
//Si la posicion sobre x es menor a 0 (figura sobre el borde izquierdo de la ventana) o mayor al ancho
//de la ventana - el ancho de la figura (figura sobre el lado derecho de la ventana) niego el valor de incremento
//sobre el eje x.
//NOTA: Al negar el valor de x una vez obtengo -x, al negarlo por segunda vez obtengo +X y asi sucesivamente...
if (xPos < 0 || xPos > 980) {
velX = -velX;
}
//Hace sobre Y la misma comprobacion que el if anterior sobre X.
if (yPos < 0 || yPos > 551) {
velY = -velY;
}
//Incrementa/Decrementa los valores de X e Y para generar el movimiento de la figura.
xPos = xPos + velX;
yPos = yPos + velY;
repaint(); //Actualiza la pantalla.
}
}
NOTA: El "throws IOException" del constructor y del metodo main estan de más. Quedaron de una prueba anterior.
Saludos.
buenas, tengo esta formula para la interacción entre una pelota y un rectángulo, el caso es que he conseguido que funcione, pero solo el rebote hacía un lado, si por ejemplo quiero que al golpear por arriba rebote lo que pongo es if (y==1){y=-1} así le digo que si la dirección y es positiva (la pelota esta bajando) al tocar tiene que ser negativa (la pelota empezará a subir y producirá la sensación de rebote) el problema es que si le pongo lo mismo por abajo if(y==-1){y=1} la pelota se vuelve loca en el sitio, podría solucionarlo con un timer creo porque lo que creo que pasa es que intenta ejecutar los dos if a la vez al hacer contacto, pero ya no se me ocurre nada para que pueda rebotar por los lados del rectángulo (al tocar ahí hace efecto tunel, se mete dentro hasta salir por el otro lado), se que tendría que manejar las x para cambiar la dirección lateral pero si le pongo que al hacer contacto cambie la dirección de la x me la cambiara cuando choque en cualquier parte del rectangulo, tengo entendido que con esta formula puedo manejar el rebote en los cuatro lados del rectángulo pero no estoy sabiendo aplicarlo, alguien podría decirme como podría hacerlo?
100 es la posición x del rectángulo.
300 es la posición y del rectángulo
170 es el ancho del rectángulo
30 es el alto del rectángulo
circlex lo posición x del centro del circulo
circley es la posición y del centro del rectángulo
public boolean golpe(Pelota circle) {
double circleDistanceX = Math.abs(circle.centrox - 100 - 170/2);
double circleDistanceY = Math.abs(circle.centroy - 300 - 30/2);
if (circleDistanceX > (170/2+ circle.radio)) { return false; }
if (circleDistanceY > (30/2 + circle.radio)) { return false; }
if (circleDistanceX <= (170/2)) { return true; }
if (circleDistanceY <= (30/2)) { return true; }
double cornerDistance_sq = Math.pow(circleDistanceX - 170/2, 2) + Math.pow(circleDistanceY - 30/2, 2);
return (cornerDistance_sq <= (Math.pow(circle.radio, 2)));
}