Thứ tư, ngày 20 tháng 9 năm 2017

AndEngine - Cách sử dụng object pool

Ngày đăng: 11/9/2012, 8:47:56PM | Lượt xem: 3,772
Hot!
tag ,

  Mình vừa nghiên cứu xong phần Object Pool của AndEngine, xin chia sẽ cùng các bạn.
Trong game, đặc biệt là trên mobile, việc tạo quá nhìu instance cho cùng 1 object sẽ gây chiếm dụng bộ nhớ, làm cho game chạy chậm đi hoặc giựt giựt. Ví dụ game bắn súng, khi người dùng bắn 1 viên đạn ra , bạn tạo 1 object viên đạn, người dùng bắn 100 viên, bạn tạo 100 object, sẽ rất tốn bộ nhớ ... Sẽ tốt hơn khi có thể sử dụng lại nếu có 1 object viên đạn nào đó mà nó finish xong chu trình của nó. Do đó object pool ra đời. 

  Và đây là ví dụ của mình, cứ mỗi giây sẽ tạo 1 object FaceSprite, di chuyển dọc trên màn hình và khi ra khỏi màn hình (tức là ko còn hiển thị trên màn hình nữa) thì sẽ đc lưu vào object pool và sẽ đc sử dụng lại.

package com.myapp.test;

import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.modifier.LoopEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.constants.TimeConstants;

public class FaceSprite extends AnimatedSprite implements TimeConstants {

	private Path path;
	private LoopEntityModifier lem ;
	private boolean isAttachToScene;
	
	public FaceSprite(float pX, float pY, float pTileWidth, float pTileHeight,
			TiledTextureRegion pTiledTextureRegion) {
		super(pX, pY, pTileWidth, pTileHeight, pTiledTextureRegion);
		
		isAttachToScene = false;
		settingMovePath();
	}

	private FaceSprite getInstance() {
		return this;
	}
	
	public boolean isAttachToScene() {
		return isAttachToScene;
	}

	public void setAttachToScene(boolean isAttachToScene) {
		this.isAttachToScene = isAttachToScene;
	}
	
	private void settingMovePath() {
		int x1 = MathUtils.random(1, 3) * 100 - 70;
		int y1 = 500;
		int x2 = x1;
		int y2 = 50;
		path = new Path(3).to(x1,y1).to(x2, y2).to(x1, y1);
		
		PathModifier pm = new PathModifier(33, path, null, new IPathModifierListener() {

			@Override
			public void onPathStarted(PathModifier pPathModifier,
					IEntity pEntity) {
				
			}

			@Override
			public void onPathWaypointStarted(PathModifier pPathModifier,
					IEntity pEntity, int pWaypointIndex) {
				
				// method animate truyen vao frame duration: thoi gian cua moi frame hien thi
				// frame bat dau va frame ket thuc fai tuong ung voi so frame
				int startFrame = 1;
				int endFrame = 5;
				int frameDuration = 200;
				getInstance().animate(new long[]{frameDuration, frameDuration, frameDuration, frameDuration, frameDuration}, startFrame, endFrame, true);
				
			}

			@Override
			public void onPathWaypointFinished(PathModifier pPathModifier,
					IEntity pEntity, int pWaypointIndex) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onPathFinished(PathModifier pPathModifier,
					IEntity pEntity) {
				// TODO Auto-generated method stub
		
			}}
			);
		lem = new LoopEntityModifier(pm);
		this.registerEntityModifier(lem);
	}
}

Đây là lớp FacePool, lớp này sẽ extend GenericPool<object>
- ArrayList<FaceSprite> arrFaceSprite : chứa tất cả object FaceSprite đc tạo ra
- Method onAllocatePoolItem dùng để tạo object FaceSprite và gắn nó và Scene bên trong class này luôn. Vì nếu bạn gọi và add từ bên ngoài thì khi recycle lại object này, nó sẽ di chuyển càng lúc càng nhanh (theo mình nghiên cứu là do nó register lại updatehandler của object FaceSprite này)
- Method onHandleRecycleItem: dùng recycle 1 object cụ thể
- Method onHandleObtainItem: reset lại object như lúc ban đầu
- Method checkAndRecycle: mình sẽ lặp qua hết các object trong Pool và sẽ recycle lại nếu thỏa điều kiện

package com.myapp.test;

import java.util.ArrayList;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.pool.GenericPool;

public class FacePool extends GenericPool<FaceSprite> {
	
	private TiledTextureRegion ttr;
	private Engine mEngine;
	private ArrayList<FaceSprite> arrFaceSprite;
	
	public FacePool(Engine engine, TiledTextureRegion pttr) {
		mEngine = engine;
		ttr = pttr;
		arrFaceSprite = new ArrayList<FaceSprite>();
	}
	
	@Override
	public FaceSprite onAllocatePoolItem() {
		FaceSprite fs=  new FaceSprite(0, 0, 45, 45, ttr.clone());
		fs.setAttachToScene(true);
		mEngine.getScene().attachChild(fs);
		arrFaceSprite.add(fs);
		return fs;
	}
	
	@Override
	public void onHandleRecycleItem(final FaceSprite fs){
		if (fs.isAttachToScene()) {
			fs.setIgnoreUpdate(false);
			fs.setVisible(true);
			fs.setAttachToScene(false);
		}
		
	}
	
	@Override
	public void onHandleObtainItem(final FaceSprite fs) {
		fs.reset();
	}
	
	public void checkAndRecycle() {
		for (FaceSprite fs : arrFaceSprite) {
			if (fs.getY()>150) {
				this.recyclePoolItem(fs);
			}
		}
	}
}

Và đây là đoạn code khi sử dụng object pool, mình sử dụng TimerHandler với method onTimePassed để liên tục tạo object FaceSprite sau mỗi giây

public void usePool(final Engine engine, final TiledTextureRegion ttr) {
		
		FACEPOOL = new FacePool(engine,ttr);

		TimerHandler th = new TimerHandler(1, true, new ITimerCallback() {
			@Override
			public void onTimePassed(TimerHandler pTimerHandler) {
				FACEPOOL.obtainPoolItem();
				
				FACEPOOL.checkAndRecycle();
			}
		});
		engine.registerUpdateHandler(th);
	}

 

Nguồn vietandroid
 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.