Hiện kết quả từ 1 tới 1 của 1

Chủ đề: Hướng dẫn tạo một Game đơn giản với AndEngine 2.0 (Phần 2)


  1. #1
    Thành Viên Mới Avatar của contuhu
    Tham gia
    Jul 2012
    Bài gửi
    14

    Hướng dẫn tạo một Game đơn giản với AndEngine 2.0 (Phần 2)

    Phần 1: Hướng dẫn tạo một Game đơn giản với AndEngine 2.0 (Phần 1)

    Main Menu

    Như thường lệ, một game sau khi load Splash Screen xong thì bước tiếp sẽ là hiển thì Menu cho chúng ta chọn. Trong trò này tôi sẽ hiển thị nút GAME START cho chúng ta click vào để bắt đầu chơi. Bây giờ chúng ta tạo ra 1 lớp mới đặt tên là : MainMenuScene và extends MenuScene, implements IOnMenuItemClickListener

    Tiếp theo chúng ta thêm 2 biến sau vào lớp này:
    Mã:
    
    
    Mã:
            private AndEngineTutorial2Activity activity;
        final int MENU_START = 0;
    Biến MENU_START là 1 biến được sử dụng để đánh dấu, nếu bạn có nhiều nút thì tương ứng có bấy nhiêu biến flag này để đánh dấu và phân biệt giữa các nút với nhau:

    Trong phương thức khởi dựng chúng ta sẽ viết đoạn code sau:


    Mã:
                    public MainMenuScene() {
            // TODO Auto-generated constructor stub
            super(AndEngineTutorial2Activity.getSharedInstance().mCamera);
    
    
            activity = AndEngineTutorial2Activity.getSharedInstance();
    
    
            setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
    
    
            IMenuItem startButton = new TextMenuItem(MENU_START, activity.mFont,
                    activity.getString(R.string.start),
                    activity.getVertexBufferObjectManager());
    
    
            startButton.setPosition(mCamera.getWidth() / 2 - startButton.getWidth()
                    / 2, mCamera.getHeight() / 2 - startButton.getHeight() / 2);
    
    
            addMenuItem(startButton);
    
    
            setOnMenuItemClickListener(this);
    
    
        }
    Chúng ta Send Camera hiện tại tới lớp cha cho nó tiện làm việc.
    Chúng ta cũng thêm vào trong strings.xml đoạn text là "GAME START"

    Mã:
    <stringname="start">GAME START</string>
    Vị trí của nó ở giữa màn hình, và thêm nó vào giống như 1 MenuItem, và sau đó chúng ta đăng ký Scene hiện tại giống như 1 MenuItemClickListener.


    Chúng ta override method onMenuItemClicked

    Mã:
           @Override
        public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
                float pMenuItemLocalX, float pMenuItemLocalY) {
            // TODO Auto-generated method stub
            switch (pMenuItem.getID()) {
            case MENU_START:
                //activity.setCurrentScene(new GameScene());
    
    
                return true;
            default:
                break;
    
    
            }
    
    
            return false;
        }
    Chúng ta chỉ cần bắt sự kiện khi button được kích. Tức là khi clicked thì trò chơi sẽ bắt đầu, trước khi test thử chúng ta mở lớp SplashScreen vào thêm vào dòng lệnh sau và đặt nó trong phuong thức loadResource(). loadResource được gọi trong constructor của lớp này.
    Thông thường SplashScreen là dùng để load Resource, vì không để người sử dụng phải chờ đợi trong khi Game load resource. Trong bài Tut này chúng ta thay vì tạo ra 1 thread để load resource thì sau 2 giây chúng ta hiển thị nút Start để bắt đầu hiển thị nút Start Game cho người chơi bắt đầu chơi.

    Mã:
    public void loadResource(){
            DelayModifier dMod=new DelayModifier(2, new IEntityModifierListener() {
                
                @Override
                public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
                    // TODO Auto-generated method stub
                    
                }
                
                @Override
                public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
                    // TODO Auto-generated method stub
                    activity.setCurrentScene(new MainMenuScene());
                }
            });
            /*DelayModifier dMod= new DelayModifier(2){
                @Override
                protected void onModifierFinished(IEntity pItem) {
                    // TODO Auto-generated method stub
                    activity.setCurrentScene(new MainMenuScene());            
                }
            };
            */
            this.registerEntityModifier(dMod);
        }
    Tiếp theo chúng ta cũng thay đổi màu màn hình khi GAME START xuất hiện (Các bạn nhớ thêm loadResource() vào Constructor của lớp này nhé)
    Sau 2 seconds thì sẽ chuyển sang màn hình:



    SHIPS (Bệ súng để bắn - di chuyển đi di chuyển lại ở cuối screen)

    Bây giờ chúng ta sẽ tạo ra 1 lớp Ships (Nó là hình chữ nhật chạy bên dưới tương tự như 1 cỗ máy để bắn đặn lên các vì sao...), trong ví dụ này chúng ta chỉ tạo ra 1 Ship, nó cũng được truy cập rất nhiều.

    OK! Bây giờ chúng ta sẽ tạo ra 1 lớp Ship:

    Mã:
    public class Ship {
        public Rectangle sprite;
    
    
        public static Ship instance;
    
    
        //boolean moveable;
        Camera mCamera;
    
    
        public static Ship getSharedInstance() {
    
    
            if (instance == null)
    
    
                instance = new Ship();
            
            return instance;
    
    
        }
    
    
        private Ship() {
    
    
            sprite = new Rectangle(0, 0, 70, 30, AndEngineTutorial2Activity.getSharedInstance()
    
    
            .getVertexBufferObjectManager());
    
    
            mCamera = AndEngineTutorial2Activity.getSharedInstance().mCamera;
    
    
            sprite.setPosition(mCamera.getWidth() / 2 - sprite.getWidth() / 2,
    
    
            mCamera.getHeight() - sprite.getHeight() - 10);
            //moveable=true;
        }
    Sprite của lớp này sẽ là 1 Hình chữ nhật, với chiều rộng 70pixels, ngang 30 pixels, vị trí của Sprite của nó là ở giữa màn hình bên dưới của camera mà chúng ta có được từ AndEngineTutorial2Activity.
    Bây giờ chúng ta cần có 1 Scene cho 1 Game thực sự. Ta gọi là lớp “GameScene
    Và khai báo 2 biến:
    Mã:
            public Ship ship;    
        Camera mCamera;
    Và constructor

    Mã:
                      
               public GameScene() {
            
                setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
                mCamera = AndEngineTutorial2Activity.getSharedInstance().mCamera;
                ship = Ship.getSharedInstance();
                attachChild(ship.sprite);
               }
    Chúng ta sử dụng màu nền game là cùng màu lúc START GAME, và sau đó khởi tạo đối tượng ship bằng cách gọi method getSharedInstance(), và sau đó ta attach Sprite của Ship này tới Scene (Ta chỉ attach Sprite không phải ship).

    Bây giờ chúng ta hãy quay lại lớp: MainMenuScene và thay đổi 1 chút ở onMenuItemClicked():

    Mã:
    
    
    Mã:
           @Override
        public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
                float pMenuItemLocalX, float pMenuItemLocalY) {
            // TODO Auto-generated method stub
            switch (pMenuItem.getID()) {
            case MENU_START:
                activity.setCurrentScene(new GameScene());//Thay đổi ở đây
    
    
                return true;
            default:
                break;
    
    
            }
    
    
            return false;
        }
    
    
    OK! Bây giờ bạn thử chạy và sẽ thấy trên màn hình đã có Sprite.


    Nào bây giờ chúng ta hãy làm dịch chuyển Sprite này:

    Ở đây chúng ta sẽ làm cho Sprite này dịch chuyển bằng cách sử dụng TILT Accelerometer của thiết bị.

    Chúng ta sẽ dữ speed data của Accelerometer trong lớp GameScene. Vì vậy ta thêm 1 biết float vào lớp này và gọi nó là “accelerometerSpeedX”, chúng ta sẽ sử dụng nó sau.
    Bây giờ ta sẽ tạo 1 lớp mới và gọi nó là “SensorListener” implements “SensorEventListener” và add các unimplements của nó.

    Mã:
    public class SensorListener implements SensorEventListener{
        static SensorListener instance;
        GameScene scene;
        
         
        public static SensorListener getSharedInstance() {
        
            if (instance == null)
                instance = new SensorListener();
    
    
            return instance;
        
        }
        public SensorListener() {
            instance = this;
        
            scene = (GameScene) AndEngineTutorial2Activity.getSharedInstance().mCurrentScene;
        
        }
    
    
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
    
    
        }
        
        @Override
        public void onSensorChanged(SensorEvent event) {    
            
        }
    
    
    }
    Và bây giờ trong method onSensorChanged() chúng ta cài đặt như sau:
    Mã:
    @Override
        public void onSensorChanged(SensorEvent event) {    
            synchronized (this) {
                    switch (event.sensor.getType()) {
                        case Sensor.TYPE_ACCELEROMETER:
                            scene.accelerometerSpeedX = event.values[1];
                            break;
                        default:
                            break;
                    }
                }
    
    
        }
    Chúng ta sử dụng synchronized để đảm bảo rằng chúng ta không có 1 concurrentModificationException (Nó giống như thread safe).

    Điều này sẽ làm accelerometerSpeedX trong GameScene chứa các giá trị của gia tốc SpeedX mà chúng ta sẽ sử dụng để xác định di chuyển ship như thế nào.
    Bây giờ chúng ta sẽ tạo ra 1 method để di chuyển Ship. Trong lớp Ship ta thêm phương thức sau:

    Mã:
    public void moveShip(float accelerometerSpeedX) {
            if (!moveable)
                return;
            if (accelerometerSpeedX != 0) {
    
    
                int lL = 0;
                int rL = (int) (mCamera.getWidth() - (int) sprite.getWidth());
    
    
                float newX;
    
    
                // Calculate New X,Y Coordinates within Limits
                if (sprite.getX() >= lL)
                    newX = sprite.getX() + accelerometerSpeedX;
                else
                    newX = lL;
                if (newX <= rL)
                    newX = sprite.getX() + accelerometerSpeedX;
                else
                    newX = rL;
    
    
                // Double Check That New X,Y Coordinates are within Limits
                if (newX < lL)
                    newX = lL;
                else if (newX > rL)
                    newX = rL;
    
    
                sprite.setPosition(newX, sprite.getY());
            }
        }
    Ta thêm 1 biến boolean và set = true ở constructor. Đây là 1 biến flag được sử dụng để tạm dừng Ship trong khi mọi thứ khác vẫn hoạt động.

    Đối với method moveShip() nó cơ bản là nhận vào 1 accelerometer khi có thay đổi và nó dịch chuyển ship theo dữ liệu nhận vào. Nó tính toán ở đâu mà sprite nên đi (vị trí hiện tại dịch chuyển sang trái hay sang phải).

    Chúng ta sẽ gọi method trên trong GameScene
    Mã:
            public void moveShip() {
            ship.moveShip(accelerometerSpeedX);
        }
    Và trước khi để nó có thể di chuyển được đi đi lại lại chúng ta phải gọi method này ở bất kỳ frame nào vì vậy chúng ta sẽ cần một IUpdateHandler. Chúng ta tạo 1 lớp GameLoopUpdateHandler và implements IUpdateHandler và sao đó add method này vào
    Mã:
        @Override
        public void onUpdate(float pSecondsElapsed) {
            // TODO Auto-generated method stub
             ((GameScene)AndEngineTutorial2Activity.getSharedInstance().mCurrentScene).moveShip();
    
    
        }
    Về cơ bản ta lấy mCurrentScene từ AndEngineTutorial2Activity và bắt nó tới GameScene (Ở lúc này Scene hiện tại là 1 instance của GameScene) và sau đó chúng ta gọi moveShip() bên trong Scene.

    Chúng ta sẽ thêm 1 chút vào constructor của GameScene như sau:

    Mã:
                        AndEngineTutorial2Activity.getSharedInstance().setCurrentScene(this);
                sensorManager = (SensorManager) AndEngineTutorial2Activity.getSharedInstance()
                
                    .getSystemService(BaseGameActivity.SENSOR_SERVICE);
                SensorListener.getSharedInstance();
                sensorManager.registerListener(SensorListener.getSharedInstance(),
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_GAME);
                registerUpdateHandler(new GameLoopUpdateHandler());

    Chúng ta thiết lập Scene hiện tại là GameScene hiện tại. Tôi biết rằng chúng ta đang làm điều đó khi chúng ta clicked vào nút START GAME, nhưng chỉ cài đặt nó sau khi lớp này được khởi tạo giống như Constructor kết thục thì được gọi. Chúng ta không cần thay đổi nó ở giữa) và sau đó nghe ngón accelerometer thay đổi .

    Phần cuối cùng chúng ta đăng ký giống như 1 UpdateHandler();
    Bây giờ bạn có thể cầm thiết bị của bạn dịch chuyển và xem nó thay đổi như thế nào.


    Nếu bạn chạy = Emulator thì chuyển từ màn hình nằm ngang sang màn hình dọc, Sprite này sẽ chạy dọc từ giữa màn hình xuống cuối màn hình như hình vẽ
    ảnh ban đầu:



    ảnh sau khi nghiên divice


    Source:
    http://www.mediafire.com/?9ojc4vbxri0f5my
    -------Vì con nhà nghèo nên chưa có device để test - HÊT P2 --------------------------------------









    Chủ đề tương tự:

    Lần sửa cuối bởi contuhu; 01-11-12 lúc 11:54 AM

Đánh dấu

Quyền viết bài

  • Bạn không thể gửi chủ đề mới
  • Bạn không thể gửi trả lời
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •