Thursday, August 11, 2016

Actor (tiếp theo)


   Trong phần tiếp theo này, mình sẽ đề cập đến các bước để thao tác với Actor :

   Đầu tiên bạn nên tạo Viewport (Nếu bạn không biết Viewport là gì thì yên tâm, mình sẽ viết bài về viewport sau):

         
                   Viewport viewport = new FitviewPort(float width , float height);

   width và height là chiều dài và chiều rộng của màn hình.

   Sau đó là về khởi tạo stage :

                   Stage stage = new Stage( viewport);

              Chắc bạn đang thắc mắc stage là gì và tại sao phải khởi tạo nó ?

   Hãy hình dung như thế này, Actor là diễn viên thì stage sẽ là đạo diễn. Stage sẽ chỉ đạo Actor, một Actor chỉ có thể hiện thị khi nó ở trong stage. và stage phải hiển thị thì Actor mới hiển thị được. Vì vậy nếu bạn chỉ khởi tạo mỗi Actor thôi mà thiếu stage thì chương trình sẽ báo quăng cho bạn vài cái exception ( ngoại lệ ) khi chạy nhé.

   Còn một cách để khởi tạo Stage là không dùng Viewport ;

                   Stage stage = new Stage();

   Với cách này thì Stage của bạn sẽ tự động vừa với màn hình của bạn.

   Sau đó ta khởi tạo Actor ;

                    Actor actor = new Actor();

   Khi khởi tao actor xong rồi bạn nên thêm các thuộc tính của actor vào như vị trí (setPosition()),góc(setRotation()),... Còn nếu bạn không thêm gì cả thì actor của bạn sẽ mặc định ở vị trí (0,0) của game và  0 độ.

   * Sau đó bạn cần cho libgdx biết actor của bạn có được hiển thị không và có "đạo diễn" không :

                actor.setVisible(true);
                stage.addActor(actor);

   Cuối cùng bạn cần để stage " chỉ đạo " actor của mình qua hai phương thức :

                stage.act(float delta);
                stage.draw();

   Phương thức đầu tiên giúp stage cập nhập về thông tin, các thuộc tính của actor có được thay đổi hay không như khi actor di chuyển, xoay,.. Còn "delta" là thời gian giữa hai frame hay khung hình. Có nghĩa là từ khung hình này chuyển qua khung hình kia sẽ mất một khoảng thời gian bằng delta.
Và delta có thể được lấy bằng phương thức :
                Gdx.graphics.getDeltatime();
   Thường thường trong libgdx chuyển được 60 frame mỗi giây ( 60 FPS- frame per second ) từ đó bạn có thể tính được giá trị của delta vào khoảng 1/60 giây.

  Phương thức draw(); của stage giúp stage gọi đến các phương thức draw(); của actor. Có thể nói phương thức draw(); của actor để các actor tự vẽ mình,  tự phác họa ra bản thân actor. Vì thế, khi gọi stage.draw(); các actor sẽ tự vẽ mình lên stage để hiển thị. Chắc hẳn các bạn cũng thắc mắc tại sao không gọi là phương thức stage.draw() vẽ các actor vào game nghe sẽ dễ hiểu hơn? Mình nói vậy để ngay sau đây mình sẽ lợi dụng cái kiểu tự vẽ mình của actor để thêm hình ảnh vào. Do đó sẽ nghe hợp lý hơn khi nói actor tự vẽ.
 
   Sau đây là đoạn code ví dụ cho bạn dễ hình dung :
public class Example {

     private Stage stage;
     private Actor actor;
     private Viewport viewport;

     public Example(){

          viewport = new FitViewport(500,500);
          Stage = new Stage(viewport);
          actor = new Actor();
          actor.setPosition(250,250);
          actor.setVisible(true);
          stage.addActor(actor);

     }

     public void render(float delta){
   
          stage.act(delta);
          stage.draw();

     }
}

   Phương thức render(float delta) bạn có thể cho vào phương thức render của Screen để chạy. ( mình sẽ bàn về Screen trong libgdx sau ).
   ps: Đừng thử mẫu này nếu bạn chưa nắm rõ cấu trúc một chương trình libgdx. Mình sẽ đăng về phần cấu trúc này sớm thôi :).

   Để thêm ảnh vào actor, mình cần bạn tạo thêm một lớp nữa gọi tên gì cũng được và kế thừa (extends) lớp Actor. Ở đây mình sẽ gọi lớp của mình là ExtraActor. sau đó bạn tạo biến toàn cục TextureRegion và đặt tên tùy bạn thích. Tiếp theo bạn sẽ tạo một phương thức để thao tác với hình ảnh. Và cuối cùng bạn sẽ chỉnh lại mã của phương thức draw(); có trong Actor.

public class ExtraActor extends Actor {

          private TextureRegion region;

          public ExtraActor(){

               region = new TextureRegion()

          }

          // phương thức thao tác với hình ảnh
          public void setImage(Texture t){

               region.setRegion(t);
               setWidth(region.getRegionWidth());
               setHeight(region.getRegionHeight());

          }

           @Override
           public void draw(Batch batch, float parentAlpha){

                 batch.draw(region, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation());

           }


}

   Về cách thức load ảnh mình đã đề cập ở mấy bài trước rồi nên chắc bạn cũng quen rồi. Còn hai phương thức setWidth(region.getRegionWidth()); và setHeight(region.getRegionHeight()); để đặt chiều dài và chiều rộng của actor bằng với hình ảnh mà mình sẽ gắn vào. Về phương thức draw(Batch batch, float parentAlpha) bạn đừng quan tâm đến batch là gì và parentAlpha là gì vì khi gọi stage.draw(); stage sẽ tự động cung cáp cho bạn. Cái bạn cần quan tâm là dòng trong dấu ngoặc kép. Mặc định phương thức draw của actor là rỗng không có gì hết. Chính vì thế, chúng ta sẽ ghi đè lên phương thức này. Chúng ta sẽ sử dụng batch để vẽ và truyền hình ảnh "region" vào. Còn mấy phương thức getX(),getY(),... là thuộc tính của actor, lớp mà chúng ta kế thừa.

   Sau đó chúng ta chỉ cần tạo biến thuộc lớp ExtraActor là có thể sử dụng phương thức setImage rồi.

 

     

 

2 comments: