Spiele programmieren mit Lazarus, Java und Python

Ähnliche Dokumente
Einbindung der Tastatur

JButton, JCheckBox, JRadioButton. Programmieren II. Vorlesung 7. Handout S. 1. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester 2009.

Jetzt sollt ihr von der Vorlage der Grundversion 1.0 ein eigenes Textadventure erstellen.

Universität Paderborn Prof. Dr. Stefan Böttcher. Kapitel 3: Java Applets

Tetris soll als Computerspiel mittels Java realisiert werden, wobei ein objektorientierter Ansatz gewählt

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 7. Grafische Benutzeroberflächen

Simulation von digitalen Schaltungen

Einführung in die Programmierung für NF. Übung 08

NTB Druckdatum:

Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer. Programmiertechnik GUI-Programmierung mit Swing

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Programmierung mit Delphi

Java I Vorlesung 11 Graphische Oberflächen mit Swing

AK-Automatisierungs und Kommunikationstechnik TI Technische Informatik. NWT Netzwerktechnik

Schritt 1 - Ein Spielfeld

Programmierung in Delphi

Abteilung Informatik, JFC/Swing 2004 Diego Schmidlin V2.2

DHBW Karlsruhe, Vorlesung Programmieren, Events Musterlösung

Programmieren II. Java im Vergleich zu anderen Sprachen. Einführung: GUI. Einführung: Grafische Benutzeroberflächen. Dr.

Institut für Informatik

Man kann bei der Deklaration einen Wert der Variablen angeben oder später den Wert zuweisen. Beide Befehlsfolgen leisten dasselbe:

Applets Belebung von Webseiten. Dipl.-Ing. Wolfgang Beer

Probeklausur: Programmierung WS04/05

Java Kurzreferenz Für Fortgeschrittene

Einstieg in die Informatik mit Java

GUI Programmierung mit JAVA Swing

GUI Programmierung in Java

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Abteilung Informatik, JFC/Swing 2004 Diego Schmidlin V2.2

Java Game Development Fabian Birzele Programmierpraktikum 2008 / 2009

6. Grafikprogrammierung

Projekt Informatik: Programmieren einer selbstgewählten Anwendungssoftware. Jenny Förster Susann Lorenz

Probeklausur: Programmierung WS04/05

Ziel dieses Kapitels: Einführung in die Grundzüge der Programmierung graphischer Benutzeroberflächen (engl.: "graphical user interface", GUI) in Java

1.2 Attribute und Methoden Aufbau einer Java-Klasse:

Drucken soll nur das Panel, nicht der ganze Rahmen gedruckt werden.

Swing :Komponenten I (Teil 2)

Algorithmen und Datenstrukturen

Hochschule der Medien Prof. Uwe Schulz 14. Juli 2010 Klausur Informatik, EDV-Nr Seite 1 von 5. Teil 2: Aufgaben

Ab jetzt: Java ohne Kara

LWB VIII. Programmieren mit Delphi Zur Laufzeit verwaltete Objekte. Zur Laufzeit verwaltete Objekte. Am Beispiel des bekannten Memory-Spieles

Swing Lernen am Code Teil 1

Einführung in die Informatik - Teil 4b - Zeichnen mit der Maus im JBuilder

Handbuch für die Erweiterbarkeit

Programmierkurs Java

Fenster in Java. von Stefanie Gerckens 1

Lösungen. 1. Aufgabe. // ActionExample.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.

Objektorientierte Software-Entwicklung

Zentrale Objekte zur Programmierung graphischer Benutzeroberflächen (GUI)

Grundlagen der Programmierung APPLETS

3 Objektorientierte Konzepte in Java

Liste Programmieren Java Überblick

Graphische Benutzungsoberflächen mit Java. Einführung in NetBeans

Graphische Benutzungsoberflächen

Interaktive Elemente, GUI-Programmierung

Graphic Coding. Klausur. 9. Februar Kurs A

Tutorial04: Swing: Erstellen eines JFrames mit einem JSplitPane

Klausur in 12.1 Themen: Zahlsysteme, Grundlagen von Delphi (Bearbeitungszeit: 90 Minuten)

Objektorientierte Programmierung

Java Schulung (Java 2 Java Development Kit 5 / 6)

Einstieg in die Informatik mit Java

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

6 Speicherorganisation

Programmieren 2 Selbststudium Semesterwoche 4

Graphische Programmierung: GUIs: graphical user interfaces

Java Einführung Abstrakte Klassen und Interfaces

Kapitel 6. Vererbung

Python - Grafische Oberflächen mit TKinter erstellen

Delphi DLL Tutorial Wie exportiere ich Komponenten aus einer DLL?

Container-Klassen in Delphi

Einführung in Javadoc

