Jump & Run Sprung Logik

  • Antworten:2
Kai Rechtern
  • Forum-Beiträge: 2

18.10.2012, 17:42:43 via Website

Hi,
ich versuche mich gerade an meinem ersten Android-Spiel. Es soll ein einfaches Jump & Run werden, in dem die Figur von alleine läuft und der per antippen des Bildschirms ein Sprung ausgeführt werden soll. Es soll ein 2D Spiel werden, daher arbeite ich mit Canvas.

Mein Problem:
Ich weiẞ nicht so recht wie ich die Figur vernünftig Springen lasse. Bisher hab ich es nur mit 2 Threads hinbekommen. Einmal der Haupt-Thread der das Spiel laufen lässt und ein zweiter der gestartet wird um die Figur springen zu lassen. Ein Thread lässt die Figur quasi nach vorne laufen, während ein zweiter bei Bedarf die Figur gleichzeitig springen lässt.

Der JumpThread arbeitet leider mit sleep, was denke ich nicht so schön ist.
1public class JumpThread extends Thread{
2
3 private boolean mjumpUp;
4 private boolean mjumpDown;
5 private OldmanView oldView;
6 private boolean run;
7
8 public JumpThread(OldmanView old){
9 oldView = old;
10 run = true;
11 mjumpUp = false;
12 mjumpDown = false;
13 }
14
15 @Override
16 public void run() {
17 // TODO Auto-generated method stub
18 while(run){
19 while(mjumpUp == true){
20 oldView.getThread().jump();
21 try {
22 sleep(1);
23 } catch (InterruptedException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }
27 }
28
29 while(mjumpDown == true){
30 oldView.getThread().jumpDown();
31 try {
32 sleep(1);
33 } catch (InterruptedException e) {
34 // TODO Auto-generated catch block
35 e.printStackTrace();
36 }
37 }
38 }
39 }
40
41 public void setRunning(boolean run){
42 this.run = run;
43 }
44
45 public void setJump(boolean mjump){
46 this.mjumpUp = mjump;
47 }
48
49 public void setJumpDown(boolean mjumpDown){
50 this.mjumpDown = mjumpDown;
51 }
52}

1public void jump(){
2
3 synchronized(holder){
4 oldmanBottom -= gravity;
5 oldmanTop -= gravity;
6
7 if(oldmanBottom <= (ground - 50)){
8 gravity = 1;
9 jThread.setJumpDown(true);
10 jThread.setJump(false);
11 }
12 }
13 }
14
15 public void jumpDown(){
16
17 synchronized(holder){
18 oldmanBottom += gravity;
19 oldmanTop += gravity;
20
21 if(oldmanBottom == ground){
22 jThread.setJumpDown(false);
23 }
24 }
25
26 }

Hoffe ihr könnt mir weiterhelfen.

Gruß

Antworten
Tobias Eckert
  • Forum-Beiträge: 155

19.10.2012, 12:33:05 via Website

Da sind eine Reihe Dinge die Du ändern musst:

Es gibt keine garantierte Laufzeit
Arbeite nicht mit absoluten Werten um die Du die Grafik verschiebst. In Deinem Thread verschiebst Du Deine Figur bei jedem Durchlauf um einen festen Wert von einem Pixel (oder welcher Wert in Deiner Variablen gravity steht). Je nachdem auf welchem Gerät Dein Spiel läuft kann zwischen zwei Durchläufen allerdings beliebig viel Zeit vergehen. Das kannst Du nicht kontollieren. Auf einem Gerät kann Dein Sprung dann eine halbe Sekunde dauern, auf dem nächsten dauert er 5 Sekunden.

Was Du hier machen musst ist das folgende: Merke Dir den Timestamp wann die Routine zuletzt gelaufen ist. Beim nächsten Durchlauf ziehst Du diesen Wert dann vom aktuellen Timestamp ab. Dann weist Du wieviel Zeit in Milisekunden seit dem letzten Durchlauf vergangen ist.

Wenn ein Sprung Deiner Figur jetzt z.B. eine Sekunde dauern soll, so nimmst Du die Anzahl der verstrichenen Millisekunden, und teilst diese durch die Gesamtdauer des Sprunges (im Beispiel 1 Sekunde = 1000 millisekunden). Diesen Bruch multiplizierst Du mit der Gesamtzahl der Pixel die es pro Sprung nach oben oder unten geht.

Beispiel: Sprungdauer soll 1000ms sein. Die Figur soll dabei um 50 Pixel verschoben werden. Seit dem letzten Durchlauf der Routine sind 500ms vergangen, also musst Du die Figur um (500ms/1000ms)*50 Pixel = 25 Pixel verschieben.

Arbeite nicht mit absoluten Pixelwerten
Jedes Gerät hat eine andere Auflösung. 50 Pixel sind auf einem HTC Wildfire schon ein Viertel der Bildschirmbreite. Auf einem Tablet dagegen gerade mal ein Zentimeter vom Display. Du willst in der Regel Deine Figur nicht um 50 Pixel springen lassen, sondern um z.B. ein Zehntel der Bildschirmhöhe. Mach also genau das. Hole Dir die Display-Dimensionen, teile die Bildschirmhöhe durch 10, schon hast Du die Anzahl Pixel um die es in einem Sprung nach oben geht.

Teile UI und Spiel-Logik auf
In Deinem Beispiel kannst Du sehr schön in Deinem Hauptprogramm eine View definieren deren Canvas Du dann zum malen verwendest. Für diese View kannst Du einen onTouch Listener verwenden. Jedesmal wenn der Bildschirm gedrückt wird kann Deine onTouch Routine dann eine Variable im Spiel-Logik-Thread setzen die diesem Thread dann signalisiert: jetzt starte einen Sprung.

Die Spiel-Logik und die Zeichen-Routine baust Du dann in diesen seperaten Thread ein.

Das war jetzt Spieleentwicklung komprimiert in drei Abschnitte. Am besten schaust Du Dir mal ein paar einschlägige Tutorials an. Die erklären das sehr viel ausführlicher.

Antworten
Kai Rechtern
  • Forum-Beiträge: 2

19.10.2012, 14:56:09 via Website

Danke für die ausführliche Antwort!

Werde dann mal die Mängel beheben und mich auf die Suche nach Tutorials machen. Vielleicht kannst du mir ja auch eins empfehlen?

Antworten