40
1 Trương Thanh Anh Tuấn Email:[email protected]

And Engine Document

Embed Size (px)

Citation preview

Page 1: And Engine Document

1

Trương Thanh Anh Tuấn Email:[email protected]

Page 2: And Engine Document

2

Trương Thanh Anh Tuấn Email:[email protected]

Mục lục

1. LÀM THẾ NÀO ĐỂ LÀM 1 GAME ? CÁCH GÌ TỐT NHẤT ĐỂ LÀM GAME ? ............................................................................. 3

2. BAO LÂU THÌ SẼ HOÀN THÀNH XONG 1 GAME ? .................................................................................................................... 3

3. TẠI SAO LẠI PHẢI SỬ DỤNG ANDENGINE MÀ KHÔNG PHẢI 1 ENGINE NÀO KHÁC ? ........................................................ 3

4. NHỮNG BƯỚC ĐẦU TIÊN TRONG LẬP TRÌNH GAME VỚI ANDENGINE (GLES2): ............................................................... 3

5. CÁC EXTENTIONS VÀ EXAMPLE CỦA ANDENGINE ................................................................................................................ 5

6. NHỮNG VẤN ĐỀ CHÍNH TRONG ANDENGINE ........................................................................................................................... 7

7. XÂY DỰNG CÁC THÀNH PHẦN ĐỂ TẠO NÊN 1 GAME (GLES2) .............................................................................................. 9

8. XÂY DỰNG CÁC THÀNH PHẦN ĐỂ TẠO NÊN 1 GAME (GLES1) ............................................................................................ 16

Page 3: And Engine Document

3

Trương Thanh Anh Tuấn Email:[email protected]

1. Làm thế nào để làm 1 game ? Cách gì tốt nhất để làm game ?

Đó thật sự là 1 vấn đề khó để trả lời vì viết 1 game sử dụng trên nhiều platform thì cần rất nhiều công sức bỏ ra để thực

hiện và cần có 1 sự kiên nhẫn nhất định để thực hiện.Nên nó không phải là cách làm tốt nhất.Trong bài viết này sẽ sử dụng 1

Engine để giúp việc thực hiện 1 game trở nên dễ dàng thực hiện hơn.

2. Bao lâu thì sẽ hoàn thành xong 1 game ?

Tùy theo độ sâu của trò chơi mà có thể chiếm cả năm trời lập trình hoặc chỉ tốn vài ngày để thực hiện nếu nó không có độ

hoành tráng trong game.

3. Tại sao lại phải sử dụng AndEngine mà không phải 1 Engine nào khác ?

Có rất nhiều Engine dùng để làm 1 game sử dụng nhiều nhất ở Việt Nam đơn cử là E3Droid hoặc AndEngine hoặc libgdx

,nhưng tại sao lại nên sử dụng AndEngine ?.Chính vì sự thuận tiện để thực hiện 1 cách dễ dàng để làm game và nó cho bạn 1

sự tự do để sử dụng các nguồn tài nguyên mà Android và Java đã cung cấp để thực hiện . Đó là 1 framework cho bạn nhiều sự

tự do nhiều hơn những framework khác nhưng bạn cũng cần phải bỏ ra chút ít công sức nữa nếu muốn sản phẩm bạn làm ra

nó sẽ là tốt nhất .Có những Framework hạn chế sự tự do tưong tác của bạn lại nên khiến cho game rất đơn giản trong cách

chơi ví dụ như libgdx và cón 1 phần quan trọng nữa là cộng đồng làm game hiện tại ở Việt Nam thì AndEngine đang phát triển

rất mạnh.

4. Những bước đầu tiên trong lập trình game với AndEngine (GLES2):

Cài đặt và chuẩn bị những yêu cầu về phần mềm

o JDK : Tốt nhất nên cài đặt phiên bản mới nhất để được sự hỗ trợ tốt nhất tại đây

o ADT : Sử dụng IDE của phát triển Android tại đây

o AndEngine Source : Bộ thư viện download tại đây , bạn có thể xem các example về các tính năng mà bộ

framework này hỗ trợ tại đây

Example đầu tiên : Hello world với AndEngine GLES2

Import thư viện AndEngine :

Tạo Project HelloWorld và import thư viện AndEngine :

Page 4: And Engine Document

4

Trương Thanh Anh Tuấn Email:[email protected]

Add image HelloWorld vào trong thư mục asset tải hình tại đây

Activity sử dụng AndEngine đều phải extend lại SimpleBaseGameActivity hoặc BaseGameActivity.

Khai báo 2 biến quan trọng :

private ITexture mHelloWorldTexture;

private ITextureRegion mHelloWorldTextureRegion;

Kích thước vùng hiển thị :

private static final int CAMERA_WIDTH = 800;

private static final int CAMERA_HEIGHT = 480;

Trong phuơng thức onCreateEngineOptions :

final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);//Quản lý cấu hình màn hình

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR,

new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);

Trong phuơng thức onCreateResources:

//Sử dụng resource đang có trong thư mục assets

this.mHelloWorldTexture = new AssetBitmapTexture(this.getTextureManager(),

this.getAssets(), "helloworld.png");

this.mHelloWorldTextureRegion = TextureRegionFactory.extractFromTexture(

this.mHelloWorldTexture);

this.mHelloWorldTexture.load();

Trong phuơng thức onCreateScene:

//Quản lý tất cả những gì bạn vẽ trên vùng hiển thị

this.mEngine.registerUpdateHandler(new FPSLogger());

final Scene scene = new Scene();

Page 5: And Engine Document

5

Trương Thanh Anh Tuấn Email:[email protected]

scene.getBackground().setColor(Color.YELLOW);

final float centerX = CAMERA_WIDTH / 2;

final float centerY = CAMERA_HEIGHT / 2;

final Sprite sprite = new Sprite(centerX, centerY,

this.mHelloWorldTextureRegion, this.getVertexBufferObjectManager());

scene.attachChild(sprite); // 1 đối tượng hình là 1 sprite trong AndEngine

return scene;

Kết quả của example trên :

5. Các Extentions và Example của AndEngine

Đầu tiên đến với AndEngine ta có 1 bất lợi là không có document cho framework này,nhưng bù lại ta có 1 lượng example

rất lớn đủ để viết 1 game theo ý muốn.Phần này sẽ huớng dẫn bạn cách thêm các Extention của AndEngine .

Download Project Example tại đây

Download Project Extention:

1. AndEngine

2. AndEngineAugmentedRealityExtension

3. AndEngineMODPlayerExtension

4. AndEngineSVGTextureRegionExtension

5. AndEnginePhysicsBox2DExtension

6. AndEngineMultiplayerExtension

7. AndEngineTMXTiledMapExtension

8. AndEngineScriptingExtension

9. AndEngineCocosBuilderExtension

10. AndEngineLiveWallpaperExtension

11. AndEngineCocosBuilderExtensionCCRotatingSpriteExtension(sm4)

12. AndEngineCocosBuilderExtensionCCRotatingSpriteExtension(nicolasgramlich)

Page 6: And Engine Document

6

Trương Thanh Anh Tuấn Email:[email protected]

Sau khi import vào ta nên Clean All Project .

