OOP Sprites

Niky

Mitglied
Ich bin gerade dabei, ein grundlegendes Tutorial zur Spiele-Programmierung in Java durchzugehen. Ich weiß, was objektorientiertes Programmieren ist, Methoden, Klassen und das ganze Zeug, Vererbung kenne ich auch schon ein wenig. Ich lerne bereits in der Schule Java, aber möchte privat noch etwas dazu lernen und kann recht wenig mit folgenden Zeilen Code des Quelltexts anfangen. :bahnhof:

Eine Erklärung wäre nett, aber es würde auch schon genügen, wenn ich wüsste wo ich nachlesen kann oder unter welchen Stichpunkten ich danach suchen kann.


Hier erstmal der Code (der ist von hier: http://www.edu4java.com/en/game/game3.html)

Java:
package com.edu4java.minitennis3;


import java.awt.Graphics2D;


public class Ball
{
    int x = 0;
    int y = 0;
    int xa = 1;
    int ya = 1;
    private Game2 game;


    public Ball(Game2 game)
    {
    this.game = game;
    }


    void move()
    {
    if (x + xa < 0)
        xa = 1;
    if (x + xa > game.getWidth() - 30)
        xa = -1;
    if (y + ya < 0)
        ya = 1;
    if (y + ya > game.getHeight() - 30)
        ya = -1;


    x = x + xa;
    y = y + ya;
    }


    public void paint(Graphics2D g)
    {
    g.fillOval(x, y, 30, 30);
    }
}

Java:
package com.edu4java.minitennis3;


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class Game2 extends JPanel
{


    Ball ball = new Ball(this);


    private void move()
    {
    ball.move();
    }


    @Override
    public void paint(Graphics g)
    {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ball.paint(g2d);
    }


    public static void main(String[] args) throws InterruptedException
    {
    JFrame frame = new JFrame("Mini Tennis");
    Game2 game = new Game2();
    frame.add(game);
    frame.setSize(300, 400);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    while (true)
    {
        game.move();
        game.repaint();
        Thread.sleep(10);
    }
    }
}


Ich kann ziemlich wenig mit folgenden Zeilen anfangen:

Ball.java

Java:
private Game2 game;
public Ball(Game2 game)
{
this.game = game;
}


Game2.java

Java:
Ball ball = new Ball(this);


In Ball.java verstehe ich nicht, was es bedeutet, eine neue Variable game mit dem Typen Game2 anzulegen. Was enthält diese neue Variable? Und wo in Game.java rufe ich den Konstruktor von Ball.java auf, um die Variable game zu übergeben?

Die Zeile "Ball ball = new Ball(this);" in Game.java ist mir absolut rätselhaft, das this als Übergabeparameter ist mir auch neu.


Eine weitere Frage:

Java:
super.paint(g);Graphics2D g2d = (Graphics2D) g;

Es wird zwar im Video erwähnt, aber so ganz habe ich das nicht verstanden: Wofür brauche ich den typecast, was bewirkt er und wofür implementiere ich die "paint-Methode"?


Tut mir Leid für die ganzen Fragen, mir fehlen eindeutig noch wichtige Grundlagen.


Danke schon mal für eure Antworten :)
 
Zuletzt bearbeitet:

franky27

Bekanntes Mitglied
Also du hast eine Game Klasse und eine Ball Klasse. Die Game Klasse bildet die Zeichenoberfläche des Spiels, deswegen erbt sie von JPanel und überschreibt die paint Methode dieser Klasse, um eben den Ball, oder was auch immer, zeichnen zu können.
Java:
private Game2 game;
public Ball(Game2 game)
{
this.game = game;
}
Deine Ball Klasse hat einen Konstruktor, der ein Objekt der Game Klasse erwartet.
Dazu hat er eine private member Variable game und mit
Java:
this.game = game
speicherst du die Referenz auf das übergebene Game Objekt in deiner member Variablen. Der Ball hat jetzt also "Zugriff" aufs Spielfeld.

Java:
Ball ball = new Ball(this);
Genau mit dieser Anweisung rufst du den Konstruktor von Ball auf, erzeugst also ein neues Ball Objekt. Der Konstruktor erwartet ja ein Game Objekt als Parameter und genau dasmachst du mit der Übergabe von "this". Du übergibst damit deine aktuelle Game instanz an den Ball.

Java:
Graphics2D g2d = (Graphics2D) g;
Kurz erklärt: Du hast mit einem Graphics2D Objekt mehr Möglichkeiten (Methoden) zur Verfügung als mit einem "normalen" Graphics Objekt. Das Graphics Objekt ist also sozusagen ein "abgespecktes" Graphics2D Objekt. Aber "dahinter" liegt eigentlich ein Graphics2D Objekt und mit dem Typecast kannst du dir das eben holen. Für was die paint Methode ist habe ich ja oben bereits erwähnt..eben um dein Spielfeld/Objekte zu zeichnen.
 
Zuletzt bearbeitet:

Saheeda

Top Contributor
Hallo,

Dein Ball weiß somit, in welchem Spiel er sich befindet. Die Variable game in der Ball-Klasse ist keine "neue" Variable in dem Sinne, sondern ein Verweis auf das initial erstelltes Game2Objekt.

