Ist meine Jump and Run Engine zu genau?

TimeIsTheKey

Aktives Mitglied
Hallo

Wollte mal nachfragen, ob ich die Sache richtig angehe oder etwas verbessern könnte, um keine Performance-Probleme zu bekommen. Lest euch bitte meine Vorgehensweise durch und gebt mir Kritik. Bräuchte das dringend.

Ich bin zurzeit an einer Jump and Run-Engine dran und habe gerade mit der Gravitation angefangen. Ich arbeite mit JPanels (jedes Objekt das angezeigt wird, hat eins) und habe eine Klasse geschrieben die stets als Superklasse verwendet wird. Ich habe mir überlegt, dass jeder neue Akteur eine eigene Unterklasse besitzen soll (z.B. Hintergrund, Spieler, Gegner, Hintergrundeffekte ect.). Der Grund dafür ist, dass später alle Akteure ihre eigene move-Methode und sonstige spezielle Attribute haben und ich, falls nötig, jedem Akteur eine KI verpassen könnte.
Jeder Akteur besitzt eine Geschwindigkeit (speed) und ein Gewicht (mass) welches für die Bewegung und Gravitation sehr wichtig ist. In der Hauptklasse ist eine run-Methode, in der ich im Moment nur ständig die run-Methode aller Akteure aufrufe.

Die Bewegung und Gravitation ist nun die Hauptthematik die mich interessiert. Bevor ich die Akteure bewege lasse ich sie nach der Geschwindigkeit (speed) sortieren, weil ich eine Problematik umgehen möchte. Die möchte euch anhang dieser Grafik zeigen:

http://img690.imageshack.us/img690/1006/prob1j.png

Die einzelnen Felder sollen Pixel oder Steps darstellen. Angenommen 1 und 2 werden bei einer Kollision mit 3 verschwinden und das 1 eine Geschwindigkeit von 6 hat und 2 eine von 3. 3 bewegt sich nicht und verschwindet auch, sobald es getroffen wird. Ohne die Sortierung könnte es passieren, dass fälschlicherweise das Objekt 2 verschwindet, obwohl logisch gesehen das Obekt 1 verschwinden müsste.

Nach der Sortierung bewege ich die Akteure der Reihe nach pixelweise. Es wird eine Schleife durchgegangen die x-mal durchläuft. X ist die höchste vorhandene Geschwindigkeit. Die Akteure schauen selbst, ob sie eine Bewegung machen dürfen oder ob sie sich schon zu Ende bewegt haben. Nachdem sich ein Akteur bewegt, wird überprüft, ob es irgend einen anderen Akteur berührt (Kollision). Nach jedem Schleifendurchgang wird eine Methode aufgerufen, die für die Gravitation zuständig ist. Für die Bewegung spielt es eine Rolle was für ein Speed/Mass-Verhältnis besteht. Ist dieses nicht gleich, wird jeweils berechnet, ob der Akteur überhaupt bewegt werden darf. Hat nämlich ein Akteur mehr Speed als Mass, so darf es die Bewegung immer machen und es wird berechnet, ob die Gravitationseinwirkung schon erfolgen darf. Ein Beispiel um das zu verständlicher zu machen:

Hat ein Akteur bei Speed 8 und bei Mass 5, so wird es 8 Schritte geben, die pixelweise erfolgen. Bei jedem move-Befehl, darf er sich bewegen, weil der Speed grösser ist. Bei Mass wird zuerst noch berechnet, ob er sich neu bewegen darf (er dürfte nur beim 2., 4., 5., 7. und 8. Step eine Gravitationseinwirkung erfolgen lassen).

Ist Mass grösser, läuft das gleiche Spiel mit Speed ab, einfach umgekehrt.