Và fix những lỗi sau trước khi xem các example của AndEngine :

1. Lỗi của SVG Extension :

Add unimplemented các phuơng thức còn thiếu,bởi vì SVG extension không có trong version AnchorCenter.

2. Lỗi của Scripting Extension :

.Sử dụng search -> file sau đó replace import org.andengine.util.color.Color; thành import

org.andengine.util.adt.color.Color;

.Xóa class RectangularShapeProxy bởi vì nó không sử dụng trong version AnchorCenter.

3. Lỗi của AndEngine Examples :

Cuối cùng ta sẽ tiếp tục fix lỗi đối với AndEngineExample ,danh sách lỗi như sau :

Search Replace

import org.andengine.extension.multiplayer.protocol import org.andengine.extension.multiplayer

import

org.andengine.extension.multiplayer.exception.BluetoothException; import org.andengine.util.exception.BluetoothException;

Page 7: And Engine Document

7

Trương Thanh Anh Tuấn Email:[email protected]

import org.andengine.entity.particle.modifier.ExpireParticleInitializer; import

org.andengine.entity.particle.initializer.ExpireParticleInitializer;

import org.andengine.extension.multiplayer.util.IPUtils; import org.andengine.util.IPUtils;

import org.andengine.extension.multiplayer.util.WifiUtils; import org.andengine.util.WifiUtils;

if(!AndEngine.isDeviceSupported()) { if(!AndEngine.isDeviceSupported(this)) {

Các IOExceltion báo lỗi ta chuyển thành Exception.

Các lỗi thư viện còn lại , ta remove dòng Import thư viện và add lại đối với các hàm cần thư viện.

Run Appliation để xem thành quả .

6. Những vấn đề chính trong AndEngine

Camera :

Camera trong game nó xác định màn hình hiển thị và trình bày cho người chơi thấy ,nó giống như 1 máy quay phim

trong 1 không gian 2 chiều và ta có thể tương tác phóng to hoặc thu nhỏ , điều khiển các vật thể tuơng tác với game.

Nó xác định một hình chữ nhật với chiều dài và chiều rộng xác định trước để vẽ lên màn hình. Có thể tất cả các thứ

trong game sẽ được nhìn thấy trên camera hoặc camera chỉ hiển thị một phần của khung cảnh, bạn phải di chuyển

camera để nhìn thấy các phần còn lại (Boundcamera) . Hoặc một camera có thể phóng to, thu nhỏ hoặc cuộn gọi là

ZoomCamera.

Scene :

Nó chứa tất cả các đối tượng mà bạn vẽ trên màn hình. Nó giống như một tờ giấy, trên đó bạn có thể vẻ tất cả các

hình, cập nhật chúng và có thế chứa các tờ giấy khác.

1 game giống như 1 bộ phim được trình chiếu đến người xem mà trong đó nó bao gồm các hoạt cảnh và các hành

động diễn ra trong 1 “bộ phim” ,những cảnh này được biên tập lại và sắp xếp với nhau 1 cách cố định nó sẽ tạo thành 1

bộ phim hoàn chỉnh .

Layer :

Các scene là tập hợp các layer đồ họa nó nằm chồng lên nhau giống như các cel được sử dụng làm phim hoạt

hình như hồi xưa ,ngoài ra các layer còn tạo hiệu ứng 21/2D.

Sprite :

Nó được ví như các “diễn viên” trong 1 bộ phim ,nó có thể là 1 con người hoặc 1 đồ vật,nó có thể di chuyển hoặc

không và nó có thể di chuyển trong các scene ,cấu trúc của 1 sprite bao gồm tập hợp các hình ảnh sprite được gọi là

sprite sheet.

Entity :

Là những Object sẽ vẽ các bức ảnh của bạn lên scene. Có thể một bức ảnh tỉnh (Sprite), một bức ảnh động

(AnimatedSprite), hoặc một bức ảnh có nhiều bức ảnh con trong nó (TitledSprite).

Trong AndEngine các entity(thực thể) là những thứ được vẽ hoặc hiển thị trên màn hình nó chính là các sprite ví dụ

như 1 viên gạch hoặc 1 đối tuợng hình học hoặc 1 dòng kẻ được vẽ trên màn hình.Tất cả các thực thể đều có các

thuộc tính như màu sắc,độ co giãn,góc xoay, vị trí đặt và nó có thể chỉnh sửa lại giá trị nếu mình muốn.

Modifier :

Modifier có thể thay đổi thuộc tính của các Entity và nó rất mạnh nhất là trong AndEngine .Nó có thể sử dụng trên

bất kỳ Entity nào đó và nó sẽ được thay đổi và cập nhật ngay lập tức trong khi game vẫn đang diễn ra .Trong 1 game

chúng TATT modifier thường xuyên sử dụng để tạo các hiệu ứng với Sprite và Entity khác.

Page 8: And Engine Document

8

Trương Thanh Anh Tuấn Email:[email protected]

Texture :

Texture Region :

Engine :

Trong game có nhiều tiến trình nhỏ chạy song song. Engine sẽ quản lí tất cả các tiến trình đó. Cái này bạn không

cần phải quan tâm nhiều vì andengine sẽ làm việc đó.

BaseGameActivity :

Là 1 lớp mở rộng của lớp Activity trong android,nó là cơ sở cho mỗi scene trong game ,nó làm tất cả các công việc

của chung của tất cả các scene và các thiết lập trong engine của game ,đối với các cảm biến và vòng đời của mỗi

Activity.

Physics Connector :

AndEngine bao gồm cả tính năng vật lý cơ bản ở trong bộ engine,Box2D Physics Engine là phần mở rộng lớn vào

những khả năng này.Chúng kết nối các đối tượng trong AndEngine với Box2D thông qua kết nối vật lý.Nếu trong game

của bạn không sử dụng Box2D thì game se không có bất cứ tương tác vật lý thông qua kết nối vật lý.

Box2D Physics Engine :

AndEngine bao gồm bộ mã nguồn mở Jbox2 nó là 1 cổng của engine Box2D vật lý.Nó có thể sử dụng để mô

phỏng tương tác thực tế của các đối tượng trong những các sau :

+Trọng lực (Gravity)

+Stable stacking

+Mô phỏng vật lý của các cơ quan trong cơ thể

Page 9: And Engine Document

9

Trương Thanh Anh Tuấn Email:[email protected]

7. Xây dựng các thành phần để tạo nên 1 game (GLES2)

3 thành phần quan trọng của 1 Activity kế thừa từ SimpleBaseGameActivity:

Mỗi 1 Activity sẽ có 1 vùng hiển thị hoạt cảnh (Scene) riêng và tất cả được quản lý bằng mEngine.

7.1 Cảnh nền (Background) :

Tùy theo thể loại game mà người sử dụng sẽ làm cảnh nền cho phù hợp,được chia ra làm 3 loại :

+Repeating Spire Background (Cảnh nền được khởi tạo full màn hình bẳng Spire được lặp theo chiều X và Y):

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

// Load ảnh từ thư mục Asset,loại Texture là Repeating

this.mBackgroundTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(),

"gfx/background_grass.png", TextureOptions.REPEATING_NEAREST);

this.mBackgroundTexture.load();

final ITextureRegion backgroundTextureRegion =

TextureRegionFactory.extractFromTexture(this.mBackgroundTexture);

// Thực hiện repeat theo chiều cao và chiều rộng của camera

this.mGrassBackground = new RepeatingSpriteBackground(CAMERA_WIDTH,CAMERA_HEIGHT,

backgroundTextureRegion,this.getVertexBufferObjectManager());

@Override

public EngineOptions onCreateEngineOptions() {

// Khởi tạo vùng quan sát (Camera) : Mặc định mỗi 1 Activity sẽ có chung phần khai báo,chiều

rộng,chiều cao,định hướng hiển thị sẽ tùy theo người sử dụng xét

final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new

RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);

}

