Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Java ::  Wie mache ich ein Spiel?     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 12:46:50 06.11.2011   Titel:   Wie mache ich ein Spiel?            Zitieren

Hall zusammen.
Ich programmiere gerade an einem Labyrinth-Spiel, welches Labyrinthe generiert, welche nachher gelöst werden können. Das ganze mache ich im Rahmen einer Prüfungsarbeit.

Wer sich den aktuellen stand des Labyrinthes angucken will, kann das hier anschauen. Das Programm wird als Applet gemacht.

Ich habe jetzt gerade angefangen die Game Engine zu schreiben, und bin schon auf das erste Problem gestossen: Wie kriege ich die fps raus???

Ich habe einen Timer, welcher möglichst oft eine Aktualisierung der game engine aufruft. In dieser Aktualisierung wird die Spielfigur bewegt und Kollisionsberechnungen etc. gemacht.
Damit das Spiel aber immer gleich schnell läuft, muss ich die fps rauskriegen um die Geschwindigkeit pro Sekunde zu erhalten.

Das ganze ist in 2D gehalten und dient nur dazu mich in die Materie zu vertiefen, es muss schlussendlich nicht unbedingt schön aussehen ;)

Wäre froh um etwas Unterstützung, da ich erst seit 4 Wochen mit Java arbeite und erst seit 2 Wochen an dem Projekt.

Grüsse
Chiller


Zuletzt bearbeitet von Chiller am 23:47:27 06.11.2011, insgesamt 1-mal bearbeitet
SideWinder
Moderator

Benutzerprofil
Anmeldungsdatum: 19.10.2001
Beiträge: 18220
Beitrag SideWinder Moderator 13:14:40 06.11.2011   Titel:              Zitieren

Statt einer FPS-Fixierung ist es geläufiger eine sogenannte Framebremse einzubauen. Das Stichwort sollte bei Google genügend Material ergeben.

MfG SideWinder

_________________
http://www.dilbert.com/2009-06-11/
http://www.dilbert.com/2009-06-14/
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 13:15:49 06.11.2011   Titel:              Zitieren

Baue einen Zähler ein, der bei jedem repaint hochzählt. Wenn (mindestens) eine Sekunde vergangen ist, weisst du wieviele Bilder pro Sekunde gezeichnet wurden. Der Zähler sollte dann wieder mit 0 initialisiert werden.
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 13:22:06 06.11.2011   Titel:              Zitieren

Steffo schrieb:
Der Zähler sollte dann wieder mit 0 initialisiert werden.

Ein Objekt wird nur 1 mal initialisiert. Und deine Methode ist unbrauchbar. Normalerweise misst man die Zeit.
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 13:40:01 06.11.2011   Titel:              Zitieren

314159265358979 schrieb:
Steffo schrieb:
Der Zähler sollte dann wieder mit 0 initialisiert werden.

Ein Objekt wird nur 1 mal initialisiert. Und deine Methode ist unbrauchbar. Normalerweise misst man die Zeit.

Mit Zeitmessung arbeitet meine Methode ja auch.

EDIT: @Chiller: Womöglich wäre das Buch "Developing Games in Java" von David Brackeen etwas für dich.


Zuletzt bearbeitet von Steffo am 13:43:58 06.11.2011, insgesamt 1-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 13:42:47 06.11.2011   Titel:              Zitieren

Zählen != Zeitmessung.
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 13:45:00 06.11.2011   Titel:              Zitieren

Ich schrieb:

Zitat:
Wenn (mindestens) eine Sekunde vergangen ist,...

Vielleicht kannst du mir erklären, wie man das ohne Zeitmessung anstellen kann!?


Zuletzt bearbeitet von Steffo am 13:45:08 06.11.2011, insgesamt 1-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 13:45:35 06.11.2011   Titel:              Zitieren

volkard hat sowas von Recht.
ntrnt
Unregistrierter




Beitrag ntrnt Unregistrierter 14:52:17 06.11.2011   Titel:              Zitieren

Ich glaube nicht, dass er meinte, Zählen == Zeitmessung.
Ich glaube, er meinte, Zählen + Zeitmessung = Framerate.
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 15:29:06 06.11.2011   Titel:              Zitieren

ntrnt schrieb:
Ich glaube nicht, dass er meinte, Zählen == Zeitmessung.
Ich glaube, er meinte, Zählen + Zeitmessung = Framerate.

So ist es. Ich muss natürlich messen, wann eine Sekunde vergangen ist und in diesem Moment gucke ich, welche Zahl mir der Zähler ausspuckt, was dann der Framerate pro Sekunde entspricht.

EDIT: Man muss sich natürlich nicht 1 Sekunde Zeit lassen. Man kann auch weniger oder länger warten und muss dann dementsprechend hoch- oder runterrechnen.


