# Pokémon typische Textausgabe



## Xym13 (20. Nov 2012)

Ich erstelle gerade ein Pokemon Edition und weiß jetzt nicht genau, wie ich die graphische Textausgabe gestalten soll.

Für die es nicht kennen: Der Text wird nicht aufeinmal ausgegeben sondern Buchstabe für Buchstabe aneinander gereiht. Insgesamt 2 Zeilen. Wird dann der A Knopf gedrückt wird, kommt der nächste Text, oder das Spiel geht weiter.

Eigentlich wollte ich Ausgaben in den Rest so einbauen:

```
Main.system.out();
```

Das erste Problem war / ist, wie "halte" das Spiel an, bis die Ausgabe vorbei ist. Dachte die Methode out ist von Type boolean und gibt erst true zurück, wenn der Text fertig ist.

Aber hab keine Idee, wie ich den Text Buchstabenweise langsam ausgeben kann.


----------



## Fab1 (20. Nov 2012)

Soll das ganze Konsolen basiert werden oder wie stellst du dir das vor?

Ansonsten könnte man ja einfach den String in die Buchstaben aufteilen und in einer Schleife mit einem kleinen Thread.sleep() die Buchstaben anzeigen. Die Buchstaben fliegen dann halt nicht rein sondern werden nur nach einander angezeigt.


----------



## Xym13 (20. Nov 2012)

Das Spiel soll als App für Android Smartphones erscheinen, aber ohne aufwendige Animation.

An einen Thread dachte ich auch. Doch wenn ich jetzt die Funktion out() aufrufe, und dort den Thread starte, wird doch die Funktion out() weiter abgearbeitet und true zurück geben, bevor der ganze Text durch ist, oder?


----------



## Fab1 (20. Nov 2012)

Ich muss ehrlich sagen ich höre das 
	
	
	
	





```
Main.system.out();
```
 zum ersten Mal. Ist das irgendwas Android (App) spezifisches?

Du wirst ja wohl kaum die statische Variable out von der statischen Klasse System meinen. Also wie bei der normalen Konsolenausgabe zum Beispiel. Falls aber doch, dass ist eine Variable vom Typ PrintStream


----------



## Xym13 (20. Nov 2012)

Ach so, Main.system.out; hatte ich selbst angelegt in meinem Programm. 

Kann man natürlich auch anders nennen.


----------



## Fab1 (20. Nov 2012)

Ok, dann sieht die Sache schonmal anders aus.

Grundsätzlich hat man bei einem Spiel ja eine Spielschleife oder irgend sowas in der Art. Bei der Spielschleife wird als Bedingung dann einfach immer überprüft, ob die booleanVariable zum Beispiel 
	
	
	
	





```
isGamePaused
```


```
true
```
ist, dann wird das Spiel pausiert. Dann kann ja einfach der Text ausgegeben werden und anschließend nachdem die Ausgabe fertig ist, setzt du die Variable wieder auf 
	
	
	
	





```
false
```


----------



## Xym13 (21. Nov 2012)

Bis hierhin erstmal vielen Dank! Die Ausgabe an sich funktioniert jetzt wie gewünscht.

Das Problem ist, wenn ein Angriff ausgeführt wird. Dafür gibt es eine Funktion angriff() in der mehrfach eine solche Ausgabe vorkommen kann. Daher bringt auch das unterbrechen der Game Loop nichts, da die Funktion erst aufgeführt wird, bevor der Game Loop angehalten wird.

Habt ihr vielleicht eine Idee, wie ich das lösen kann?


----------



## trääät (21. Nov 2012)

ich weis schon worauf du hinaus willst (bin ja mit pokemon aufgewachsen) ...

ich kenne mich jetzt zwar nicht mit android aus ... aber wenn ich das ganze als normale swing-app zusammenkleben müsste würde ich dafür eine art event-handling nutzen

würde vermutlich so aussehen

der game-loop prüft ob ein event nach dem motto "zeigeTextAn" vorliegt ... und zwar BEVOR sowas kommt wie "angriff()" oder "zeichneAnimation" ... also relativ weit oben im game-loop
liegt ein solches event vor wird ein thread angestoßen der dann für das aufbauen des text-fensters sowie dessen darstellung und des reagierens auf user-input zuständig ist ... und der game-loop in einen modus "esWirdTextAngezeigt" versetzt ... ich würde es mit nem if-block machen und dann lediglich ganz unten das repaint callen ...
der anzeige-thread kümmert sich nun also darum erstmal die text-box aufzubauen und dann den text anzuzeigen ... und dann wartet er in einem loop darauf das der user "A" bzw "B" drückt um weiter zu machen
zusätzlich muss eine logik eingebaut werden wenn es "fragen" gibt (also das typisch JA / NEIN") ... ich würde es so machen das der selbe thread dann dies einfach zeichnet und dann normal auf user-input wartet , diesen aber durch ein flag entsprechend anders auswertet
ist der dialog zu ende oder die frage beantwortet muss dies der logik des game-loops gesagt werden was als nächstes zu tun ist ... und dann erst wird das flag "textWirdAngezeigt" wieder rausgenommen und der game-loop läuft dann wieder normal weiter und beginnt mit der verarbeitung der daten aus dem text ... also z.b. entsprechend der antwort eine bestimmte aktion auslösen oder nach einem trainer-dialog den kampf einleiten ... oder oder oder ... ist ja ziemlich komplex (wobei ich mich hier gerade nur auf die aller erste generation beziehe ... hatte leider nie mit der zweiten oder sogar noch weiteren zu tun ... weis aber das diese noch komplexer sind)
im kampf selbst würde ich jetzt nicht unbeidngt den selben thread neben den man für normale dialoge nimmt ... würde davon aber eine abgewandelte form für das kampf-menü und allen von dort aus erreichbaren screens entwickeln ... was ja über "items anzeigen , auswählen und einsetzen" bis hin zu "pokemon wechseln , selektieren , status ansehen und verändern" reicht ...
die aufgabe des game-loops wäre dann lediglich vom kampf-thread informiert zu werden WAS anzuzeigen ist ... und das zu zeichnen ... das würde ich nämlich nicht direkt im kapmf-thread machen ...
(wobei unter swing eh alles an den EDT gereicht werden müsste ... weis nicht wie das unter android ist)


du siehst also : selbst wenn man nur einen klon der ersten generation versuchen würde hätte man schon für eine normale desktop-swing-app einiges zu tun ... aber ganze noch in android zu quetschen wo man sich mit begrenzter API rumschlagen muss und lange nicht die rechen-power eines normalen systems hand dürfte das schön aufwändig werden ...


----------



## Xym13 (25. Nov 2012)

Die Ausgabe funktioniert jetzt ( etwas umständlich, aber es läuft  )

Jetzt habe ich nur das Problem, dass ich keine Truetype Fonts laden kann. Daher wollte ich mir eine Klasse erstellen, die die Schrift aus einem Bild baut.

Ich hab es so versucht:

```
package de.game;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;

public class Font {
	
	public static Image b[] = new Image[62];
	public SpriteSheet sheet = null;
	Image img = null;
	
	public Font() throws SlickException {
		sheet = new SpriteSheet("resources/images/font.png", 7, 12);
		
		// Zahlen 0 - 9 ^= 0 - 9
		for(int i=0;i<10;i++) {
			b[i] = sheet.getSprite(i, 1);
		}
		
	}
	
	public void drawString(String text, int x, int y, Graphics g) {
		for(int i = 0; i < text.length(); i++) {
			String split = text.substring(i, i+1);
			if(split.equals("0"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("1"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("2"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("3"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("4"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("5"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("6"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("7"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("8"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
			else if(split.equals("9"))
				g.drawImage(b[Integer.parseInt(split)], x, y);
		}
	}
}
```

Das erste Problem ist, dass nur weiße Bilder angezeigt wird. Hier ist das Bild ( Directupload.net - 4kupscz4.png ).

Und dann noch eine Frage:
Habt ihr eine Idee, wie ich den Teil in der render Funktion vereinfachen kann? Wenn ich das weiter mit allen Buchstaben ausbaue wird rechts komplex..


----------



## trääät (26. Nov 2012)

hmm .. wenn du den Font nicht laden kannst liegt er vielleicht in einem format vor was java nicht drauf hat ... da solltest noch mal nach anderen files suchen ...

was das sheet angeht : kenne mich mit slick nicht aus und weis daher nicht was da abläuft ...

zum rendern : wenn du ne elegantere lösung haben willst solltest du vielleicht mal in den source von Graphics.drawString() oder so gucken ... weil selbst fällt mir jetzt auch nicht wirklich was besseres ein .. obwohl ich dir mit meinem post hoffentlich wenigstens eine idee liefern konnte


----------



## Xym13 (27. Nov 2012)

Also Java kann eigentlich mit Truetyps Fonts umgehen. Das Problem ist nur, dass es bei Android zwar auch geht, man die Schriftart einem androidspezifischen Objekt zuweisen muss. Solche habe ich aber nicht, da ich mit Slick arbeite. Daher scheidet das direkte einbinden aus.

Mein Plan war es jetzt, die einzelnen Buchstaben aus den Bild jeweils in einem Bild zu speichern, und dann je nach Text richtig auszugeben.

Ich weiß jetzt nicht warum die Bilder immer weiß sind..
Und Gprahics.drawString() scheidet auch aus, da ich ja mit den einzelnen Bildern arbeiten muss / will.


----------



## tröööt (28. Nov 2012)

hmm ... stimmt ... android ... da war ja noch was ...
aber auch dafür sollte es doch möglich sein irgendwas zu finden was mit slick kompatibel is ...
kann mir nich vorstellen das sich da irgendwas so in die haare bekommt das man standard-funktionen von java , nämlich truetype-fonts zu nutzen , irgendwie blockiert ...

aber naja ... das is ne andere sache

was du vorhast war mir schon klar ... du hast aber die anpielung falsch verstanden ...
meine idee war eigentlich mal so in den code von Graphics.drawString() zu gucken wie dort der string eben "gezeichnet" wird ... leider fehlanzeige da alles abstract und keine vernünftige implementierung ...
war aber ne idee ...

und das mit der sprite-map ist zwar auch n ansatz ... birgt aber einiges an fehlerpotenzial ...
wie genau das intern von slick läuft weis ich wie gesagt nicht ... und das dein code da unten eher beispiel ist ist mir auch klar ...
ich denke mal das slick irgendwas beim zerlegen der tilemap macht was so nicht sein soll und daher zu fehlern führt ...
alternativ könntest du mal versuchen den ganzen mist per hand zu machen (dürfte umständlich werden) oder einmal manuell alle tiles über ein hilfs-programm in einzelne kleine daten zerlegen und dann anstatt eines großen spritesheets halt für jedes zeichen ein eigenes image was so direkt geladen wird ...

thema laden ...
es kann auch sein das die resource nicht oder zu langsam geladen wird ...
das kennt man auch wenn man z.b. große bilder in ein programm laden will und diese dann gleich anzeigt ... meist kommt dabei nämlich genau das raus was du hier hast ... "leere" ... da eben beim laden irgendwas zu langsam läuft ...
auch kann es am daten-format liegen ... müsste man mal bei slick gucken was erwartet wird (wobei am ende java sehr viele formate ins RAW-BufferedImage umsetzen kann ... und damit kann man zumindest innerhalb von java eigentlich alles machen ... erst beim rendern oder wieder rausschreiben über codecs wirds dann wieder interessant) ...
auch kannst du mal versuchen die tilemap über ImageIO zu laden und das ergebnis dann irgendwie an slick weiter zu geben ... da weis ich aber nicht ob das so auch unter android möglich ist ...
ich bezieh mich halt grunsätzlich auf SE ...

ist halt alles nicht so einfach wenns für android sein soll


----------