@Override

public void onCreateResources() throws IOException {

// Khởi tạo nguồn tài nguyên từ Asset/Drawable/Folder bất kỳ/Load từ bộ nhớ

...

}

@Override

public Scene onCreateScene() {

// Khởi tạo vùng hiển thị hoạt cảnh (Scene) bao gồm các Spire/Particle/Button Sprite...

...

}

Page 10: And Engine Document

10

Trương Thanh Anh Tuấn Email:[email protected]

3.Method onCreateScene() :

Source đính kèm

RepeatingBackground.zip

+AutoParallax Background (Tạo cảnh nền di chuyển):

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

3.Method onCreateScene() :

final Scene scene = new Scene(); scene.setBackground(this.mGrassBackground);

this.mParallaxLayerBackTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(), "gfx/parallax_background_layer_back.png"); this.mParallaxLayerBackTextureRegion = TextureRegionFactory.extractFromTexture(this.mParallaxLayerBackTexture); this.mParallaxLayerBackTexture.load(); this.mParallaxLayerMidTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(), "gfx/parallax_background_layer_mid.png"); this.mParallaxLayerMidTextureRegion = TextureRegionFactory.extractFromTexture(this.mParallaxLayerMidTexture); this.mParallaxLayerMidTexture.load(); this.mParallaxLayerFrontTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(), "gfx/parallax_background_layer_front.png"); this.mParallaxLayerFrontTextureRegion = TextureRegionFactory.extractFromTexture(this.mParallaxLayerFrontTexture);

this.mParallaxLayerFrontTexture.load();

final Sprite parallaxLayerBackSprite = new Sprite(0, 0, this.mParallaxLayerBackTextureRegion, vertexBufferObjectManager); parallaxLayerBackSprite.setOffsetCenter(0, 0); autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(0.0f, parallaxLayerBackSprite)); final Sprite parallaxLayerMidSprite = new Sprite(0, CAMERA_HEIGHT - this.mParallaxLayerMidTextureRegion.getHeight() - 80, this.mParallaxLayerMidTextureRegion, vertexBufferObjectManager); parallaxLayerMidSprite.setOffsetCenter(0, 0); autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-5.0f, parallaxLayerMidSprite)); final Sprite parallaxLayerFrontSprite = new Sprite(0, 0, this.mParallaxLayerFrontTextureRegion, vertexBufferObjectManager); parallaxLayerFrontSprite.setOffsetCenter(0, 0);

autoParallaxBackground.attachParallaxEntity(new ParallaxEntity(-10.0f,

parallaxLayerFrontSprite));

Page 11: And Engine Document

11

Trương Thanh Anh Tuấn Email:[email protected]

Source đính kèm

ParallaxBackground.zip

+TMX TiledMap (Tạo Background từ TiledMap):Thuận lợi là tạo map dễ dàng do sử dụng Tool

Source đính kèm

TMXTiledBackground.zip

7.2 Các đối tượng :

7.2.1 ANIMATE SPRITE :

Cũng như Sprite nhưng Animate Sprite có thêm chức năng hoạt ảnh bằng cách chia 1 tấm ảnh ra thành nhiều vùng

và duyệt từng vùng của tấm ảnh khiến ta thấy ảnh chuyển động.

VD : Với tấm ảnh bên dưới để hoạt cảnh ta chia tấm ảnh ra 12 vùng:

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

TiledTextureRegion mSnapdragonTextureRegion mSnapdragonTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this,

"snapdragon_tiled.png", 4, 3);

3.Method onCreateScene() :

final AnimatedSprite snapdragon = new AnimatedSprite(CAMERA_WIDTH * 0.33f, CAMERA_HEIGHT * 0.66f,

this.mSnapdragonTextureRegion, this.getVertexBufferObjectManager());

snapdragon.animate(100); //Di chuyển sang vùng khác với độ trễ là 100ms

scene.attachChild(snapdragon);

Source đính kèm

AnimatedSprites.zip

7.2.2 BUTTON SPRITE :

Với những đối tượng không cần đến chuyển động thì Button Sprite là hợp lý nhất vì nó sẽ hạn chế được tài nguyên

sử dụng tấm ảnh mà không cần hoạt cảnh,các sử kiện trong GLES2 đối với Button Sprite gần như tương tự như

Widget Button của Android nhưng khác đối với sự kiện Long Click,đối với phần này phải viết riêng ra.

Page 12: And Engine Document

12

Trương Thanh Anh Tuấn Email:[email protected]

Chúng ta để ý kỹ là nếu như làm 1 button thì nó sẽ có hover effect và over effect,Sprite hoặc là Animated Sprite sẽ

không có 2 phần này còn muốn thực hiện thì ta sẽ khởi tạo 2 Sprite hoặc 2 Animated Sprite và khi Click lên mà giữ lâu

thì sẽ Visible = true Sprite hoặc Animated Sprite Hover lên thả ra thì Visible = false Sprite hoặc Animated Sprite Hover

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

this.mBuildableBitmapTextureAtlas = new BuildableBitmapTextureAtlas(this.getTextureManager(), 512, 512);

this.mButtonNormalTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBuildableBitmapTextureAtlas, this,

"button_normal.png");//Button ở trạng thái bình thường

this.mPressedTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBuildableBitmapTextureAtlas, this,

"button_pressed.png");");//Button ở trạng thái khi click lên

this.mDisabledTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBuildableBitmapTextureAtlas, this,

"button_disabled.png");//Button ở trạng thái khi Enable = false

try {

this.mBuildableBitmapTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource,

BitmapTextureAtlas>(0, 0, 0));

this.mBuildableBitmapTextureAtlas.load();

} catch (TextureAtlasBuilderException e) {

Debug.e(e);

}

3.Method onCreateScene() :

buttonSprite = new ButtonSprite(centerX, centerY, this.mButtonNormalTextureRegion,

this.mPressedTextureRegion, this.mDisabledTextureRegion, this.getVertexBufferObjectManager(), this); ");//Cả 3

trạng thái của 1 button sẽ được gom lại cho 1 Button Sprite

Source đính kèm

ButtonSprite.zip

7.2.3 SPRITE :

Đối với những yêu cầu như thể hiện 1 đối tượng tĩnh nào đó mà không quan trọng lắm trong game vd như cây cối

hoặc mây trôi thuyển trôi xe chạy .v.v… thì Sprite là sẽ phù hợp nhất để thực hiện.

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