Zuletzt bearbeitet von Steffo am 15:45:41 06.11.2011, insgesamt 2-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 18:54:44 06.11.2011   Titel:              Zitieren

Du kannst aber nicht festlegen, wann dein Code für "1 Sekunde" ausgeführt wird. Und im Endeffekt musst du eben doch wieder die Zeit messen, was deinen Zähler überflüssig macht.
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 19:07:02 06.11.2011   Titel:              Zitieren

314159265358979 schrieb:
Du kannst aber nicht festlegen, wann dein Code für "1 Sekunde" ausgeführt wird. Und im Endeffekt musst du eben doch wieder die Zeit messen, was deinen Zähler überflüssig macht.

Ich fürchte, du missverstehst mich. Mein Code wird nicht "1 Sekunde lang ausgeführt", sondern ich messe, wieviel Zeit ein repaint in Anspruch nimmt und addiere das zur Gesamtzeit (Zeitmessung). Wenn die Gesamtzeit >= 1 Sek. ist, dann gucke ich, was mein Zähler sagt (Frames per Second). Danach wird wieder Zähler, als auch der Wert der Variable "gesamtzeit" wieder auf 0 gesetzt.
Ja, die Zeit muss natürlich gemessen werden. Das sage ich doch schon die ganze Zeit. Wenn du eine Methode ohne Zählvariable kennst, dann sei doch so freundlich und beschreibe sie mal. Jeder hier ist offen, wie man etwas noch besser implementieren kann.

L. G.
Steffo
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 20:17:04 06.11.2011   Titel:              Zitieren

Oh man.
27182818284590
Unregistrierter




Beitrag 27182818284590 Unregistrierter 20:27:43 06.11.2011   Titel:              Zitieren

314159265358979 schrieb:
Oh man.

Du bist auch ein bisschen schwer von Verstand, oder? :confused:
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 20:31:48 06.11.2011   Titel:              Zitieren

Jo.
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 23:47:05 06.11.2011   Titel:              Zitieren

Mensch, es muss nicht immer so schwer sein...
Ich mache es glaub ich so, dass ich bei jedem Aufruf gucke wie viel Zeit vergangen ist (neue Zeit - alte Zeit) und kann somit raus finden wie viel Zeit seit dem Letzten Frame vergangen ist.
Da der Benutzer keine Ahnung von fps haben muss, sondern die ganze Information nur intern verwendet werden muss, reicht diese Methode vollkommen.
Falls meine Überlgeung grundlegende Mängel aufweist, dann sagt es bitte.

Ich brauche das auch nur, um die Geschwindigkeit der Spielfigur auf jedem PC gleich zu haben. Es wird auch kein Hightech Game, sondern dient einzig und alleine dazu, mich selber weiterzubilden und eine gute Note zu erhalten... ;)

Gebräuchlich ist bei Labyrinthen ja, dass man eine Spielfigur um ein Feld verschiebt pro Tastendruck, ich habe aber vor, das ganze etwas dynamischer zu gestalten.

@Steffo:
Ich guck mir das Buch mal an, vlt hilft es ja.

Grüsse
Chiller


Zuletzt bearbeitet von Chiller am 23:48:31 06.11.2011, insgesamt 1-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4621
Beitrag 314159265358979 Mitglied 16:08:49 07.11.2011   Titel:              Zitieren

@Chiller: Genau, so macht man das.

@Steffo: Deine Methode ist total ungenau (bzw ungleichmäßig ungenau). Wenn, dann nimmt man die Zeit der letzten X Frames, aber bestimmt nicht jede Sekunde einen Reset.
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 11:43:16 08.11.2011   Titel:              Zitieren

Ähmmmmm
Wie kann ich die Zeit rauskriegen?
Hab es mit java.awt.calendar versucht, aber irgendwie krieg ich das nicht zum laufen.
Ich brauche nur die Anzahl Milisekunden die seit dem Letzten Refresh vergangen sind.
Die FPS krieg ich dann mit der umkehrfunktion (1/x) raus.

Grüsse
Chiller
asldjxylc
Unregistrierter




Beitrag asldjxylc Unregistrierter 17:35:18 08.11.2011   Titel:              Zitieren

probiers mit System.currentTimeMillis()
lolalter
Unregistrierter




Beitrag lolalter Unregistrierter 17:12:33 09.11.2011   Titel:              Zitieren

nein, dafür nimmt man seit 1.5: System.nanoTime();
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 10:49:02 21.11.2011   Titel:              Zitieren

So, ich hab das erste Problem gelöst.

Jetzt habe ich das nächste Problem:
Wie kann ich rausfinden ob sich zwei geometrische Figuren (2D) flächenmässig überschneiden?

Ich brauche die Information für die Kollisionsberechnung.

Für ein Beispiel und den aktuellen Stand des Projekts könnt ihr hier schauen.

