Bài 0 - Hướng dẫn cơ bản về Andengine

Thảo luận trong 'Điện thoại, viễn thông' bắt đầu bởi tuann, 2/9/12.

  1. tuann Guest

    tuann

    Sau khoảng 2 tuần nghiên cứu AndEngine, mình xin chia sẽ với các bạn 1 ít kiến thức của mình tự mày mò được. Hi vọng sẽ giúp các bạn mau chóng nắm bắt và sử dụng được AndEngine. Mình sẽ đính kèm file ví dụ của mình làm nhé. :mad:
    AndEngine là 1 công cụ rất hiệu quả giúp bạn có thể code game nhanh chóng, hỗ trợ khá nhìu chức năng game cần thiết... Tuy nhiên nó cũng có mặt hạn chế của nó: performance, ko có document, ko có nhìu sự trợ giúp vì nó còn đang phát triển..v.v..

    Sau đây là hướng dẫn chi tiết:
    1. Tao Project Android là SimpleAE
    [​IMG]
    Tạo 1 thư mục lib, và add gói AndEngine.jar vào thư mục lib. Download tại http://andengineexamples.googlecode..../andengine.jar. Sau đó right click vào gói AndEngine.jar, chọn Build Path > Add to build path
    Mở file SimpleAEActivity, lớp SimpleAEActivity đang kế thừa lớp Activity theo mặc định, bạn hãy sừa thành BaseGameActivity. Sau đó xóa những dòng code mà Eclipse sinh ra, và nhấn Ctrl + Shift + O để import thư viện hoặc nhấn Ctrl + Spacebar.
    Tiếp theo rê chuột vào lớp SimpleAEActivity và chọn Add unimplement method.
    PHP:
       package com.myapp.test;

    import org.anddev.andengine.engine.Engine;
    import org.anddev.andengine.entity.scene.Scene;
    import org.anddev.andengine.ui.activity.BaseGameActivity;

    public class 
    SimpleAEActivity extends BaseGameActivity {

        @
    Override
        
    public Engine onLoadEngine() {
            
    // TODO Auto-generated method stub
            
    return null;
        }

        @
    Override
        
    public void onLoadResources() {
            
    // TODO Auto-generated method stub
            
        
    }

        @
    Override
        
    public Scene onLoadScene() {
            
    // TODO Auto-generated method stub
            
    return null;
        }

        @
    Override
        
    public void onLoadComplete() {
            
    // TODO Auto-generated method stub
            
        
    }
        
    }
    2. Sửa file AndroidManifest.xml, thêm vào trước thẻ application <uses-permission android:name="android.permission.WAKE_LOCK"/>

    *** Giờ mình sẽ hướng dẫn các bạn chi tiết 1 chút, trước khi nói về code:
    BASEGAMEACTIVITY: đây là 1 lớp bắt buộc. Bạn phải extend nó mỗi khi viết 1 game. Nó sẽ quản lí Engine và các nội dung bên trong của game ...
    ENGINE: quản lí việc show các nội dung lên Scene. Mỗi Engine chỉ có duy nhất 1 Scene. Nhưng có 1 ngoại lệ... mình đang nghiên cứu thêm hihi
    CAMERA: là 1 lớp sẽ định nghĩa 1 khung chữ nhật của Scene mà nội dung sẽ hiển thị lên màn hình bên trong khung chữ nhật này.
    SCENE: là 1 lớp sẽ chứa tất cả những đối tượng ENTITY cần hiển thị trên màn hình: ví dụ SpriteAnimate, ...
    ENTITY: là đối tượng sẽ đc vẽ bên trong SCENE, và nó có thể di chuyển, xoay, ....
    TEXTURE: là 1 class đc xem như là bộ nhớ của hình ảnh. Nó ko trực tiếp lưu image, nó chỉ xem như bộ nhớ để chứa image đó. Ví dụ image có kích thước: 45 x 126, thì bạn phải tạo texture với kích thước X to hơn kích thước image thật sự ( X phải là kết quả của mũ 2 ) , tức là texture 64x128
    TEXTUREREGION: load image vào texture và cắt ra theo 1 khung chữ nhật với kích thước do bạn chọn. Dùng để vẽ sprite, image....

    3. SimpleAEActivity, đầu tiên cần phải load Engine trước.
    Bạn hãy tạo 1 lớp InstantEngine có hàm dựng là 3 tham số, chiều rộng, chiều cao, màn hình ngang hay dọc.
    PHP:
      package com.myapp.test;

    import org.anddev.andengine.engine.Engine;
    import org.anddev.andengine.engine.camera.Camera;
    import org.anddev.andengine.engine.options.EngineOptions;
    import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
    import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;

    public class 
    InstantEngine {
        private 
    Engine mEngine;
        private 
    Camera mCamera;
        
        public 
    Engine getEngine() {
            return 
    mEngine;
        }
        
        public 
    Camera getCamera() {
            return 
    mCamera;
        }
        
        public 
    InstantEngine(int widthint heightboolean isPORTRAIT) {
            
    mCamera = new Camera(00widthheight);
            
    RatioResolutionPolicy rc =new RatioResolutionPolicy(widthheight);
            
    EngineOptions eo;
            if (
    isPORTRAIT) {
                
    eo = new EngineOptions(trueScreenOrientation.PORTRAITrcmCamera);
            } else {
                
    eo = new EngineOptions(trueScreenOrientation.LANDSCAPErcmCamera);
            }
            
    mEngine = new Engine(eo);
        }
    }
    4. Tiếp theo là phần onLoadResource, chúng ta sẽ load image vào.
    Tạo 1 thư mục assets/gfx và thêm image này vào [​IMG]
    Tạo 1 lớp LoadingTexture có hàm dựng là tham số Context.
    Biến tr_spr_animate sẽ load image trên và cắt thành 6 miếng . Và sẽ đc dùng để vẽ từng miếng 1 trên màn hinh.
    PHP:
    package com.myapp.test;

    import org.anddev.andengine.entity.sprite.Sprite;
    import org.anddev.andengine.opengl.font.Font;
    import org.anddev.andengine.opengl.font.FontFactory;
    import org.anddev.andengine.opengl.texture.Texture;
    import org.anddev.andengine.opengl.texture.TextureOptions;
    import org.anddev.andengine.opengl.texture.region.TextureRegion;
    import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
    import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
    import org.anddev.andengine.opengl.texture.source.AssetTextureSource;

    import android.content.Context;
    import android.graphics.Color;

    public class 
    LoadingTexture {
        
        
    //face
        
    private Texture tt_face;
        
        
    // animate sprite
        
    private TiledTextureRegion tr_spr_animate;

        public 
    LoadingTexture(Context context) {
            
            
    // face
            
    tt_face = new Texture(51264TextureOptions.BILINEAR_PREMULTIPLYALPHA);
            
            
    // animate sprite
            
    tr_spr_animate TextureRegionFactory.createTiledFromAsset(tt_facecontext"gfx/face.png"0061);    
        }
        
        public 
    Texture getFaceTexture() {
            return 
    tt_face;
        }
        
        public 
    TiledTextureRegion getFaceTiledTextureRegion() {
            return 
    tr_spr_animate.clone();
        }
    }
    Edit lại SimpleAEActivity
    PHP:
        private LoadingTexture texture;
        @
    Override
        
    public void onLoadResources() {
            
    texture = new LoadingTexture(this);
            
    mEngine.getTextureManager().loadTexture(texture.getFaceTexture());
            
        }
    5. Bây giờ cần phải tạo 1 scene để hiển thị, các bạn tạo 1 lớp ví dụ WelcomeScene kế thừa từ lớp Scene.
    Trong lớp Scene này mình sẽ tạo background và tạo 1 hình vuông và cho nó rơi theo trọng lực. ^^ http://337play.net/images/ym_smilies/15.gif
    Các bạn cần download: andenginephysicsbox2dextension.jar , và add vào build path.
    Và thêm file libandenginephysicsbox2dextension.so vào 1 thư mục mới libs/armeabi

    PHP:
         package com.myapp.test;

    import org.anddev.andengine.entity.primitive.Rectangle;
    import org.anddev.andengine.entity.scene.Scene;
    import org.anddev.andengine.entity.scene.background.ColorBackground;
    import org.anddev.andengine.entity.shape.Shape;
    import org.anddev.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
    import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
    import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
    import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
    import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
    import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;

    import android.hardware.SensorManager;

    import com.badlogic.gdx.math.Vector2;
    import com.badlogic.gdx.physics.box2d.Body;
    import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
    import com.badlogic.gdx.physics.box2d.FixtureDef;

    public class 
    WelcomeScene extends Scene implements IAccelerometerListener {
        
        private 
    FixedStepPhysicsWorld mFSW;
        
        public 
    WelcomeScene() {
            
            
    this.setBackground(new ColorBackground(0.09804f0.6274f0.8784f));
            
            
    // Library andenginephysicsbox2dextension not found
            // add file libandenginephysicsbox2dextension.so vao thu muc libs/armeabi
            
    mFSW = new FixedStepPhysicsWorld(30, new Vector2(0,SensorManager.GRAVITY_EARTH), false);
            
            
    FixtureDef fd PhysicsFactory.createFixtureDef(0.5f0.5f0.5f);
            
            
    Shape ground = new Rectangle(10206060);
            
    Body bodyGround PhysicsFactory.createBoxBody(mFSWgroundBodyType.DynamicBodyfd);
            
    this.attachChild(ground);
            
    mFSW.registerPhysicsConnector(new PhysicsConnector(groundbodyGround ));
            
            
            
    Shape bottom = new Rectangle(030020010);
            
    Body bodyBottom PhysicsFactory.createBoxBody(mFSWbottomBodyType.StaticBodyfd);
            
    this.attachChild(bottom);
            
    mFSW.registerPhysicsConnector(new PhysicsConnector(bottombodyBottom ));
            
            
    this.registerUpdateHandler(mFSW);
        }
        
        public 
    WelcomeScene getInstance(){
            return 
    this;
        }

        @
    Override
        
    public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
            
    Vector2 gravity Vector2Pool.obtain(pAccelerometerData.getX(),pAccelerometerData.getY());
            
    mFSW.setGravity(gravity);
            
    Vector2Pool.recycle(gravity);
            
        }
    }
    6. Tiếp theo tạo 1 lớp FaceSprite kế thừa từ AnimatedSprite, lớp này sẽ vẽ 1 sprite và tự động xoay, và sẽ di chuyển theo 1 đường dãn ngẫu nhiên
    PHP:
       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 
    int rotation 0;
        private 
    Path path;
        
        public 
    FaceSprite(float pXfloat pYfloat pTileWidthfloat pTileHeight,
                
    TiledTextureRegion pTiledTextureRegion) {
            
    super(pXpYpTileWidthpTileHeightpTiledTextureRegion);
            
            
    settingMovePath();
        }
        
        private 
    FaceSprite getInstance() {
            return 
    this;
        }
        
        private 
    void settingMovePath() {
            
    int x1 MathUtils.random(0600);
            
    int y1 MathUtils.random(0400);
            
    int x2 MathUtils.random(0600);
            
    int y2 MathUtils.random(0400);
            
    path = new Path(3).to(x1,y1).to(x2y2).to(x1y1);
            
            
    PathModifier pm = new PathModifier(33pathnull, new IPathModifierListener() {

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

                @
    Override
                
    public void onPathWaypointStarted(PathModifier pPathModifier,
                        
    IEntity pEntityint 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[]{frameDurationframeDurationframeDurationframeDurationframeDuration}, startFrameendFrametrue);
                    
                }

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

                @
    Override
                
    public void onPathFinished(PathModifier pPathModifier,
                        
    IEntity pEntity) {
                    
    // TODO Auto-generated method stub
            
                
    }}
                );
            
    this.registerEntityModifier(new LoopEntityModifier(pm));
        }
        
        @
    Override
        
    public void onManagedUpdate(final float pSecondsElapsed) {
            
    super.onManagedUpdate(pSecondsElapsed);
                    
            
    // quay nao'
            
    rotation=rotation+5;
            
    this.setRotation(rotation);

        }
    }
    7. Giờ là lúc đặt sprite trên vào Scene. Tạo 1 lớp GamePlay như sau:
    PHP:
        package com.myapp.test;

    import org.anddev.andengine.entity.scene.Scene;

    public class 
    GamePlay {
        
        private 
    WelcomeScene welcomeScene;
        private 
    LoadingTexture texture;
        private 
    FaceSprite faceSpr;

        public 
    GamePlay(LoadingTexture object) {
            
    texture object;
            
        }
        
        public 
    Scene getWelcomeScene() {
            
    welcomeScene = new WelcomeScene();
            
    faceSpr = new FaceSprite(1002004545texture.getFaceTiledTextureRegion());
            
            
    welcomeScene.attachChild(faceSpr);
            
            return 
    welcomeScene;
        }


     
    8. Add GamePlay vào onLoadScene
    PHP:
        private Scene mScene;
        @
    Override
        
    public Scene onLoadScene() {
            
    mEngine.registerUpdateHandler(new FPSLogger());
            
    GamePlay game = new GamePlay(texture);
            
    mScene game.getWelcomeScene(); 
            
            return 
    mScene;
        }
    9. Chạy thử và kết quả:
    [​IMG]

    Xong, hi vọng sẽ giúp các bạn trong việc nghiên cứu AndEngine và có thể làm đc game của mình.

    (nếu copy bài viết nhớ ghi nguồn nhé )

    Link download toàn bộ source: SimpleAndEngine.zip
    tkminh: Nguôn: cunghocandroid
     
    4 people like this.
    Đang tải...
  2. Dong Dinh New Member

    Dong Dinh

    Tham gia ngày:
    4/1/13
    Bài viết:
    9
    Đã được thích:
    9
    Điểm thành tích:
    0
    Bạn ơi cho mình hỏi . Mình chay các project đơn gian cung luôn bị cái lỗi như thế này :trong Logcat :"Link of class MainActivity faild "
     

    Các file đính kèm:

  3. Dong Dinh New Member

    Dong Dinh

    Tham gia ngày:
    4/1/13
    Bài viết:
    9
    Đã được thích:
    9
    Điểm thành tích:
    0
    Ai chạy đươc ví dụ nay cho minh hỏi với. hic. hic. Minh chay luôn bị lỗi trong Mainifest. Cho minh xin nick chat hoăc Skype, Email nhé
     
  4. tinhbka New Member

    tinhbka

    Tham gia ngày:
    7/3/13
    Bài viết:
    2
    Đã được thích:
    0
    Điểm thành tích:
    0
    Giới tính:
    Nam
    mình cũng gặp lỗi k chạy đc. ad giúp đỡ với nhá. Lỗi như #2
     

Chia sẻ trang này