Meine Hauptproblematik ist, dass ich nicht weiss, ob das zu viel Performance schluckt und ob das überhaupt so genau durchgesetzt werden sollte. Das ist ziemlich viel Text, aber ich wollte versuchen, meine Überlegungen mit euch zu teilen und Verbesserungsmöglichkeiten von euch einfliessen lassen. Wer den ganzen Code sehen möchte, muss das nur sagen. Ich mache ihn nur ungerne öffentlich, weswegen ich es den Personen jeweils per PN schicken werde. Nur so als kleine Vorwarnung: Die Gravitation funktioniert noch nicht (Bug), aber sie kann leicht ausgeschaltet werden.

Würde mich sehr freuen, wenn ein erfahrener Programmierer sich die Zeit nehmen würde mir Kritik zu geben.
 
Zuletzt bearbeitet:

schlingel

Gesperrter Benutzer
Ich arbeite mit JPanels (jedes Objekt das angezeigt wird, hat eins) und habe eine Klasse geschrieben die stets als Superklasse verwendet wird.

Nein! Mach das bloß nicht so. Wenn du schon mit Swing für ein Spiel hernehmen möchtest, dann zeichne deine Objekte auf ein einziges Canvas. Die Lösung mit den JPanels frisst auf jeden Fall unnötig Ressourcen.

Ich habe mir überlegt, dass jeder neue Akteur eine eigene Unterklasse besitzen soll (z.B. Hintergrund, Spieler, Gegner, Hintergrundeffekte ect.). Der Grund dafür ist, dass später alle Akteure ihre eigene move-Methode und sonstige spezielle Attribute haben und ich, falls nötig, jedem Akteur eine KI verpassen könnte.

Du hast offensichtlich für alle diese Objekte eine Basisklasse und das wäre Akteur. Warum hier künstlich weitere Kindklassen einführen? Es würde sich z.B. anbieten mit dynamischen Binden die Kontrolle eines Objektes zu regeln und nicht über Vererbung.

Die einzelnen Felder sollen Pixel oder Steps darstellen. Angenommen 1 und 2 werden bei einer Kollision mit 3 verschwinden und das 1 eine Geschwindigkeit von 6 hat und 2 eine von 3. 3 bewegt sich nicht und verschwindet auch, sobald es getroffen wird. Ohne die Sortierung könnte es passieren, dass fälschlicherweise das Objekt 2 verschwindet, obwohl logisch gesehen das Obekt 1 verschwinden müsste.

Ehrlich gesagt sehe ich auch nach mehrmaligen Lesen das Problem nicht. Wenn ein Objekt langsamer ist bewegt es sich einfacher weniger weit pro Tick. (Siehe z.B. XNA als Beispiel wie das gelöst wird.)

Nach der Sortierung bewege ich die Akteure der Reihe nach pixelweise. Es wird eine Schleife durchgegangen die x-mal durchläuft. X ist die höchste vorhandene Geschwindigkeit. Die Akteure schauen selbst, ob sie eine Bewegung machen dürfen oder ob sie sich schon zu Ende bewegt haben. Nachdem sich ein Akteur bewegt, wird überprüft, ob es irgend einen anderen Akteur berührt (Kollision). Nach jedem Schleifendurchgang wird eine Methode aufgerufen, die für die Gravitation zuständig ist. Für die Bewegung spielt es eine Rolle was für ein Speed/Mass-Verhältnis besteht. Ist dieses nicht gleich, wird jeweils berechnet, ob der Akteur überhaupt bewegt werden darf. Hat nämlich ein Akteur mehr Speed als Mass, so darf es die Bewegung immer machen und es wird berechnet, ob die Gravitationseinwirkung schon erfolgen darf. Ein Beispiel um das zu verständlicher zu machen:

Hat ein Akteur bei Speed 8 und bei Mass 5, so wird es 8 Schritte geben, die pixelweise erfolgen. Bei jedem move-Befehl, darf er sich bewegen, weil der Speed grösser ist. Bei Mass wird zuerst noch berechnet, ob er sich neu bewegen darf (er dürfte nur beim 2., 4., 5., 7. und 8. Step eine Gravitationseinwirkung erfolgen lassen).