this.mFaceTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(), "gfx/face_box.png");

this.mFaceTextureRegion = TextureRegionFactory.extractFromTexture(this.mFaceTexture);

this.mFaceTexture.load();

3.Method onCreateScene() :

Page 13: And Engine Document

13

Trương Thanh Anh Tuấn Email:[email protected]

final Sprite sprite = new Sprite(centerX, centerY, this.mFaceTextureRegion,

this.getVertexBufferObjectManager());

scene.attachChild(sprite);

Source đính kèm

Sprite.zip

7.2.4 PARTICLE SYSTEM :

Hệ thống hạt bản thân cũng là các Sprite kèm theo các chuyển động theo 1 Path với thời gian sống của mỗi hạt

được đính kèm theo mỗi hạt để tiết kiệm bộ nhớ mỗi khi sử dụng,đối với những yêu cầu như làm tuyết rơi,hoa rơi,lá

rơi,hiệu ứng lửa,nước chảy .v.v… thì Particle System là 1 lựa chọn phù hợp nhất.

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

this.mParticleTexture = new AssetBitmapTexture(this.getTextureManager(), this.getAssets(),

"gfx/particle_fire.png", TextureOptions.BILINEAR_PREMULTIPLYALPHA);

this.mParticleTextureRegion = TextureRegionFactory.extractFromTexture(this.mParticleTexture);

this.mParticleTexture.load();

3.Method onCreateScene() :

final BatchedPseudoSpriteParticleSystem particleSystem = new BatchedPseudoSpriteParticleSystem(new

PointParticleEmitter(0, ParticleSystemCoolExample.CAMERA_HEIGHT), 6, 10, 200,

this.mParticleTextureRegion,this.getVertexBufferObjectManager());

particleSystem.setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);

particleSystem.addParticleInitializer(new VelocityParticleInitializer<Entity>(15, 22, -60, -90));

particleSystem.addParticleInitializer(new AccelerationParticleInitializer<Entity>(5, 15));

//Góc xoay khi khởi tạo,nó sẽ random từ 0->360 độ

particleSystem.addParticleInitializer(new RotationParticleInitializer<Entity>(0.0f, 360.0f));

//Màu lúc khởi tạo theo hệ màu RBG

particleSystem.addParticleInitializer(new ColorParticleInitializer<Entity>(1.0f, 0.0f, 0.0f));

//Thời gian sống của mỗi hạt

particleSystem.addParticleInitializer(new ExpireParticleInitializer<Entity>(11.5f));

//Scale lớn ra theo thời gian thực

particleSystem.addParticleModifier(new ScaleParticleModifier<Entity>(0, 5, 0.5f, 2.0f));

particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(2.5f, 3.5f, 1.0f, 0.0f));

particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(3.5f, 4.5f, 0.0f, 1.0f));

Page 14: And Engine Document

14

Trương Thanh Anh Tuấn Email:[email protected]

//Màu sẽ chuyển từ màu nào sang màu nào theo hệ màu RBG

particleSystem.addParticleModifier(new ColorParticleModifier<Entity>(0.0f, 11.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f));

particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(4.5f, 11.5f, 1.0f, 0.0f));

Source đính kèm

ParticleSystem.zip

7.2.5 TEXT :

Các thông điệp hiển thị theo dạng text và có thể sửa đổi do người sử dụng thì chỉ duy nhất có Text mới có thể làm

được.

1.Method onCreateEngineOptions() : Khai báo mặc định như trên

2.Method onCreateResources() :

//Định đường dẫn chứa Font cần sử dụng

FontFactory.setAssetBasePath("font/");

//Khai báo kích thước,màu sắc,loại font cần sử dụng

this.mDroidFont = FontFactory.createFromAsset(this.getFontManager(), this.getTextureManager(), 256, 256,

TextureOptions.BILINEAR, this.getAssets(), "Droid.ttf", FONT_SIZE, true, Color.BLACK);

this.mDroidFont.load();3.Method onCreateScene() :

3.Method onCreateScene() :

final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();

//Set text và hiển thị lên Scene với kiểu Font đã được định nghĩa như trên

scene.attachChild(new Text(centerX, 400, this.mDroidFont, "Droid Font", vertexBufferObjectManager));

//Cập nhật text liên tục

scene.registerUpdateHandler(new TimerHandler(1 / 10.0f, true, new ITimerCallback() {

@Override

public void onTimePassed(final TimerHandler pTimerHandler) {

textExample.setText(String.format("FPS: %.2f", fpsCounter.getFPS()));

}

}));

Source đính kèm

TextExample.zip

Page 15: And Engine Document

15

Trương Thanh Anh Tuấn Email:[email protected]

7.3 Tương tác vật lý : Tương tác vật lý đóng vai trò quan trọng trong 1 game giúp người dùng tương tác trực tiếp với

các Sprite giúp game thêm sinh động và hấp dẫn,có nhiều phần trong AndEngine Physics,nhưng đây là những phần

cốt lõi nhất.

7.3.1 XÁC ĐỊNH VA CHẠM GIỮA 2 SPRITE :

1.Method onCreateScene() :

scene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() { }

@Override

public void onUpdate(final float pSecondsElapsed) {

// CollidesWith : Xác định va chạm giữa vật thể A và vật thể B

if(centerRectangle.collidesWith(sprite)) {

centerRectangle.setColor(1, 0, 0);

} else {

centerRectangle.setColor(0, 1, 0);

}

...

}

});

Source đính kèm

CollisionDetection.zip

7.3.2 TOUCH AND DRAG :

1.Method onCreateScene() :

final Sprite sprite = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager()) {

@Override

public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float

pTouchAreaLocalY) {

this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2, pSceneTouchEvent.getY() - this.getHeight() / 2);

return true;

}

};

Source đính kèm

TouchAndDrag.zip

7.4 Scene Manager : Trong 1 game,mỗi 1 cảnh hiện trên màn hình là 1 scene bao gồm các hoạt cảnh,như vậy nếu nhiều

scene thì việc quản lý và chuyển đổi qua lại giữa các scene sẽ như thế nào,do đó ta sẽ cần 1 Scene Manager để quản

lý tất cả các Scene.

Page 16: And Engine Document

16

Trương Thanh Anh Tuấn Email:[email protected]

Trong Example bên dưới sẽ demo việc load 1 game từ Scene Splash Screen xong sẽ đến Scene Menu

Screen,việc chuyển giữa các Scene sẽ mượt hơn khi dùng "sceneManager.setCurrentScene(AllScenes.MENU);“.

Source đính kèm

SceneManager.zip

8. Xây dựng các thành phần để tạo nên 1 game (GLES1 chỉ nên tham khảo thêm)

Chúng ta sẽ lấy thư viện được build sẵn để sử dụng khi xây dựng game, file bên dưới đang sử dụng AndEngine GLES1:

8.1 Dựng ảnh nền (Background):

