# Einfaches Ping-Pong Spiel



## MoSe (18. Mai 2011)

Hallo liebe community,
eigentlich funktioniert unser Programm schon recht gut. Allerdings haben wir noch ein paar Probleme:
- wir können nur einen Schläger (Actor) bewegen
- die Actors können das Spielfeld verlassen (wir haben erfolglos versucht das Problem mit einem BorderListener zu lösen)
- wir wissen nicht wie wir den Punktzähler im Titel zum zählen bringen (er soll bei jeder Schlägerkollision einen Punkt dazu addieren).

Hier unser Quelltext:

```
import ch.aplu.jgamegrid.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
import ch.aplu.jgamegrid.GGKeyListener;
import ch.aplu.jgamegrid.GGActorCollisionListener;
import ch.aplu.jgamegrid.Actor;
//import java.awt.Point;
import java.awt.event.KeyAdapter;

public class Spiel_1 extends GameGrid implements GGActorCollisionListener
{
       
    
private class WhiteThread extends Thread            //Thread für Balken
    {                                               //(Black und White)
        @Override
      public void run()
        {
          addKeyListener(white);
        }
    }

private class BlackThread extends Thread
    {
        @Override
        public void run()
        {
            addKeyListener(black);
        }
    }

    private Black black= new Black();
    private White white= new White();

public Spiel_1()
  {
    super(820, 450, 1, "sprites/tennisfeld.gif");   //Spielfeld
    Ball green = new Ball();
    //White bar = new White();//Schläger 1
    //Black white = new Black();//Schläger 2
    addActor(white, new Location(795, 225));        //Startpositionen der Actors
    addActor(black, new Location(35, 225));
    addActor(green, new Location(400,225));
    black.addCollisionActor(green);
    black.addActorCollisionListener(this);
    white.addCollisionActor(green);
    white.addActorCollisionListener(this);
    WhiteThread wt = new WhiteThread();             //Threads werden definiert
    BlackThread bt = new BlackThread();
    wt.start();                                     //und gestartet
    bt.start();
 
    show();
  
    int nbPunkte=0;
    setTitle("Ping-Pong Punkte  "+nbPunkte);
    nbPunkte++;
    
  }

  public int collide(Actor actor1,Actor actor2){    //Kolisionsverhalten
    actor1.setDirection(actor1.getDirection() + 180);
    actor2.setDirection(actor2.getDirection() + 180);
    playSound(this, GGSound.DUMMY);
    return(10);
  }
  
  public interface BorderListener{
      void bordercrossed(double x, double y);
  }

    
 public static void main(String[] args)
  {
    new Spiel_1();
  }
}

//----------------------------Actors-------------------------------------------

class Black extends Actor implements GGKeyListener  //Eigenschaften des scwarzen
{  boolean isFinished=false;                        //Balkesn
    public Black()
    {
    super("sprites/Balken_schwarz.jpg");
    }

  public void run()                                 //kopiert aus.... FROG??
  {
    if (getLocation().y < 25)
    {
      if (!isFinished)
      {
        isFinished = true;
        gameGrid.playSound(this, GGSound.FROG);
      }
    }
    else
      isFinished = false;
  }

  public boolean keyPressed(KeyEvent evt)           //Steuerung des schwarzen
  {                                                 //Balkens
    int keyCode=evt.getKeyCode();
    switch (keyCode)
    {
      case KeyEvent.VK_W:
        setLocation(new Location(getLocation().x, getLocation().y - 15));
        break;
      case KeyEvent.VK_S:
        setLocation(new Location(getLocation().x, getLocation().y + 15));
        break;
    }
    return true;  // Consume
  }
 public boolean keyReleased(KeyEvent evt)
  {
    return true;
  }
}


class White extends Actor implements GGKeyListener  //Eigenschaften des weißen
{  boolean isFinished=false;                        //Balkens
    public White()
    {
    super("sprites/Balken_weiß.jpg");
    }
    
    private final double step = 0;
    private final int POLLPERIOD = 200;
    private BorderListener borderListener;
    
    public void addBorderListener(BorderListener listener){
        borderListener = listener;
        ActionListener pollPerformer = new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        double x = getX();
                        double y = getY();
                        
                        if (x < 0 || x > 420 || y < 0 || y > 790)
                            borderListener.borderCrossed(x,y);
                    }
                };
        Timer pollTimer = new Timer(POLLPERIOD, pollPerformer);
        pollTimer.start();
    }

  public void run()
  {
    
      
    if (getLocation().y < 25)
    {
      if (!isFinished)
      {
        isFinished = true;
        gameGrid.playSound(this, GGSound.FROG);
      }
    }
    else
      isFinished = false;
  }

 public boolean keyPressed(KeyEvent evt)           //Steuerung des weißen
  {                                                //Balkens
    //Location loc = getLocation();
     //if(loc.y > 420){
        
    int keyCode=evt.getKeyCode();
    switch (keyCode)
    {
      case KeyEvent.VK_UP:
        setLocation(new Location(getLocation().x, getLocation().y - 15));
        break;
      case KeyEvent.VK_DOWN:
        setLocation(new Location(getLocation().x, getLocation().y + 15));
        break;
    }
    return true;  // Consume
     
  }
 
 public boolean keyReleased(KeyEvent evt)
  {
    return true;
  }
}     


class Ball extends Actor                            //Eigenschaften des Balls
{
    public Ball()
  {
    super("sprites/ball.gif");
  }

    private final double step = 0.1; //Winkel des Balls
    
   public int collide(Actor Ball,Actor bar)         //Kollisionsverhalten
    {
    Ball.setDirection(Ball.getDirection() + 180);
    bar.setDirection(bar.getDirection() + 180);
    return(10);
        }
   
  public void act()
  {

    Location loc = getLocation();
    double dir = (getDirection() + step) % 360;     

    if (loc.x < 30)                             //Abprallen: wann? wohin?
    {
      dir = 180 - dir;
      setLocation(new Location(31, loc.y));
      //Ball.delay(1500);
    }
    if (loc.x > 790)
    {
      //dir = 180 - dir;
      setLocation(new Location(400, 225));
      Ball.delay(1500);
    }
    if (loc.y < 30)
    {
      dir = 360 - dir;
      setLocation(new Location(loc.x, 31));
    }
    if (loc.y > 420)
    {
      dir = 360 - dir;
      setLocation(new Location(loc.x, 419));
    }
    setDirection(dir);
    move();
    
  }
}
```