Prinzipiell halte ich es schon für fragwürdig dass du an einer Stelle eine Schleife einbaust an der eine Formel genügen sollte. Noch dazu sehe ich hier auch nicht den Sinn. Was spricht dagegen dein Physikbuch aufzuschlagen dir die Formel dort rauszusuchen und die einzubauen anstatt hier eine Schleife zu verwenden?
 

TimeIsTheKey

Aktives Mitglied
Nein! Mach das bloß nicht so. Wenn du schon mit Swing für ein Spiel hernehmen möchtest, dann zeichne deine Objekte auf ein einziges Canvas. Die Lösung mit den JPanels frisst auf jeden Fall unnötig Ressourcen.

Okay. Also einfach in der run-Methode eine draw-Methode einbauen, die alles zeichnet.

Du hast offensichtlich für alle diese Objekte eine Basisklasse und das wäre Akteur. Warum hier künstlich weitere Kindklassen einführen? Es würde sich z.B. anbieten mit dynamischen Binden die Kontrolle eines Objektes zu regeln und nicht über Vererbung.

Ich glaube ich habe es schon so implementiert, wie du es meinst. Da gibt es eine Basisklasse (heisst bei mir AnimatedSprite) und diese ist abstract (move mit und ohne Parameter sind abstrakt). Dann habe ich weitere Klassen die von AnimatedSprite erben. In diesen werden die Methode ausprogrammiert. In einer for-Schleife gehe ich dann ein ArrayList durch die mit AnimatedSprites gefüllt ist (eigentlich Refferenzen der Akteure) und greife auf die abstrakte Methode zu. Ist doch so programmiert, wie du es meinst, oder?

Ehrlich gesagt sehe ich auch nach mehrmaligen Lesen das Problem nicht. Wenn ein Objekt langsamer ist bewegt es sich einfacher weniger weit pro Tick. (Siehe z.B. XNA als Beispiel wie das gelöst wird.)

Naja. Die Problematik ist nicht so gross. Falls 1 links von 3 und 2 rechts von 3 ist und beide nur noch 1 Feld brauchen um 3 zu berühren, taucht diese "Problematik" auf. Logisch gesehen muss 1 zuerst 3 berühren, weil die Geschwindigkeit höher ist.

Prinzipiell halte ich es schon für fragwürdig dass du an einer Stelle eine Schleife einbaust an der eine Formel genügen sollte. Noch dazu sehe ich hier auch nicht den Sinn. Was spricht dagegen dein Physikbuch aufzuschlagen dir die Formel dort rauszusuchen und die einzubauen anstatt hier eine Schleife zu verwenden?

Der Sinn ist irgendwie schwer in Worte festzuhalten. Es wäre einfacher wenn ich es dir an einem Blatt zeigen könnte, aber ich versuche es mit Sätzen. Das Problem ist nicht die Formel (berechne ich schon). Damit meine Akteure sich nicht teleportieren (z.B. wenn der Speed 10 betragen würde) und auch keine Kollision verpassen (z.B. falls in diesen 10 Pixeln ein Akteur wäre), gehen sie jedes Pixel während ihrer Bewegung durch. Dabei wird auch die Geschwindigkeit der anderen Akteure in Betracht gezogen. Das erste was beachtet wird, ist wieviele Schritte gemacht werden. Falls der höchste Speed 6 ist, darf ein Akteur mit einem Speed von 3 nur bei jedem 2. Step eine Bewegung machen. Bis hier sollte es noch verständlich sein. Mir fällt auf, dass ich es ein bisschen falsch implementiert habe, aber das lässt sich leicht beheben.
Nun kommt aber noch die Gravitation dazu. Angenommen ein Akteur hat 8 Speed und 5 Mass (in diesem Beispiel ist die Gravitation auf 1 gesetzt). Würde sich der Akteur in der Luft nun nach rechts bewegen, dürfte er nicht nach jedem Step 1 nach runter gehen, sondern berechnen, wann er 1 nach unten gezogen werden kann. Hier ein Beispiel wie sich der Akteur bewegen würde:

