Comment dessiner beaucoup d'images sur l'écran dans un jeu Android sans ralentir les performances
Je veux faire une tuile de base de jeu pour android. Pour le moment, je suis de dessin de chaque pièce séparément, comme une image bitmap. J'ai une grande boucle qui lit à partir d'une chaîne et attire de tuiles différentes selon le caractère qu'il trouve à tirer le niveau.
J'ai permis à l'utilisateur de faire défiler l'écran à l'aide de gestes de défilement. Cependant, le jeu est trop lent. Il faut du temps pour mettre à jour l'écran après que l'utilisateur fait défiler. Je présume que c'est parce qu'il a de tirer chaque tuile bitmap individuellement.
Ce qui serait un moyen plus rapide pour dessiner le niveau? Je pensais que je pouvais fusionner toutes les tuiles dans un bitmap. Mais je ne sais pas comment faire. Des idées?
En tout cas voici mon code pour que vous voyez le problème:
package org.example.tutorial2d;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.OnGestureListener;
import org.example.tutorial2d.Panel;
public class Tutorial2D extends Activity implements OnGestureListener {
GestureDetector gestureScanner;
Panel main;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gestureScanner = new GestureDetector(this);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
main = new Panel(this);
setContentView(main);
}
@Override
public boolean onTouchEvent(MotionEvent me)
{
return gestureScanner.onTouchEvent(me);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
main.handleScroll(distanceX,distanceY);
return true;
}
////////////////////
///////////////////
//////////////////
@Override
public boolean onDown(MotionEvent e)
{
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
return true;
}
@Override
public void onLongPress(MotionEvent e){ }
@Override
public void onShowPress(MotionEvent e) { }
@Override
public boolean onSingleTapUp(MotionEvent e)
{
return true;
}
////////////////////
///////////////////
//////////////////
}
Et la classe qui fait tout le travail:
package org.example.tutorial2d;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import org.example.tutorial2d.Point;
public class Panel extends View {
private int scrollX = 0;
private int scrollY = 0;
public Panel(Context context)
{
super(context);
}
@Override
public void onDraw(Canvas canvas)
{
/*Bitmap scratch;
//Drawable scratch;
//scratch = getContext().getResources().getDrawable(
// R.drawable.icon);
canvas.drawColor(Color.BLACK);
//scratch.draw(canvas);
int origin = 0;
scratch = BitmapFactory.decodeResource(getResources(), R.drawable.horizontal5);
canvas.drawBitmap(scratch, origin, origin, null);
int width = scratch.getWidth();
int height = scratch.getHeight();
scratch = BitmapFactory.decodeResource(getResources(), R.drawable.room4entrynesw3x3);
canvas.drawBitmap(scratch, origin + width, origin - 32, null);
*/
String sucide_mission =
" wwwww\n" +
" wfffw\n" +
" wfffw\n" +
" wfffw\n" +
" wwfww\n" +
" wfw\n" +
" wfw\n" +
" wfw\n" +
" wwwwwwwfwwwwwfw\n" +
" wfffffffffffffw\n" +
" wfwwwwwfwwwwwfw\n" +
" wwwww wfw wfw wfw\n" +
"wwwwwwfffwwwwwfwwwwwfwwwwwfw\n" +
"fffffffffffffffffffffffffffw\n" +
"wwwwwwfffwwwwwwwwwwwfwwwwwfw\n" +
" wwfww wfw\n" +
" wfw wfw\n" +
" wfw wfw\n" +
" wfw wfw\n" +
" wfw wfw\n" +
" wwfww wfw\n" +
" wfffwwfw fff\n" +
" wffffffw www\n" +
" wfffwwfw\n" +
" wwwww";
canvas.drawColor(Color.BLACK);
int x = 0, y = 0;
for (int i = 0; i < sucide_mission.length(); i++)
{
Bitmap tileImage;
char tile = sucide_mission.charAt(i);
Log.d("Draw tiles", Character.toString(tile) + " " + x + "," + y);
switch (tile)
{
case 'w':
if (x < tileImage = BitmapFactory.decodeResource(getResources(), R.drawable.walla);
canvas.drawBitmap(tileImage, x - scrollX, y - scrollY, null);
x += 32;
break;
case 'f':
tileImage = BitmapFactory.decodeResource(getResources(), R.drawable.floore);
canvas.drawBitmap(tileImage, x - scrollX, y - scrollY, null);
x += 32;
break;
case ' ':
x += 32;
break;
case '\n':
y += 32;
x = 0;
break;
}
}
//canvas.drawBitmap(adapt, 0, 0, paint);
//canvas.drawBitmap(corner, origin -scrollX , origin -scrollY, paint);
}
public void handleScroll(float distX, float distY)
{
//X-Axis ////////////////////////////////
if(distX > 6.0)
{
if(scrollX < 460)
{
scrollX += 30;
}
}
else if(distX < -6.0)
{
if(scrollX >= 30)
{
scrollX -= 30;
}
}
////////////////////////////////////////////
//Y-AXIS //////////////////////////////////
if(distY > 6.0)
{
if(scrollY < 100)
{
scrollY += 30;
}
}
else if(distY < -6.0)
{
if(scrollY >= 30)
{
scrollY -= 30;
}
}
////////////////////////////////////////////
if((scrollX <= 480) && (scrollY <= 120))
{
//adapt = Bitmap.createBitmap(bmp, scrollX, scrollY, 320, 480);
invalidate();
}
}
}
OriginalL'auteur | 2009-09-16
Vous devez vous connecter pour publier un commentaire.
On dirait que vous êtes la création d'une nouvelle instance de chaque image bitmap pour chaque tuile rendus. Peut-être au lieu de cela, vous pouvez créer une instance pour chaque type de tuile? ex:
Puis de réutiliser la même tuile exemple à chaque fois que la tuile est dessiné. Si cela ne fonctionne pas, vous devez les mettre dans une sorte de mesure du rendement pour voir quelle partie du code est de prendre le plus de temps, et de minimiser la quantité de fois que le code est exécuté, ou d'essayer de mince vers le bas.
Avertissement: je ne suis pas un programmeur Android
OriginalL'auteur
Le problème est assez évident. Vous êtes tout simplement la fuite d'un enfer de beaucoup de mémoire. Prendre un coup d'oeil dans le LogCat et vous verrez ce que je veux dire.
1. Ne JAMAIS allouer des chaînes de chaque image. Ils sont immuables de sorte que chaque opération avec une des chaînes est égal à la mémoire de la fuite. Utiliser à la place un simple char[] objet que vous modifiez.
2. Arrêter de créer des objets bitmap, encore et encore. Je suppose que le DecodeBitmap méthode interne alloue un objet bitmap pour chaque appel. C'est mal de faire que chaque image.
Comme une règle du pouce -> une fuite de mémoire et c'est copain de la GC sont très coûteuses opérations éviter lors de la rédaction.
OriginalL'auteur
Je n'ai jamais programmé pour Android avant, donc je ne suis pas sûr à 100% sur ce qui se passe sous le couvre-il, mais en supposant que:
ce bout de code va et des charges jusqu'à une image bitmap en mémoire, il semblerait que vous êtes recharger chaque bitmap, comme vous le dessiner.
Ce que j'ai fait lors de l'élaboration de petits jeux dans le passé, c'est quand vous allez à la charge d'un niveau, travailler sur toutes les ressources dont vous aurez besoin, puis de les charger en mémoire une fois, puis de les réutiliser.
OriginalL'auteur
}
OriginalL'auteur
une autre pensée, d'un non programmeur, est peut-être créer un grand carreau de fond qui défile, etc.. et une seconde couche supérieure où des biens mobiliers (joueurs, pnj, items) sont dessinées au-dessus de l'arrière-plan. par conséquent, le défilement est plus rapide et moins de (re)rendu.
J'imagine que ce serait peut-être plus de ressources que le référencement déjà rendu de tuiles (comme mentionné dans une autre suggestion ci-dessus).. mais il pourrait ne pas être, vous auriez à donner un coup de feu et voir. 🙂
OriginalL'auteur
Comment sur le déplacement de l'ensemble de la vue lorsque l'utilisateur fait défiler. Lorsque vous faites défiler les fenêtres, vous fait déplacer la fenêtre dans la direction opposée de ce que vous percevez. Vous faites défiler vers le bas, les fenêtres se déplace vers le haut..
Je suis sûr que vous pourriez recueillir tous les éléments dans une vue (la grille) et déplacer l'ensemble de la vue..
Le rendu des images hors de l'écran (plus rapide) et de les déplacer au besoin..
Il y a des exemples disponibles.. je sais que vous pouvez obtenir tout le code de l'écran d'accueil, et il défile de gauche à droite. Peut-être quelque chose à regarder. Je suis assez sûr que ils n'a que application.
OriginalL'auteur