2017-03-08 3 views
0

Je développe un jeu Android 2D simple et je veux dessiner l'arrière-plan de chaque niveau lorsque le niveau commence. L'arrière-plan sera statique pour chaque niveau, il ne s'animera pas et ne bougera pas. Dans un premier temps, je dessinais l'arrière-plan dans une vue personnalisée en utilisant une toile et je chargeais cette vue comme arrière-plan du niveau. Cela a fonctionné, cependant j'ai remarqué que si je dessine beaucoup de lignes et de formes, l'interface utilisateur commence à bégayer. J'ai résolu le problème en tirant l'arrière-plan via la toile et l'enregistrer directement dans un bitmap, que je puis charger en arrière-plan ImageView comme vous pouvez le voir ci-dessous:Android 2D jeu de toile - dessiner bitmap de fond

CustomView bgView = new CustomView(this); //this view draws the background 
Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); 
Canvas canvas = new Canvas(bitmap); 
bgView.draw(canvas); 
ImageView imageViewBg = (ImageView) findViewById(R.id.imageViewBg); 
imageViewBg.setImageBitmap(bitmap); 

Le problème que je remarque avec cette approche est que je suis en train de créer un bitmap avec une taille de [screenWidth x screenHeight] qui pourrait provoquer un OutOfMemoryError. Alors, quelle est la meilleure approche pour dessiner l'arrière-plan d'un jeu en plein écran? Le problème est que je veux dessiner dynamiquement, je ne peux pas le charger directement à partir des actifs. (Je pourrais utiliser le profil Bitmap.Config.RGB_565, mais cela ne fera que réduire la taille de l'image bitmap de moitié, ce n'est pas la solution optimale).

Répondre

0

J'utilise Bitmap.createScaledBitmap():

Bitmap b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.background),WIDTH,HEIGHT,false); 

Obtenez le width and height of the screen

dessiner ensuite comme d'habitude:

canvas.drawBitmap(b, 0, 0, null); 

EDIT:

Chargez le bitmap comme vous le feriez comme. Pour les besoins de l'exemple, l'objet Bitmap sera appelé b. Alors d'abord:

WIDTH = b.getWidth(); 
HEIGHT = b.getHeight(); 

Passer à rendre:

public void render(Canvas c){ 
    final float scaleFactorX = getWidth()/(WIDTH*1.f); 
    final float scaleFactorY = getHeight()/(HEIGHT*1.f); 
    //check if the canvas is null first. 
    int savedState = c.getSaveCount(); 
    c.scale(scaleFactorX, scaleFactorY); 
    //draw your bitmap. 
    c.restoreToCount(); 
    //Do normal rendering 

} 

Explication

Ce que je fais ici est à l'échelle du rendu seulement pour le bitmap. Cela signifie que tout ce qui est rendu ne sera pas affecté par cela.

Nous avons besoin d'obtenir les facteurs d'échelle à l'échelle de l'écran lors du rendu Bitmap:

final float scaleFactorX = getWidth()/(WIDTH*1.f); 
final float scaleFactorY = getHeight()/(HEIGHT*1.f); 

puis enregistrez l'état de la toile pour recharger plus tard.

int savedState = c.getSaveCount(); 

Maintenant, nous l'échelle de l'image bitmap en utilisant le scaleFactors précédemment défini

c.scale(scaleFactorX, scaleFactorY); 

et restaurer le bitmap à son état d'origine pour attirer tout le reste dans tout type d'échelle dont vous avez besoin. Si vous n'avez pas besoin de zoomer l'image bitmap (si vous avez un zoom), vous pouvez ajouter cette mise à l'échelle après la mise à l'échelle de l'arrière-plan.

c.restoreToCount(); 
+0

Je peux voir que vous chargez le bitmap à partir de ressources, alors que je veux le créer à partir de zéro. De plus, si le bitmap a la taille de l'écran, ne serait-il pas encore énorme en termes d'allocation d'octets? – MScott

+0

Je l'ai chargé à partir de ressources pour le rendre testable. Comment vous chargez le bitmap est à vous. Comme si la mémoire, c'est un problème que je n'ai pas considéré ici. Je vais mettre à jour la réponse avec une solution différente. – Zoe

+0

Voir les modifications apportées à la réponse – Zoe