http://img88.imageshack.us/img88/1702/prob2d.png

Hoffe man sieht was ich meine.
 

schlingel

Gesperrter Benutzer
Okay. Also einfach in der run-Methode eine draw-Methode einbauen, die alles zeichnet.
Das ist auch der falsche Weg. Das Objekt sollte sich nicht selbst zeichnen sondern es sollte alles von einer zentralen Stelle ausgehen. Ein gutes Beispiel ist da XNA da hier das Framework das ganze so vorgibt.

Es gibt eine Methode die wird jeden Tick aufgerufen und dient dir dazu die Kalkulationen in deinen Objekten durchzuführen. Diese Methode gibt dir die Info mit wieviel Zeit seit dem letzten Methodenaufruf vergangen ist damit du weißt wie weit sich deine Objekte bewegen sollen.

In einer zweiten Methode, die ebenfalls periodisch aufgerufen wird, zeichnest du. Aber tatsächlich nur zeichnen. Du rufst von jedem Objekt seine Position auf und das aktuelle Bild welches du aus dem SpriteBatch zeichnen musst.

Ich glaube ich habe es schon so implementiert, wie du es meinst
Ich glaube nicht. Es reicht wenn du eine Klasse hast die, die Infrastruktur für das Sprite-Zeichnen und das Bewegen zur Verfügung stellt. Diese Klasse wird dann intern über irgend eine Logik gesteuert. Genau diese Logik sollte austauschbar sein. Dadurch verändert sich dann das Verhalten deines Akteurs.

Generell sehe ich aber keinen Grund den Code der zeichnet und sonstige infrastrukturelle Angelegenheiten kalkuliert und den Code der das Objekt im Spiel beschreibt zu vermischen. Dafür bietet sich das Strategy Pattern bzw. Dynamisches Binden an.

Zu deiner Physikberechnung: Ich glaube mittlerweile verstanden zu haben wie du das meinst und ich glaube dass die Idee richtig ist. Doch sollte die zeit- bzw. wegabhängige Kalkulation nicht relativ vom jeweiligen Objekt sondern zentral vom Spiel bestimmt werden. Das heißt jeden Tick sollte für alle Objekte kalkuliert werden wo sie sich aktuell befinden und wie die Masse/Geschwindigkeit sich verändert hat.
 

TimeIsTheKey

Aktives Mitglied
Das ist auch der falsche Weg. Das Objekt sollte sich nicht selbst zeichnen sondern es sollte alles von einer zentralen Stelle ausgehen. Ein gutes Beispiel ist da XNA da hier das Framework das ganze so vorgibt.

Es gibt eine Methode die wird jeden Tick aufgerufen und dient dir dazu die Kalkulationen in deinen Objekten durchzuführen. Diese Methode gibt dir die Info mit wieviel Zeit seit dem letzten Methodenaufruf vergangen ist damit du weißt wie weit sich deine Objekte bewegen sollen.

In einer zweiten Methode, die ebenfalls periodisch aufgerufen wird, zeichnest du. Aber tatsächlich nur zeichnen. Du rufst von jedem Objekt seine Position auf und das aktuelle Bild welches du aus dem SpriteBatch zeichnen musst.

Ich habe mir das XNA noch nicht angeschaut, aber ich werde es nachholen. Eigentlich hatten wir aber beide genau das Gleiche gemeint. Meine Mainklasse hat die Schnittstelle Runnable und somit die run-Methode implementiert. Die würde dann so aussehen:

