Probleme mit Pong-App

Simon Kurt

Grünschnabel
Hallo, wie der Name schon vermuten lässt, habe ich Probleme beim programmieren einer Pong-App, die bis Montag fertig sein soll.
Das benutzte Programm ist Eclipse - Helios.

Das wichtigste Problem ist die Kollisionsabfrage wenn der Ball an eines der Paddle prallt. Wenn dies passiert, soll der Ball seine Bewegungsrichtung ändern.
Diese wird über einen x-Wert und einen y-Wert angegeben um die sich der Ball verschieben soll bevor er wieder gezeichnet wird.
In diesem Fall soll ja im Falle einer Kollision der x-Wert mit -1 multipliziert werden.
Allerdings weiß ich nicht wie ich jetzt die Kollisions-Abfrage gestalten muss bzw. wie ich das ganze dann in ein "if"-statement verpacke.

Ein anderes Problem ist noch der HitCounter, also die Punkteangabe für beide Spieler, und jedesmal wenn der Ball die rechte bzw. linke Wand erreicht soll der Hitcounter des jeweils anderen Spieler um eins erhöht werden.
Die Punkte sollen links und rechts von der (noch nicht erstellten) Mittellinie angezeigt werden.

Ich stelle auch meinen Quellcode rein um das ganze anschaulicher zu machen.
Bin für jede Rückmeldung dankbar!!

Also das ganze besteht aus 4 klassen:
PongApp
Ball
Paddle
HitCounter


Quelltext für PongApp:

Java:
import de.ur.mi.graphics.Image;
import java .awt. event . KeyEvent ;
import java .awt. event . KeyListener ;
import de.ur.mi. graphicsapp .*;
import de.ur.mi. graphics .*;
import de.ur.mi.graphicsapp.GraphicsApp;

/*
 * File: PongApp.java
 * -----------------------
 * 
 * This class handles user interaction and plays the game. Game Objects (Ball, Paddle and HitCounter)
 * are created and updated from this class.
 *
 */

public class PongApp extends GraphicsApp implements KeyListener {
	
	private static final long serialVersionUID = 1L;

	/* private constants (add more constants as necessary)*/
	// screen properties
	private static final int SCREEN_WIDTH = 640;
	private static final int SCREEN_HEIGHT = 480;

	private static final int MOVE_PIXELS = 40;
	private static final Color BG_COLOR = Color . BLACK ;
	
	private static final int MOVE_UP_PLAYER_ONE = 38; // up arrow
	private static final int MOVE_DOWN_PLAYER_ONE = 40; // down arrow
	
	private static final int MOVE_UP_PLAYER_TWO = 87; // key w
	private static final int MOVE_DOWN_PLAYER_TWO =83; // key s
	
	// paddle properties (e.g. width and height)
	private static final int PADDLE_WIDTH = SCREEN_WIDTH / 32;
	private static final int PADDLE_HEIGHT = SCREEN_HEIGHT / 8;

	// ball properties (size and speed)
	private static final int BALL_SIZE = SCREEN_WIDTH / 32;
	private static int BALL_SPEED = SCREEN_WIDTH / 160;
	private static int dx = BALL_SPEED;
	private static int dy = BALL_SPEED;
	//Instance variables
	private Image background;
	private Paddle paddlePlayerOne;
	private Paddle paddlePlayerTwo;
	private Ball ball;
	private HitCounter counter;

	public void setup() {
		setupCanvas();
		setupBackground();
		setupBall();
		setupPaddlePlayerOne();
		setupPaddlePlayerTwo();
		 //setup graphical elements
	}

	public void draw() {
		drawBackground();
		updateBall();
		ball.ball_check_for_collision_with_ground_and_ceiling(dx, dy, SCREEN_WIDTH, SCREEN_HEIGHT, BALL_SIZE);
		ball.ball_check_for_collision_with_right_and_left_wall(dx, dy, SCREEN_WIDTH, SCREEN_HEIGHT, BALL_SIZE);
		//ball.ball_check_for_collision_with_paddle_one_and_paddle_two(dx, dy, );
		drawPaddlePlayerOne();
		drawPaddlePlayerTwo();
		drawBall();
	    //draw graphical elements and check for collisions
	}
	
	
	

