如何抽签在屏幕上的位图在Android游戏,而降低性能 [英] How to draw lots of bitmaps on screen in an Android game without slow performance

查看:122
本文介绍了如何抽签在屏幕上的位图在Android游戏,而降低性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想打一个基于区块的游戏为Android。目前,我正在绘制每个切片作为一个单独的位图。我有一个大的循环,读取一个字符串并绘制不同的瓷砖取决于它找到绘制水平是什么角色。

我已经允许用户滚动通过滚动手势的屏幕。然而,比赛的节奏太慢。这需要很长的时间用户滚动后更新屏幕。我presume这是因为它有单独绘制每瓦的位图。

什么将是一个更快的方法来画的水平?我想我可以合并所有的瓷砖到一个位图。但我不知道如何做到这一点。任何想法?

反正这是我的code所以你可以看到这个问题:

 包org.example.tutorial2d;

进口android.app.Activity;
进口android.os.Bundle;
进口android.view.GestureDetector;
进口android.view.MotionEvent;
进口android.view.GestureDetector.OnGestureListener;

进口org.example.tutorial2d.Panel;

公共类Tutorial2D扩展活动实现OnGestureListener {

GestureDetector gestureScanner;
面板为主;

/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);

    gestureScanner =新GestureDetector(本);

    //requestWindowFeature(Window.FEATURE_NO_TITLE);
    主要=新的面板(本);
    的setContentView(主);

}

@覆盖
公共布尔的onTouchEvent(MotionEvent我)
{
 返回gestureScanner.onTouchEvent(箱);
}

@覆盖
公共布尔onScroll(MotionEvent E1,E2 MotionEvent,浮distanceX,浮动distanceY)
{
 main.handleScroll(distanceX,distanceY);
 返回true;
}

////////////////////
///////////////////
//////////////////
@覆盖
公共布尔onDown(MotionEvent E)
{
 返回true;
}

@覆盖
公共布尔onFling(MotionEvent E1,E2 MotionEvent,浮velocityX,浮动velocityY)
{
 返回true;
}

@覆盖
公共无效onLong preSS(MotionEvent E){}

@覆盖
公共无效OnShow中preSS(MotionEvent E){}

@覆盖
公共布尔onSingleTapUp(MotionEvent E)
{
 返回true;
}
////////////////////
///////////////////
//////////////////
}
 

和做所有的工作类:

 包org.example.tutorial2d;

进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.drawable.Drawable;
进口android.util.Log;
进口android.view.View;
进口org.example.tutorial2d.Point;

公共类面板扩展视图{

私人诠释scrollX = 0;
私人诠释scrollY = 0;

公共面板(上下文的背景下)
{
超(上下文);
}

@覆盖
公共无效的OnDraw(帆布油画)
{
/ *位图划伤;
//绘制对象划伤;
//从头=的getContext()。getResources()。getDrawable(
    // R.drawable.icon);
canvas.drawColor(Color.BLACK);
//scratch.draw(canvas);
INT原点= 0;
划伤= BitmapFactory.de codeResource(getResources(),R.drawable.horizo​​ntal5);
canvas.drawBitmap(划伤,产地,产地,NULL);
INT宽度= scratch.getWidth();
INT高= scratch.getHeight();
划伤= BitmapFactory.de codeResource(getResources(),R.drawable.room4entrynesw3x3);
canvas.drawBitmap(划伤,产地+宽,产地 -  32,NULL);
* /

字符串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();我++)
{
位图tileImage;
炭砖= sucide_mission.charAt(ⅰ);

Log.d(画砖,Character.toString(瓦)++ X +,+ y)基

开关(瓦)
{
案W:
如果(X< tileImage = BitmapFactory.de codeResource(getResources(),R.drawable.walla);
canvas.drawBitmap(tileImage,X  -  scrollX,Y  -  scrollY,NULL);
X + = 32;
				打破;
案例'F':
tileImage = BitmapFactory.de codeResource(getResources(),R.drawable.floore);
canvas.drawBitmap(tileImage,X  -  scrollX,Y  -  scrollY,NULL);
X + = 32;
				打破;
			外壳 ' ':
X + = 32;
				打破;
案'\ n'的
Y + = 32;
X = 0;
				打破;
}

}

//canvas.drawBitmap(adapt,0,0,油漆);
//canvas.drawBitmap(corner,产地-scrollX,产地-scrollY,油漆);

}

 公共无效handleScroll(浮动distX,浮动distY)
 {
      // X轴////////////////////////////////

      如果(distX> 6.0)
      {
           如果(scrollX< 460)
           {
                scrollX + = 30;
           }
      }
      否则,如果(distX< -6.0)
      {
           如果(scrollX> = 30)
           {
                scrollX  -  = 30;
           }
      }
      ////////////////////////////////////////////

      // y轴//////////////////////////////////
      如果(distY> 6.0)
      {
           如果(scrollY&小于100)
           {
                scrollY + = 30;
           }
      }
      否则,如果(distY< -6.0)
      {
           如果(scrollY> = 30)
           {
                scrollY  -  = 30;
           }
      }
      ////////////////////////////////////////////

      如果((scrollX&其中; = 480)及及(scrollY&其中; = 120))
      {
           //适应= Bitmap.createBitmap(BMP,scrollX,scrollY,320,480);
           无效();
      }
 }
}
 

解决方案

看起来你正在为每一个渲染瓦每个位图图像的新实例。而不是做,也许,你可以为每瓦类型创建一个实例?例如:

 私人位图wallTile = BitmapFactory.de codeResource(getResources(),R.drawable.walla);
私人位图floorTile = BitmapFactory.de codeResource(getResources(),R.drawable.floore);
 

然后每个瓦片被绘制时重复使用相同的瓷砖实例。如果这样做不行,你应该把某种绩效测量的,看看有什么的code部分占用了最长的时间,最大限度地减少了倍,code运行时的金额,或尝试苗条它记下来。

免责声明:我不是一个Android程序员

I want to make a tile based game for android. At the moment I am drawing each tile as a separate bitmap. I have a big for loop that reads from a string and draws different tiles depending on what character it finds to draw the level.

I have allowed the user to scroll the screen using scrolling gestures. However the game is too slow. It takes a long time to update the screen after the user scrolls. I presume this is because it has to draw each tile's bitmap individually.

What would be a faster way to draw the level? I was thinking I could merge all the tiles into one bitmap. But I don't know how to do this. Any ideas?

Anyway here is my code so you can see the problem:

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;
}
////////////////////
///////////////////
//////////////////
}

And the class that does all the work:

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();
      }
 }
}

解决方案

It looks like you are creating a new instance of each bitmap image for every tile rendered. Maybe instead of doing that, you could create one instance for each tile type? ex:

private Bitmap wallTile = BitmapFactory.decodeResource(getResources(), R.drawable.walla);
private Bitmap floorTile = BitmapFactory.decodeResource(getResources(), R.drawable.floore);

Then reuse the same tile instance each time the tile is drawn. If this doesn't work, you should put in some kind of performance measurement to see what part of the code is taking the longest time, and minimize the amount of times that code is run, or try to slim it down.

Disclaimer: I am not an Android programmer

这篇关于如何抽签在屏幕上的位图在Android游戏,而降低性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