Problemdefinition. Datum 26.Oktober Projektbezeichnung Softwareversion von Würfelpoker

1. Typen und Literale (6 Punkte) 2. Zuweisungen (6 = Punkte)

Kapitel 6. Vererbung

Ein Manager mit CardLayout layout/cards.java

4 Codierung nach Viginere (Lösung)

Grafikausgabe mit dem Abstract- Windowing-Toolkit. Eine Einführung

Objektorientierte Programmierung

5.4 Klassen und Objekte

Komponente PortIO für Delphi 5.0

5.14 Generics. Xiaoyi Jiang Informatik I Grundlagen der Programmierung

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Wiederholung: Interfaces

II.3.1 Rekursive Algorithmen - 1 -

Theorie zu Übung 8 Implementierung in Java

Kapitel 6. Vererbung

Programmieren in Java

Übungen zur Android Entwicklung

import java.awt.*; import java.awt.event.*; import javax.swing.*;

von Anja Austermann Drag and Drop

Transkript:

Spiele programmieren mit 1. Einsatz eines Timers... 2 2. Kollision zweier Objekte... 3 3. Einbinden von Bildern für Spieler- oder Gegenspielerfiguren... 5 4. Bewegungen von Objekten (z.b. Bildern)... 6 5. Tastatureingaben und virtuelle Tastencodes... 7 6. Listenverarbeitende visuelle Komponente (ListBox)... 8 7. Mausclicks auf visuelle Komponenten... 9 1

1. Einsatz eines Timers Timersymbol in der Reiterleiste und Timerprozedur Timer an: Timer aus: Timer1.enabled := true; Timer1.enabled := false; I) Implementieren des Timers In gibt es (meines Wissens) keine Klasse für einen Timer. Hier muss ein wenig "getrickst" werden, indem eine normale Prozedur ich nenne sie "Timer"- definiert wird, die sich wieder rekursiv zeitverzögert aufruft. Die Prozedur 'after' des Fensterobjekts, die zeitverzögert eine Prozedur aufrufen kann, ist hier dienlich. Gestartet wird der Timer über den "after"-aufruf in der GUI. def Timer(): Fenster.after(500, Timer) #GUI Fenster = tkinter.tk() Fenster.after(50, Timer) II) An- und Ausschalten des Timers Das An- und Ausschalten des Timers kann über eine boolesche Variable geregelt werden. timeron = True timeron = False def Timer(): if (timeron == True): Fenster.after(500, Timer) #GUI Fenster = tkinter.tk() I) Implementieren des Timers Für den Timer gibt es mehrer Klassen. Wir können den Timer der javax.swing nehmen. Wir der Timer nicht explizit importiert, kann es zu einer Fehlermeldung kommen, da in der java.awt auch ein Timer implementiert ist. import javax.swing.timer; Timer t; ActionListener TimerProzedur = new ActionListener() { public void actionperformed (ActionEvent evt) { t = new Timer(500, TimerProzedur); II) Ein- und Ausschalten des Timers t.start(); t.stop(); 2

2. Kollision zweier Objekte Der Ursprung des Bildschirmkoordinatensystems liegt oben links und geht auf x- und y- Achse in den positiven Bereich. Objekt2 kollidiert mit Objekt1, wenn es gleichzeitig in den horizontalen Schraffurbereich und in den vertikalen Schraffurbereich des Objekts1 hineinragt. Objekt1.top Objekt2.top Objekt1.left Objekt1 Objekt2.left Objekt2 Objekt2.height Objekt2.height Objekt1.getY() Objekt2.getY() Objekt1.getX() Objekt1 Objekt2.getX() Objekt2 Objekt2.getHeight() Objekt2.getWidth() 3

