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

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


  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 3)

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

    Nào chúng ta lại tiếp tục phần 3 nhé, trong phần này chúng ta sẽ tạo ra đạn để bắn vào vật thể.

    OK! Trước khi vào phần này bạn bạn nên tham khảo Object pool của bài viết TKminh ở vietandroid.com nhé, ở đây tôi không giới thiệu nó.

    Let’s start:

    Để bắn đi từ Ship tới mục tiêu, chúng ta cần những viên đạn, vì vậy chúng ta sẽ tạo ra đạn ở đây: Ta tạo ra lớp đạn và đặt tên là Bullet
    Mã:
    public class Bullet {
     
           public Rectangle sprite;//Đạn hình vuông nhỏ
           public Bullet(){
    sprite = new Rectangle(0,0,10,10,AndEngineTutorial2Activity.getSharedInstance().
    getVertexBufferObjectManager());
                  sprite.setColor(1f,0f,0f);
           }
    }
    Mỗi viên đạn là 1 hình vuông có size 10x10 pixels, và màu nó là màu đỏ (RGB). Ở đây bạn cũng có thể sử dụng hình ảnh thay vì các viên đạn bạn chỉ cần thay sprite thành Sprite và điều chỉnh một chút bên trong lớp là OK.

    OK Bây giờ chúng ta sẽ sử dụng pool để tái sử dụng lại các viên đạn
    Chúng ta tạo ra 1 lớp mới đặt tên là: BulletPool
    Mã:
    public class BulletPool extends GenericPool<Bullet> {
           public static BulletPool instance;
     
           public static BulletPool sharedBulletPool() {
                  if (instance == null)
                         instance = new BulletPool();
                  return instance;
           }
     
           private BulletPool() {
                  super();
           }
     
           @Override
           protected Bullet onAllocatePoolItem() {
                  // TODO Auto-generated method stub
                  return new Bullet();
           }
     
                  // Dung de Recycle 1 bullet
           protected void onHandleRecycleItem(final Bullet b) {
                  b.sprite.clearEntityModifiers();
                  b.sprite.clearUpdateHandlers();
                  b.sprite.setVisible(false);
                  b.sprite.detachSelf();
           }
    }
    Đầu tiên chúng ta cần phải theo dõi xem viên đạn bắn ra từ đâu, và đi như thế nào từ đâu đến đâu để chúng ta còn loại bỏ nó. Và khi viên đạn gặp cái gì đó (đích, hoặc ngoài màn hình).

    Bây giờ chúng ta hãy trở lại lớp GameScene tạo mới LinkedList của các viên đạn và biến để đếm chúng.
    Mã:
     
           public int bulletCount;
           public LinkedList<Bullet> bulletList;
    Bên trong Constructor chúng ta new bulletlist
    Mã:
           bulletList = new LinkedList<Bullet>();
    Chúng ta trở lại lớp Ship và them vào method (shoot() ) như sau:
    Mã:
     
    public void shoot() {
                      if (!moveable)
                          return;
                      GameScene scene = (GameScene)                                                  AndEngineTutorial2Activity.getSharedInstance().mCurrentScene;
                      Bullet b = BulletPool.sharedBulletPool().obtainPoolItem();
                      b.sprite.setPosition(sprite.getX() + sprite.getWidth() / 2,
                          sprite.getY());
                      MoveYModifier mod = new MoveYModifier(1.5f, b.sprite.getY(),
                          -b.sprite.getHeight());
                      b.sprite.setVisible(true);
                      b.sprite.detachSelf();
                      scene.attachChild(b.sprite);
                      scene.bulletList.add(b);
                      b.sprite.registerEntityModifier(mod);
                      scene.bulletCount++;
           }
    Kiểm tra nếu Ship mà không dịch chuyển được thì bỏ qua (Vì không dịch chuyển được thì không bán đạn làm gì)

    Chúng ta có được Scene hiện tại. và lấy được 1 viên đạn từ pool sau đó chúng ta thiết lập nó ở vị trí giữa bên trên Ship.
    Chúng ta tạo ra 1 MoveYModifier và dịch chuyển viên đạn này dọc theo trục Y.
    Trong trường hợp hiện tại của chúng ta, chúng ta cho di chuyển viên đạn từ vị trí ban đầu tới vị trí hết màn hình. Và ta cho hiển thị viên đạn này lên, và sau đó detach bản thân nó từ pool (Mặc dù khi ta lấy nó ra bằng obtain….() thì bản thân nó đã detach rồi, nhưng ở đây tôi cứ viết thêm cho nó rõ hơn).
    Tiếp theo chúng ta attach viên đạn tới Scene hiện tại và đồng thời add nó tới linked list, sau đó đăng ký modifier nếu chúng ta không thực hiện điều này thì viên đạn không thể dịch chuyển được, Sau đó ta tăng biến đếm lên 1 đơn vị.

    Trước khi chúng ta chạy chương trình này chúng ta cần thực hiện thêm một số bước nhỏ.
    Ta trở lại GameScene và implements IOnSceneTouchListener

    Trong constructor chúng ta
    Mã:
     setOnSceneTouchListener(this)
    //Và thêm method touch như sau:
    Mã:
     
           @Override
           public boolean onSceneTouchEvent(Scene pScene, TouchEvent            pSceneTouchEvent) {
                  synchronized (this) {
                         ship.shoot();
                  }
                  return true;
     
           }
    Mỗi lần ta touch on the screen thì nó sẽ gọi shoot(), ta thực hiện hàm này ngay ở đây và không cần chuyển nó đến nới khác để xử lý.

    OK đến đây khi bạn touch thì đã có bullet rồi. Nhưng chúng ta còn một công việc nữa đó là chúng ta chưa làm sạch các viên đạn (Không trả lại chúng tới pool) khi chúng tới đích vì vậy chúng ta sẽ làm tiếp việc này trước khi chúng ta kết thúc phần này.

    Ta thêm vào trong GameScene method sau:
    Mã:
     
    public void cleaner() {
                  synchronized (this) {
                         Iterator<Bullet> it = bulletList.iterator();
                         while (it.hasNext()) {
                               Bullet b = it.next();
                               if (b.sprite.getY() <= -b.sprite.getHeight()) 
                               {                                                          
     
                                      BulletPool.sharedBulletPool().recyclePoolItem(b);
                                      it.remove();
                                      continue;
                               }
                         }
                  }
           }
    Chúng ta lặp đi lặp lại trên linked list (Sử dụng 1 bộ lặp) và nếu viên đạn đi ra màn hình, chúng ta sẽ trả lại nó về pool (Tái sử dụng nó), và sau đó remove nó từ linked list và tiếp tục lặp lại.

    Bây giờ chúng ta chỉ cần gọi method này, chúng ta sẽ thực hiện điều này qua GameLoopUpdateHanler bằng cách add thêm dòng lệnh sau vào onUpdate()
    Mã:
     
    ((GameScene)AndEngineTutorial2Activity.getSharedInstance().mCurrentScene).cleaner();
    OK! Đến đây bạn có thể chạy thử nhé:


    Chủ đề tương tự:


  2. #2
    Thành Viên Mới Avatar của hungvu
    Tham gia
    Feb 2014
    Bài gửi
    4
    Xin hỏi tác giả một tí. Đến đây mới tạo đc ship và bắn đạn, vậy còn phần tương tác với các mục tiêu hay enemies thì sao, nhờ tác giả hướng dẫn thêm vì đối với người mới tập tành làm game thì cái phần tương tác này cũng là cả 1 vấn đề. Làm sao để xuất hiện enemies 1 cách ngẫu nhiên hoặc theo 1 quy luật nào đó do mình đặt ra?



  3. #3
    Thành Viên Mới Avatar của dragonbk91
    Tham gia
    Mar 2014
    Bài gửi
    4
    Google đi bác ơi, engine này lâu đời lắm rồi nên rất nhiều tut cả tiếng Anh lẫn tiếng Việt. Trước em cày nát diễn đàn của nó rồi cũng viết dc 1 game đơn giản )



  4. #4
    Thành Viên Mới Avatar của hungvu
    Tham gia
    Feb 2014
    Bài gửi
    4
    Cho mình hỏi thêm tí. Nó có 2 kiểu import library: một là import source code trực tiếp từ github, hai là copy file .jar. Nhưng 2 kiểu import này lại là 2 library khác nhau, tức là class khác nhau, method khác nhau. Vậy thì nên xài cách nào. Search tut thì nó ra kết quả lẫn lộn cách xài giữa 2 library này nên rất là mệt. Muốn biết nên xài library kiểu nào là tốt nhất. Có ai có lời khuyên ko?



Đá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
  •