	private void setupPaddlePlayerOne() {
		paddlePlayerOne = new Paddle (280,20);
		paddlePlayerOne.setSize(PADDLE_WIDTH, PADDLE_HEIGHT);
		paddlePlayerOne.setPosition(SCREEN_WIDTH/10-PADDLE_WIDTH, SCREEN_HEIGHT/2 - PADDLE_HEIGHT/2);
	}

	private void setupPaddlePlayerTwo() {
		paddlePlayerTwo = new Paddle (20,20);
		paddlePlayerTwo.setSize(PADDLE_WIDTH, PADDLE_HEIGHT);
		paddlePlayerTwo.setPosition(SCREEN_WIDTH/10*9, SCREEN_HEIGHT/2 - PADDLE_HEIGHT/2);
	}

	private void setupBall() {
		double dx = BALL_SPEED;
		double dy = BALL_SPEED;
		ball = new Ball (SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
	}

	private void setupBackground() {
		
	}
	
	private void setupCanvas() {
		setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
	}

	
	private void drawPaddlePlayerOne() {
		// TODO Auto-generated method stub
		paddlePlayerOne.draw();	
	}

	private void drawPaddlePlayerTwo() {
		paddlePlayerTwo.draw();
	}
	
	private void drawBall(){
		ball.draw();
		ball.setSize(BALL_SIZE, BALL_SIZE);
	}
	
	private void updateBall() {
		ball.move (dx, dy);
	}

	private void drawBackground() {
		background(BG_COLOR);
	}

	
	public void keyPressed (KeyEvent e){System.out.println (e.getKeyCode());
		switch (e.getKeyCode()){
		case MOVE_UP_PLAYER_ONE:
			movePaddlePlayerOne (0,-MOVE_PIXELS);
			break;
		case MOVE_DOWN_PLAYER_ONE:
			movePaddlePlayerOne (0, MOVE_PIXELS);
			break;
		case MOVE_UP_PLAYER_TWO:
			movePaddlePlayerTwo (0,-MOVE_PIXELS);
			break;
		case MOVE_DOWN_PLAYER_TWO:
			movePaddlePlayerTwo (0, MOVE_PIXELS);
			break;
		}
	}

	private void movePaddlePlayerTwo(int xDiff, int yDiff) {
		paddlePlayerTwo.move(xDiff, yDiff);
	}

	//add methods for handling user interaction

	private void movePaddlePlayerOne(int xDiff, int yDiff) {
		paddlePlayerOne.move(xDiff, yDiff);
	}
	
	//add private methods (decomposition!)

}

Quelltext für Ball:

Java:
import de.ur.mi.graphics.Color;
import de.ur.mi.graphics.Ellipse;

public class Ball extends Ellipse{
	
	private static final int RADIUS = 20;
	private static final Color BALL_COLOR = Color.ORANGE;
	
	public Ball(double x, double y) {
		super(x, y, RADIUS, RADIUS, BALL_COLOR);
		
	}
	
	public void ball_check_for_collision_with_ground_and_ceiling(double current_dx, double current_dy, int screen_height, int ball_size) {
		double ballX = getX();
		double ballY = getY();
		double dx = current_dx;
		double dy = current_dy;
		int SCREEN_HEIGHT = screen_height;
		int BALL_SIZE = ball_size;
		
		if ( ballY > SCREEN_HEIGHT - BALL_SIZE || ballY
				< BALL_SIZE ) {
			dy *= -1;
		}
		
		move(dx,dy);
	}

