2.3.1. Biểu đồ Use case
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 27
2.3.2. Mô tả Actor
Tên Actor Mô tả
Ngƣời chơi Bắt đầu chơi game.
Ngƣời chơi điều khiển xe để tránh các xe đi ngƣợc chiều và ăn các vật phẩm trên đƣờng để tăng điểm số. AI Sự điều khiển xe của các xe ngƣợc chiều.
n 4: Đặc t Actor
Tên Use case Mô tả
Điều khiển xe của ngƣời chơi
Use case này cho phép ngƣời chơi điều khiển chiếc xe của mình, thay đổi tốc độ của xe.
Xem hƣớng dẫn chơi Use case này cho phép ngƣời chơi xem hƣớng dẫn cách chơi của game.
Xem điểm cao Use case này cho phép ngƣời chơi xem top năm những điểm số cao nhất.
Play game Use case này cho phép ngƣời chơi bắt đầu chơi game. Điều khiển xe của AI Use case này cho phép xe đối thủ tự động di chuyển
cản trở xe của ngƣời chơi.
n 5: Đặc t Use case
2.4. XÂY DỰNG GAME ENGINE
2.4.1. Trạng thái game và vòng lặp game
Trạng thái game
Game là một chuỗi các trạng thái đƣợc diễn ra một cách tuần tự dƣới sự điều khiển của ngƣời chơi. Các trạng thái game luôn có liên quan và ảnh hƣởng lẫn nhau.
Một số trạng thái game cơ bản nhƣ: game loading, game play, game menu, high score, help state…
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 28
H nh 24: Mô h nh chuyển đổi trạn thái ame
Vòng lặp game
Vòng lặp game là quá trình thực hiện lặp đi lặp lại một số công việc để duy trì hoạt động và ổn định của game. Vòng lặp game là thành phần cơ bản nhất mà của game mà game nào cũng có.
Mỗi trạng thái game đƣợc thiết kế bằng một vòng lặp game, trƣớc khi chuyển qua các trạng thái tiếp theo, một vòng lặp game đƣợc tổ chức nhƣ sau:
Vòng lặp game đƣợc bắt đầu bằng quá trình khởi tạo các thành phần cần thiết cho các quá trình sau hoạt động.
Quá trình update thực hiện tất cả các vấn đề liên quan đến tính toán nhƣ: tính toán va chạm, di chuyển, cập nhật các trí tuệ nhân tạo, đối tƣợng, âm thanh..
Quá trình render thực hiện vẽ tất cả các đối tƣợng ra màn hình.
Kết thúc là quá trình thu dọn các tài nguyên hệ thống nhƣ dọn dẹp, giải phóng bộ nhớ…
Quá trình update và render đƣợc thực hiện lặp đi lặp lại cho đến khi ngƣời chơi kết thúc game, mỗi lần quá trình update và render đƣợc thực hiện gọi là một khung hình.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 29 Để đảm bảo sự độc lập của tốc độ game và các thiết bị khi thực hiện quá trình update sẽ đƣợc tính toán tỉ lệ thuận với thời gian giữa hai khung hình.
H nh 25: Vòn lặp game
2.4.2. Xây dựng cấu trúc game
Một đối tƣợng trong game 3D luôn chứa ba thành phần: shader, texture, model. Nhƣ vậy, hai đối tƣợng khác nhau có thể dùng chung một mô hình, shader hoặc texture, để thuận tiện cho việc quản lý và tránh lãng phí bộ nhớ ta sẽ cần xây dựng một trình quản lý các tài nguyên này.
Trong game, nhiều đối tƣợng đƣợc vẽ ra cùng một lúc, cùng một thời điểm, vì vậy ta sẽ cần xây dựng một chƣơng trình quản lý tất cả các đối tƣợng này để đảm bảo các đối tƣợng đều đƣợc vẽ ra hoặc đƣợc cập nhật trạng thái khi thay đổi. Từ những vấn đề đã đề cập ở trên ta đƣa ra cấu trúc của một game thỏa mãn đƣợc các yêu cầu trên:
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 30
H nh 26: Cấu trúc ame en ine
Ta xây dựng hai file Resourcer manager và Scene Manager. Trong đó file Resource Manager để quản lý toàn bộ các tài nguyên nhƣ model, texture của game. File Scene Manager chứa các thông tin hiển thị trên màn hình game.
Lớp Object: Là một lớp trừu tƣợng dùng để mô ta các đối tƣợng 2D, 3D và các hiệu ứng đƣợc sử dụng trong chƣơng trình.
H nh 27: Lớp dẫn xuất cơ b n của lớp Object
Lớp Object2D: dùng để vẽ các đối tƣợng 2D gồm có các thuộc tính:
ID background STATE 1
TEXTURE 15 X Y 0.0, 0.0 SIZE 800, 600
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 31 SHADER 3
POSITION -400.0, -240.0, 0.0 SCALE 2.0, 1.7, 1.0
Trong đó:
- IDlà một giá trị duy nhất cho một đối tƣợng. - STATE trạng thái của đối tƣợng ẩn hoặc hiện. - TEXTURE ID của texture.
- X Y là tọa độ lấy màu của sprite.
- SIZE width, height - Kích thƣớc chiều dài và chiều rộng lấy màu trong sprite lớn.
- POSITION là vị trí của đối tƣợng trong không gian.
- ROTATION là góc quay theo trục x, y, z.
- SCALE là tỷ lệ của đối tƣợng.
Lớp Object3D: dùng để vẽ các đối tƣợng 3D gồm có các thuộc tính sau:
#Objects: 1 #ROAD ID 0 MODEL 8 TEXTURES 1 TEXTURE 4 CUBETEXTURES 0 SHADER 0 LIGHTS 0 LIGHT 0 POSITION 0.0, 0.0, 0.0 ROTATION 0.0, 0.0, 0.0 SCALE 0.15, 0.03, 5.0 - #Objects: số lƣợng đối tƣợng 3D. - #Tên đối tƣợng.
- ID thuộc tính duy nhất của game. - MODEL ID của model.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 32 - TEXTURE ID của texture.
- CUBETEXTURES Số lƣợng của texture bube. - SHADER ID của shader.
- LIGHTS Số lƣợng ánh sáng. - LIGHT ID của ánh sáng.
- POSITION là vị trí của đối tƣợng trong không gian.
- ROTATION là góc quay theo trục x, y, z.
- SCALE là tỷ lệ của đối tƣợng.
Lớp Resource manager: Chứa tất cả các tài nguyên đƣợc sử dụng trong chƣơng trình, bao gồm texture, shader, các model 3D và 2D, có chức năng khởi tạo tất cả tài nguyên khi chƣơng trình bắt đầu thực thi và thu dọn tất cả càng tài nguyên này khi chƣơng trình kết thúc.
Lớp Scene manager: Chứa một danh sách các đối tƣợng 2D, 3D trong chƣơng trình nhƣ nhân vật, thực đơn, camera… khi chƣơng trình cập nhật, hay thực hiện vẽ thì tất cả các đối tƣợng trong Scenes đều đƣợc cập nhật hay vẽ ra màn hình.
H nh 28: Sơ đồ cấu trúc mối quan hệ giữa Resource mana er và Scene mana er
Scene Manager và Resource Manager đều đƣợc xây dựng với cấu trúc Singleton. Để dễ truy cập và xử lý.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 33 Cấu trúc file có dạng: #Models: 2 ID 0 FILE ../sdcard/ExamGL/Resources/Models/gateway.nfg ID 1 FILE ../sdcard/ExamGL/Resources/Models/SkyBox.nfg #Textures: 2 ID 0 FILE ../sdcard/ExamGL/Resources/Textures/Terrain.tga TILING REPEAT ID 1 FILE ../sdcard/ExamGL/Resources/Textures/background_ gamePlay.tga TILING CLAMP #Shaders: 2 ID 0 VS ../sdcard/ExamGL/Resources/Shaders/Basic.vs FS ../sdcard/ExamGL/Resources/Shaders/Basic.fs ID 1 VS ../sdcard/ExamGL/Resources/Shaders/Basic.vs FS ../sdcard/ExamGL/Resources/Shaders/Cube.fs Trong đó Model: - #Model số lƣợng.
- ID: một giá trị duy nhất cho một model. - FILE: đƣờng dẫn tƣơng đối đến file model.
Texture:
- #Textures: Số lƣợng texture. - ID giá trị duy nhất của texture.
- FILE: đƣờng dẫn tƣơng đối đến filetexture.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 34
Shader:
- #Shaders: Số loại shader - ID giá trị duy nhất của shader.
- VS đƣờng dẫn tƣơng đối đến file vertex shader. - FS đƣờng dẫn tƣơng đối đến file fragment shader.
Lớp GameState: Là một lớp trừu tƣợng chứa thông tin một trạng thái của chƣơng trình. Tƣơng tự nhƣ một vòng lặp game. Dùng SetState để chuyển đổi giữa các game state với nhau.
Từ đó ta xây dựng các lớp dẫn xuất của game state để tạo ra các state cho game.
H nh 29: Lớp dẫn xuất của lớp game state
Lớp GamePlay: Là lớp chính thực hiện các thao tác lời gọi khởi tạo, cập nhật các đối tƣợng, vẽ các đối tƣợng và dọn dẹp các tài nguyên khi chƣơng trình kết thúc.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 35
2.4.3. Xử lý va chạm giữa các đối tƣợng
Nhằm đơn giản các tính toán, tính toán các va chạm trong game đƣợc quy đổi về các bài toán tính toán va chạm của các khối hình học nhƣ là khối hộp.
Trong khi đọc dữ liệu từ các model, ta xác định đƣợc các tọa độ theo trục theo các trục Ox, Oy, Oz lần lƣợt nhƣ sau: Xmax, Xmin, Ymax, Ymin, Zmax, Zmin. Từ đó xác định khối hộp bao quanh vật.
H nh 30: Khối hộp bao quanh đối tượng
Để xác định va chạm giữa hai vật trong không gian ta xác định khối hộp của hai đối tƣợng đó và kiểm tra so sánh tọa độ giữa hai vật.
Ta xét vị trí của hai vật A và B.
Trƣờng hợp 1 Trƣờng hợp 2
Ở trƣờng hợp 1: Xét vị trí tƣơng đối A ở bên cạnh B. Nếu Axmax > Axmin→ Hai vật không va chạm nhau.
Nếu Axmax <= Bxmin → Hai va hạm nhau.
Ở trường hợp 2: Xét vị trí tươ g đối A ở trước B. Nếu Azmin > Azmax →
Hai vật khô g va hạm nhau.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 36
2.5. XÂY DỰNG CẦU NỐI CỦA GAME TRÊN WINDOWS VÀ ANDROID ANDROID
2.5.1. Trên Windows
Window cung cấp sẵn các hàm tạo các cửa sổ hiển thị, tạo môi trƣờng cho OpenGL ES hoạt động, các hàm để tiếp nhận sự kiện.
Đầu tiên ta tạo cửa sổ hiển thị trong windows là khởi tạo môi trƣờng. Tạo hàm tiếp nhận xử lý sự kiện.
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRet = 1;
int x = LOWORD(lParam);
int y = HIWORD(lParam);
static bool mouseDown = false;
switch (Msg) { case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_KEYDOWN:
Game::GetInstance()->OnKey((unsigned char) wParam, true);
break;
case WM_KEYUP:
Game::GetInstance()->OnKey((unsigned char) wParam, false);
break; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: mouseDown = true; Game::GetInstance()->OnPointer(POINTER_DOWN, x, y); break; case WM_LBUTTONUP: case WM_RBUTTONUP: mouseDown = false; Game::GetInstance()->OnPointer(POINTER_UP, x, y); break; case WM_MOUSEMOVE: if (mouseDown) { Game::GetInstance()->OnPointer(POINTER_DRAGGED, x, y); } break; default:
lRet = DefWindowProc (hWnd, Msg, wParam, lParam);
break;
}
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 37
}
Hàm kiểm tra lỗi
bool Game::TestEGLError(HWND hWnd, char* pszLocation)
{
EGLint iErr = eglGetError();
if (iErr != EGL_SUCCESS)
{
TCHAR pszStr[256];
sprintf_s(pszStr, ("%s failed (%d).\n"), pszLocation, iErr);
MessageBox(hWnd, pszStr, ("Error"), MB_OK|MB_ICONEXCLAMATION); return false; } return true; } Vòng lặp game int main() {
Game* game = Game::GetInstance(); game->Init(800, 480);
game->SetState(new LoadingState());
while ( game->IsRuning() ) { game->Update(); } Game::FreeInstance(); ResourceManager::FreeInstance(); } 2.5.2. Trên Android
Khởi tạo môi trƣờng và xử lý sự kiện
Android cung cấp lớp GLSurfaceView cho khởi tạo môi trƣờng hoạt động cho OpenGL ES.
private static class Renderer implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) {
GL2JNILib.step(); }
public void onSurfaceChanged(GL10 gl, int width, int height) {
GL2JNILib.init(width, height); }
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
} }
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 38 Lớp GLSurfaceView.Render cung cấp cho ta các hàm onDrawFrame dùng để vẽ, onSurfaceChanged dùng để tiếp nhận xử lý khi có sự thay đổi của môi trƣờng vẽ, nhƣ kích thƣớc, trạng thái… hàm onSurfaceCreated đƣợc gọi đến một lần đầu tiên khi môi trƣờng vẽ đƣợc thực hiện.
Khai báo các hàm native ở ứng dụng Android:
public static native void BridgeJ2C(GL2JNILib obj);
public static native void init(int width, int height);
public static native void step();
public static native void pointer(int type, int x, int y, int x2, int y2);
Ở chƣơng trình C++ ta hiện thực các hàm native tƣơng ứng:
extern "C" {
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_init(JNIEnv * env,
jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_step(JNIEnv * env,
jobject obj);
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_pointer(JNIEnv *
env, jobject obj, jint type, jint x, jint y, jint x2, jint y2);
void Java_com_drybones_evate_GL2JNILib_BridgeJ2C( JNIEnv* env, jobject thiz,
jobject obj ) {
bridge = obj; jclass glViewClass;
(jVM)->GetEnv((void**) &env, JNI_VERSION_1_6);
bridge = (jobject)(env)->NewGlobalRef( obj); glViewClass = (env)->GetObjectClass( bridge); }
};
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_init(JNIEnv * env,
jobject obj, jint width, jint height) {
Game* game = Game::GetInstance(); game->Init(width, height);
game->SetState(new LoadingState());
}
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_step(JNIEnv * env,
jobject obj) {
Game::GetInstance()->Update(); }
JNIEXPORT void JNICALL Java_com_drybones_evate_GL2JNILib_pointer(JNIEnv *
env, jobject obj, jint type, jint x, jint y, jint x2, jint y2) { if (type == 1) { InputManager::GetInstance()->OnTouch(POINTER_DOWN, x, y, x2, y2); } else if (type == 2)
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 39 { InputManager::GetInstance()->OnTouch(POINTER_UP, x, y, x2, y2); } else if (type == 3) { InputManager::GetInstance()->OnTouch(POINTER_DRAGGED, x, y, x2, y2); } }
2.5.3. Port từ C++ qua Android
Cần tải các tool sau và cài đặt làm môi trƣờng để tiến hành port qua Android. http://developer.android.com/tools/sdk/ndk/index.html http://developer.android.com/sdk/index.html http://mirrors.digipower.vn/apache//ant/binaries/apache-ant-1.9.3-bin.zip http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads- 1880260.html
Trƣớc tiên cần Update project để để tạo file build.xml
Vào cửa sổ chứa thƣ mục android cần port qua bật cửa sổ cmd và gõ dòng lệnh sau:
Xây dựng file .so:
Android đƣợc biết đến nhƣ là một nền tảng phát triển trên ngôn ngữ java. Tuy nhiên chúng ta hoàn toàn có thể phát triển các ứng dụng bằng ngôn ngữ C++. Nhiệm vụ của chúng ta là xây dựng tất cả các mã C++ vào một file định dạng “.so” để java đọc nó nhƣ là một thƣ viện.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 40 Kết quả sau khi thực hiện: file “.so” đã đƣợc build.
Build để tạo file .apk
Sau khi tạo file apk ta dùng file này để cài đặt lên thiết bị Android để chơi.
TÓM TẮT CHƢƠNG 2
Chƣơng này đã trình bày việc phân tích yêu cầu của game đặc tả chức năng từ đó xây dựng game, thiết lập liên kết giữa game tử Windows và Android. Trên cơ sở đó đã đƣa ra đƣợc cách xây dựng một game engine đơn giản để xây dựng game Highway và biết đƣợc cách thức để port game từ ngôn ngữ C++ qua java.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 41
CHƢƠNG 3: MỘT SỐ KẾT QUẢ ĐẠT ĐƢỢC
Màn hình của loading game
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 42 Màn hình của chức năng chọn xe
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 43 Màn hình của sub menu
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 44 Màn hình của gameover
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 45
KẾT LUẬN
Kết quả đạt đƣợc
- Cơ bản nắm đƣợc ngôn ngữ lập trình C++.
- Nắm đƣợc một số kỹ thuật phát triển game trên điện thoại di động.
- Tìm hiểu đƣợc cấu trúc cơ bản của game, cách xây dựng một game đơn giản. Xây dựng đƣợc một cấu trúc của game giúp ngƣời chơi có thể dễ dàng tiếp cận và sử dụng.
- Xây dựng đƣợc một game thử nghiệm sử dụng game engine đã xây dựng kết hợp với những hiệu ứng và kỹ thuật đã tìm hiểu trên hệ điều hành Windows và Android.
Hạn chế
- Giao diện chƣa đẹp.
- Chƣơng trình chạy còn chƣa nhanh.
- Windows chƣa có âm thanh và Android dữ liệu chƣa đƣa đƣợc vào asset.
- Do thời gian có hạn nên chƣa thể áp dụng hết các kỹ thuật đƣợc học vào thực hiện game.
Hƣớng phát triển
- Phát triển thêm nhiều mức độ chơi khó hơn, mang tính cạnh tranh hơn.
- Phát triển game có thể chạy trên nhiều hệ điều hành hơn, không chỉ dừng lại hệ điều hành Windows và Android.
- Tìm hiểu và tiếp cận thêm một số nền tảng khác nhƣ iOS, Windows Phone…
Kết luận
- Thông qua đồ án tốt nghiệp này, em đã hiểu đƣợc các kỹ thuật lập trình đồ họa 3D và thực hiện trên thƣ viện lập trình đồ họa Opengl ES 2.0. Đặc biệt hơn, đó là quy trình làm ra một ứng dụng game đơn giản. Với những tiền đề này sẽ tạo cho em một nền tảng kiến thức để có thể tự tin tham gia vào các dự án sau khi ra trƣờng.
- Đối với game Highway hi vọng sẽ góp phần làm đa dạng thêm các loại hình game.
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 46
TÀI LIỆU THAM KHẢO
[1]. Addison Wesley – OpenGL ES 2.0 Programming Guide
[2]. Tài liệu công ty Gameloft-3dBasic&OpenGLES 2.0 - 1.Concepts-BasicGLSL
[3]. GettingStartedCpp
[4]. Phạm Văn Ất - C++ và lập trình hướng đối tượng
[5]. http://opengles-android.blogspot.com/2012/10/opengl-es20-for-android.html [6]. http://vi.wikipedia.org/wiki/Android
Nguyễn Thị Ngọc Thúy – 10CNTT4 Trang 47