public class MainActivity extends BaseGameActivity {

// Khai báo thêm 2 biến quan trọng

private Camera MyCamera;// Biến này thường để cấu hình màn hình

private Scene MyScene;// Quản lý những gì bạn vẽ.

private int WIDTH = 320;

private int HEIGHT = 480;

@Override

public Engine onLoadEngine() {

// Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

// Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true,

ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(WIDTH,

HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {}

@Override

public Scene onLoadScene() {

MyScene = new Scene();

// Dựng màu ảnh nền từ hệ màu RGB

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));

return MyScene;

Page 17: And Engine Document

17

Trương Thanh Anh Tuấn Email:[email protected]

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test01.rar

8.2 Thao tác với hiển thị text:

public class MainActivity extends BaseGameActivity {

// Khai báo thêm 2 biến quan trọng

private Camera MyCamera;// Biến này thường để cấu hình màn hình

private Scene MyScene;// Quản lý những gì bạn vẽ.

private int WIDTH = 320;// Chiều rộng vùng hiện thị

private int HEIGHT = 480;// Chiều cao vùng hiện thị

private BitmapTextureAtlas mFontTexture;// Lưu font vào bộ nhớ

private Font mFont;// Dùng để lưu lại font

@Override

public Engine onLoadEngine() {

// Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

// Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true,

ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(WIDTH,

HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

this.mFontTexture = new BitmapTextureAtlas(256, 256,

TextureOptions.BILINEAR_PREMULTIPLYALPHA);

// Tạo font mạc định và style là chữ đậm, cỡ chứ 14 màu đen

this.mFont = new Font(this.mFontTexture, Typeface.create(

Typeface.DEFAULT, Typeface.BOLD), 14, true, Color.BLACK);

Page 18: And Engine Document

18

Trương Thanh Anh Tuấn Email:[email protected]

// Load

this.mEngine.getTextureManager().loadTexture(this.mFontTexture);

this.mEngine.getFontManager().loadFont(this.mFont);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));// Đặt màu nền

// Khai báo 3 hiến text. Dùng HorizontalAlign để căn lề.

final Text textCenter = new Text(20, 60, this.mFont,

"Text A",

HorizontalAlign.CENTER);

final Text textLeft = new Text(20, 200, this.mFont,

"Text B",

HorizontalAlign.LEFT);

final Text textRight = new Text(20, 340, this.mFont,

"Text C",

HorizontalAlign.RIGHT);

// Hiện thị lên màn hình

MyScene.attachChild(textCenter);

MyScene.attachChild(textLeft);

MyScene.attachChild(textRight);

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test02.rar

8.3 Cập nhật game thời gian thực :

Page 19: And Engine Document

19

Trương Thanh Anh Tuấn Email:[email protected]

public class MainActivity extends BaseGameActivity {

//Khai báo thêm 2 biến quan trọng

private Camera MyCamera;//Biến này thường để cấu hình màn hình

private Scene MyScene;//Quản lý những gì bạn vẽ.

private int WIDTH = 320;//Chiều rộng vùng hiện thị

private int HEIGHT = 480;//Chiều cao vùng hiện thị

private BitmapTextureAtlas mFontTexture;//Lưu font vào bộ nhớ

private Font mFont;//Dùng để lưu lại font

private int dem = 0;

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

@Override

public Engine onLoadEngine() {

//Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

//Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT,

new RatioResolutionPolicy(WIDTH, HEIGHT),

this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

this.mFontTexture = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

//Tạo font mạc định và style là chữ đậm, cỡ chứ 14 màu đen

this.mFont = new Font(this.mFontTexture, Typeface.create(Typeface.DEFAULT, Typeface.BOLD), 14, true,

Color.BLACK);

//Load

this.mEngine.getTextureManager().loadTexture(this.mFontTexture);

this.mEngine.getFontManager().loadFont(this.mFont);

Page 20: And Engine Document

20

Trương Thanh Anh Tuấn Email:[email protected]

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));//Đặt màu nền

//Khai báo ChangeableText dùng để hiện thị thời gian theo từng giây

final ChangeableText textchange = new ChangeableText(10, 10, this.mFont, "", 10);//Tối đa hiện thị 10 ký tự

MyScene.attachChild(textchange);

//Cập nhật (coi như vòng lặp hoạt cảnh)

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {}

//Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

try {

//Tạm dừng cập nhật trong 1s

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//Cập nhật lại những gì bạn cần vẽ lại liên tục

dem++;

textchange.setText(String.valueOf(dem));//Cứ sau 1s ta lại hiện thị đếm

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test03.rar

Page 21: And Engine Document

21

Trương Thanh Anh Tuấn Email:[email protected]

8.4 Tạo 1 sprite :

Thêm 1 ảnh vào thư mục asset :

Pic 1 : ball.png

Đoạn code chính trong BaseGameActivity

public class MainActivity extends BaseGameActivity {

// Khai báo thêm 2 biến quan trọng

private Camera MyCamera;// Biến này thường để cấu hình màn hình

private Scene MyScene;// Quản lý những gì bạn vẽ.

private int WIDTH = 320;// Chiều rộng vùng hiện thị

private int HEIGHT = 480;// Chiều cao vùng hiện thị

private BitmapTextureAtlas bitmapTextureAtlas;// Lưu ảnh trong bộ nhớ

private TextureRegion textureRegion;// Lưu khi load ảnh

private Sprite sprite;// Sprite quả bóng

@Override

public Engine onLoadEngine() {

// Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

// Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true,

ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(WIDTH,

HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

// Khai báo vùng lưu trữ ảnh có kích thước 256,256. Đây là cái khó nhất

// đó. Sẽ giải thích sau.

this.bitmapTextureAtlas = new BitmapTextureAtlas(256, 256,

TextureOptions.BILINEAR_PREMULTIPLYALPHA);

// Load ảnh

Page 22: And Engine Document

22

Trương Thanh Anh Tuấn Email:[email protected]

this.textureRegion = BitmapTextureAtlasTextureRegionFactory

.createFromAsset(this.bitmapTextureAtlas, this, "ball.png", 0,

0);

mEngine.getTextureManager().loadTextures(this.bitmapTextureAtlas);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));// Đặt màu nền

// Đặt sprite tại vị trí x = 100,y = 100

this.sprite = new Sprite(100, 100, this.textureRegion);

MyScene.attachChild(sprite);// Add vào MyScene

// Cập nhật (coi như vòn lặp hoạt cảnh)

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {

// TODO Auto-generated method stub

}

boolean chuyen = false;

// Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

try {

// Tạm dừng cập nhật trong 10 ms

Thread.sleep(10);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// Di chuyển sang phải

if (!chuyen) {

sprite.setPosition(sprite.getX() + 5, 100);

if (sprite.getX() > 200)// Vượt quá giới hạn thì cho di

Page 23: And Engine Document

23

Trương Thanh Anh Tuấn Email:[email protected]

// chuyển ngược lại

chuyen = true;

} else {

sprite.setPosition(sprite.getX() - 5, 100);

if (sprite.getX() < 10)

chuyen = false;

}

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test04.rar

8.5 Tuơng tác với giao diện và sprite :

Thêm 1 ảnh vào thư mục asset :

Pic 1 : ball.png

Đoạn code chính trong BaseGameActivity

public class MainActivity extends BaseGameActivity {

// Khai báo thêm 2 biến quan trọng

private Camera MyCamera;// Biến này thường để cấu hình màn hình

private Scene MyScene;// Quản lý những gì bạn vẽ.

private int WIDTH = 320;// Chiều rộng vùng hiện thị

private int HEIGHT = 480;// Chiều cao vùng hiện thị

private BitmapTextureAtlas bitmapTextureAtlas;// Lưu ảnh trong bộ nhớ

Page 24: And Engine Document

24

Trương Thanh Anh Tuấn Email:[email protected]

private TextureRegion textureRegion;// Lưu khi load ảnh

private Sprite sprite;// Sprite quả bóng

/** Called when the activity is first created. */

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

@Override

public Engine onLoadEngine() {

// Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

// Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true,

ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(WIDTH,

HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

// Khai báo vùng lưu trữ ảnh có kích thước 256,256. Đây là cái khó nhất

// đó. Sẽ giải thích sau.

this.bitmapTextureAtlas = new BitmapTextureAtlas(256, 256,

TextureOptions.BILINEAR_PREMULTIPLYALPHA);

// Load ảnh

this.textureRegion = BitmapTextureAtlasTextureRegionFactory

.createFromAsset(this.bitmapTextureAtlas, this, "ball.png", 0,

0);

mEngine.getTextureManager().loadTextures(this.bitmapTextureAtlas);

}

@Override

Page 25: And Engine Document

25

Trương Thanh Anh Tuấn Email:[email protected]

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));// Đặt màu nền

// =================LẮNG NGHE SỰ KIỆN CHẠM VÀO MÀN HÌNH MyScene=======================

// Bắt sự kiện khi chạm vào MyScene

MyScene.setTouchAreaBindingEnabled(true);// cho phép lắng nghe

MyScene.setOnSceneTouchListener(new IOnSceneTouchListener() {

public boolean onSceneTouchEvent(final Scene pScene,

final TouchEvent pSceneTouchEvent) {

System.out.println("MyScene onSceneTouchEvent: chạm vào màn hình");

System.out.println("Tọa độ X = " + pSceneTouchEvent.getX());

System.out.println("Tọa độ Y = " + pSceneTouchEvent.getY());

// Khi chạm vào màn hình ta di chuyển sprite theo tọ độ y.

sprite.setPosition(sprite.getX(), pSceneTouchEvent.getY());

return true;

}

});

// =====================LẮNG NGHE SỰ KIỆN KHI CHẠM VÀO SPRITE==========================

// Đặt sprite tại vị trí x = 100,y = 100

this.sprite = new Sprite(100, 100, this.textureRegion) {

// Lắng nghe sự kiện khi chạm vào sprite

@Override

public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,

final float pTouchAreaLocalX, final float pTouchAreaLocalY) {

if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) {

System.out.println("Sprite onAreaTouched: chạm vào sprite");

System.out.println("Tọa độ X = " + pTouchAreaLocalX);

System.out.println("Tọa độ Y = " + pTouchAreaLocalY);

}

return true;

}

};

MyScene.attachChild(sprite);// Add vào MyScene

MyScene.registerTouchArea(sprite);// Phải đăng ký là cho phép sprite này được lắng nghe sự kiện

// ======================================================================================

// Cập nhật (coi như vòn lặp hoạt cảnh)

Page 26: And Engine Document

26

Trương Thanh Anh Tuấn Email:[email protected]

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {

// TODO Auto-generated method stub

}

boolean chuyen = false;

// Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

try {

// Tạm dừng cập nhật trong 10 ms

Thread.sleep(10);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// Di chuyển sang phải

if (!chuyen) {

sprite.setPosition(sprite.getX() + 5, sprite.getY());

if (sprite.getX() > 200)// Vượt quá giới hạn thì cho di chuyển ngược lại

chuyen = true;

} else {

sprite.setPosition(sprite.getX() - 5, sprite.getY());

if (sprite.getX() < 10)

chuyen = false;

}

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

Page 27: And Engine Document

27

Trương Thanh Anh Tuấn Email:[email protected]

AndEngine_Test05.rar

8.6 Tạo sprite chuyển động từ 1 ảnh :

Thêm 1 ảnh vào thư mục asset :

Pic 1 : sprite.png

Đoạn code chính trong BaseGameActivity

public class MainActivity extends BaseGameActivity {

//Khai báo thêm 2 biến quan trọng

private Camera MyCamera;//Biến này thường để cấu hình màn hình

private Scene MyScene;//Quản lý những gì bạn vẽ.

private int WIDTH = 320;//Chiều rộng vùng hiện thị

private int HEIGHT = 480;//Chiều cao vùng hiện thị

private BitmapTextureAtlas bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TiledTextureRegion tiledTextureRegion;//Lưu khi load ảnh

private AnimatedSprite animatedSprite ;//AnimatedSprite

/** Called when the activity is first created. */

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

Page 28: And Engine Document

28

Trương Thanh Anh Tuấn Email:[email protected]

return true;

}

@Override

public Engine onLoadEngine() {

//Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

//Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT,

new RatioResolutionPolicy(WIDTH, HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

//Bức ảnh chỉ rộng 512 và cao 512 nên ta khai báo theo đúng kích thước để đỡ tốn bộ nhớ

this.bitmapTextureAtlas = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR);

//Số 4 ở đây là 4 cột và 4 hàng

this.tiledTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.bitmapTextureAtlas, this,

"sprite.png", 0, 0, 4, 4);

this.mEngine.getTextureManager().loadTexture(this.bitmapTextureAtlas);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));//Đặt màu nền

//=====================LẮNG NGHE SỰ KIỆN CHẠM VÀO MÀN HÌNH

MyScene===============================

//Bắt sự kiện khi chạm vào MyScene

MyScene.setTouchAreaBindingEnabled(true);//cho phép lắng nghe

MyScene.setOnSceneTouchListener(new IOnSceneTouchListener() {

public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {

System.out.println("Sprite onSceneTouchEvent: chạm vào màn hình");

System.out.println("Tọa độ X = "+pSceneTouchEvent.getX());

System.out.println("Tọa độ Y = "+pSceneTouchEvent.getY());

Page 29: And Engine Document

29

Trương Thanh Anh Tuấn Email:[email protected]

//Khi chạm vào màn hình ta di chuyển AnimatedSprite theo tọ độ y.

animatedSprite.setPosition(animatedSprite.getX(), pSceneTouchEvent.getY());

return true;

}

});

//====================LẮNG NGHE SỰ KIỆN KHI CHẠM VÀO ANIMATEDSPRITE=============================

//Đặt AnimatedSprite tại vị trí x = 100,y = 100

this.animatedSprite = new AnimatedSprite(100, 100, this.tiledTextureRegion){

//Lắng nghe sự kiện khi chạm vào sprite

@Override

public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float

pTouchAreaLocalY) {

if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){

System.out.println("AnimatedSprite onAreaTouched: chạm vào animatedSprite");

System.out.println("Tọa độ X = "+pTouchAreaLocalX);

System.out.println("Tọa độ Y = "+pTouchAreaLocalY);

}

return true;

}

};

animatedSprite.animate(100);//Sau 100milis ta sẽ đổi bức ảnh

MyScene.attachChild(animatedSprite);//Add vào MyScene

MyScene.registerTouchArea(animatedSprite);//Phải đăng ký là cho phép AnimatedSprite này được lắng nghe sự kiện

//=====================================================================================

//Cập nhật (coi như vòng lặp hoạt cảnh)

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {

// TODO Auto-generated method stub

}

boolean chuyen = false;

//Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

try {

//Tạm dừng cập nhật trong 10 ms

Thread.sleep(10);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

Page 30: And Engine Document

30

Trương Thanh Anh Tuấn Email:[email protected]

e.printStackTrace();

}

//Di chuyển sang phải

if(!chuyen){

animatedSprite.setPosition(animatedSprite.getX()+5, animatedSprite.getY());

if(animatedSprite.getX() > 200)//Vượt quá giới hạn thì cho di chuyển ngược lại

chuyen = true;

}else{

animatedSprite.setPosition(animatedSprite.getX()-5, animatedSprite.getY());

if(animatedSprite.getX() < 10)

chuyen = false;

}

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test06.rar

8.7 Tạo kết hợp sprite chuyển động và ảnh nền :

Thêm 1 ảnh vào thư mục asset :

Pic 1: sprite.png

Pic 2: ball.png

Page 31: And Engine Document

31

Trương Thanh Anh Tuấn Email:[email protected]

Đoạn code chính trong BaseGameActivity :

public class MainActivity extends BaseGameActivity {

//Khai báo thêm 2 biến quan trọng

private Camera MyCamera;//Biến này thường để cấu hình màn hình

private Scene MyScene;//Quản lý những gì bạn vẽ.

private int WIDTH = 320;//Chiều rộng vùng hiện thị

private int HEIGHT = 480;//Chiều cao vùng hiện thị

private BitmapTextureAtlas bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TiledTextureRegion tiledTextureRegion;//Lưu khi load ảnh

private AnimatedSprite animatedSprite ;//AnimatedSprite

private RepeatingSpriteBackground mGrassBackground;//Khai báo đối tượng để làm thực hiện lặp ảnh tạo cảnh nền

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

public Engine onLoadEngine() {

//Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

//Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT,

new RatioResolutionPolicy(WIDTH, HEIGHT),

this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

Page 32: And Engine Document

32

Trương Thanh Anh Tuấn Email:[email protected]

//Bức ảnh chỉ rộng 64 và cao 32 nên ta khai báo theo đúng kích thước để đỡ tốn bộ nhớ

this.bitmapTextureAtlas = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR);

//Số 2 ở đây là 2 cột. Số 1 tức là có 1 hàng

this.tiledTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.bitmapTextureAtlas, this,

"sprite.png", 0, 0, 4, 4);

//Load ảnh từ thư mục Assets

this.mGrassBackground = new RepeatingSpriteBackground(WIDTH, HEIGHT, this.mEngine.getTextureManager(), new

AssetBitmapTextureAtlasSource(this, "ball.png"));

this.mEngine.getTextureManager().loadTexture(this.bitmapTextureAtlas);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

MyScene.setBackground(this.mGrassBackground);//Đặt đối tượng mGrassBackground làm cảnh nền

//=====================LẮNG NGHE SỰ KIỆN CHẠM VÀO MÀN HÌNH MyScene==============================

//Bắt sự kiện khi chạm vào MyScene

MyScene.setTouchAreaBindingEnabled(true);//cho phép lắng nghe

MyScene.setOnSceneTouchListener(new IOnSceneTouchListener() {

public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {

System.out.println("Sprite onSceneTouchEvent: chạm vào màn hình");

System.out.println("Tọa độ X = "+pSceneTouchEvent.getX());

System.out.println("Tọa độ Y = "+pSceneTouchEvent.getY());

//Khi chạm vào màn hình ta di chuyển AnimatedSprite theo tọ độ y.

animatedSprite.setPosition(animatedSprite.getX(), pSceneTouchEvent.getY());

return true;

}

});

//====================LẮNG NGHE SỰ KIỆN KHI CHẠM VÀO ANIMATEDSPRITE============================

//Đặt AnimatedSprite tại vị trí x = 100,y = 100

this.animatedSprite = new AnimatedSprite(100, 100, this.tiledTextureRegion){

//Lắng nghe sự kiện khi chạm vào sprite

@Override

Page 33: And Engine Document

33

Trương Thanh Anh Tuấn Email:[email protected]

public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float

pTouchAreaLocalY) {

if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){

System.out.println("AnimatedSprite onAreaTouched: chạm vào animatedSprite");

System.out.println("Tọa độ X = "+pTouchAreaLocalX);

System.out.println("Tọa độ Y = "+pTouchAreaLocalY);

}

return true;

}

};

