1 | P a g e
Game C/C++ cho newbie - 01. Lập trình game bắt đầu từ đâu?
bởi Nguyễn Khánh Duy
Game là gì? Nhìn chung, khi chưa từng biết qua lập trình game, chúng ta thường hay đặt những câu hỏi: lập trình
game là như thế nào? Có giống lập trình ứng dụng không? Có khó không? Có đòi hỏi những kỹ thuật gì
đặt biệt không ?
Câu trả lời của tôi là: game cũng chỉ là một ứng dụng, và nó cũng như bao ứng dụng khác. Khi viết một
ứng dụng, bạn có thể bắt đầu từ hàm main, hoặc dùng IDE sinh code tự động để hổ trợ. Game cũng vậy.
Bạn cũng có thể bắt đầu viết game từ hàm main, hoặc dùng các engine hổ trợ.
Đứng về khía cạnh lập trình, hay từ chủ quan của tôi, game đơn giản là một vòng lặp vô tận. Trong vòng
lập đó, bạn vẽ, bạn xử lý các diễn biến của game, xử lý sự kiện tương tác từ người chơi. Vậy là đủ cho
một game. Tuy nhiên, để làm game cho mục đích thương mại, đòi hỏi bạn nhiều hơn thế.
Một cách nhìn khác, game là một cuốn phim có tương tác. Nếu như một bộ phim cần nhiều thứ như kịch
bản tốt, dàn dựng hay, hậu kỳ, kiểm duyệt, quãng bá, thì game cũng vậy. Game cũng cần một nội
dung hay (kịch bản), coding tốt (dàn dựng, hậu kỳ), kiểm soát chất lượng (kiểm duyệt), quãng bá Nếu
một phim thành công được đánh giá qua doanh thu, thì game cũng vậy. Tuy nhiên, khi mới bắt đầu, thì
doanh thu, lợi nhuận, cần được gạt ra khỏi tư tưởng của mình, để có đủ tỉnh táo tập trung vào chuyên
môn. Lập trình game cần những kiến thức gì? Đã là lập trình hiển nhiên cần phải biết lập trình, tư duy lập trình. Không nhất thiết bạn phải xuất sắc;
biết ít, làm ít, biết nhiều, làm nhiều. Một chút kiến thức kỹ năng về game. Hay nói cách khác, biết chơi game, và từng chơi game.
Biết một ngôn ngữ lập trình nào đó.
Biết một ít kiến thức về toán, vật lý (google it, nếu cần)
3 | P a g e
Một số kiến thức về đồ họa 2D, 3D
Trong phần này, ta sẽ bắt đầu code game.
Chuẩn bị Bạn cần cài đặt một số tool cần thiết sau: Visual studio express 2010
Notepad ++
Python 2.7
Tạo main.cpp từ template
với nội dung:
1
2
3
4
#include "stdio.h"
int main()
{
while(true)
6 | P a g e
5
6
7
8
{
printf("Hello Game\n");
}
}
{
while(true)
{
printf("Hello Game\n");
Sleep(80);
}
7 | P a g e
11
}
Game C/C++ cho newbie - 03. Quản lý vòng đời game
bởi Nguyễn Khánh Duy
Giới thiệu Với tư tưởng hướng đối tượng, trong bước này, ta sẽ thiết kế những lớp cần thiết cho việc quản lý
game.
Đối tượng đầu tiên ta thấy chính là game: lớp CGame Class quản lý game (CGame)
Về cơ bản, ta lớp CGame cần có các phương thức:
7
8
9
10
11
12
13
14
15
16
/// CGame.h
#ifndef __CGAME_H__
#define __CGAME_H__
namespace GameTutor
{
class CGame
{
public:
CGame();
virtual ~CGame() {}
virtual void Run();
virtual void Exit();
virtual void Pause();
virtual void Resume();
9 | P a g e
17
3
4
5
6
7
8
9
10
11
/// CGame.cpp
#include "CGame.h"
#include "stdio.h"
#include "windows.h"
namespace GameTutor
{
CGame::CGame(): m_isPaused(false), m_isAlived(true){}
void CGame:: Pause()
10 | P a g e
12
13
14
15
16
17
18
void CGame::Exit()
{
m_isAlived = false;
}
void CGame::Run()
{
this->Init();
while (m_isAlived)
{
if (m_isPaused)
{
printf("paused\n");
}
else
{
printf("running\n");
}
Sleep(80);
11 | P a g e
40
41
42
43
}
Destroy();
}
}
using namespace GameTutor;
class CExample:public CGame
{
12 | P a g e
10
11
12
13
14
15
16
17
18
19
public:
CExample(): CGame() {}
virtual ~CExample() {}
protected:
void Init();
void Destroy();
};
#endif
13 | P a g e
Hàm main được thiết kế đơn giản như sau:
1
2
3
4
5
6
7
/// main.cpp
#include "CExample.h"
int main()
{
(new CExample())->Run();
}
Game C/C++ cho newbie - 04.Chia để trị
bởi Nguyễn Khánh Duy
Phương pháp chung
Màn hình giới thiệu game (poster)
Menu chính (gồm các nút play, option )
Các menu phụ chọn màn chơi
Loading trước khi vào màn chơi
Màn chơi Mỗi giai đoạn như vậy, ta có thể gọi là một state, hay một scene. ta chọn khái niệm state để gần gũi với
mô hình UML.
15 | P a g e
State vs sub-State
Với một state quá lớn, ta lại nghĩ đến trường hợp chia nhỏ state thành các sub-state. Tuy nhiên, nên
thận trọng trong việc chia sub-state. Việc chia thành các sub-state bên trong state đòi hỏi chi phí quản lý
cao hơn. Do đó, không nên nếu không thật sự cần thiết. Thiết kế State như thế nào ?
Nhìn chung, State cũng giống như một ứng dụng thu nhỏ, do đó cũng có các bước cơ bản sau:
Init
Run
7
8
9
10
11
12
13
14
/// CState.h
#ifndef __CSTATE_H__
#define __CSTATE_H__
namespace GameTutor
{
class CState
{
public:
CState(){}
virtual ~CState(){}
virtual void Init() = 0;
virtual void Update() = 0;
virtual void Render() = 0;
17 | P a g e
15
16
17
18
virtual void Exit() = 0;
18 | P a g e
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
19 | P a g e
31
32
}
#endif Trong file trên, CStateManagement được thiết kế theo kiểu Singleton pattern. Điều này đảm bảo lớp
CStateManagement tồn tại duy nhất 1 instance trong suốt game. Tiếp theo, ta xem ví dụ mẫu về cách quản lý state thông qua hàm update và switch state: 1
2
3
4
5
6
7
8
9
10
11
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
m_pCurrentState->Exit();
delete m_pCurrentState;
}
if (m_pNextState)
{
m_pNextState->Init();
}
m_pCurrentState = m_pNextState;
}
//update state
if (m_pCurrentState)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// CGame.h
#ifndef __CGAME_H__
#define __CGAME_H__
namespace GameTutor
{
class CGame
{
public:
static CGame* GetInstance() {return s_pInstance;}
virtual ~CGame() {}
virtual void Run();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// CGame.cpp
#include "CGame.h"
#include "stdio.h"
#include "windows.h"
#include "CStateManagement.h"
namespace GameTutor
{
CGame* CGame::s_pInstance = 0;
CGame::CGame(): m_isPaused(false), m_isAlived(true)
40
41
42
43
void CGame:: Pause()
{
m_isPaused = true;
}
void CGame::Resume()
{
m_isPaused = false;
}
void CGame::Exit()
{
m_isAlived = false;
}
void CGame::Run()
{
this->Init();
while (m_isAlived)
{
if (m_isPaused)
{
CStateManagement::GetInstance()->Update(true);
}
else
1
2
3
4
5
6
7
8
9
/// CStateLogo.h
#ifndef __CSTATELOGO_H__
#define __CSTATELOGO_H__
#include "CState.h"
using namespace GameTutor;
class CStateLogo: public CState
{
25 | P a g e
10
11
12
13
14
15
16
17
12
13
/// CStateLogo.cpp
#include "CStateLogo.h"
#include "CStateManagement.h"
#include "CStatePoster.h"
#include
CStateLogo::CStateLogo():m_iCount(0), CState()
{}
void CStateLogo::Init()
{
printf("State Logo: Init\n");