Wie man am Quelltext schon erkennen kann sind wir keine Experten, darum bitte so einfach wie möglich antworten.
Danke für eure Mühen
Mo und Se


----------



## Matthias K. (18. Mai 2011)

Hallo Mo und Se,
ich habe mit java schon einige kleine Spiele programmiert.
Ich nutze aber einen komplett anderen Aufbau.
Ihr nutzt spezielle Bibliotheken für Spiele.
Ich würde euch empfehlen, Graphics-Methoden (Canvas), sowie das Event-Handling zu nutzen.
Keine Sorge!
Ich poste euch alle Befehle und stehe gerne für Fragen zur Verfügung.

++++++++++++++++++++++++++++++++++++++++++++++++++++++

Außerdem solltet ihr euch einen nachvollziehbaren Programmierstil angewöhnen.
Für diesen gibt es einige Vereinbarungen.

++++++++++++++++++++++++++++++++++++++++++++++++++++++

Falls dies euer erstes Projekt ist, solltet ihr euch langsam in JAVA einarbeiten und nicht direkt Befehle raussuchen 
und diese nutzen.
Ich kann euch auch gerne ein paar Tutorials posten oder Quelltexte schicken.

++++++++++++++++++++++++++++++++++++++++++++++++++++++

Gruß,
Matthias


----------



## MoSe (21. Mai 2011)

Hallo Matthias,

danke erst einmal für deine Antwort. Ja das ist unser erstes Projekt. Wir arbeiten allerding schon seiteiner weile mit Turtles. Da dies ein Schulprojekt ist sollten wir auch das Gamegrid benutzen und auch eher Dinge die wir im Unterricht behandelt haben. Die Idee mit Canvas ist sicherlich ganz gut allerdings weiß ich weder was das ist noch haben wir die Zeit unser Projekt neu aufzuziehen. Wir hatten eher an ein paar kurz Tipps zu unserem jetztigen Programm gedacht. Quasi wo wir was einfügen müssen damit des funktioniert oder mit was für einer Sache wir das realisieren können.

Z.B. hatten wir die Idee mit beide Schläger über eine Tastatur bewegen, mit Threads zu realisieren allerding bewegt sich immernoch nur einer. Daraufhin haben wir es mit einem KeyAdapter probiert den einzufügen allerdings hatten wir des Problem, dass wir nicht wussten wohin mit dem Ausführbefehl des keyAdapters. Also ob der in die mainclass spiel eins oder in die Threads oder evtl. zu den Schlägern muss.

Wir danken dir auf alle Fälle für deine Antwort und das du dir Zeit für unser Problem genommen hast. 
Und naja unseren Programmierstil können wir auf die schnelle auch nichts mehr machen.

LG Mo und Se


----------



## panmari (9. Aug 2011)

Hallo zusammen!

Ist zwar schon ein etwas älterer Thread, aber vielleicht schaut ja noch mal wer vorbei...

Gute Sache, dass ihr es mit GameGrid versucht! Da es eine etwas spezielle Bibliothek ist, gibt es dazu sogar ein eigenes Forum: Forum

Ich habe selbst auch schon einige Dinge mit GameGrid gemacht und mir euren Code mal angeschaut. Schön, dass ihr es mit Multithreading versucht, aber die GameGrid-Bibliothek nimmt uns all diese Arbeit ab. Ich würde also eher von der Idee abkommen, für die Pads eigene Threads zu starten. 

Ihr könnt auch nicht zwei Keylistener gleichzeitig registriert haben, der eine überschreibt dann den
anderen. Versucht doch, den Keylistener in der GameGrid-Klasse zu implementieren und dann von dort aus die beiden Pads zu steuern (die ihr als Instanzvariablen abgespeichert habt).

Auch die run()-Methode in den beiden Pads scheint ihr nicht zu benutzen, könntet ihr sie nicht auch löschen?

Und damit die sich nicht ausserhalb des Grids bewegen, müsst ihr an einem geeigneten Ort
eine kleine if-Abfrage einbauen. 

Falls meine Tipps nicht helfen, kann ich euch sonst einen kleinen Umriss schicken...

greetz panmari


----------