animatedSprite.animate(100);//Sau 100milis ta sẽ đổi bức ảnh

MyScene.attachChild(animatedSprite);//Add vào MyScene

MyScene.registerTouchArea(animatedSprite);//Phải đăng ký là cho phép AnimatedSprite này được lắng nghe sự kiện

//======================================================================================

//Cập nhật (coi như vòng lặp hoạt cảnh)

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {

// TODO Auto-generated method stub

}

boolean chuyen = false;

//Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

try {

//Tạm dừng cập nhật trong 10 ms

Thread.sleep(10);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//Di chuyển sang phải

if(!chuyen){

animatedSprite.setPosition(animatedSprite.getX()+5, animatedSprite.getY());

if(animatedSprite.getX() > 200)//Vượt quá giới hạn thì cho di chuyển ngược lại

chuyen = true;

}else{

animatedSprite.setPosition(animatedSprite.getX()-5, animatedSprite.getY());

if(animatedSprite.getX() < 10)

Page 34: And Engine Document

34

Trương Thanh Anh Tuấn Email:[email protected]

chuyen = false;

}

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test07.rar

8.8 Xác định va chạm giữa 2 sprite với nhau :

Thêm 1 ảnh vào thư mục asset :

Pic 1: bg_image.png

Pic 3 : ball.png

Đoạn code chính trong BaseGameActivity :

public class MainActivity extends BaseGameActivity {

//Khai báo thêm 2 biến quan trọng

private Camera MyCamera;//Biến này thường để cấu hình màn hình

private Scene MyScene;//Quản lý những gì bạn vẽ.

private int WIDTH = 320;//Chiều rộng vùng hiện thị

private int HEIGHT = 480;//Chiều cao vùng hiện thị

Page 35: And Engine Document

35

Trương Thanh Anh Tuấn Email:[email protected]

private BitmapTextureAtlas bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TextureRegion textureRegion;//Lưu khi load ảnh

private Sprite sprite1,sprite2;//Sprite quả bóng

private BitmapTextureAtlas bg_bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TextureRegion bg_textureRegion;//Lưu khi load ảnh

private Sprite bg_sprite;//Sprite tạo cảnh nền

/** Called when the activity is first created. */

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

@Override

public Engine onLoadEngine() {

//Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

//Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT,

new RatioResolutionPolicy(WIDTH, HEIGHT),

this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

//Khai báo vùng lưu trữ ảnh có kích thước 256,256. Đây là cái khó nhất đó. Sẽ giải thích sau.

this.bitmapTextureAtlas = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

//Load ảnh

this.textureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.bitmapTextureAtlas, this, "ball.png", 0,

0);

mEngine.getTextureManager().loadTextures(this.bitmapTextureAtlas);

Page 36: And Engine Document

36

Trương Thanh Anh Tuấn Email:[email protected]

this.bg_bitmapTextureAtlas = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

this.bg_textureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.bg_bitmapTextureAtlas, this,

"bg_image.png", 0, 0);

mEngine.getTextureManager().loadTextures(this.bg_bitmapTextureAtlas);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

this.bg_sprite = new Sprite(0, 0, this.bg_textureRegion);

MyScene.setBackground(new SpriteBackground(this.bg_sprite));

//Đặt sprite1 tại vị trí x = 0,y = 100

this.sprite1 = new Sprite(0, 100, this.textureRegion);

MyScene.attachChild(sprite1);//Add vào MyScene

//Đặt sprite2 tại vị trí x = 300,y = 100

this.sprite2 = new Sprite(300, 100, this.textureRegion);

MyScene.attachChild(sprite2);//Add vào MyScene

//Cập nhật (coi như vòng lặp hoạt cảnh)

MyScene.registerUpdateHandler(new IUpdateHandler() {

@Override

public void reset() {

// TODO Auto-generated method stub

}

//Muốn cập nhật cái gì thì cho vào đây

@Override

public void onUpdate(float pSecondsElapsed) {

//Quả bóng đầu tiên là chạy từ phải qua trái

MainActivity.this.sprite1.setPosition(MainActivity.this.sprite1.getX()+1, MainActivity.this.sprite1.getY());

//Quả bóng thứ 2 sẽ chạy được lại từ trái qua phải

MainActivity.this.sprite2.setPosition(MainActivity.this.sprite2.getX()-1, MainActivity.this.sprite2.getY());

Page 37: And Engine Document

37

Trương Thanh Anh Tuấn Email:[email protected]

//Nếu 2 quảng bóng này va chạm vào nhau ta cho nó quay lại vị trí khởi tạo

if(MainActivity.this.sprite1.collidesWith(MainActivity.this.sprite2)){

MainActivity.this.sprite1.setPosition(0, MainActivity.this.sprite1.getY());

MainActivity.this.sprite2.setPosition(300, MainActivity.this.sprite2.getY());

}

}

});

return MyScene;

}