"This" bezieht sich immer auf das aktuelle Objekt, egal ob als Parameter oder als Referenz auf eine Variable/Methode. Du übergibst einfach nur das aktuelle Game2-Objekt.


Die paint-Methode kommt vom JPanel, da du davon erbst. Ich vermute, Graphics2D ist eine von Graphics abgeleitete Klasse. Indem du g castest, kannst du auch auf Methoden zugreifen, die nur in Graphics2D existieren. Andernfalls könntest du nur alle Graphics-Methoden benutzen.

Ansonsten ist die Doku immer ein guter Anlaufpunkt.

EDIT:
Zu langsam..
 
Zuletzt bearbeitet:

Niky

Mitglied
Danke an euch beide, hab das Prinzip verstanden. :)

Nur noch eine Frage zum Typecast: Warum muss ich das machen, wenn Graphics2D ja sowieso von Graphics erbt, kann ich ja eigtl. gleich benutzen da es ja alles von Graphics hat, oder nicht?
 

freddy79

Mitglied
Die Methode "setRenderingHint(RenderingHints.Key hintKey, Object hintValue) "gibt es in der Klasse "Graphics" nicht.
Insofern muss ich nach "Graphics2D" casten wenn ich die Methode nutzen will.
 

Saheeda

Top Contributor
@Niky

Graphics2D besitzt alle Methoden von Graphics.
Graphics besitzt nicht alle Methoden von Graphics2D.

Oder anders:
Jede Katze ist ein Tier. Jede Katze kann miauen.

Aber nicht jedes Tier ist eine Katze. Nicht jedes Tier kann miauen.
 

franky27

Bekanntes Mitglied
Naja der Parameter g der PaintComponent Methode ist ja ein Graphics Objekt. Graphics selbst hat nicht die Methoden seiner Unterklasse Graphics2D. Willst du "g" jetzt aber als Graphics2D nutzen um auf dessen Methoden zugreifen zu können musst du es -Stichwort Polymorphie - natürlich erst in ein Graphics2D Objekt casten. Jedes 2D ist auch ein Graphics Objekt, aber nicht jedes Graphics Objekt ein Graphics2D Objekt.

Edit: Jetz war ich zu spät:p
 
Zuletzt bearbeitet:

Niky

Mitglied
Die Methode "setRenderingHint(RenderingHints.Key hintKey, Object hintValue) "gibt es in der Klasse "Graphics" nicht.
Insofern muss ich nach "Graphics2D" casten wenn ich die Methode nutzen will.

Warum kann ich nicht einfach die Klasse Graphics2D benutzen, die sollte doch alles haben, was auch in Graphics ist und zusätzlich noch mehr (also auch das setRenderingHint)? Warum benutze ich trotzdem Graphics und "übergebe" ihr alles Graphics2D Objekte, das ist ja quasi andersherum?
 

Network

Top Contributor
Warum kann ich nicht einfach die Klasse Graphics2D benutzen, die sollte doch alles haben, was auch in Graphics ist und zusätzlich noch mehr (also auch das setRenderingHint)? Warum benutze ich trotzdem Graphics und "übergebe" ihr alles Graphics2D Objekte, das ist ja quasi andersherum?

Du bekomst von der Methode ein Objekt der Klasse "Graphics" und theoretisch bist du erstmal auf die Klasse "Graphics" und ihre Methoden limitiert.
Jedoch ist bekannt, dass es sich bei dem übergebenen "Graphics" Objekt eigentlich um die Kindklasse "Graphics2D" handelt, weshalb man zu "Graphics2D" castet um zusätzlich alle Funktionen der "Graphics2D" nutzen zu können ohne dass der Compiler meckert. In diesem Fall weist du einfach mehr als der Compiler.

Graphics2D g2d = (Graphics2D) g;
> Gibt dem Compiler bescheid: Ich verwende das Objekt jetzt als "Graphics2D" anstatt "Graphics", bitte zur Laufzeit prüfen ob das funktioniert.
> Wenn sich zur Laufzeit herausstellt, dass das übergebene Objekt in der Variable "g" zwar vom Typ Graphics ist aber nicht die Kindklasse Graphics2D wird eine Exception geworfen.

Beispielprogramm:
Java:
Tier tier;
tier = new Katze(); // Katze extends Tier, geht
tier = new Hund(); // Hund extends Tier, geht

tier.bellen(); // Geht nicht
Hund hund = (Hund) tier;
hund.bellen();

tier.schnurren() // Geht nicht
katze = (Katze) tier; // Geht nicht, das Objekt tier ist vom Typ Hund
katze.schnurren();
 
Zuletzt bearbeitet:

franky27

Bekanntes Mitglied
Hm also ich versteh nicht was du nicht verstehst... es wurde dir doch jetzt mehr als einmal beschrieben...
Du "musst" nicht casten, wenn du keine Graphics2D Methoden nutzt. Willst du sie nutzen musst du casten. Ansonsten wie bereits von mir erwähnt, oder im oberen Beispiel Programm gezeigt, schau dir das Thema PolyMorphie an.
 

Neue Themen


Oben