	public void ball_check_for_collision_with_right_and_left_wall(double current_dx, double current_dy, int screen_width, int screen_height, int ball_size) {
		double ballX = getX();
		double ballY = getY();
		double dx = current_dx;
		double dy = current_dy;
		int SCREEN_WIDTH = screen_width;
		int SCREEN_HEIGHT = screen_height;
		int BALL_SIZE = ball_size;
		
		if ( ballX > SCREEN_WIDTH - BALL_SIZE || ballX
				< BALL_SIZE ) {
			setPosition(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
		}
		
		move(dx,dy);
	}
	
	public void ball_check_for_collision_with_paddle_one_and_paddle_two(double current_dx, double current_dy, int ball_size) {
		double ballX = getX();
		double ballY = getY();
		double dx = current_dx;
		double dy = current_dy;
		int BALL_SIZE = ball_size;
		
		if (){
			dx *= -1;
		}
		
		move(dx,dy);
	}

}


Quelltext für Paddle:

Java:
import de.ur.mi.graphics.Color;
import de.ur.mi.graphics.Rect;

public class Paddle extends Rect {
	
	private static final int PADDLE_WIDTH = 10;
	private static final int PADDLE_HEIGHT = 60;
	private static final Color PADDLE_COLOR = Color.ORANGE;

	public Paddle(int x, int y) {
		super(x, y, PADDLE_WIDTH, PADDLE_HEIGHT, PADDLE_COLOR);
	}	
}


Quelltext für HitCounter bis jetzt:

Java:
public class HitCounter {

}
 
Zuletzt bearbeitet:
Hi Simon und herzlich Willkommen hier im Forum,

bitte verwende statt der [code]-Tags die [code=java]-Tags, dann klappt auch das Syntax-Highlighting.

Ich kann das bei mir jedoch jetzt nicht probieren oder genauer anschauen, da du verschiedene imports hast, die ne extener Library erfordern (Package de.ur.mi.*). Kannst du die bitte an den Thread noch hochladen? Warum verwendest du nicht die Standard-Java Klassen?

// Edit #2: Hier schon mal ne kleine Anmerkung:
Wiso für die Wände und die Paddeln unterschiedliche Kollisions-Abfragen? Du hast 2 Rechtecke, schau dir die Methode intersects(Rectangle) der java.awt.Rectangle mal an.

Gruß,
BK
 
Zuletzt bearbeitet:
Ah, hallo BK, denk mal du kennst mich eh noch oder?^^

Also die Library ist vonmeiner Uni.
Wir sollen unser Zeug von der importieren und nicht woanders her...

Und wegen der Kollisionsabfragen:
Wenn der Ball links oder rechts an die Wand prallt soll der Counter um 1 erhöht werden und der Ball wird wieder auf seine Startposition in der Mitte gesetzt werden.
Wenn der Ball allerdings an eines der Paddle prallt soll er nur die Richtung ändern und weiterfliegen.
Hoffe das war, was du wissen wolltest.

Was die Intersect Methode betrifft, funktioniert die dann überhaupt**** Ich müsste die ja dann in der Klasse "ball" machen aber die erbt ja nur von ellipse...
Werd daraus jetz leider nicht schlau, sorry... :(
 
Hi Simon,

jep, kenn dich noch ;)

Also ohne den Klassen von der Uni oder einer anständigen JavaDoc-Api dazu kann ich dir da leider so nicht weiterhelfen.
Mit meiner Anmerkung meinte ich nur, dass du jetzt 3 Methoden hast, die zum Teil das selbe machen (eben die Kollisionsabfrage). Die Berechnung ob Kollision oder nicht kannst du in eine eigene Methode auslagern, somit müssen die 3 anderen nur noch die Richtung entsprechend ändern.

Vom Ablauf her also:
- Ball eine Einheit bewegen
-> Auf Kollision mit Paddel 1 und 2 prüfen (ggf. x invertieren)
-> Auf Kollision mit oben und unten prüfen (ggf. y invertieren)
-> Auf Kollision mit links und rechts prüfen (reset, punkt vergeben etc.)
- Ball eine Einheit bewegen
usw.

Die Methode zur Kollision-Erkennung würde ich in der Ball Klasse machen, ja.

Grüße,
BK
 
Zuletzt bearbeitet:
Zurück