@Override

public void onLoadComplete() {}

}

8.9 Tạo controler tương tác với sprite :

Thêm 1 ảnh vào thư mục asset :

Pic 1 : ControlBase.png

Pic 2 : ControlKnob.png

Pic 3 : ball.png

Pic 4 : bg_image.png

Page 38: And Engine Document

38

Trương Thanh Anh Tuấn Email:[email protected]

Đoạn code chính trong BaseGameActivity :

public class MainActivity extends BaseGameActivity {

//Khai báo thêm 2 biến quan trọng

private Camera MyCamera;//Biến này thường để cấu hình màn hình

private Scene MyScene;//Quản lý những gì bạn vẽ.

private int WIDTH = 480;//Chiều rộng vùng hiện thị

private int HEIGHT = 320;//Chiều cao vùng hiện thị

private BitmapTextureAtlas bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TextureRegion textureRegion;//Lưu khi load ảnh

private Sprite sprite;//Sprite quả bóng

private BitmapTextureAtlas bg_bitmapTextureAtlas;//Lưu ảnh trong bộ nhớ

private TextureRegion bg_textureRegion;//Lưu khi load ảnh

private Sprite bg_sprite;//Sprite tạo cảnh nền

//Khai báo các biến dùng cho vùng điều khiển

private DigitalOnScreenControl mDigitalOnScreenControl;

private BitmapTextureAtlas mOnScreenControlTexture;

private TextureRegion mOnScreenControlBaseTextureRegion;

private TextureRegion mOnScreenControlKnobTextureRegion;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

Page 39: And Engine Document

39

Trương Thanh Anh Tuấn Email:[email protected]

@Override

public Engine onLoadEngine() {

//Khởi tạo vùng hiện thị là 320*480

this.MyCamera = new Camera(0, 0, WIDTH, HEIGHT);

//Yêu cầu màn hình hiện thị nằm ngang thì ScreenOrientation.LANDSCAPE

Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,

new RatioResolutionPolicy(WIDTH, HEIGHT), this.MyCamera));