Code:
public void run(){
		while(game_running){
			if(!break){
				moveObjects();
                                drawObjects();
				repaint();
			}
			try {
				Thread.sleep(speed);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
}

Das mit der Zeit ist schon eingebaut. Die Akteure haben individuelle Wartezeiten und die Akteure werden sich nur bewegen, wenn sie ihre Wartezeit abgesessen haben.

Ich glaube nicht. Es reicht wenn du eine Klasse hast die, die Infrastruktur für das Sprite-Zeichnen und das Bewegen zur Verfügung stellt. Diese Klasse wird dann intern über irgend eine Logik gesteuert. Genau diese Logik sollte austauschbar sein. Dadurch verändert sich dann das Verhalten deines Akteurs.

Generell sehe ich aber keinen Grund den Code der zeichnet und sonstige infrastrukturelle Angelegenheiten kalkuliert und den Code der das Objekt im Spiel beschreibt zu vermischen. Dafür bietet sich das Strategy Pattern bzw. Dynamisches Binden an.

Hmmm... Bin mir nicht sicher, ob das "dynamisch gebunden" ist, aber ich schätze (zwar ohne überschreiben, aber macht keinen grossen Unterschied):


Code:
public abstract class Sprite extends JPanel implements Comparable<Object>{

	public abstract void moveSprite(int x, int y);
	public abstract void moveSprite();

}

Code:
public class Player extends Sprite {

public void moveSprite(int x, int y) { ... }
public void moveSprite() { ... }

}

Code:
public void moveObjects(){
...
for(Sprite sprites: spritelist){
	sprites.moveSprite();
}
...
}

Zu deiner Physikberechnung: Ich glaube mittlerweile verstanden zu haben wie du das meinst und ich glaube dass die Idee richtig ist. Doch sollte die zeit- bzw. wegabhängige Kalkulation nicht relativ vom jeweiligen Objekt sondern zentral vom Spiel bestimmt werden. Das heißt jeden Tick sollte für alle Objekte kalkuliert werden wo sie sich aktuell befinden und wie die Masse/Geschwindigkeit sich verändert hat.

Hast recht. Im Moment gebe ich den Befehl sich zu bewegen und überprüfe erst dann, ob überhaupt zum aktuellen Tick eine Bewegung gemacht werden muss. Das Gleiche werde ich mit der Gravitation machen. Sollte den Ablauf verschnellern und mir die Programmierung erleichtern. Danke!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Meine Erfahrung und mein Tipp Spiele- und Multimedia-Programmierung 4
coolian meine funktion um die höhe des terrains an bestimmter position in diesem fall spieler position zu bekommen giebt nur 0 zurück Spiele- und Multimedia-Programmierung 6
K Wie mache ich meine HP vertrauenswürdig ? Spiele- und Multimedia-Programmierung 22
F Meine Aufgabe: Client-Server am Beispiel einer Implementation eines Tic-Tac-Toe Netzwerkspieles Spiele- und Multimedia-Programmierung 7
K Mein Jump and Run charakter bewegt sich nicht mehr rückwärts... Spiele- und Multimedia-Programmierung 0
E Möchte Jump and Run programmieren Spiele- und Multimedia-Programmierung 2
N Jump and run Spiel - wo anfangen / weitermachen? Spiele- und Multimedia-Programmierung 11
F Jump'n Run Background wiederholen Spiele- und Multimedia-Programmierung 3
E Java Jump and Run Map zu groß Spiele- und Multimedia-Programmierung 14
S Jump 'n' Run-Spiel Kollisionserkennung Spiele- und Multimedia-Programmierung 3
Finalspace Entwicklung eines Jump & Run Spiels Video-Tutorial Spiele- und Multimedia-Programmierung 12
C Doodle Jump Sprung Physik? Spiele- und Multimedia-Programmierung 4
M Jump 'n' Run Game - Blöcke? Spiele- und Multimedia-Programmierung 7
N Problem mit Kollisionsabfrage beim Fallen Jump & Run Spiele- und Multimedia-Programmierung 5
M Empfehlungen für ein 2D-Jump'n'run Spiele- und Multimedia-Programmierung 4
W Doodle Jump Spiele- und Multimedia-Programmierung 6
H Jump&Run Tutorial Spiele- und Multimedia-Programmierung 3
D Jump'n'run Kollision bei Blöcken Spiele- und Multimedia-Programmierung 10
K Jump'N'Run Hügel Spiele- und Multimedia-Programmierung 11
T Jump and Run - Unklarheiten Spiele- und Multimedia-Programmierung 5
Arcus Jump and Run etwas komplizierter - Benötige Starthilfe Spiele- und Multimedia-Programmierung 12
N Grundlagen für ein Jump&Run Spiele- und Multimedia-Programmierung 3
F "Doodle Jump" Projekt Spiele- und Multimedia-Programmierung 8
U Jump n' Run 2D Geometrie und Kollisionsabfrage? Spiele- und Multimedia-Programmierung 11
L Jump-n-Run Auslastung verringern Spiele- und Multimedia-Programmierung 16
Apo Kollisionserkennung bei Jump'n'Run Spiele- und Multimedia-Programmierung 69
F jump and run idee Spiele- und Multimedia-Programmierung 2
T Umsetzung eines 2D Jump and Runs Spiele- und Multimedia-Programmierung 7
K Jump n Run Keylistener und Schleifen Spiele- und Multimedia-Programmierung 8
F DJADD Jump and Run Spiele- und Multimedia-Programmierung 10
D Jump 'n run die 2. [spielerbewegen mit zeit] Spiele- und Multimedia-Programmierung 6
D Jump and Run Game -- Kollisionsabfrage Spiele- und Multimedia-Programmierung 30
S Kollisionsprob bei Jump&Run Spiele- und Multimedia-Programmierung 9
S Jump'n'Run: Probleme mit Kollision Spiele- und Multimedia-Programmierung 13
C 3d Engine : Fragment Shader , aber wie? Spiele- und Multimedia-Programmierung 17
C 3d Game Engine : PERFORMANTE Räumliche Verdeckung Spiele- und Multimedia-Programmierung 5
C Eine eigene 3d Engine : Shader - aber wie ? Spiele- und Multimedia-Programmierung 2
E 3D Engine Spiele- und Multimedia-Programmierung 5
R Vererbbarer GameLoop für Engine Spiele- und Multimedia-Programmierung 14
V Suche 2D Engine Spiele- und Multimedia-Programmierung 11
S Engine2D - Java 2D Engine Spiele- und Multimedia-Programmierung 20
D Physik Engine und Collision Spiele- und Multimedia-Programmierung 5
R Ratschlag für 2D-3D Engine für die Spieleentwicklung gesucht Spiele- und Multimedia-Programmierung 4
M [JME3] Jmonkey Engine und Wavefront import aus Blender Spiele- und Multimedia-Programmierung 3
K Einfache Engine für einfaches 3D gesucht Spiele- und Multimedia-Programmierung 10
N Eigene Java 3D Engine erstellen. Spiele- und Multimedia-Programmierung 11
K Game Engine für selbstprogrammiertes Spiel Spiele- und Multimedia-Programmierung 27
Luk10 Tipps für bessere Animationen / Grafik Engine Spiele- und Multimedia-Programmierung 2
X Möglichst komplette 2D Game Engine? Spiele- und Multimedia-Programmierung 12
J 2D-Game-Engine? Spiele- und Multimedia-Programmierung 2
N 1600 Zeilen Engine Spiele- und Multimedia-Programmierung 23
R Physics Engine benutzen Spiele- und Multimedia-Programmierung 11
Steev EGE - Easy Game Engine Spiele- und Multimedia-Programmierung 2
Developer_X Java Mokey Engine Spiele- und Multimedia-Programmierung 7
G kleine "2d" Physik Engine Spiele- und Multimedia-Programmierung 3
M Gibt es ein deutsches Board für die jmonkey engine? Spiele- und Multimedia-Programmierung 7
Landei jMonkeyEngine als 3D Engine Spiele- und Multimedia-Programmierung 12
R Grafik-Engine? MemoryImageSource? Spiele- und Multimedia-Programmierung 10
U 3D Engine und anderes Spiele- und Multimedia-Programmierung 4
sparrow 3D-Game-Engine Spiele- und Multimedia-Programmierung 20
M Welche ist die beste Java3D-Engine Spiele- und Multimedia-Programmierung 15
B Schnelle 3D-Engine gesucht Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben