Skalierung eine Feste SurfaceView zu füllen und vertikal Seitenverhältnis beibehalten
Ich habe versucht, auf der Suche nach einer Antwort und kann nicht scheinen, einen zu finden (es ist eine ziemlich unkonventionelle Herangehensweise an die Programmierung einer android-Spiel, es ist also zu erwarten, zumindest glaube ich).
Ich versuche zu schaffen, ein GBA-Stil RPG-Spiel in Android (für die Nostalgie). OpenGL war nicht gut genug für mich, denn es war nicht anpassbar genug in der Spiel-Schleife (ich will nur zeichnen aufgerufen werden, wenn es etwas gibt, das muss gezogen werden, da ich möchte, dass dieses Spiel zu uber-effiziente, wie es verwendet die Batterie, die bedeutet, dass es wirken mehr wie ein polling-app als ein Spiel). Ich erstellte eine benutzerdefinierte Oberfläche Ansicht mit seinen eigenen thread, der aufgerufen wird, wenn die Zeichnung gemacht werden muss (ich modellierte Sie nach der Probe LunarLander android-Spiel in der SDK).
Die Sache ist die, ich will das Spiel selbst eine Feste Größe zu werden (208x160) und dann eine Skalierung auf die Größe des Bildschirms. Das problem das ich habe ist, es scheint nicht zu sein, jedenfalls von innerhalb der normalen Parameter des erweiterten SurfaceView in XML. Das Spiel in seinem aktuellen Zustand ist unten dargestellt. Ich bin versucht, um es zu Strecken, um die Höhe des Bildschirms und pflegen-Verhältnis auf die Breite, während auch nicht hinzufügen, um den sichtbaren Spiel (halten Sie es fest, unabhängig von der Bildschirmgröße).
http://i.stack.imgur.com/EWIdE.png (Ich war zu veröffentlichen der eigentlichen Bild-in-line. Spam-Prävention kann mich beißen >.<)
Derzeit bin ich immer der SurfaceView die Leinwand und zeichnen direkt auf Sie, und die Versorgung meiner Größe als hart codierte pixel dimension (208px, 160px).
Dies ist, was der thread derzeit aussieht, bekommen die Leinwand und zeichnen es. Was wäre ein besserer Weg, um zu zeichnen auf eine Leinwand, ohne änderung der Größe ich will das Spiel praktisch aus?
@Override
public void run()
{
Canvas c = null;
try
{
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder)
{
draw(c);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (c != null)
surfaceHolder.unlockCanvasAndPost(c);
}
}
Die draw-Methode ist diese (StringBuilder ist meine eigene codierten Objekt in der engine):
public void draw(Canvas canvas)
{
canvas.drawColor(Color.GRAY);
StringBuilder stringBuilder = new StringBuilder(canvas, Color.BLACK, letters);
stringBuilder.drawString("Oh, hello there!");
stringBuilder.setLocation(10, 20);
stringBuilder.drawString("Why am I so small?");
}
Irgendwelche Ideen?
- Haben Sie sich überlegt die Skalierung Ihrer Leinwand zu passen, die
SurfaceView
? - Die Leinwand kommt von der SurfaceView selbst.... Aufruf von run() (das ist der thread die run-Methode) erzeugt eine Leinwand, und dann legt die Leinwand auf den SurfaceHolder, die dann sperrt die Leinwand, die ich dann ziehen, um es dann zu entsperren und zu post zu der Ansicht, wenn Sie fertig sind. Es sei denn, ich lese die original-code aus dem LunarLander Beispiel falsch...
- So... ? Kannst du nicht einfach anrufen
scale
drauf??? - Ich habe versucht, Skala, aber das funktioniert nur, wenn ich didn ' T Pflege über die Größe der Leinwand. In diesem Fall habe ich zu tun, und die Größe der Arbeitsfläche wird durch die Ansicht. Wenn ich match_parent und dann zu skalieren, es wird größer, klar, aber die Leinwand Größe ist nicht die Größe, die ich möchte es zu bleiben. Im Grunde habe ich nur wollen, zu zeichnen, zu einer festen Größe der Leinwand, und dann vielleicht, wenn es einen Weg zu zeichnen, die auf eine andere Leinwand, aber skaliert, dann könnte das für diese Arbeit.
- Eigentlich sollte man das zeichnen auf eine Leinwand, als ob die Zeichnung zu einer festen Größe der Leinwand, aber zunächst rufen
scale
so, dass die Inhalte angemessen zu skalieren Aufrechterhaltung von Seitenverhältnis. - Super.. ich bin devloping einem scrable Spiel, wo Vorstand und Brief-rack Zeichnung im canvas-Bereich.. was ich will ist nur zu skalieren board Teil.. wenn ich cliprect der Vorstand Teil machen, der andere Teil schwarz.. bitte helft mir..
Du musst angemeldet sein, um einen Kommentar abzugeben.
Davon aus, dass Ihr
draw
Funktion umbenannt, umdrawBase
statt. Hier ist, wie Sie es tun:(Die akzeptierte Antwort von K-ballo ist in Ordnung, aber in den 2,5 Jahren, seit es geschrieben wurde, zeigt, bekommen haben viel dichter, was bedeutet, dass das Rendern über die software ist immer teurer. Es ist wichtig, um die hardware zu helfen, die Arbeit zu tun.)
Rendern in einer bestimmten Auflösung, die Sie verwenden können,SurfaceHolder#setFixedSize(). Dies legt die Größe der Oberfläche, auf der die genauen Abmessungen, die Sie angeben. Die Oberfläche wird skaliert, um die Größe der Ansicht durch den hardware-scaler, die gehen, um effizienter sein als die Skalierung der software. Die Funktion, die beschrieben wird in diesem blog-post, und Sie können sehen, Sie in Aktion in Grafika ist "hardware-scaler exerciser" Aktivität (demo-video).
Pflegen Sie die richtige Seitenverhältnis für die unterschiedlich großen displays durch die Anpassung der Größe der Oberfläche (was die Grafika ist für die demo), oder durch anpassen der Ansicht für Brief - oder pillar-box das layout. Sie finden ein Beispiel für die letztere in der Grafika ist AspectFrameLayout-Klasse, die verwendet wird, für verschiedene Kamera-und video-demos.
Diesbezüglich:
Haben Sie zwei Möglichkeiten. Erstens können Sie GLSurfaceView#setRenderMode() zu deaktivieren kontinuierliche rendering. Zweitens, Sie brauchen nicht zu verwenden GLSurfaceView mit OpenGL. Die meisten der GLES-code in Grafika arbeitet auf SurfaceView oder TextureView.