Die Funktion bbox liefert ein 4-Tupel, das die linke obere und die rechte untere Ecke des Rahmens eines Objekts (x1, y1, x2, y2) beinhaltet a = canvas.bbox(objekt1) b = canvas.bbox(objekt2) a[1] b[1] a[0] Objekt1 b[0] Objekt2 b[3]-b[1] b[2]-b[0] Damit sieht die Kollisionsabfrage so aus: function testekollision: boolean; begin result := false; if (objekt1.top < objekt2.top + objekt2.height) and (objekt1.top + objekt1.height > objekt2.top) and (objekt1.left < objekt2.left + objekt2.width) and (objekt1.left + objekt1.width > objekt2.left) then result := true; end; def testekollision(): Rueckgabe = False a = canvas.bbox(objekt1) b = canvas.bbox(objekt2) if ((a[1]<b[3]) and (a[3]>b[1]) and (a[2]>b[0]) and (a[0]<b[2])): Rueckgabe = True return Rueckgabe public boolean testekollision() { boolean Ergebnis = false; if ((objekt1.gety() < (objekt2.gety() + objekt2.getheight())) & ((objekt1.gety() + objekt1.getheight()) > objekt2.gety()) & (objekt1.getx() < objekt2.getx() + objekt2.getwidth()) & (objekt1.getx() + objekt1.getwidth() > objekt2.getx())){ Ergebnis = true; return Ergebnis; 4

3. Einbinden von Bildern für Spieler- oder Gegenspielerfiguren --> Image-Komponente Bild laden über die Eigenschaft: Picture Ladedialog Bild proportional darstellen über Eigenschaft: proportional := true I) Neue Klasse für die Bildanzeige Zur Darstellung von Bildern definiert man am Besten eine neue Klasse "Bildanzeige", die von einer bilddarstellungsfähigen Klasse abgeleitet wird (Canvas oder JPanel). Die Funktion "anzeigen" kann neue Bilder zur Laufzeit laden. // externe Klasse, um Bilder im Formular anzuzeigen import java.awt.*; public class Bildanzeige extends Canvas { private Image Image1 = null; Bildanzeige( String s ) { Image1 = Toolkit.getDefaultToolkit().getImage( s ); // Objekt Image1 vom Typ Image enthält die Grafik-Ressource if (Image1!= null) repaint(); // Grafik wird neu gezeichnet public void paint( Graphics g ) { g.drawimage(image1, 0, 0, this ); public void anzeigen (String s) { Image1.flush(); // Bild freigeben Image1 = Toolkit.getDefaultToolkit().getImage( s ); if (Image1!= null) repaint(); // Ende der Klasse "Bildanzeige" II) Bild im Formular anlegen Ein erzeugtes Objekt vom Typ "Bildanzeige" kann nun im Frame angezeigt werden. public Bildanzeige a = new Bildanzeige("FlappyBirdGif.gif"); a.setbounds(100, 300, 51, 36); cp.add(a); 5

Ähnlich wie bei muss ein Image in ein Objekt vom Typ PhotoImage geladen werden, um dann auf einer Zeichenfläche (canvas) angezeigt zu werden. Als Formate sind neben gif und pgm angeblich noch jpg möglich. #GUI Bild = tkinter.photoimage(file="flappybirdgif.gif") canvas=tkinter.canvas(fenster, width=600, height=600, bg='white') canvas.pack() b = canvas.create_image(200,300,image=bild, anchor=tkinter.nw) 4. Bewegungen von Objekten (z.b. Bildern) In können die Attribute left und top direkt verändert werden. Objekt1.left := Objekt1.left + 10; Objekt1.top := Objekt1.top -20; Hier können die Koordinaten der linken oberen Ecke x und y ausgelesen und über "setlocation()" neu belegt werden. objekt1.setlocation(objekt1.getx()+10, objekt1.gety()-20); Wenn Images (oder andere Komponenten) in einem Fenster erstellt werden, so werden sie intern durchnummeriert. Mit der Nummer kann das entsprechende Objekt relativ zu seiner aktuellen Position bewegt werden. canvas.create_image(200,yposition,image=bild, anchor=tkinter.nw) canvas.move(1,10,-20) Hier wird das erste erstellte Objekt unser Bild- um 10 in x-richtung und um -20 in y- Richtung bewegt. Das Arbeiten mit diesen Nummern ist allerdings sehr unsicher, da die Nummern in Erstellreihenfolge der Objekte angelegt werden. Vertauscht sich da was, ist alles hin. Um diese Unsicherheit mit den Nummern zu umgehen, sollte eine Referenz auf das Bild angelegt werden: Bild = tkinter.photoimage(file="flappybirdgif.gif") b = canvas.create_image(200,200,image=bild, anchor=tkinter.nw) canvas.move (b, 10, -20) 6

5. Tastatureingaben und virtuelle Tastencodes Um Tastatureingaben abzufangen, sollte zunächst das Formularattribut "keypreview" auf true gesetzt werden. procedure TForm1.FormCreate(Sender: TObject); begin Form1.KeyPreview:=true; end; In der Unit LCLType sind die sog. virtuellen Tastencodes enthalten, die in der FormKeyDown in der Referenzvariablen Key bei Tastendruck abgefangen und abgefragt werden können. uses LCLType; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_UP : // Pfeil hoch VK_RIGHT : // Pfeil rechts VK_DOWN : // Pfeil unten VK_LEFT : [... ] // Pfeil links VK_SPACE : // Leertaste end; end; Um Tastatureingaben auf z.b. der Canvas abzufangen, sollte zunächst der Fokus auf das Canvas gesetzt werden. canvas1.requestfocus(); In der Klasse "KeyEvent" sind die sog. virtuellen Tastencodes enthalten, die in einem KeyListener bei Tastendruck über "getkeycode()" abgefangen und abgefragt werden können. canvas1.addkeylistener(new KeyAdapter() { public void keypressed(keyevent evt) { canvas1_keypressed(evt); if (evt.getkeycode() == KeyEvent.VK_RIGHT ) { //Pfeil hoch else if (evt.getkeycode() == KeyEvent.VK_LEFT ) { // Pfeil rechts else if (evt.getkeycode() == KeyEvent.VK_UP ) { // Pfeil hoch else if (evt.getkeycode() == KeyEvent.VK_DOWN ) { //Pfeil unten repaint(); ); 7

Ereignisse (Tastenereignisse/ Mausereignisse) können an eine Komponente "gebunden" werden. Bei der Bindung wird der Verbindung Komponente-Taste eine Prozedur zur Ausführung zugeordnet. def rechts (event): def links (event): def hoch(event): def runter(event): #GUI Fenster = tkinter.tk() Fenster.bind("<KeyPress-Left>", links) Fenster.bind("<KeyPress-Right>", rechts) Fenster.bind("<KeyPress-Down>", runter) Fenster.bind("<KeyPress-Up>", hoch) #GUI ENDE 6. Listenverarbeitende visuelle Komponente (ListBox) Komponente: ListBox I) Markierte Zeilennummer auslesen: procedure TForm1.ListBox1Click(Sender: TObject); var index : Integer; begin index := ListBox1.ItemIndex+1; // Nummer fängt bei 0 an end; II) Markierten Text auslesen: s := Listbox1.GetSelectedText; III) Befüllen: ListBox1.Items.append('Beispiel'); Hier kann die Klasse "JList" als Liste benutzt werden. Um eine Liste zu befüllen braucht es eine Adapter-Klasse ListModel. private JList jlist1 = new JList(); private DefaultListModel jlist1model = new DefaultListModel(); jlist1.setmodel(jlist1model); I) Eine Liste zu befüllen führt nun über den Adapter: 8

jlist1model.removeallelements(); jlist1model.addelement("beispieltext"); II) Das Auslesen der Nummer der geklickten Zeile: public void jlist1_mouseclicked(mouseevent evt) { int index = jlist1.getselectedindex(); Komponente: ListBox def Liste1Click(event): [... #GUI Liste1 = tkinter.listbox (width=30, height = 10) Liste1.bind('<<ListboxSelect>>', Liste1Click) # Die doppelten eckigen Klammern sind richtig I) Markierte Zeilennummer auslesen: def Liste1Click(event): Tupel = Liste.curselection() index = int(tupel[0]) II) Markierten Text auslesen: def Liste1Click(event): Tupel = Liste1.curselection() index = int(tupel[0]) s = Liste1.get(index) III) Befüllen: Liste1.delete("0","end") Liste1.insert(" Beispieltext")) 7. Mausclicks auf visuelle Komponenten Die Struktur der Ereignisprozeduren (hier: MouseDown) in erhält man am leichtesten, wenn man für eine entsprechende Beispielkomponente auf dem Formular die Prozedur auswählt und dann die Komponente und Sender: TObject weglässt: procedure TForm1.Button1MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 9

Bei abgeleiteten Komponenten wird einfach die MouseDown (oder eine andere) überschrieben. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure TMineButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); begin if button = mbleft then if button = mbright then In unserer -Version wird im Constructor einfach ein Mouse-Listener hinzugefügt, der bei mousepressed die Methode LinksClick() bzw. RechtsClick() aufruft. Die Maustasten werden durch das Attribut evt.ismetadown() == true unterschieden. True bei rechter Maustaste, false bei linker Maustaste. this.addmouselistener(new MouseAdapter() { public void mousepressed(mouseevent evt) { if (evt.ismetadown() == true) { //rechte Maustaste- bei false linke Maustaste RechtsClick(); else { LinksClick(); ); void LinksClick() { void RechtsClick() { Die Click-Methode muss bei separate als einfache Methode implementiert und über die Methode bind an das Mausereignis <ButtonPress-1> für die linke Maustaste bzw. <ButtonPress-3> für die rechte Maustaste gebunden werden. widget.bind(event, handler) linke Maustaste: <Button-1>, <ButtonPress-1> oder <1> mittlere Maustaste: <Button-2>, <ButtonPress-2> oder <2> rechte Maustaste <Button-3>, <ButtonPress-3> oder <3> linke Taste loslassen <ButtonRelease-1> Doppelclick <Double-Button-1> http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm def init (self, master): Label. init (self, master) self.bind(sequence="<buttonpress-1>", func=self.linksclick) self.bind(sequence="<buttonpress-3>", func=self.rechtsclick) 10