CHƯƠNG VIII. CAMERA

Link Source code HD không che: Download 
Các bạn nên mở sources code vừa đọc vừa so sánh với tut này vì mình sẽ giải thích những gì trong sources code.

1. Sơ lược về Camera

  • Khi chơi game platform bạn sẽ thấy màn hình map đằng sau, các nhân vật đều di chuyển theo hướng ngược lại với nhân vật. Giống như bạn coi trên tivi qua camera thì chỉ 1 phần của khung cảnh được hiển thị lên màn hình. Vì vậy chúng ta chỉ có thể hiển thị 1 phần khung cảnh của thế giới game lên màn hình, và bình thường camera sẽ đi theo player. Đúng theo bản chất thì nó còn phần Viewport nữa nhưng mình sẽ gộp chung vào class Camera. Nên Camera của mình sẽ giống như một hình chữ nhật và Anchor Point là giữa tâm Camera.


2. Class Camera

  • class Camera cũng không có gì quá phức tạp, vì nó chỉ chứa thông tin của camera như một hình chữ nhật, có vị trí và chiều dài, chiều rộng. cho nên các bạn tham khảo code trong source code vì nó chỉ là kiểu chứa thông tin và lấy thông tin không xử lý nhiều trong này.





3. Áp dụng camera vào Map

  • Tiếp đến mình sẽ code để ta có thể di chuyển map theo Camera, về bàn chất thì chúng ta sẽ thực hiện phép dời hình (translate) để vẽ các sprite về vị trí của screen. Như màn hình game thì sẽ giới hạn theo hình chữ nhật (0, 0, ScreenWidth, ScreenHight), còn map thì được giới hạn theo hình chữ nhật (0,0 MapWidth, MapHeight), trong 1 game thì map rất là rộng nên chúng ra sẽ chuyển 1 vùng của map từ vị trí Camera về màn hình. Dưới đây là 2 hệ tọa độ của World và Screen




  • Để hiển thị vùng của World Map tương ứng với vị trí Camera thì mình sẽ thực hiện phép dời hình, giống như trong hình học mình sẽ dời hình những tile nào nằm trong vùng Camera ngoài vùng Camera thì mình sẽ không Draw lên màn hình. VD: Camera ở vị trí (800, 800) thì dĩ nhiên đúng nó sẽ vượt ra biên màn hình (màn hình size (600, 600)) lúc này vector translate = (300, 300) – (800, 800) = (-500, -500) và những Sprite nào trong vùng Camera đều sẽ translate 1 vector (-500, -500) (thật ra translate sẽ lấy Position Sprite cộng với vector translate). Sau khi cộng thì các Sprite trong vùng Camera sẽ có tọa độ (0 -> Screen Width, 0 -> Screen Height) nên sẽ được hiển thị lên màn hình.




  • Việc translate thì mình sẽ thực hiện hết trong hàm Draw của Map nên mọi người có thể xem trong hàm này để hiểu thêm.
D3DXVECTOR2 trans = D3DXVECTOR2(GameGlobal::GetWidth() / 2 - mCamera->GetPosition().x,
                                GameGlobal::GetHeight() / 2 - mCamera->GetPosition().y);
….
sprite->Draw(position, sourceRECT, D3DXVECTOR2(), trans);


  • Tiếp theo để hoạt động đúng của ViewPort chức là thằng nào nằm trong vùng camera thì mình mới vẽ lên thì mình sẽ kiểm tra xem những tile nào trong vùng Camera với vẽ lên.
if (mCamera != NULL)
                    {
                        RECT objRECT;
                        objRECT.left = position.x - tileWidth / 2;
                        objRECT.top = position.y - tileHeight / 2;
                        objRECT.right = objRECT.left + tileWidth;
                        objRECT.bottom = objRECT.top + tileHeight;
                        //neu nam ngoai camera thi khong Draw
                        if (isContain(objRECT, mCamera->GetBound()) == false)
                            continue;
                    }

4. Tạo Camera

  • Mình có tạo Camera trong Source code ở class DemoScene. Các bạn có thể vào đó tham khảo thêm.
Camera *mCamera;
mCamera = new Camera(GameGlobal::GetWidth(), 
GameGlobal::GetHeight());
mCamera->SetPosition(GameGlobal::GetWidth() / 2, 
                             mMap->GetHeight() - GameGlobal::GetHeight() / 2);
mMap->SetCamera(mCamera);


  • Nhớ set Camera cho map để map có thể di chuyển theo Camera.

5. Tạo object cho map.

  • Trong map ngoài thông tin các tile để vẽ lên thì các bạn có thể cho thêm về thông tin các object game như viên gạch này sẽ đặt ở đâu,… vì các object này có tương tác va chạm với nhân vật nên nó phải được tạo trong code và map sẽ lưu thông tin vị trí và trạng thái của object. Mình sẽ tạo 1 Layer mới và vẽ nhưng viên gạch lên để dễ dàng nhận biết và sau khi làm xong mình sẽ set Layer này có visible = false để không vẽ nó lên.


  • Có 1 layer object mình dùng nó để set những object tĩnh có body vì dụ nền gạch, ống nước,… sẽ sử dụng ở phần Collision.
  • Thì hiện tại mình sẽ nói về cách tạo mình sẽ trình bày cách sử dụng nó ở phần sau. Sau khi qua phần Player và State Machine.

Tổng Kết

  • Còn 1 kĩ thuật trong việc sử dụng Camera nữa là Clipping nhưng vì nó là kĩ thuật thêm (kiểu nâng cao hơn) với lại mình cũng khá bận chưa có thời gian code đoạn này. Vì các tile có Size là 32 x 32 nếu Camera nằm ở vị trí số không chia hết cho 32 thì tile sẽ bị mất và hiện tượng viền đen sẽ xuất hiện, các bạn có thể Để Camera một size khác nhỏ hơn Screen thì sẽ nhận ra điều này. Trong project nhóm mình làm phần clipping có được làm bởi bạn Hoàng Mạnh Thắng các bạn có thể clone về và xem clipping trong Camera của project đấy: https://github.com/loctho1995/DirectX-Contra

  • Trong source code các bạn dùng các phím mũi tên để di chuyển Camera.
Share on Google Plus

About Lộc Thọ

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.

1 Comment:

  1. Link hỏng rồi bạn ơi úp lại được không? :/

    ReplyDelete