Grüsse
Chiller
_kermit
Mitglied

Benutzerprofil
Anmeldungsdatum: 24.01.2011
Beiträge: 74
Beitrag _kermit Mitglied 12:57:55 21.11.2011   Titel:              Zitieren

Chiller schrieb:
Wie kann ich rausfinden ob sich zwei geometrische Figuren (2D) flächenmässig überschneiden?


Für Rechtecke hat die Klasse java.awt.Rectangle die Methode intersects(), die dir sagt, ob sich zwei Rechtecke überschneiden.

Falls es um eine Kollisionserkennung mit Kreis und Wänden geht, könntest du z.B. ein Rectangle erzeugen, in das dein Kreis genau reinpasst und dann über intersects() auf Kollision mit einer Wand prüfen.

http://download.oracle.com/javase/6/docs/api/java/awt/Rectangle.html#intersects%28java.awt.Rectangle%29
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 14:42:48 21.11.2011   Titel:              Zitieren

Das Problem ist, dass das Kollisionsobjekt des Kreises ein kreis sein muss. Sonst ist es schwierig mit der Spielfigur um eine Kurve zu gehen.

Grüsse
Chiller
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 17:26:51 28.11.2011   Titel:              Zitieren

So mein spiel ist eigentlich fertig. Die Grundfunktionen laufen :)
Ich werde noch ein paar Funktionen hinzufügen, aber im Grossen und Ganzen läuft es.
Ich wäre froh um Rückmeldungen, vor allem was Bugs anbelangt.

Das Spiel findet ihr hier, viel Spass. ;)

Edit:
Weil ich die Website angepasst habe, habe ich den Link geändert. Der originale Link verweist auf meine Homepage: hier

Grüsse
Chiller


Zuletzt bearbeitet von Chiller am 19:13:50 17.12.2011, insgesamt 1-mal bearbeitet
Spieler
Unregistrierter




Beitrag Spieler Unregistrierter 23:06:52 13.12.2011   Titel:              Zitieren

Ich hab's gespielt!

Und ich hab gewonnen!

Gut, oder?
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 19:04:12 17.12.2011   Titel:              Zitieren

Jojo.
Ich werde noch nen Algorithmus einbauen, welcher dir ne Punktezahl gibt.
Diese wird abhängig sein von:
- Verbrauchte Zeit
- Länge des Lösungswegs
- Gebrauchte Felder (Je weniger Falsche Wege man genommen hat desto besser)

Das wird dann angezeigt, aber im Moment habe ich noch viel zu viel um den Ohren um an diesem Projekt weiterarbeiten zu können. Ich versuche das ganze aber vor Weihnachten fertig zu kriegen.
Zudem habe ich noch ein paar Programmier-Fehler entdeckt und möchte noch machen, dass man fortan keine Grössenbeschränkung mehr hat.

Grüsse
Chiller
Steffo
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.05.2010
Beiträge: 481
Beitrag Steffo Mitglied 17:23:19 18.12.2011   Titel:              Zitieren

Also ich finds gut! :leak: :live:
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 00:36:53 21.12.2011   Titel:              Zitieren

Hmmm
Ich hab in der letzten Zeit noch etwas Zeit zusammen gekratzt, in der ich das Labyrinth erweitert/verbessert habe. Aber jetzt habe ich einen ganz komischen Fehler...
Aus irgend einem Grund funktioniert das Spiel nicht mehr. Ich hab das ganze zwar ursprünglich mit Textpad geschrieben, aber um den Fehler zu suchen habe ich es dennoch mal in Eclipse geöffnet und siehe da... Die Zeile
Java Code:
avatar = new Avatar ();
Java Code:
avatar = new Avatar ();
Java Code:
avatar = new Avatar ();
macht einen Fehler. Das Objekt avatar gibt es bereits, der Klassenname ist richtig geschrieben, und bis jetzt hat diese Zeile nie ein Problem verursacht, zudem motzt oracle beim Compilieren kein bisschen.

Hat jemand ne Ahnung was der Fehler sein könnte?

Da ich keine Ahnung habe was den Fehler auslöst, habe ich auch keine Ahnung welche Codefragmente euch weiterhelfen würden. Ich lade darum mal einfach etwas rauf. ;)