return engine;

}

@Override

public void onLoadResources() {

//Khai báo vùng lưu trữ ảnh có kích thước 256,256. Đây là cái khó nhất đó. Sẽ giải thích sau.

this.bitmapTextureAtlas = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

//Load ảnh

this.textureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.bitmapTextureAtlas, this, "ball.png", 0,

0);

mEngine.getTextureManager().loadTextures(this.bitmapTextureAtlas);

this.bg_bitmapTextureAtlas = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

this.bg_textureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.bg_bitmapTextureAtlas, this,

"bg_image.png", 0, 0);

mEngine.getTextureManager().loadTextures(this.bg_bitmapTextureAtlas);

//Load phần điều khiển

this.mOnScreenControlTexture = new BitmapTextureAtlas(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

this.mOnScreenControlBaseTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "ControlBase.png", 0, 0);

this.mOnScreenControlKnobTextureRegion =

BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "ControlKnob.png", 128, 0);

this.mEngine.getTextureManager().loadTextures(this.mOnScreenControlTexture);

}

@Override

public Scene onLoadScene() {

this.mEngine.registerUpdateHandler(new FPSLogger());

MyScene = new Scene();

this.bg_sprite = new Sprite(0, 0, this.bg_textureRegion);

Page 40: And Engine Document

40

Trương Thanh Anh Tuấn Email:[email protected]

MyScene.setBackground(new SpriteBackground(this.bg_sprite));

//Đặt sprite1 tại vị trí x = 100,y = 100

this.sprite = new Sprite(100, 100, this.textureRegion);

MyScene.attachChild(sprite);//Add vào MyScene

//=======================================ĐIỂM QUAN TRỌNG NHẤT================

//Khai báo và sử lý điều kiện khi ta chạm vào vùng điều khiển

mDigitalOnScreenControl = new DigitalOnScreenControl(0, HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(),

this.MyCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f,

new IOnScreenControlListener() {

public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float

pValueY) {

// vùng điều khiển thay đổi ta sẽ cho sprite di chuyển theo hướng ta điều khiển

MainActivity.this.sprite.setPosition(MainActivity.this.sprite.getX() + pValueX, MainActivity.this.sprite.getY() + pValueY);

}

});

mDigitalOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA,

GL10.GL_ONE_MINUS_SRC_ALPHA);

mDigitalOnScreenControl.getControlBase().setAlpha(0.7f);

mDigitalOnScreenControl.getControlBase().setScaleCenter(0, 128);

mDigitalOnScreenControl.getControlBase().setScale(0.8f);

mDigitalOnScreenControl.getControlKnob().setScale(0.8f);

mDigitalOnScreenControl.refreshControlKnobPosition();

MyScene.setChildScene(mDigitalOnScreenControl);

//==============================================================================

return MyScene;

}

@Override

public void onLoadComplete() {}

}

Source đính kèm

AndEngine_Test09.rar

Nguồn tham khảo:

+android.vn

+andengine.org