Street Hockey
Java Source:
import java.awt.*;
import java.util.*;
import java.applet.*;
import java.net.*;
public class Main extends Applet implements Runnable
{
// Deklaration der Variablen und Objekte
public int score1; // Zählt die Tore des Spielers
public int score2; // Zählt die Tore des Computers
public int maus_y; // Speichert die Mausposition an Stelle y
Ball puck; // Ballobject
Player bat1; // Playerobject Tor
Player bat2; // Playerobject Stürmer
Computer bat3; // Computerobject Tor
Computer bat4; // Computerobject Stürmer
Thread th;
// Fängt den von wheresBall gelieferten Wert auf und zeitg an, wer ein Tor geschossen hat
public int whosgoal;
// Titelbild
private Image titleImg;
// Variablen für die Doppelpufferung
private Image dbImage;
private Graphics dbg;
// Variablen für die Audiodateien
AudioClip kicknoise; // Ball trifft Paddel
AudioClip goalnoise; // Tor
// Variablen für die momentanen Spielzustände (Pause und Run)
boolean play;
boolean end;
boolean title;
// Initialisierung des Applets
public void init ()
{
// Initialisierung der scores
score1 = 0;
score2 = 0;
// Hintergrundfarbe
setBackground (Color.black);
// Objekte initialisieren
puck = new Ball (8, 250, 175, 0, 0, Color.black, this);
bat1 = new Player (15, 175);
bat2 = new Player (375, 175);
bat3 = new Computer (475, 175);
bat4 = new Computer (115, 175);
// Initialisierung der Spielzustände
play = false;
end = false;
title = true;
// Laden des Titelbildes
titleImg = getImage(getCodeBase(), "Title.gif");
// Audiodateien initialisieren
kicknoise = getAudioClip (getCodeBase(), "hit.au");
kicknoise.play();
kicknoise.stop();
goalnoise = getAudioClip (getCodeBase(), "chime.au");
goalnoise.play();
goalnoise.stop();
}
// Start - Methode, hier beginnt das Applet zu laufen
public void start ()
{
// Schaffen eines neuen Threads, in dem das Spiel läuft
th = new Thread (this);
th.start ();
}
public void stop ()
{
th.stop();
}
// Implementierung der Runmethode
public void run ()
{
// Erniedrigen der ThreadPriority um zeichnen zu erleichtern
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (true)
{
// Neumalen des Fensters
repaint();
// Bewegen des Pucks
puck.move ();
// bewegen der Computerpaddel
bat3.ComputerMove (puck);
// Testen wo sich der Ball im Moment befindet
whosgoal = puck.wheresBall ();
// Wenn jemand ein Tor geschossen hat, Punkte hinzuzählen und Ball zurücksetzen
if (whosgoal != 0)
{
if (whosgoal == 1)
{
score1 += 1;
goalnoise.play();
puck.pos_x = 250;
puck.vx = 4;
puck.vy = -4;
if (score1 == 10)
{
play = false;
end = true;
puck.isStoped = true;
puck.vx = 0;
puck.vy = 0;
}
}
else if (whosgoal == 2)
{
score2 += 1;
goalnoise.play();
puck.pos_x = 250;
puck.vx = 4;
puck.vy = 4;
if (score2 == 10)
{
play = false;
end = true;
puck.isStoped = true;
puck.vx = 0;
puck.vy = 0;
}
}
}
/** Testet nach Collisionen von Ball und Spielerpaddel. Dies ist nur relevant, wenn
sich der Ball auf die Paddel zubewegt */
if (puck.vx < 0)
{
puck.PCollision (bat1, bat2, kicknoise);
}
else if (puck.vx > 0)
{
puck.CCollision (bat3, bat4, kicknoise);
}
try
{
// Stoppen des Threads für 10 Millisekunden
Thread.sleep (10);
}
catch (InterruptedException ex)
{
break;
}
// Zurücksetzen der ThreadPriority auf Maximalwert
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
}
}
/** Diese Methode fängt Mausereignisse im Frame auf und Speichert die Y Position des Mauszeigers
desweiteren bestimmt sie die neue Position der beiden Spielerpaddel und testet, ob sich das Paddel
im Aus befindet*/
public boolean mouseMove (Event e, int x, int y)
{
maus_y = y;
// Testen, ob das Paddel im Aus ist, wenn nicht, Paddel bewegen
if (maus_y > 25 & maus_y < 325)
{
bat1.PaddelMove (maus_y);
bat2.PaddelMove (maus_y);
}
return true;
}
public boolean mouseDown (Event e, int x, int y)
{
if (!play)
{
play = true;
end = false;
title = false;
puck.vx = 4;
puck.vy = 4;
score1 = 0;
score2 = 0;
puck.isStoped = false;
}
return true;
}
/** Paint - Methode */
public void paint (Graphics g)
{
// Spielfeld malen
g.setColor (Color.cyan);
g.fillRect (0, 0, 500, 8); // Obere Linie
g.fillRect (0, 342, 500, 8); // Untere Linie
g.fillRect (0, 0, 8, 75); // Linke obere Seitenlinie
g.fillRect (0, 275, 8, 75); // Linke untere Seitenlinie
g.fillRect (492, 0, 8, 75); // Rechte obere Seitenlinie
g.fillRect (492, 275, 8, 75); // Rechte untere Seitenlinie
// Ball malen
puck.DrawBall (g);
// Paddel 1 malen
bat1.DrawPaddel (g);
// Paddel 2 malen
bat2.DrawPaddel (g);
// Paddel 3 malen
bat3.DrawPaddel (g);
// Paddel 4 malen
bat4.DrawPaddel (g);
// Farbe für strings
g.setColor (Color.yellow);
// Spielertore zeichnen
g.drawString ("Player: " + score2, 50, 370);
// Computertore zeichnen
g.drawString ("Computer: " + score1, 400, 370);
if (title)
{
g.drawImage (titleImg, 150, 70, this);
g.drawString ("This game was programmed by FBI", 155, 200);
g.drawString ("Please visit us at www.javacooperation.gmxhome.de", 125, 220);
g.drawString ("Click on Applet to start game!", 175, 240);
}
else if (end)
{
g.drawImage (titleImg, 150, 70, this);
g.drawString ("This game was programmed by FBI", 155, 200);
g.drawString ("Please visit us at www.javacooperation.gmxhome.de", 125, 220);
if (score1 == 10)
{
g.drawString ("Computer won the game!!", 180, 240);
}
else if (score2 == 10)
{
g.drawString ("Player won the game!!", 180, 240);
}
g.drawString ("Click on Applet to restart game!", 170, 260);
}
}
/** Update - Methode, Realisierung der Doppelpufferung zur Reduzierung des Bildschirmflackerns */
public void update (Graphics g)
{
// Initialisierung des DoubleBuffers
if (dbImage == null)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics ();
}
// Bildschirm im Hintergrund löschen
dbg.setColor (getBackground ());
dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
// Auf gelöschten Hintergrund Vordergrund zeichnen
dbg.setColor (getForeground());
paint (dbg);
// Nun fertig gezeichnetes Bild Offscreen auf dem richtigen Bildschirm anzeigen
g.drawImage (dbImage, 0, 0, this);
}
}
class Ball
{
/** Diese Klasse enthält alle Funktionen, die für die Bewegung, Konstruktion, Positionsbestimmung,
Graphik und Abschiesen des Ball - Objektes von Bedeutung sind. */
// Deklaration der Variablen
public int pos_x; // X - Position des Balles
public int pos_y; // Y - Position des Balles
public int vx; // X - Geschwindigkeit des Balles
public int vy; // Y - Geschwindigkeit des Balles
public int radius; // Radius des Balles
public boolean isStoped; // Zeigt an, ob der Ball gestoped ist
private int ball_top; // Obergrenze des Balles
private int ball_bottom; // Untergrenze des Balles
private int ball_left; // Linke Grenze des Balles
private int ball_right; // Rechte Grenze des Balles
private int player_top; // Oberkante des Paddels
private int player_bottom; // Unterkante des Paddels
private int player_right; // rechte Kante des Paddels
private int comp_top; // Oberkante des Computerpaddels
private int comp_bottom; // Unterkante des Computerpaddels
private int comp_left; // Rechte Seite des Computerpaddels
private final int max_vx; // Variable für die maximale Ballgeschwindigkeit in x - Richtung
private final int max_vy; // Variable für die maximale Ballgeschwindigkeit in y - Richtung
public Color ballfarbe; // Frage des Balles
Image ballImg; // Bild des Balles
Component mom; // Wird benötigt um Ball mit Bild zu überlagern
/** Construktor */
public Ball (int r, int x, int y, int vx, int vy, Color c, Component parent)
{
// Initialisierung der Variablen
pos_x = x; // Startposition des Balles
pos_y = y; // Startposition des Balles
radius = r; // Radius des Balles
this.vx = vx; // Startgeschwindigkeit in X - Richtung
this.vy = vy; // Startgeschwindigkeit in Y - Richtung
ballfarbe = c; // Ballfarbe
max_vx = 5; // Ballgeschwindigkeit in x - Richtung
max_vy = 5; // Ballgeschwindigkeit in y - Richtung
isStoped = true; // Ball bewegt sich am Anfang nicht
// Laden des Ballbildes
ballImg = ((Applet) parent).getImage (((Applet) parent).getCodeBase(), "Ball.gif");
// Speichern des Frames in mom
mom = parent;
}
/** Move - Methode, berechnet die Bewegung des Balls. Bei jedem Aufruf wird der
Ball um vx und die vy verschoben.*/
public void move ()
{
// Hält die Geschwindigkeit der Balles in richtigem Rahmen
if (vx > max_vx) vx = max_vx;
else if (vx < -max_vx) vx = -max_vx;
else if (vy > max_vy) vy = max_vy;
else if (vy < -max_vy) vy = -max_vy;
else if (vx == 0 && !isStoped) vx = 1;
pos_x += vx;
pos_y += vy;
}
/** Diese Methode testet, wo sich der Ball im Moment befindet. Kommt er den Grenzen
des Spielfeldes zu nahe, so wird er gebounct. Die Methode testet auch, ob der Ball
in eines der Tore gegangen ist. Ist dies der Fall, so wird entweder 1 bzw. 2 als
Wert zurückgegeben */
public int wheresBall ()
{
if (vy > 0)
{
if (pos_y > 330) // Ball unten im Aus
{
vy = -vy;
return 0;
}
}
else if (vy < 0)
{
if (pos_y < 20) // Ball oben im Aus
{
vy = -vy;
return 0;
}
}
if (vx < 0)
{
if (pos_x < 15 && pos_y < 75) // Ball stößt an linke obere Bande
{
vx = -vx;
return 0;
}
else if (pos_x < 15 && pos_y > 275) // Ball stößt an linke untere Bande
{
vx = -vx;
return 0;
}
else if (pos_x < 15) // Ansonsten Ball im linken Tor
{
vx = -vx;
return 1;
}
else return 0;
}
else if (vx > 0)
{
if (pos_x > 485 && pos_y < 75) // Ball stößt an rechte obere Bande
{
vx = -vx;
return 0;
}
else if (pos_x > 485 && pos_y > 275)// Ball stößt an rechte untere Bande
{
vx = -vx;
return 0;
}
else if (pos_x > 485) // Ansonsten Ball im rechten Tor
{
vx = -vx;
return 2;
}
else return 0;
}
else return 0;
}
/** Diese Methode testet ob es zu einer Collision zwischen Ball und Paddel gekommen ist.
Ist dies der Fall, so wird die Geschwindigkeit des Balles in X - Richtung umgekehrt.
Später soll die Methode auch in der Lage sein, die Geschwindigkeit des Balles insgesamt
zu ändern, je nach dem, wie der Ball getroffen wird */
public void PCollision (Player bat1, Player bat2, AudioClip k)
{
// Initialisierung der Ballpositionen
ball_top = pos_y - radius;
ball_bottom = pos_y + radius;
ball_left = pos_x - radius;
ball_right = pos_x + radius;
// Initialisierung der momentanen Positionen des Paddels
player_top = bat1.pos_y;
player_bottom = bat1.pos_y + bat1.size_y;
// Ist die Y - Position des Balles zwischen den beiden Paddel - Positionen?
if ((ball_top >= player_top - 10) && (ball_bottom <= player_bottom + 10))
{
// Ist erstes oder zweites Paddel in der Nähe?
if (ball_left <= 25 || (ball_left <= 380 && ball_left >= 370))
{
// Abspielen der Audiodatei
k.play();
// Normales Bouncen
vx = - vx;
// Macht die Geschwindigkeit des Balles etwas unberechenbarer
if (bat1.vy < 0)
{
vy --;
}
else if (bat1.vy > 0)
{
vy += bat1.vy;
}
}
}
}
public void CCollision (Computer bat3, Computer bat4, AudioClip k)
{
// Initialisierung der Ballpositionen
ball_top = pos_y - radius;
ball_bottom = pos_y + radius;
ball_left = pos_x - radius;
ball_right = pos_x + radius;
// Initialisierung der momentanen Positionen des Paddels
comp_top = bat3.pos_y;
comp_bottom = bat3.pos_y + bat3.size_y;
// Ist die Y - Position des Balles zwischen den beiden Paddel - Positionen?
if ((ball_top >= comp_top - 10) && (ball_bottom <= comp_bottom + 10))
{
// Ist erstes oder zweites Paddel in der Nähe?
if (ball_right >= 475 || (ball_right <= 125 && ball_right >= 115))
{
// Abspielen des AudioClips
k.play();
// Normales Bouncen
vx = - vx;
// Macht die Geschwindigkeit des Balles etwas unberechenbarer
if (bat3.vy < 0)
{
vy --;
}
else if (bat3.vy > 0)
{
vy += bat3.vy;
}
}
}
}
// Hier kommt noch eine Methode, die die aktuellen Abstände aktualisiert
/** Diese Methode zeichnet den Ball in das Spielfeld */
public void DrawBall (Graphics g)
{
g.setColor (ballfarbe);
g.fillOval (pos_x - radius, pos_y - radius, 2 * radius, 2 * radius);
g.drawImage (ballImg, pos_x - 10, pos_y - 10, mom);
}
/** Liefert des X - Wert des Balles zurück */
public int posX ()
{
return pos_x;
}
/** Liefert des Y - Wert des Balles zurück */
public int posY ()
{
return pos_y;
}
}
class Player
{
/** Diese Klasse behandelt alle vom Benutzer verursachten Ereignisse, zeichnet das Paddel,
testet nach Collisionen mit dem Ball und bewegt das Paddel */
// Deklaration der Variablen
public final int pos_x; // X - Position des Paddels, gilt nur für ein Paddel
public static int pos_y; // Y - Position des Paddels, gilt für beide Paddel
public final int size_x; // Größe des Paddels in x - Richtung
public final int size_y; // Größe des Paddels in y - Richtung
public static int vy; // Geschwindigkeit in y - Richtung
private Color paddelcolor; // Farbe der Paddel
// Construktor
public Player (int x, int y)
{
pos_x = x;
Player.pos_y = y;
size_x = 10;
size_y = 50;
paddelcolor = Color.red;
vy = 0;
}
/** Diese Methode bewegt das Paddel */
public void PaddelMove (int maus_y)
{
int new_y_pos;
new_y_pos = maus_y - (size_y / 2);
// Berechne Paddelgeschwindigkeit
if (new_y_pos < Player.pos_y) vy = (Player.pos_y - new_y_pos) / 2;
else vy = (new_y_pos - Player.pos_y) / 2;
// neue Position
Player.pos_y = new_y_pos;
}
/** Diese Methode zeichnet das Paddel */
public void DrawPaddel (Graphics g)
{
g.setColor (paddelcolor);
g.fillRect (pos_x, Player.pos_y, size_x, size_y);
}
}
class Computer
{
/** Diese Klasse Implementiert die Bewegungen des Computers und zeichnet auch die
Computerpaddel */
// Deklaration der Variablen
public final int pos_x; // X - Position des Paddels, gilt nur für ein Paddel
public static int pos_y; // Y - Position des Paddels, gilt für beide Paddel
public final int size_x; // Größe des Paddels in x - Richtung
public final int size_y; // Größe des Paddels in y - Richtung
public int vy; // Geschwindigkeit in y - Richtung
public int real_y; // Speichert die wirkliche Paddelposition (Mitte)
private Color paddelcolor; // Farbe der Paddel
// Construktor
public Computer (int x, int y)
{
pos_x = x;
pos_y = y;
size_x = 10;
size_y = 50;
paddelcolor = Color.blue;
vy = 3;
}
/** Diese Methode bewegt das Paddel */
public void ComputerMove (Ball b)
{
real_y = pos_y + (size_y / 2);
// Wenn sich Ball von Paddel wegbewegt, werden die Paddel in die Mitte zurückbewegt
if (b.vx < 0)
{
// Paddel oberhalb der Mitte
if (real_y < 175)
{
pos_y += vy;
}
// Paddel unterhalb der Mitte
else if (real_y > 175)
{
pos_y -= vy;
}
}
else if (b.vx > 0)
{
// Solange Paddel nicht auf Höhe des Balles ist wird es bewegt
if ( real_y != b.pos_y)
{
// Ball oberhalb von Paddel
if (b.pos_y < real_y)
{
pos_y -= vy;
}
// Ball unterhalb von Paddel
else if (b.pos_y > real_y)
{
pos_y += vy;
}
}
}
}
/** Diese Methode zeichnet das Paddel */
public void DrawPaddel (Graphics g)
{
g.setColor (paddelcolor);
g.fillRect (pos_x, pos_y, size_x, size_y);
}
}
Back to Street Hockey
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|