In dieser Methode schmiert das Applet ab
Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void startGame(Level CurrentLevel, boolean playWithKeys)
{
    avatar = new Avatar();    //Generates a new empty avatar
    level = CurrentLevel;    //Gets the level for the new game

    oldSize.width = level.getSize().width;
    oldSize.height = level.getSize().height;

    previousTime = System.currentTimeMillis();    //saves the previous thime for fps calculating (first step is not precise)

    playWithKeyboard = playWithKeys;    //Sets if the game will be played with the keyboard (WASD + Arrows)

    //gets the values for the avatar

    Point startPoint = new Point(level.getQuadrant(0,0).getPosition().x, level.getQuadrant(0,0).getPosition().y);
    int durchmesser = level.getQuadrant(0,0).getDurchmesser();

    //Sets all needet propertys of the avatar
    avatar.setPosition(startPoint.x + (durchmesser/2.0), startPoint.y + (durchmesser/2.0));    //Sets the avatar position on the center of the startfield
    avatar.setRadius((int)(((durchmesser / 4.0) * 0.8) + 0.5));    //Sets the avatar radius so that is is smaler than the way
    avatar.setColor(Color.BLUE);    //Sets the avatar color

    avatar.setVelocity(0, 0);    //stops the movement of the avatar
}
Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void startGame(Level CurrentLevel, boolean playWithKeys)
{
avatar = new Avatar(); //Generates a new empty avatar
level = CurrentLevel; //Gets the level for the new game

oldSize.width = level.getSize().width;
oldSize.height = level.getSize().height;

previousTime = System.currentTimeMillis(); //saves the previous thime for fps calculating (first step is not precise)

playWithKeyboard = playWithKeys; //Sets if the game will be played with the keyboard (WASD + Arrows)

//gets the values for the avatar

Point startPoint = new Point(level.getQuadrant(0,0).getPosition().x, level.getQuadrant(0,0).getPosition().y);
int durchmesser = level.getQuadrant(0,0).getDurchmesser();

//Sets all needet propertys of the avatar
avatar.setPosition(startPoint.x + (durchmesser/2.0), startPoint.y + (durchmesser/2.0)); //Sets the avatar position on the center of the startfield
avatar.setRadius((int)(((durchmesser / 4.0) * 0.8) + 0.5)); //Sets the avatar radius so that is is smaler than the way
avatar.setColor(Color.BLUE); //Sets the avatar color

avatar.setVelocity(0, 0); //stops the movement of the avatar
}
Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void startGame(Level CurrentLevel, boolean playWithKeys)
{
    avatar = new Avatar();    //Generates a new empty avatar
    level = CurrentLevel;    //Gets the level for the new game

    oldSize.width = level.getSize().width;
    oldSize.height = level.getSize().height;

    previousTime = System.currentTimeMillis();    //saves the previous thime for fps calculating (first step is not precise)

    playWithKeyboard = playWithKeys;    //Sets if the game will be played with the keyboard (WASD + Arrows)

    //gets the values for the avatar

    Point startPoint = new Point(level.getQuadrant(0,0).getPosition().x, level.getQuadrant(0,0).getPosition().y);
    int durchmesser = level.getQuadrant(0,0).getDurchmesser();

    //Sets all needet propertys of the avatar
    avatar.setPosition(startPoint.x + (durchmesser/2.0), startPoint.y + (durchmesser/2.0));    //Sets the avatar position on the center of the startfield
    avatar.setRadius((int)(((durchmesser / 4.0) * 0.8) + 0.5));    //Sets the avatar radius so that is is smaler than the way
    avatar.setColor(Color.BLUE);    //Sets the avatar color

    avatar.setVelocity(0, 0);    //stops the movement of the avatar
}

Die obige Methode bereitet die GameEngine auf ein neues Spiel vor, und an der habe ich eigentlich nichts geändert.

Grüsse
Chiller
Chiller
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.09.2011
Beiträge: 65
Beitrag Chiller Mitglied 13:39:30 26.12.2011   Titel:              Zitieren

So konnte das Problem lösen, besser gesagt, der Neustart vom PC hat es gelöst.

Mittlerweile bin ich eigentlich fertig mit dem Labyrinth, Punktevergabe etc ist eingebaut.

Link: www.chillersanim.bplaced.net/Labyrinth/Labyrinth.html

Features:
- Generiert ein zufälliges, perfektes Labyrinth
- Grösse wird automatisch an Fenstergrösse angepasst
- Auflösung ist fast beliebig einstellbar (Begrenzung nur durch Fenstergrösse)

- Labyrinth kann gespielt (gelöst) werden mit Tastatur oder Maus
- Spielgeschwindigkeit ist einstellbar
- Anzeige der gebrauchten Zeit und der aktuellen fps
- Sobald das Labyrinth gelöst ist wird eine Punktes Zahl berechnet

- Eingebauter Lösungsalgorithmus kann das Labyrinth automatisch lösen
- Zeigt Informationen zum Labyrinth

Viel Spass beim ausprobieren.
Wer einen Bug findet soll ihn doch hier Posten. ;)

Grüsse
Chiller


Zuletzt bearbeitet von Chiller am 13:41:16 26.12.2011, insgesamt 1-mal bearbeitet
C/C++ Forum :: Java ::  Wie mache ich ein Spiel?   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.