TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN CÔNG NGHỆ TRI THỨC
NGUYỄN THANH PHONG
ỨNG DỤNG TRÍ TUỆ NHÂN TẠO
TRONG XÂY DỰNG GAME
KHÓA LUẬN CỬ NHÂN TIN HỌC
TP. HCM, 2005
TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN CÔNG NGHỆ TRI THỨC
NGUYỄN THANH PHONG - 0112191
ỨNG DỤNG TRÍ TUỆ NHÂN TẠO
TRONG XÂY DỰNG GAME
KHÓA LUẬN CỬ NHÂN TIN HỌC
GIÁO VIÊN HƯỚNG DẪN
TH.S BÙI TIẾN LÊN
NIÊN KHÓA 2001-2005
NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪ
120 trang |
Chia sẻ: huong20 | Ngày: 08/01/2022 | Lượt xem: 451 | Lượt tải: 0
Tóm tắt tài liệu Khóa luận Ứng dụng trí tuệ nhân tạo trong xây dựng game, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
N
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
LỜI CẢM ƠN
Em sẽ không thể hoàn thành luận văn nếu không có sự hướng dẫn và chỉ
bảo tận tình của thầy Bùi Tiến Lên. Em xin chân thành cảm ơn sự chỉ bảo của
thầy.
Em cũng rất cảm ơn các thầy cô trong khoa Công nghệ Thông tin trường
Đại học Khoa học Tự nhiên Tp.Hồ Chí Minh đã tận tình giảng dạy, truyền đạt
những kiến thức quý báu và tạo điều kiện cho em hoàn thành luận văn này.
Xin chân thành cảm ơn sự giúp đỡ, động viên của của tất cả các bạn trong
quá trình thực hiện luận văn.
Em cũng muốn cảm ơn những người thân trong gia đình đã động viên, giúp
đỡ và tạo điều kiện để hoàn thành luận văn.
Mặc dù đã cố gắng hoàn thành luận văn với tất cả sự nổ lực của bản thân,
nhưng luận văn chắc chắn không tránh khỏi những thiếu xót. Em rất mong
nhận được sự thông cảm và chỉ bảo tận tình của các thầy cô và các bạn.
Tp.HCM 7/2005
Sinh viên thực hiện
Nguyễn Thanh Phong
Mục lục
MỤC LỤC
Chương 1 GIỚI THIỆU ................................................................................... 1
1. Lý do chọn đề tài ....................................................................................... 1
1.1. Các ngôn ngữ lập trình game............................................................ 1
1.2. Phân loại game.................................................................................. 2
1.2.1. Game hành động....................................................................... 2
1.2.2. Game nhập vai.......................................................................... 3
1.2.3. Game đua xe............................................................................. 3
2. Mục đích của đề tài ................................................................................... 3
Chương 2 CÁC THUẬT TOÁN TÌM ĐƯỜNG ĐI ....................................... 4
1. Mô tả các thủ tục tìm kiếm rộng, sâu và sâu dần ...................................... 6
2. Thuật giải tìm đường đi có giá thành nhỏ nhất AT ................................... 7
3.Tìm kiếm với tri thức bổ sung.................................................................... 8
4.Tìm đường đi trên đồ thị tổng quát ............................................................ 9
Chương 3 GAME ENGINE ........................................................................... 12
I. WED editor:................................................................................................... 13
1. Những khái niệm cơ bản ......................................................................... 13
a. Giao diện người dùng......................................................................... 13
b. Thanh Icon ......................................................................................... 15
c. Mode .................................................................................................. 15
d. Thiết kế một khung cảnh ................................................................... 14
e. Hướng đối tượng................................................................................ 16
f. Cửa sổ dự án ....................................................................................... 18
2. Các lệnh trong WED ............................................................................... 19
2.1.Các lệnh trong các thực đơn ............................................................ 19
2.1.1. Thực đơn file .......................................................................... 20
2.1.2. Thực đơn edit: ........................................................................ 24
i
Mục lục
2.1.3. Thực đơn mode ...................................................................... 25
2.1.4. Thực đơn Object..................................................................... 29
2.1.5. Thực đơn Texture................................................................... 32
2.1.5. Thực đơn View....................................................................... 33
2.1.6. Thực đơn help ........................................................................ 34
2.2 Giao diện sử dụng ............................................................................ 35
2.3. Cửa sổ dự án ................................................................................... 36
2.3.1. Tab đối tượng ......................................................................... 36
2.3.2. Tab Views .............................................................................. 38
2.3.3. Tab Texture ............................................................................ 38
2.3.4. Tab Resource.......................................................................... 41
2.4. Cửa sổ Bookmark ........................................................................... 41
2.5. Thuộc tính của khối ........................................................................ 41
2.6. Thuộc tính của thực thể .................................................................. 43
3. Thiết kế một map..................................................................................... 45
4. Thực thể................................................................................................... 46
4.1. Thực thể mô hình............................................................................ 46
4.2. Thực thể Sprite................................................................................ 47
4.3. Thực thể Map.................................................................................. 47
4.4. Thực thể Địa hình (terrain) ............................................................. 48
4.5. Bóng................................................................................................ 48
4.5. Thuộc tính trong suốt...................................................................... 49
II. CÁCH SỬ DỤNG MED.............................................................................. 50
1. Trình thiết kế ........................................................................................... 50
1.1. Các thực đơn ................................................................................... 50
1.1.1. Thực đơn File ......................................................................... 50
1.1.2. Thực đơn Edit......................................................................... 53
1.1.3. Thực đơn View....................................................................... 55
ii
Mục lục
1.1.4. Thực đơn Options................................................................... 56
1.1.5. Thực đơn Help........................................................................ 57
1.2. Toolbars................................................................................................ 58
1.2.1. Toolbar File ............................................................................ 58
1.2.2. Toolbar Edit............................................................................ 58
1.2.3. Toolbar Select ........................................................................ 60
1.2.4. Toolbar Mesh ......................................................................... 60
1.2.5. Toolbar các đối tượng cơ sở................................................... 61
1.2.6. Toolbar view .......................................................................... 62
1.2.7. Toolbar Frame........................................................................ 63
1.2.8. Thanh trạng thái ..................................................................... 64
2.Trình thiết kế Skin.................................................................................... 64
2.1. Các thực đơn ................................................................................... 65
2.1.1. Thực đơn File ......................................................................... 65
2.1.2. Thực đơn Edit......................................................................... 66
2.1.3. Thực đơn View....................................................................... 67
2.2. Các Toolbar..................................................................................... 68
2.2.1. Toolbar Skin........................................................................... 68
2.2.2. Toolbar Edit............................................................................ 68
2.2.3. Toolbar Paint .......................................................................... 69
III. SED, C-Script editor ................................................................................... 70
1. Giao diện sử dụng.................................................................................... 71
2. Soạn thảo ................................................................................................. 72
2.1. Lệnh Insert ...................................................................................... 72
2.2. Dòng chú thích................................................................................ 72
2.3. Nhảy đến một đoạn mã ................................................................... 72
2.4. Sử dụng danh sách các thành phần ................................................. 73
2.5. Kiểm tra cú pháp............................................................................. 73
iii
Mục lục
2.6. Soạn thảo thông minh ..................................................................... 73
3. Cấu hình .................................................................................................. 74
4. Thực đơn.................................................................................................. 75
4.1. Thực đơn File.................................................................................. 75
4.2. Thực đơn Edit ................................................................................. 76
4.3. Thực đơn Options ........................................................................... 76
4.4. Thực đơn Tools............................................................................... 77
4.5. Thực đơn Debug ............................................................................. 77
IV. Giao tiếp với các DLL ................................................................................ 79
1. Bắt đầu với SDK ..................................................................................... 79
2. Sử dụng đối tượng C-Script trong một DLL........................................... 82
3. Sử dụng các hàm API.............................................................................. 83
4. Lập trình một game trong C++................................................................ 87
Chương 4 CÀI ĐẶT........................................................................................ 89
I. Người chơi ..................................................................................................... 89
1. Chuyển động vật lý.................................................................................. 89
a. Gia tốc, quán tính và lực ma sát......................................................... 89
b. Rơi từ trên xuống ............................................................................... 93
2. Cách di chuyển camera theo người chơi ................................................. 97
2.1. Tầm nhìn của người thứ nhất.......................................................... 97
2.2. Quay tự do tầm nhìn của người thứ 3 ........................................... 101
2.3. Cách để cho camera tránh chạm vào tường.................................. 106
II. Xe tự động.................................................................................................. 108
Tránh chướng ngại vật trên đường đi ........................................................ 108
iv
Chương 1: Giới thiệu
Chương 1
GIỚI THIỆU
1. Lý do chọn đề tài
Ngày nay, do nhu cầu đời sống của con người ngày càng được nâng cao,
trong đó nhu cầu giải trí của con người được quan tâm đến rất nhiều. Trong đó
việc giải trí bằng Game máy tính ngày càng phát triển nhanh và lan rộng ra do
sự lôi cuốn rất mạnh mẽ của nó. Hầu như ai đã sử dụng máy tính đều đã giải trí
bằng một số game nào đó trên máy tính. Có thể nói Game là một thể loại phóng
phú nhất trong tất cả các loại chương trình trên máy tính.
Mặc dù các chương trình Game rất nhiều, nhưng để có thể viết ra được một
game hay, có thể chơi được quả là một điều không dễ. Tuy vậy, với niềm đam
mê về game máy tính, em cũng muốn tiếp cận với lĩnh vực này.
1.1. Các ngôn ngữ lập trình game
Có rất nhiều chương trình hỗ trợ cho việc viết game: các ngôn ngữ lập trình
như C++, Visual C++, Delphi, Dark Basic Pro, 3D Game Studio.
Nhưng với các ngôn ngữ lập trình C++, Visual C++, DelPhi có thể là
những ngôn ngữ rất mạnh, có thể viết ra được những game có quy mô lớn. Đây
là những ngôn ngữ lập trình có thể hoạt động trong nhiều lĩnh vực: với cơ sở dữ
liệu, lập trình hệ thống, hoặc viết gameDo đó sự hỗ trợ của nó trong việc viết
game là rất ít. Để có thể viết được một game bằng những ngôn ngữ lập trình
này mà không sử dụng một thư viện nào, đòi hỏi phải bỏ ra rất nhiều công sức.
Với engine Dark Basic Pro, đây là loại engine rất đơn giản và dễ sử dụng, là
một ngôn ngữ Script theo họ Basic. Nó chỉ thích hợp với các game nhỏ.
Tại sao lại sử dụng ngôn ngữ 3D Game Studio để viết game?
3D Game Studio là chương trình chuyên dụng dùng để tạo ra game 3D.
1
Chương 1: Giới thiệu
Với hàng trăm game đã được phát hành, 3D Game Studio xứng đáng là một
ngôn ngữ lập trình game lớn. Với 3D Game Studio, chúng ta có thể:
- Tạo ra một game đơn giản từ những script mẫu có sẵn.
- Tạo ra các game thương mại viết bằng ngôn ngữ script.
- Có thể sử dụng VisualC++ hoặc Delphi để kết hợp với 3D Game Studio
để viết game.
Có rất nhiều tài liệu hướng dẫn lập trình game bằng 3D Game Studio. Ngay
cả với những người chưa có kiến thức về lập trình, nhưng nếu theo từng bước
hướng dẫn tạo một game hành động đơn giản thì cũng có thể hoàn thành nó
trong một thời gian ngắn.
Theo Dr.Dobb's Journal: “Đây là bộ công cụ tuyệt vời để nhanh chóng tạo
ra mẫu ban đầu và phát triển ứng dụng 3D”. Chúng ta có thể sử dụng ngôn ngữ
script trong 3D Game Studio để viết và phân phối một game thương mại. Dưới
đây là những game thương mại được làm bằng 3D Game Studio:
1.2. Phân loại game
Thể loại của game thì rất phong phú và đa dạng, ở đây chúng ta chỉ xét các
thể loại game thường thấy nhất là:
1.2.1. Game hành động
Game hành động xuất hiện rất nhiều trong cả game 3D và game 2D. Game
loại này có đặc điểm chúng là tính co giật trong game, như trong game bắn
2
Chương 1: Giới thiệu
súng. Game hành động thường đơn giản hơn tất cả các loại game khác bởi vì
những người bình thường dễ dàng biết cách chơi và chơi hay game này .
1.2.2. Game nhập vai
Game nhập vai thường có hai đặc trưng là: sự thay đổi, phát triển nhân vật
và một câu chuyện mà trong đó nhân vật sẽ trải qua.
1.2.3. Game thể thao
Game thể thao là sự thách thức cho các nhà thiết kế game. Không giống như
hầu hết các thể loại game khác, người chơi biết rất ít về nó, trong game thể thao
người chơi biết rất rõ vì nó mô phỏng một môn thể thao có sẵn trong thực tế.
1.2.3. Game đua xe
Game đua xe tạo ra cảm giác giống như người chơi đang lái xe bên ngoài
thế giới thực.
Tuy trong đề tài của em không thể nói là viết ra được một game chơi được
như một game đua xe, mà đây chỉ là một chương trình ở mức độ mô phỏng
giao thông trên đường phố.
2. Mục đích của đề tài
Tìm hiểu ngôn ngữ lập trình game trong 3D GameStudio:
- Tìm hiểu về WED, một chương trình thiết kế khung cảnh trong game.
- Tìm hiểu về MED, một chương trình thiết kế các mô hình trong game.
- Tìm hiểu về SED, trình soạn thảo dùng để viết các câu lệnh script để kết
nối các mô hình được tạo ra trong MED, các khung cảnh được tạo ra trong
WED và sử dụng những hàm có sẵn trong SED hoặc trong các DLL khác để
tạo ra một game.
Sử dụng thuật toán cổ điển A* tìm kiếm đường đi để một đối tượng có thể
chuyển động theo một hướng mong muốn nào đó.
3
Chương 2: Các thuật toán tìm đường đi
Chương 2
CÁC THUẬT TOÁN TÌM
ĐƯỜNG ĐI
Hầu hết các bài toán hoặc vấn đề đều có thể phát biểu dưới dạng “từ một
trạng thái xuất phát hãy tìm đường dẫn đến một trạng thái kết thúc mong
muốn”
Việc tìm “đường dẫn” từ trạng thái xuất phát (S0) đến trạng thái kết thúc
(Sn) gồm có một số bước sau đây:
− Chọn không gian tìm kiếm thích hợp.
− Tiến hành tìm kiếm có hệ thống và hiệu quả trong không gian tìm kiếm.
− Sử dụng triệt để các nguồn tri thức liên quan trong quá trình tìm kiếm
tương ứng với miền đối tượng cụ thể.
Không gian tìm kiếm của một vấn đề cần giải trên máy tính thường được
biểu diễn bằng đồ thị hay một dạng đặt biệt của đồ thị là cây. Đồ thị là một tập
hợp giữa các đỉnh và các cung nối giữa các đỉnh. Các cung có thể được định
hướng hoặc không định hướng, gán giá trị hoặc không gán giá trị.
Cây là đồ thị định hướng đặt biệt có duy nhất một đỉnh mà không có cung
nào hướng đến (gốc của cây), và mỗi đỉnh khác của cây chỉ có duy nhất một
cung hướng đến.
Sau khi bài toán hoặc vấn đề được biểu diễn lại dưới dạng đồ thị hoặc cây:
− Mỗi đỉnh là một trạng thái của quá trình giải bài toán.
− Mỗi cung là tác động biến đổi quá trình từ giai đoạn này sang giai đoạn
khác.
Như vậy, việc giải quyết một bài toán cũng chỉ là tìm đường đi từ trạng thái
ban đầu đến trạng thái mong muốn được biểu diễn qua hai đỉnh nào đó của đồ
4
Chương 2: Các thuật toán tìm đường đi
thị hoặc cây tìm kiếm. Nhiều bài toán phức tạp nếu giải quyết bằng phương
pháp tìm kiếm ngẫu nhiên thì hầu như vô vọng vì số đường đi có thể sẽ tăng lên
theo hàm mũ của số đỉnh. Chính ở đây biểu lộ toàn bộ bản chất của trí tuệ nhân
tạo khi giải quyết các vấn đề: Đó là nghệ thuật xử trí với các vấn đề lớn bằng
cách giảm số lượng tìm kiếm.
Các thủ tục tìm kiếm điển hình bao gồm:
− Tìm kiếm rộng: đường đi được tìm theo mọi hướng có thể ở mỗi bước.
− Tìm kiếm sâu: đường đi sâu mãi theo một hướng đến khi nào không tiếp
tục được nữa mới chuyển sang hướng khác.
− Tìm kiếm sâu dần: kết hợp tìm kiếm rộng và tìm kiếm sâu trên cơ sở cho
trước mức sâu n rồi tìm kiếm rộng ứng với mức sâu đó.
− Tìm kiếm cực tiểu hóa giá thành: mỗi cung của cây (đồ thị) được gán giá
thành và hướng tìm kiếm được xác định bởi việc cực tiểu hóa giá thành
đường đi.
− Tìm kiếm với tri thức bổ sung: hướng tìm kiếm được xác định với tri
thức bổ sung ở mỗi bước.
Trước hết các thủ tục tìm kiếm rộng, sâu và sâu dần sẽ được mô tả qua một
ví dụ. Sau đó một số thuật giải tìm kiếm cực tiểu hóa giá thành và bổ sung tri
thức sẽ được trình bày chi tiết.
5
Chương 2: Các thuật toán tìm đường đi
1. Mô tả các thủ tục tìm kiếm rộng, sâu và sâu dần
Tìm kiếm rộng: quá trình tìm kiếm sẽ lần lượt là A, B, C, D, E, F, G, H, I,
J, K, L, M, N, O, P, Q, R, S, T, U, V
Tìm kiếm sâu: quá trình tìm kiếm sẽ lần lượt là A, E, K, O, Q, S, T, U, V,
B, F, C, G, L, H, M, D, I, J, N, P, R.
Chú ý: nếu nhánh dưới v dài vô hạn thì quá trình tìm kiếm sẽ không bao giờ
đến được mục tiêu.
Tìm kiếm sâu dần: ứng với mức sâu 2: (A,E), (B,F), (C,G), (C,H), (D,I),
(D,J).
R
V
U
T
S
Q
P O
K L M N
J I H G F E
A
B C
D
1
1
1
1
1 1
1
1
1
10
100 1
17
1 10 12 1
1 1 1
1
1
Trạng thái mong muốn
6
Chương 2: Các thuật toán tìm đường đi
ứng với mức sâu 3: (A,E,K), (B,F), (C,G,L), (C,H,M), (D,I), (D,J,N).
2. Thuật giải tìm đường đi có giá thành nhỏ nhất
AT (Algorithm for Trees) với mỗi đỉnh n tương ưng số g(n) là giá thành
đường đi từ đỉnh đầu tới n. (g(n) có thể chưa xác định đối với các đỉnh thuộc
phần cây chưa hướng đến). Mỗi đỉnh n có thể là:
− Đỉnh đóng: nghĩa là đỉnh đã được xem xét;
− Đỉnh mở: là đỉnh giả định sẽ được xem ở bước sau;
− Đỉnh ẩn: là đỉnh mà hàm g(n) tương ứng chưa được tính đến và chưa
được xem xét đến.
Thuật giải AT gồm các bước sau:
Bước 1: Đầu tiên, mọi đỉnh n và mọi giá trị g(n) đều là ẩn. Mở đỉnh đầu tiên
(coi đỉnh đầu tiên là đỉnh mở và đặt giá trị g tương ứng bằng 0).
Bước 2: Chọn đỉnh mở với giá thành g tương ứng nhỏ nhất. Gọi đỉnh này là
N, nếu N là đỉnh mục tiêu thì đường dẫn tới N là đường đi có giá thành nhỏ
nhất g(n) và vấn đề đã được giải. Nếu không còn đỉnh mở nào thì cây biểu
diễn vấn đề không có đường đi tới mục tiêu. Nếu có từ 2 đỉnh trở lên cùng
giá trị g nhỏ nhất thì kiểm tra trong số đó có đỉnh mục tiêu không? Nếu có
thì chọn đỉnh mục tiêu đó và quá trình giải kết thúc. Nếu không thì chọn tùy
ý một đỉnh trong số đó và gọi là N.
Bước 3: Đóng đỉnh N và mở các đỉnh sau N (có cùng hướng đến N), với
mỗi đỉnh sau N gọi là s, ta tính:
g(s)=g(N)+(giá thành cung từ N tới s)
Bước 4: Quay trở lại bước 2.
Thuật giải AT đã được chứng minh là luôn luôn tìm được đường đi với giá
thành nhỏ nhất nếu như tồn tại đường đó trên đồ thị và là thuật giải tối ưu theo
nghĩa số đỉnh đóng trong quá trình tìm kiếm là ít nhất.
7
Chương 2: Các thuật toán tìm đường đi
3. Tìm kiếm với tri thức bổ sung
Thuật giải AT là thuật giải tìm kiếm đường đi tốt nhất đối với các cây chỉ có
thông tin về đỉnh, cung và giá thành cung. Nhưng trong nhiều trường hợp việc
tìm kiếm đường đi sẽ được định hướng rõ thêm nếu sử dụng các tri thức thu
được dựa trên những hiểu biết về tình huống vấn đề ở mỗi bước. Các thủ tục
tìm kiểm dựa trên 3 cách tiếp cận:
− Không tính đến các tri thức bổ sung ngoài thông tin về đỉnh, cung, giá
thành.
− Sử dụng tri thức bổ sung để tìm cách giải riêng biệt cho vấn đề mà bỏ
qua việc xây dựng cây biểu diễn cho vấn đề.
− Xây dựng biểu diễn vấn đề dưới dạng cây có tính đến tri thức bổ sung
trong cấu trúc cây hoặc giá thành các cung.
Ngoài ra có có cách tiếp cạn theo hướng xây dựng các thuật giải “vạn
năng”, tìm kiếm đường đi với tri thức bổ sung. Họ thuật giải này mang tên là
AKT(Algorithm for knowledgeable Tree search). Tri thức bổ sung ở mỗi đỉnh
được tương ứng một giá trị . Chẳng hạn đó là ước lượng giá thành đường
đi từ n đến mục tiêu (như vậy là ước lượng giá thành đường đi con chương
biết đến).
)(nh
∧
∧
h
Thuật giải AKT gồm các bước sau:
a) Đầu tiên, mọi đỉnh cũng như giá trị g, , là chưa biết. Mở đỉnh đầu
tiên (o) và gán g(0), sử dụng tri thức bổ sung để ước tính h(0) và tính
.
∧
h
∧
f
)0()0()0(
∧∧ += hgf
b) Chọn đỉnh mở có giá trị nhỏ nhất. Gọi đỉnh này là N. Nếu
N là mục tiêu thì đường tới N là đường đi có giá thành nhỏ nhất g(N). Nếu
không tồn tại đỉnh mở nào thì cây không tồn tại đường đi tới mục tiêu. Nếu có
)()( nhngf
∧∧ +=
8
Chương 2: Các thuật toán tìm đường đi
từ 2 đỉnh mở trở lên cùng giá trị nhỏ nhất, hãy kiểm tra trong các đỉnh này
có chứa mục tiêu không? Nếu một trong các đỉnh này là mục tiêu thì vấn đề đã
được giải quyết, còn không thì chọn tùy ý một trong các đỉnh này là N.
∧
f
c) Đóng đỉnh N, mở đỉnh sau N. Với mỗi đỉnh S sau N ta tính
g(s)=g(N)+(giá thành cung từ N đến S). Sử dụng tri thức bổ sung ở bước này,
ước lượng và gán cho f(s) giá trị . )(sh
∧
)()()( shsgsf
∧∧ +=
d) Quay về bước 2.
Giải thích ý nghĩa AKT: giả sử h(n) là giá thành nhỏ nhất được biết chính
xác từ n đến mục tiêu. Như vậy h(n) chỉ là ước lượng gần đúng về h(n). nếu
thì A)()( nhnh ≡∧ KT là thủ tục hoàn toàn tuyệt đối (các đỉnh đóng đúng là các
đỉnh nằm trên đường đi ngắn nhất đến mục tiêu). Trong trường hợp không có
tri thức bổ sung, và A0)( =∧ nh KT suy biến thành AT. Ta thấy rõ ràng rằng giữa
và sẽ tồn tại các thuật giải với mức độ hiệu quả rất thú vị. Nếu
(với mọi n), A
0=∧h hh =∧
hh ≤∧ KT sẽ bảo đảm tìm ra được đường đi giá thành nhỏ nhất và
tối ưu theo nghĩa sử dụng số đỉnh đóng ít nhất so với mọi thuật giải cũng chỉ
làm việc với các tri thức như vậy.
Nếu (với mọi n, hoặc với một số đỉnh). Ahh >∧ KT không bảo đảm tìm được
đường đi giá thành nhỏ nhất nhưng đường đi mà AKT tìm ra vẫn dùng được
trong nhiều trường hợp thực tiễn giải quyết vấn đề.
4. Tìm đường đi trên đồ thị tổng quát
Các phần trên đã trình bày thuật giải tìm đường đi trên đồ thị dạng cây. Tuy
nhiên biểu diễn dạng cây nhiều khi sẽ lặp lại quá nhiều một trạng thái. Điều đó
sẽ tăng thêm thời gian tim kiếm. Để khắc phục cần nới bỏ điều kiện mỗi đỉnh
chỉ có một cung hướng đến và do vậy phải nghiên cứu thuật giải tìm đường đi
9
Chương 2: Các thuật toán tìm đường đi
trên một đồ thị dạng tổng quát. Ta cũng có thể mở rộng thuật giải AKT thành
thuật giải tổng quát A* như sau:
Bước 1: Đầu tiên, mọi đỉnh và các giá trị g, , đều xem như chưa biết,
mở đỉnh đầu tiên 0, gán cho g(0)=0, ước lượng và gán .
∧
h
∧
f
)0(
∧
h )0()0(
∧∧ = hf
Bước 2: Chọn đỉnh mở với giá trị nhỏ nhất và gọi là N. Nếu N là
mục tiêu thì đường dẫn tới N đã tìm được và g(N) là giá thành của đường đi đó.
Nếu không tồn tại đỉnh mở thì đồ thị đó không tồn tại đường đi đến mục tiêu.
Nếu có từ 2 đỉnh mở trở lên cùng giá trị và 1 trong 2 đỉnh đó là mục tiêu thì
quá trình tìm đường đi cũng kết thúc, còn không thì chọn tùy ý một trong 2
đỉnh đó là N.
∧∧ += hgf
∧
f
Bước 3: Đóng đỉnh N và đối với mỗi đỉnh sau đó, ta tính +=′ )()(g Ngs (giá
thành cung từ N đến S). Nếu đỉnh S đã mở và )(gg(s) s′≤ thì bỏ qua S. Ngược
lại ta mở S và đặt )(gg(s) s′= , tính và . )(sh∧ )()()( shsgsf ∧∧ +=
Bước 4: Quay về bước 2.
Bây giờ chúng ta có thể dùng A* để tìm đường đi ngắn nhất giữa 2 thành
phố dựa theo bản đồ giao thông với tri thức bổ sung có thể là khoảng cách
đường chim bay từ điểm (thành phố) n tới mục tiêu (thành phố cần đến). Do
khoảng cách đường chim bay bao giờ cũng nhỏ hơn khoảng cách đường giao
thông nên với mọi n. Thuật giải A* với tri thức bổ sung như
trên sẽ tìm được đường đi ngắn nhất (hoặc giá thành n... độ lớn và phạm vi của tài nguyên âm thanh.
Add Position: Đặt một vị trí vào map. Vị trí có thể được xác định trong lúc viết
mã. Nếu không có thực thể người chơi, vị trí đầu tiên được sử dụng là vị trí bắt
đầu của camera.
31
Chương 3: Game Engine – Cách sử dụng WED
Add Map Entity: Đặt một thực thể map (tập tin WMB) như cửa, thang máy, sân
ga. Thực đơn hiện ra tất cả các thực thể map trong thư mục map và trong các
thư mục con. Chúng ta có thể tự tạo ra một thực thể thể map bằng cách mở một
đối tượng đã được làm sẵn, và BUILD để tạo ra tập tin WMB. Khi thêm một
thực thể mới vào WED sẽ đặt chúng vào chính giữa 4 cửa sổ thiết kế.
Add Model: đưa một thực thể mô hình (tập tin MDL) vào map, là các thực thể
có thể chuyển động. Thực đơn hiện ra tất cả các thực thể mô hình trong thư
mục map và trong các thư mục con. Chúng ta có thể tạo ra một thực thể mô
hình bằng cách sử dụng chương trình thiết kế các mô hình, MED.
Add Terrain: đưa một thực thể địa hình (tập tin HMP; không được hỗ trợ trong
tất cả các phiên bản). Thực thể địa hình có thể được tạo ra bằng chương trình
MED. Thực thể địa hình có thể được di chuyển và thay đổi kích thướt nhưng
không quay được.
Add Sprite: đưa một thực thể cảnh (tập tin PCX), như đồng cỏ, câyThực đơn
hiện ra tất cả các thực thể cảnh trong thư mục map và trong các thư mục con.
Có thể sử dụng các chương trình vẽ hình, như Paint Shop Pro, để tạo ra một
thực thể cảnh. Nhớ lưu tâp tin PCX theo định dạng có màu sắc thật.
Add Path: Thêm vào một đường dẫn, để các thực thể hành động sử dụng
(không được hỗ trợ trong mọi phiên bản). Chúng ta có thể đặt tên cho đường
dẫn trong properties; còn không thì một tên mặc định được tạo ra. Trong chế
độ Vertex Mode, các điểm trong đường dẫn có thể được tạo thêm hoặc xóa đi.
Load Entity: Đưa một tập tin thực thể từ một thư mục nào đó, đưa nó vào map,
và sao chép nó vào thư mục map. Cẩn thận nếu không nó sẽ đè lên thực thể có
cùng tên.
Load Sound: Đưa một tập tin WAV từ một thư mục nào đó, đưa nó vào map, và
sao chép nó vào thư mục map.
32
Chương 3: Game Engine – Cách sử dụng WED
Load Prefab: Đưa tập tin WMP như là đối tượng kiểu khối vào khung cảnh
thiết kế.
Save Prefab: Lưu khối đối tượng được chọn vào tập tin WMP, để sử dụng
trong các khung cảnh thiết kế khác.
2.1.5. Thực đơn Texture
Apply to Object: Lệnh này gắn kết cấu được chọn trong
cửa sổ texture đến tất cả các mặt của đối tượng được
chọn. Hoặc chúng ta có thể nhấp double vào kết cấu được
chọn trong cửa sổ kết cấu.
Texture Bookmarks: Lệnh này mở ra một cửa sổ cho phép cất giữ các kết cấu
ưa thích trong cửa sổ kết cấu.
Texture Manager: Lệnh này đưa ra một hộp thoại, trên đó chúng ta có thể thêm
hoặc xóa đi bộ kết cấu WAD trong thanh
texture. Trên đó có các tùy chọn sau:
New WAD: Tạo ra một tập tin WAD rỗng, để
chúng ta có thể thêm các kết cấu mới vào thanh
texture.
Add WAD: Thêm một tập tin WAD vào texture.
Add Folder:Thêm tất cả các tập tin WAD trong
thư mục được chọn.
Save WAD: Lưu tập tin WAD sau khi nó đã bị thay đổi như thêm vào hoặc bỏ
đi một kết cấu nào đó.
Build WAD: Tạo ra một tập tin WAD mới chứa đựng tất cả các kết cấu được sử
dụng trong lúc thiết kế.
Remove WAD: Xóa đi một kết cấu trên thanh kết cấu.
33
Chương 3: Game Engine – Cách sử dụng WED
2.1.6. Thực đơn View
GXL Properties: Danh sách các thuộc tính của thư
viện đồ họa được sử dụng trong khung nhìn 2D và 3D.
Toolbars: Hiển thị hoặc ẩn đi một toolbar nào đó hoặc
cửa sổ dự án.
Add View: Thêm một cửa sổ khung nhìn mới ngoài 4
cửa số thiết kế đã có.
Wireframe: Chọn loại biểu diễn trong cửa sổ 3D theo
dạng khung dây.
Solid: Chọn loại biểu diễn trong cửa sổ 3D theo dạng khối đặc.
Textured: Chọn loại biểu diễn trong cửa sổ 3D theo dạng kết cấu.
Goto Center: Đưa tiêu điểm của 4 cửa sổ thiết kế đến phạm vi của đối tượng
đang chọn.
Lock Views: Mặc định, tiêu điểm của 4 cửa sổ thiết kế nằm trên cùng một
điểm trong không gian. Khi thay đổi vị trí của một khung nhìn, các khung nhìn
thiết kế khác cũng sẽ tự động cập nhật vị trí của chúng tùy vào tiêu điểm mới.
Lệnh Lock Views sẽ cho phép hoặc vô hiệu đặc điểm này. Khi vô hiệu, các cửa
sổ thiết kế này có thể di chuyển một cách độc lập, không phụ thuộc vào nhau.
Decrease View Depth: làm cho dễ dàng thấy cửa sổ thiết kế hơn, WED sẽ
không hiển thị những phần của khung cảnh nằm ngoài phạm vi nào đó. Lệnh
này sẽ làm giảm phạm vi tầm nhìn này.
Increase View Depth: làm cho dễ dàng thấy cửa sổ thiết kế hơn, WED sẽ không
hiển thị những phần của khung cảnh nằm ngoài phạm vi nào đó. Lệnh này sẽ
tăng phạm vi tầm nhìn này.
2.1.6. Thực đơn help
34
Chương 3: Game Engine – Cách sử dụng WED
Tutorial: mở tập tin hướng dẫn sử dụng 3D GameStudio.
About WED: Thông tin về WED và phiên bản GameStudio.
2.2. Giao diện sử dụng
4 cửa sổ thiết kế hiển thị khung cảnh mà chúng ta xây dựng từ 4 khung nhìn
khác nhau theo các hướng: hướng trên, sau lưng, bên cạnh và ở một góc tùy ý
trong cửa sổ 3D. Theo mặc định, 4 khung nhìn có tiêu điểm nằm trên cùng một
điểm trong không gian. Có thể cuộn một cửa sổ bằng cách nhấp phải và kéo rê
chuột, và phóng to, thu nhỏ bằng nút lăn chuột hoặc giữ phím [SHIFT] và rê
nút chuột phải. Khi di chuyển một khung nhìn trong cửa sổ WED sẽ tự động
cập nhật các khung nhìn khác tùy vào vị trí của tiêu điểm mới. Chúng ta có thể
khóa hoặc mở khóa khung nhìn của 4 cửa sổ bằng cách chọn Lock Views.
Engine sử dụng hệ tọa độ thuận tay phải trong lúc thiết kế. Để hiểu được hệ
thống này, hãy tưởng tượng về con đường đi hằng ngày. Chiều dương của trục
X chỉ về hướng đông, và hướng đến cạnh bên phải trong cửa sổ khung nhìn
trên. Chiều dương của trục Y chỉ về hướng bắc, và hướng lên trên trong cửa sổ
khung nhìn trên. Còn trục Z thì chỉ chiều cao của khung cảnh. Chiều dương của
trục Z tiến ra bên ngoài cửa sổ khung nhìn trên và hướng về phía chúng ta. Cửa
sổ sau lưng quy định khung nhìn hướng đến hướng bắc, và cửa sổ bên cạnh quy
định khung nhìn hướng đến hướng tây. Hệ thống lưới của cửa sổ không chia
lưới tọa độ theo bội số của 10, như chúng ta mong đợi mà được chia theo bội số
của 8 (có thể điều chỉnh trong Preference). Theo phương pháp này chúng ta có
thể dễ dàng tạo ra một đối tượng có chính xác cùng kích thướt với kết cấu của
mình, thông thường kích thướt của nó chính là bội số của 2 (như 64x64,
128x128, hoặc 256x256). Sử dụng mạng lưới mặc định và kích thướt của kết
cấu, ví dụ với một kết cấu 128x128 điểm sẽ bao phủ 128 hình lập phương đơn
vị mà không cần phải lợp thêm vào nữa. Kích thướt của một hộp lưới nhỏ, và
số hộp nhỏ trên hộp lưới lớn, được cho biết trên thanh tiêu đề.
35
Chương 3: Game Engine – Cách sử dụng WED
Trong cửa sổ 3D chỉ là một khung nhìn quay xung quanh tiêu điểm thiết kế
trong không gian. Cửa sổ 3D có thể được biểu diễn ở dạng khung dây, rắn,
hoặc kết cấu để xem trước. Cách biểu diễn này có thể được thay đổi bằng cách
chọn thực đơn View/Render. Trong Preferences chúng ta có thể chọn giữa phần
mềm biểu diễn cơ sở (GXL_BASE) và biểu diễn DirectX 8.1(GXL_DX81) cho
khung nhìn 2D và khung nhìn 3D. Tất cả chúng cũng đều hiển thị màu sắc của
nguồn sáng và đưa ra một khung nhìn khá thực cho toàn cảnh, tuy nhiên nó
không có cùng chất lượng như sản phẩm cuối cùng. Nếu phần mềm biểu diễn là
DirectX, chúng ta có thể điều chỉnh các tham số biểu diễn bằng cách nhấn phải
chuột vào cửa sổ và chọn GXL_Properties. Lúc này chúng ta có thể điều chỉnh
tác dụng của mặt trời, ánh sáng được biểu diễn trong cửa sổ 3D.
Chúng ta có thể đưa các khung nhìn của các cửa sổ thiết kế trở về trạng thái
ban đầu bằng lệnh View/Home. Cửa sổ thiết kế có giới hạn theo chiều sâu.
Nhiều đối tượng của khung cảnh sẽ không được hiển thị nếu nó vượt ra khỏi
phạm vi nào đó của khung nhìn. Nó rất hữu ích khi chúng ta xây dựng một
level quá lớn, bởi vì nó có thể làm giảm số đối tượng được hiển thị trên màn
hình. Chúng ta có thể điều chình giá trị khoảng cách trong GXL_Properties
hoặc sử dụng lệnh View/Decrease ViewDepth và View/Increase View Depth.
Để dọn dẹp cửa sổ thiết kế trong lúc xây dựng level, chúng ta có thể tắt việc
hiện thị các thực thể trong map. Chúng ta có thể việc này bằng cách bỏ chọn
tùy chọn Show Entities trong cửa sổ Preferences.
2.3. Cửa sổ dự án
2.3.1. Tab đối tượng
Cửa sổ này hiển thị danh sách tất cả các đối tượng ở dạng cây trong toàn bộ
level. Đối tượng được chọn được làm nổi bật trong cây danh sách. Chúng ta có
thể chọn một đối tượng bằng cách nhấp double vào nó. Có thể chọn nhiều đối
36
Chương 3: Game Engine – Cách sử dụng WED
tượng trong cây đối tượng bằng cách giữ phím [CTRL] trong khi nhấp vào các
đối tượng. Khi nhấp phải vào một đối tượng sẽ đưa ra tùy chọn sau đây:
Scope to: Giới hạn lại một nhóm trong cửa sổ
2D và 3D.
Goto Object: Trung tâm của khung nhìn được
chọn bao quanh đối tượng được chọn.
New Group: Tạo ra một nhóm mới bên trong
nhóm hiện tại.
Ungroup: Đưa các đối tượng ra khỏi nhóm
hiện tại.
Cut/Copy/Delete: Thay đổi một đối tượng
hoặc nhóm đối tượng.
Render style:
Chọn loại biểu diễn (khung dây, đặc, kết cấu) của đối
tượng hoặc nhóm. Cũng cho phép nó không được chọn
(disable) và di chuyển đối tượng, và làm cho nó không thể
nhìn thấy được (invisible) trong khung nhìn.
Đối tượng hoặc nhóm các đối tượng có thể được bỏ qua trong quá trình biên
dịch, để tăng tốc độ biên dịch để kiểm tra các phần khác trong toàn level. Để
làm điều này, chúng ta có thể nhấp chuột phải vào đối tượng và chọn Render
Style->Ignore
Properties: mở ra cửa sổ thuộc tính của đối tượng.
37
Chương 3: Game Engine – Cách sử dụng WED
2.3.2 Tab Views
Cửa sổ này hiển thị một danh sách các khung nhìn đã được lưu, và cho phép
lưu vị trí một khung nhìn nào đó bằng cách nhấp phải chuột.
Add View Setting: vị trí mới của khung
nhìn.
Save View Settings: lưu vị trí của khung nhìn.
Restore View Setting: Gọi lại vị trí của khung nhìn.
Delete: Xóa vị trí của khung nhìn đang chọn.
2.3.3. Tab Texture
Cửa sổ này hiển thị tất cả các kết cấu từ các tập tin kết
cấu đã được xác định trong texture manager. Chúng ta có
thể mở một bộ các kết cấu WAD bằng cách nhấp vào nó,
thay đổi kích thướt cửa số texture bằng cách kéo rê chuột ở
cạnh phía dưới, và có thể cuộn một WAD bằng thanh cuộn
nằm ở phía bên phải. Nếu con chuột đang nằm trên một
texture nào, thì tên của nó sẽ được hiển thị trong cửa sổ cửa
sổ Texture. Khi nhấp vào một kết cấu thì hình ảnh của nó sẽ được xuất hiện ở
38
Chương 3: Game Engine – Cách sử dụng WED
cửa sổ Texture, chúng ta có thể thay đổi các thuộc tính của kết cấu bằng cách
nhấp phải chuột vào nó và chọn Setting. Khi nhấp double chuột vào một kết
cấu, thì nó sẽ xuất hiện trong cửa sổ Object và gắn đến tất cả các mặt của khối
đang chọn. Muốn thay đổi kết cấu của một khối map, đầu tiên chọn khối, rồi
cuộn đến cửa sổ kết cấu, nhấp trái chuột vào kết cấu mong muốn, rồi nhấp
chuột phải vào nó và chọn lệnh apply.
Hộp thoại cũng cho phép thêm vào hoặc xóa đi một kết cấu
trong bộ sưu tập các kết cấu WAD. Nhấp chuột phải vào một kết
cấu đưa ra những tùy chọn sau đây:
Apply: Gắn kết cấu vào đối tượng được chọn.
Settings: Xuất hiện bảng điều chỉnh các thuộc tính của một kết
cấu.
Tên, độ phân giải, độ sâu của màu sắc.
x – y offset: độ dịch chuyển của kết cấu.
x – y scale: kích thướt của kết cấu.
Angle: góc quay của kết cấu.
Ambient: điều chỉnh cường độ ambient.
Albedo: Albedo dưới 5 để điều chỉnh màu sương mù, trên 5 chỉ cường độ suất
phân chiếu.
Flags Được sử dụng trong lúc viết mã.
Smooths Để điều chỉnh độ mịn của bóng.
Mirror Làm cho kết cấu có độ phản chiếu lại.
Shaded kết cấu vô hình
Flat kết cấu phẳng
39
Chương 3: Game Engine – Cách sử dụng WED
Sky kết cấu bầu trời
Turbulence kết cấu chuyển động
None không có kết cấu
Add Teture: sẽ thêm một kết cấu PCX, BMP, TGA đến WAD, để làm kết cấu
cho các bề mặt. Tên kết cấu được tạo từ các kí tự thông thường, số, gạch dưới
(không chứa các kí tự đặc biệt và khoảng cách). Các trường hợp ngoài lệ: nếu
một kết cấu được đặt tên bắt đầu là một kí tự ‘+’, theo sau là 1 số, thì kết cấu
này là một hoạt ảnh với chu trình từ ‘+0+9’. Nếu tên bắt đầu là ‘*’ thì đây
chính là một kết cấu chuyển động hỗn loạn có thể qua lại được; nếu nó bắt đầu
với sky, thì nó chính là kết cấu loại bầu trời.
Remove Texture: sẽ xóa kết cấu đang chọn ra khỏi WAD.
Rename: đổi tên kết cấu đang chọn.
Extract Texture: lưu kết cấu được chọn vào tập tin BMP hoặc PCX.
Add to Bookmarks: thêm kết cấu được chọn vào tập các kết cấu được làm dấu.
Save WAD: Lưu tập tin WAD. Chú ý rằng tập tin WAD trong
GameStudio có định dạng khác với định dạng tập tin WAD trong Quake. Tuy
nhiên, WED đều có thể truy cập cả hai loại theo cách thức riêng.
Show Texture: Đưa ra nhiều cách thức hiển thị của kết cấu.
1:1 hiển thị kết cấu cùng với
kích thướt gốc của nó
64x64 hiển thị kết cấu có kích
thướt là 64x64
32x32 hiển thị kết cấu có kích
thướt là 32x32
40
Chương 3: Game Engine – Cách sử dụng WED
Texture Name hiển thị tên của kết cấu
dưới ảnh của nó
Texture Name
Only
chỉ hiển thị tên của kết
cấu
2.3.4. Tab Resource
Cửa sổ này hiển thị danh sách tất cả các tập tin và mã nguồn trong game.
Chúng ta có thể xem mã nguồn hoặc nhấp double chuột vào một tập tin nào đó
để mở nó bằng trình soạn thảo của nó.
2.4. Cửa sổ Bookmark
chúng ta sử dụng cửa sổ này để đánh dấu những kết cấu trong cửa sổ
texture. Để mở cửa sổ này chọn lệnh Textures/Bookmarks. Để đánh dấu một
kết cấu thường sử dụng, nhấp phải chuột vào kết cấu
trong cửa sổ kết cấu rồi chọn lệnh Add to
Bookmarks.
2.5. Thuộc tính của khối
Properties
Block: Cho phép đặt tên cho một khối.
Texture Lock: kết cấu được giữ thẳng hàng trong lúc di chuyển khối. Chúng
không được giữ thẳng hàng trong lúc quay và thay đổi kích thướt.
Passable: Được dùng khi muốn tạo ra một môi trường chất lỏng. Để cho
khối có thể qua lại được và có thể thấy được bề mặt có nó từ bên trong.
Invisible: Chướng ngại vật không nhìn thấy được. Chú ý rằng những khối
không nhìn thấy thì không thể được dò tìm bởi lệnh trace(). Nếu muốn một
41
Chương 3: Game Engine – Cách sử dụng WED
khối khối nhìn thấy nhưng có thể được dò tìm bằng lệnh trace() thì hãy sử dụng
cờ none.
Surface/Texture
Surface: Cho phép gắn một kết cấu khác đến từng bề mặt của khối được chọn,
và điều chỉnh các tham số của bề mặt này. sử dụng nút >> và nút << để chuyển
đến bề mặt mong muốn. Bề mặt được chọn sẽ có màu vàng trong khung nhìn
hiện tại. Để gắn một kết cấu khác đến bề mặt này, chọn một kết cấu mới trong
cửa sổ kết cấu, nhấp phải chuột và chọn apply. Sử dụng X/Y offset, và X/Y scale
để sửa lại cho kết cấu thẳng hàng với cạnh bề
mặt nếu cần. Chúng ta có thể quan sất kết quả
trong khung nhìn 3D. Điều chỉnh Angle để
quay hướng của kết cấu trên bề mặt. Ô flags
cho phép thay đổi các thuôc tính của bề mặt.
Ambient: làm tối hoặc chiếu sáng kết cấu của khối, -100..+100 (mặc định là
0).
Albedo/Fog: hệ số phản xạ của mặt trời (10..100, mặc định là 50), hệ số phản
xạ của gương hoặc màu sắc (1..4).
Shaded: kết cấu thông thường có bóng mờ với ánh sáng tĩnh và ánh sáng
động.
Flat: kết cấu phía bên ngoài, không có bóng mờ. Bóng thẳng theo góc
chiếu sáng của mặt trời.
Sky: bề mặt bầu trời nhiều lớp, cần thiết cho hộp bầu trời bao quanh
khung cảnh. Là mặc định nếu tên kết cấu bắt đầu là ‘sky’.
Turbulence: được dùng cho các chất lỏng, kết cấu này được dùng cho nước
hoặc dung nham. Là mặc định nếu tên kết cấu bắt đầu là ‘*’.
42
Chương 3: Game Engine – Cách sử dụng WED
None: bề mặt không được hiển thị.
Flag1..7 thông thường được sử dụng trong lúc viết mã.
Mirror: xác định bề mặt này có chiều ngang hoặc dọc (chỉ sử dụng trong
các phiên bản chuyên nghiệp).
Possition: cho phép chỉnh sửa bằng số để
di chuyển, quay, kích thướt của khối. Các giá
trị quay và kích thướt có thể nhập vào nhưng
không được thay đổi.
Object: Hiển thị vị trí cục bộ (trong một
nhóm) và toàn cục của một khối.
2.6. Thuộc tính của thực thể
Nhấp phải chuột vào thực thể, rồi
chọn Properties để hiển thị hộp thoại
này. Tùy chọn bên phải xuất hiện:
Name: Mỗi thực thể có một tên
duy nhất, để xác định thực thể trong lúc viết mã. Tên này được phát sinh tự
động nhưng cũng có thể được sửa lại (tối đa 20 kí tự).
File: Tên tập tin địa hình, map, mô hình, ảnh của thực thể (tối đa 32 kí
tự).
Ambient: giảm hoặc tăng độ sáng cho thực thể (-100...+100).
43
Chương 3: Game Engine – Cách sử dụng WED
Flags: Transparent – làm cho thực thể trở nên trong mờ.
Invisible – thực thể không nhìn thấy được, nhưng nó vẫn còn là một
chướng ngại vật.
Shadow – thực thể sẽ có bóng nửa trong suốt trên nền đất.
Overlay – chuyển kết cấu của các mô hình hoặc map từ đen sang
trong suốt.
Flare – sự trong suốt của một mô hình hoặc một cảnh phụ thuộc vào
độ sáng của nó.
Bright – tăng độ sáng của một mô hình hoặc cảnh trong mờ, cho các
ngọn lửa hoặc tia sáng.
Metal – làm cho vỏ bên ngoài của thực thể có thể phản xạ lại khi bị
ánh sáng mặt trời chiếu vào.
Action: Hành vi của thực thể, nhận
được từ mã nguồn.
Flag1..Flag8: Có nhiệm vụ là làm
một công tắc, phụ thuộc vào hành vi
của thực thể trong mã nguồn. Chúng
có thể xuất hiện dưới tên gọi khác
được định nghĩa bởi khai báo define
trong mã nguồn.
Skill1..Skill20: chứa các giá trị kiểu
số, phụ thuộc vào hành vi của thực thể
trong mã nguồn. Chúng có thể xuất
hiện dưới tên gọi khác được định
44
Chương 3: Game Engine – Cách sử dụng WED
nghĩa bởi khai báo define trong mã nguồn.
Position: Cho phép di chuyển, quay và thay
đổi kích thướt của thực thể bằng cách nhập
giá trị vào các ô position, angle, scale.
Object: hiển thị vị trí cục bộ (trong một
nhóm) và vị trí toàn cục của thực thể.
3.Thiết kế một map
Không những về mặt thẩm mỹ mà còn cả những kỹ thuật phát sinh cũng
phải được đề cập đến trong lúc thiết kế một level. Một cấu trúc cây BSP chứa
tất cả các bề mặt mà cắt với các mặt khác. Các cạnh và đỉnh không được nhận
từ WED, mà được tính toán từ các phần giao nhau. Ưu điểm của ý tưởng này là
chúng ta có thể sử dụng những khối trùng lắp lên nhau - những phần giao
không nhìn thấy được sẽ bị bỏ đi trong quá trình xử lý, và các cạnh và đỉnh mới
sẽ tự động được thêm vào phần giao nhau. Chính vì đặc điểm này mà biên dịch
sẽ nhanh hơn, bởi vì những khối bị trùng lắp, không thấy được không được
biên dịch (những engine khác sẽ biên dịch tất cả các khối giao với nhau).
Khuyết điểm của ý tưởng này chính là khi các đỉnh tạo ra một góc quá nhỏ dẫn
đến sự chênh lệch vị trí giữa các đỉnh là rất lớn. Nếu bề mặt tiếp xúc hoặc giao
nhau tạo ra một góc rất nhỏ, sai lệch khoảng 1/100 độ có thể cách vị trí các
cạnh khoảng một vài pixel thì có thể thấy được trong level.
Với đặc điểm này, chúng ta không nên sử dụng những khối quá hẹp, quá
dài, hoặc quá nhọn. Không nên tạo ra những khối có cạnh nhỏ hơn 2 quants.
Hãy thiết kế các map có bề mặt ít nhất như có thể, và sử dụng những khối dày
như có thể. Đôi khi chúng ta không thể không sử dụng những bề mặt có góc
quá nhỏ, những vẫn có một cách thiết kế tốt và xấu để thiết kế những bề mặt
này. Ví dụ, khi thiết kế một đoạn đường dốc như thế này:
45
Chương 3: Game Engine – Cách sử dụng WED
Thiết kế tồi: sử dụng khối quá mỏng, góc chênh lệch quá nhỏ. Và các chỗ
nối sẽ có thể giống như là những lỗ hổng.
Thiết kế tốt: sử dụng 3 khối với 15 bề mặt thay vì 5 khối với 20 bề mặt, và
sự sai lệch của một góc, khi xảy ra cũng không nhìn thấy được.
4. Thực thể
Thực thể là loại tập tin ngoài nằm ở thư mục work hoặc trong các thư mục
con của nó. Có 4 loại thực thể có thể đưa vào WED.
4.1. Thực thể mô hình
Một mô hình là một đối tượng 3D có thể chuyển động, được lưu trữ trong
tập tin ngoài MDL. Nó bao gồm một mạng lưới 3D với vỏ bao rất mịn. Mô
hình thực thể thường dùng là các đối tượng nhỏ có thể chuyển động: diễn viên,
quái vật hoặc giống như vậy. Chúng có thể được tạo ra bằng cách sử dụng
46
Chương 3: Game Engine – Cách sử dụng WED
chương trình thiết kế mô hình, như MED, là một thành phần của 3D
gameStudio. Hầu hết tất cả các chương trình thiết kế mô hình, kể cả MED, đều
có thể hiểu các định dạng 3D khác như 3DS, X, hoặc MD2 và chuyển nó thành
mô hình MDL. Vì thế nếu muốn đưa các đối tượng, cảnh được tạo ra bởi một
chương trình khác, như Truespace®, Maya® hoặc 3D Studio MAX®. Với các
mô hình nhận được từ các chương trình như MAX hoặc MAYA có thể được tải
từ trang web GameStudio.
4.2 Thực thể Sprite
Một sprite là một hình phẳng 2 chiều, nó giống như là một hình vẽ trên một
bức tường, hoặc luôn luôn đối mặt với camera nếu cả 3 góc của nó đều là 0. Nó
được lưu trữ trong các tập tin ngoài theo các định dạng PCX, BMP, TGA và có
thể được tạo ra bằng các chương trình vẽ hình chuẩn, như PaintShop Pro hoặc
Adobe Photoshop. Loại tập tin TGA có chứa kênh alpha có thể đưa ra được giá
trị trong suốt trong từng điểm ảnh. Thực thể sprite được biên dịch nhanh hơn
các thực thể map hoặc thực thể mô hình, và rất thích hợp để sử dụng để tạo ra
các vụ nổ, nguồn sáng, ngọn lửa hoặc như thứ tương tự như vậy.
Nếu không muốn một thực thể luôn luôn di chuyển theo camera, thì cần
thiết lập các góc của nó khác 0, như 0.1 chẳng hạn. Với các sprite có thể
chuyển động, cất tất cả các khung chuyển động liên tục trong cùng một tập tin,
ví dụ như tập tin explo+7.pcx trong thư mục template. Thông thường, cần đặt 4
sprite vào một hình dạng ‘X’ để tạo ra một đối tượng giống thế giới thực như
các loại cây. Một vài chương trình làm ảnh chuyển động 3D, như VoodooT
không cho phép kích thướt của các sprite lớn hơn 256x256 điểm ảnh.
4.3 Thực thể Map
Một thực thể map là một đối tượng 3D tĩnh, được lưu trữ trong tập tin ngoài
có định dạng WMB. Thực thể map có thể được sử dụng như là các thành phần
47
Chương 3: Game Engine – Cách sử dụng WED
của level như cửa, nền đất, các loại xe cộ. Bởi vì chúng chỉ là một map đã được
biên dịch, vì thế chúng ta có tạo ra chúng bằng trình thiết kế WED. Thí dụ,
chúng ta có thể chuyển từng map đã được làm sẵn thành một thực thể bằng
cách mở nó, thực hiện BUILD với tùy chọn Map Entity, rồi chép tập tin WMB
vào thư mục hiện tại. Chúng ta có thể tìm thấy các loại map đã được làm sẵn
như cửa, đồ đạc, xe cộ trong thư mục con prefab. Các thực thể mô hình
(model), ảnh (sprite), địa hình (terrain) đều là như bộ phận cấu thành thực thể
map sẽ được đưa vào level khi thực thể map được đưa vào level. Như vậy, một
nhóm thực thể có thể được định nghĩa và biên dịch thành các thực thể map.
Chúng ta có thể truy cập đến các thực thể trong thực thể map bằng chỉ lệnh
map_subents.
4.4. Thực thể Địa hình (terrain)
Thực thể địa hình gồm nhiều kết cấu được ánh xạ vào mạng lưới hình chữ
nhật. Nó được tập tin ngoài HMP (không được hỗ trợ trong tất cả các phiên
bản). Giống như tên gọi thực thể địa hình có thể được sử dụng như là các thành
phần lớn hoặc nhỏ của level mà không theo bất kì quy luật nào của địa hình.
Địa hình không quay được.
4.5. Bóng
Chỉ các thực thể mô hình mới có bóng động trên mặt đất. Tuy nhiên, nếu
một thực thể không di chuyển mà không hoạt động, như cây, chúng ta nên chọn
loại bóng cho nó là bóng tĩnh. Bóng tĩnh thì mịn hơn và được biên dịch nhanh
hơn, và được hỗ trợ trong tất cả các phiên bản. Tạo ra một khối có kích thướt
và hình dạng gần giống như thực thể, đặt vào vị trí của thực thể, bật cờ detail
và chọn chế độ kết cấu cho tất cả các mặt của nó là None để cho nó không thấy
được. Khối sẽ tạo ra một bóng tĩnh trên nền đất và nó các tác dụng như một
48
Chương 3: Game Engine – Cách sử dụng WED
chướng ngại vật, nhưng không thấy được. Có thể bật cờ passable để cho sự dò
tìm thực thể được nhanh hơn.
4.5. Thuộc tính trong suốt
Thực thể có thể trở nên trong suốt nếu bật cờ transparent hoặc cờ flare,
hoặc sử dụng ảnh có định dạng với kênh alpha cho các thực thể sprite hoặc vỏ
bao bên ngoài của thực thể.
49
Chương 3: Game Engine – Cách sử dụng MED
II. Cách sử dụng MED
MED được sử dụng để tạo hoặc chuyển đổi định dạng các mô hình hoặc các địa
hình 3D trong 3D GameStudio. Giao diện rất dễ sử dụng để tạo ra các mô hình
3D và vỏ bao bên ngoài đơn giản.
1. Trình thiết kế
Dưới đây là giao diện của MED:
Chúng ta thấy rằng 4 khung nhìn của MED rất giống 4 khung nhìn của
WED. Tuy nhiên, vì chức năng và nhiệm vụ của nó là thiết kế một mô hình
chuyển động, khác so với WED là thiết kế level, nên tương tác với người dùng
là khác. Khi kéo rê vào các thanh trong các khung nhìn thì sự cân xứng của các
khung nhìn sẽ bị thay đổi.
Khi nhấp phải vào khung nhìn 3D và chọn GXL Properties, thì thuộc tính
của nó như độ sáng và phạm vi khung nhìn có thể được thay đổi.
1.1. Các thực đơn
1.1.1. Thực đơn File
Với thực đơn file, chúng ta có thể lưu, gọi lại, nhập hoặc xuất các tập tin từ
MED.
50
Chương 3: Game Engine – Cách sử dụng MED
New Model: Tạo ra một mô hình mới.
New Terrain:Tạo ra một địa hình mới.
Open
Save Lưu mô hình hoặc địa hình với
đến tập tin hiện trong các định dạng MDL5,
MDL7, HMP của GameStudio. Định dạng
MDL không giống như định dạng mô hình
có cung phần mở rộng trong QuakeT. Khung xương chỉ được hỗ trợ trong
định dạng MDL7.
Save As: Lưu với tên mới.
Merge: Cộng mô hình khác vào mô hình hiện tại, vì thế kết quả là sự
kết hợp của hai mô hình.
Choose Palette: Gọi một bảng màu cho các mô hình mà vỏ bọc có kết cấu kiểu
8 bit. Bảng màu có thể nhận được từ các định dạng như BMP, PCX, PAL, LMP
hoặc RAW.
Import / Append Vertices: Nhập một mô hình từ các định dạng .ASC hoặc .3DS.
Lệnh này sẽ nhập các mô hình được tạo ra từng các ứng dụng 3D như 3D
Studio. Cả hình dạng và kết cấu của các mô hình đều được đưa vào. Muốn đưa
một mô hình đã được tạo ra bởi các ứng dụng khác, đầu tiên cần đưa khung vào
trước, rồi sử dụng tùy chọn "Import Append Frames" giữ nguyên các khung.
Khi nhập một tập tin 3DS quá phức tạp, chúng ta nên chọn tùy chọn Model
Properties / Fast Prec trước khi lưu nó. Sau khi nhập theo phương pháp này,
các bản vẽ và kết cấu có thể được tạo ra bằng trình thiết kế skin.
Import / Append Frames: Đưa vào một vài khung chuyển động của một mô
hình. Để cho các khung theo đúng thứ tự, đầu tiên, chọn khung cuối cùng, rồi
51
Chương 3: Game Engine – Cách sử dụng MED
giữ phím SHIFT, rồi chọn tập tin đầu tiên trong nhóm muốn đưa vào, rồi nhấn
OK.
Import / Frame Names From Text : Lệnh này nhập các khung có tên trong tập
tin kiểu text. Để tạo ra một tập tin kiểu text, đặt tên một khung trên một dòng
không có khoảng trống.
Export / Q1 MDL: Xuất mô hình ra định dạng Quake 1 MDL.
Export / MD2: Xuất mô hình ra định dạng Quake 2 MDL, là định dạng
được sử dụng rất phổ biến và là phần thứ 3 của trình thiết kế mô hình. Sẽ xuất
hiện một hộp thoại lưu các tập tin có định dạng .MD2 này trong đó cần nhập
đường dẫn để lưu tập tin skin của mô hình.
Export / AQM: Xuất mô hình ra định dạng .AQM, là định dạng được sử
dụng trong trình thiết kế mô hình Quake 2.
Export / Frame to ASC: Xuất khung hiện thời ra định dạng .ASC.
Export / Model to ASC: Xuất mô hình hiện thời ra nhiều định dạng .ASC tùy
thuộc vào số khung của nó.
Export / Frame to 3DS: Xuất mô hình hiện thời ra định dạng .3DS (không có
skin).
Export / Model to 3DS: Xuất mô hình hiện thời ra nhiều định dạng .3DS tùy
thuộc vào số khung của nó.
History: Chỉ 8 tập tin đã mở.
Exit: Thoát khỏi chương trình.
52
Chương 3: Game Engine – Cách sử dụng MED
Open:
Mở hoặc đưa một mô hình hoặc địa hình. Danh sách các tập tin này đưa ra
nhiều định dạng khác nhau. Chúng ta có thể mở các định dạng MDL, MD2,
WMP hoặc X đối với các mô hình, và các định dạng PCX, BMP hoặc HMP đối
với các địa hình. Khi nhập một định dạng nào đó thì một cửa sổ sẽ hiện ra để
chúng ta có thể chọn các thuộc tính của cần đưa vào. Khi nhập một mô hình
phức tạp có định dạng là MD2 hoặc X thì tùy chọn Model Properties/Fast Prec
nên được chọn trước khi lưu chúng.
Một bản đồ địa hình có định dạng PCX, BMP hoặc RAW có thể được tạo ra
từ các chương trình vẽ phong cảnh hoặc địa hình. Các định dạng bitmap sẽ
được nhập vào và chuyển thành mô hình theo định dạng HMP. Chúng ta có thể
xác định giá trị tốt nhất của độ phân giải của một mắt lưới theo chiều ngang
hoặc chiều dọc theo mỗi hướng từ 30 đến 100 đỉnh. Một vài hướng có thể được
phát sinh tự động.
1.1.2. Thực đơn Edit
53
Chương 3: Game Engine – Cách sử dụng MED
Undo: Quay trở lại hành động vừa mới thực hiện.
Redo: Quay trở lại hành động Undo vừa mới thực hiện.
Copy Selected: Lưu phần được chọn vào clipboard.
Paste: Dán dữ liệu đã được sao chép vào mô hình. Hộp
thoại đưa ra các tùy chọn cho phép thay thế các vị trí của
các đỉnh trong mô hình và thêm vào mô hình như đó là
các đỉnh mới. Việc thay các đỉnh cũng có một nhân tố pha
trộn, vì thế khi chép dữ liệu từ một khung và dán vào
khung khác, chúng ta có thể pha trộn giữa hai bộ dữ liệu.
Paste range: Dán dữ liệu đã được sao chép vào một phần nào đó của khung,
tùy vào yếu tố pha trộn ở trên.
Change Frame Name: Đổi tên khung hiện tại. Thông thường tên khung nên
bao gồm một từ mô tả và 1 số, như “walk1”, “walk2”. Tên khung xác định các
khung này có chức năng là đi bộ, tấn công, chết Các hoạt động này sẽ được
gắn vào sau.
Goto Frame: Nhảy đến một khung xác định, chọn khung mà bạn
muốn đến trong danh sách và nhấp OK.
Add New Frame: Thêm một khung mới. Hộp thoại sẽ đưa ra những tùy
chọn là đặt khung mới sau khung cuối cùng, trước
khung đầu tiên, hoặc sau một khung nào đó. Chúng ta
cũng có thể nhập vào tên của một khung.
Delete Current Frame: Xóa khung hiện tại, xuất hiện hộp thoại xác nhận quyế...rotate)((long)target,(long)&(ent->pan));
Có một ít khác so với việc thường gọi một hàm trong C++. Tuy nhiên, nó khá
dễ hiểu: Chúng ta có một con trỏ hàm, vì thế để gọi nó, chúng ta phải sử dụng
(*). Và đối số được đưa luôn luôn là kiểu fixed hoặc long. Chúng ta đã ép
kiểu nó thành kiểu long thay cho kiểu fixed, đó chỉ là sự thỏa thuận rằng chúng
ta đang đưa một tham số con trỏ. Tất cả các chỉ lệnh vector đều đòi hỏi một con
trỏ các số fixed.
Nếu chỉ lệnh không đòi hỏi một vector hoặc một giá trị mà là cái gì đó phức
tạp hơn như là một thực thể. Chúng ta chỉ cần đưa một con trỏ A4_ENTITY
được ép sang kiểu long. Nhưng nếu nó đòi hỏi một chuỗi thì sao – chúng ta sẽ
sử dụng con trỏ kiểu A4_STRING hoặc chỉ cần đưa char*? Chúng ta phải sử
dụng A4_STRING. Trong thí dụ ackdll.cpp, chúng ta có thể tìm thấy cách để
đưa một hằng chuỗi vào một chỉ lệnh trong C-Script.
long pSTRING(char* chars)
{
static A4_STRING tempstring;
static char tempchar[256];
strncpy(tempchar,chars,255);
tempstring.chars = tempchar;
tempstring.link.index = 4<<24;
85
Chương 3: Game Engine – Cách viết một DLL
return (long)&tempstring;
}
//thí dụ được ra một chuỗi để tạo một thực thể
DLLFUNC
fixed create_warlock(long vec_pos) {
static
wdlfunc3 ent_create =
(wdlfunc3)a5dll_getwdlfunc("ent_create");
return
(*ent_create)(pSTRING("warlock.mdl"),vec_pos,0);
}
Một vài chỉ lệnh không thể được gọi trực tiếp từ một DLL. Tuy nhiên, chúng
có thể được thi hành trực tiếp bằng cách gọi một script thực hiện những chỉ
lệnh đó. Script có thể được gọi từ DLL bằng hàm sau:
long a5dll_getscript(char *name);
Hàm này trả về địa chỉ của một hàm script được định nghĩa bởi người dùng có
tên được đưa. Nó có thể được dùng để gọi một hàm hoặc hành động trong C-
Script được định nghĩa bởi người dùng bên trong một DLL. Nếu hàm không
tìm thấy, NULL sẽ được trả về và phát sinh ra một lỗi.
fixed a5dll_callscript(long script,long p1=0,long p2=0,long p3=0,long p4=0);
fixed a5dll_callname(char *name,long p1=0,long p2=0,long p3=0,long
p4=0);
Hàm này gọi một hàm script được định nghĩa bởi người dùng có địa chỉ hoặc
tên được đưa. 4 tham số được đưa có thể là một số kiểu fixed, mảng, hoặc một
con trỏ đến một đối tượng C-Script. Nếu hàm yêu cầu ít hơn 4 tham số, các
tham số còn lại đặt là 0.
Thí dụ một hàm DLL gọi một hàm đã được định nghĩa trong C-Script:
DLLFUNC fixed WDLBeep(fixed value)
{
// lấy con trỏ hàm
static long beeptwice =
a5dll_getscript("beeptwice");
// gọi hàm
86
Chương 3: Game Engine – Cách viết một DLL
return a5dll_callscript(beeptwice,0,0,0,0);
}
Hàm DLL này sẽ yêu cầu hàm trong C-Script sau sẽ được gọi:
function beeptwice() { beep; beep; }
4. Lập trình một game trong C++
Sử dụng đối tượng A4_ENTITY, một DLL có thể thực thi một hàm AI phức
tạp, mà nó sẽ rất khó để viết trong C-Script. Ngay cả toàn bộ game đều có thể
được viết trong một DLL. Thí dụ sau chỉ ra cách thay đổi tham số thực thể
trong một hàm DLL.
// lăn tròn thực thể được đưa một góc 180 độ
DLLFUNC fixed FlipUpsideDown(long entity)
{
if (!entity) return 0;
// lấy con trỏ đến thực thể được đưa
A4_ENTITY *ent = (A4_ENTITY *)entity;
// gán góc lăn tròn của thực thể đến 180 độ
ent->roll = FLOAT2FIX(180);
return 0;
}
Hàm này sẽ được gọi trong C-Script bằng hàm FlipUpsideDown(my). Để điều
khiển toàn bộ thực thể trong một DLL, giả sử chúng ta viết toàn bộ một game
bằng ngôn ngữ C++, một hành động giả trong C-Script có thể được gắn vào
thực thể như sau:
var appdll_handle;
dllfunction dll_entmain(entity);
dllfunction dll_entevent(entity);
function main()
{
// Mở DLL
appdll_handle = dll_open("myapp.dll");
...
}
action myent_event {
dll_handle = appdll_handle;
87
Chương 3: Game Engine – Cách viết một DLL
dll_entevent(my); // hàm DLL này điều khiển tất cả
các sự kiện của thực thể
}
action myentity {
my.event = myent_event;
while(1) {
dll_handle = appdll_handle;
dll_entmain(my); // hàm DLL này điều khiển thực
thể
wait(1);
}
}
88
Chương 4: Cài đặt
89
Chương 4
CÀI ĐẶT
Game được tạo thành từ các thành phần: các khối và các thực thể.
Các khối sẽ được kết hợp lại trong lúc thiết kế bằng WED để tạo ra một
khung cảnh môi trường tĩnh trong game.
Các thực thể: sprite (núi, mặt trời, mây), mô hình (bao gồm cây trồng, xe
của người chơi và các xe tự điều khiển), terrain (tạo ra một địa hình có hình
dạng phức tạp).
Các thành phần tĩnh hoặc không cần xử lý hoặc đòi hỏi xử lý rất ít trong lúc
viết mã. Do đó lúc cài đặc chủ yếu tập trung vào hai đối tượng quan trọng là
chiếc xe do người chơi khiển khiển và những chiếc xe tự chuyển động theo một
hướng nào đó.
I. Cài đặt cho người chơi
1. Chuyển động vật lý
a. Gia tốc, quán tính và lực ma sát
Giả định rằng, người chơi di chuyển thẳng về phía trước, quãng đường mà
nó đi được tăng lên theo vận tốc và thời gian:
ds=v*dt
v là tốc độ đo bằng quants (khoảng 1 inch) trên tick(khoảng 1/16s).
ds quãng đường đi được đo bằng quants.
dt thời gian để người chơi đi được quãng đường ds, do bằng tick.
Nếu muốn thay đổi vận tốc của người chơi, chúng ta cần phải tác dụng một
lực lên người chơi, lực càng lớn làm cho vận tốc người chơi thay đổi càng
Chương 4: Cài đặt
90
nhanh. Theo vật lý học, thì khi một vật thay đổi vận tốc, thì nó sẽ bị một sự
kháng cự nào đó. Đó chính là quán tính, phụ thuộc vào khối lượng m của một
vật. Với cùng một lực tác dụng, thì vật có khối lượng càng lớn có sự thay đổi
vận tốc càng nhỏ.
Ta đã biết được các công thức:
a - gia tốc – sự thay đổi của vận tốc trên 1 tick
f - lực tác dụng
m - khối lượng của vật.
Chúng ta sẽ xem xét 3 loại lực tác dụng.
- Lực đẩy (propelling force): Lực này dùng để thay đổi vận tốc người chơi,
được tạo ra khi ấn phím. Trong một game đơn giản, lực này sẽ tùy thuộc vào
khối lượng của người chơi. Đối với người chơi có khối lượng càng lớn thì lực
tác dụng đến nó càng lớn.
p=p*m
- Lực thứ hai là lực hấp dẫn, có thể là một lực hút người chơi đến một
hướng nào đó, hoặc là trọng lực của trái đất. Lực hấp dẫn thay đổi từ nơi này
đến nơi khác. Trong game, độ lớn của lực này cũng tùy thuộc vào khối lượng
của người chơi. Điều này rất dễ thấy trong trường hợp lực này là trọng lực:
d=d*m
- Lực thứ 3 tác dụng lên người chơi là lực ma sát. Lực này làm cản trở hoạt
động của người chơi, liên tục làm giảm tốc độ của anh ta. Không giống như vật
lý học, là lực hãm bao gồm lực ma sát và những thành phần suy giảm, chúng ta
sử dụng lực giả tạo, nó sẽ tăng với khối lượng người chơi (sức ép lên mặt đất)
và tốc độ:
r= - f*m*v
r: lực ma sát.
dv = a*dt
a=f/m
Chương 4: Cài đặt
91
f: hệ số ma sát.
v: vận tốc.
m: khối lượng.
Hệ số của lực ma sát tùy thuộc vào bề mặt mà người chơi đang di chuyển
trên đó: tuyết có hệ số ma sát thấp hơn đá. Trong không trung, hệ số ma sát hầu
như bằng 0. Dấu trừ chỉ rằng lực lực có chiều ngược hướng với vận tốc của
người chơi. Khối lượng của người chơi là m, cũng là một thành phần trong
phương trình, bởi vì trong game, nếu trọng lượng của người chơi lớn thì lực ma
sát ép vào bề mặt càng lớn. Như vậy, 3 lực: lực đẩy f, lực hấp dẫn d và lực
giảm tốc độ r đều làm thay đổi vận tốc của người chơi.
dv phải được thêm vào vận tốc sau mỗi trạng thái (frame). p, d và f là các lực
đẩy, lực hấp dẫn, lực ma sát. dt là khoảng thời gian mà vận tốc thay đổi - ở đây
nó là thời giữa hai trang thái, bởi vì chúng ta đang tính vận tốc mới sau mỗi
trạng thái. Chúng ta sẽ làm cho tất cả các lực cân xứng với trọng lượng, vì thế
yếu tố khối lượng sẽ không còn cần thiết nữa, nó không còn có tác dụng gì
trong chuyển động vật lý nữa, chúng ta sẽ loại nó ra khỏi phương trình. Chúng
ta sẽ viết mã nguồn cho công thức cuối cùng như sau:
dv = a * dt
dv = (p + d + r) / m * dt
dv = (p + d - f * v) * dt
Chương 4: Cài đặt
92
Lực tác dụng là 10, lực ma sát là 0.7 trong cả lúc quay và lúc di chuyển. Chúng
ta sử dụng các skill (biến có sẵn của thực thể), để lưu giữ vận tốc hiện tại của
thực thể, bởi vì cần biết vận tốc của người chơi ở trạng thái trước để tính toán
lực tác dụng hiện tại vào người chơi. Chúng ta đã sử dụng skill14 để cất giữ
vận tốc góc, và skill11 để lưu vận tốc di chuyển về phía trước. time là dt trong
công thức tính quãng đường đi được, vì thế người chơi sẽ di chuyển cùng vận
tốc trên mọi PC, nó hầu như độc lập với tốc độ khung! Chú ý rằng, chúng ta đã
thay đổi công thức gốc, theo lý thuyết thì công thức tính sự thay đổi của vận tốc
trên một chu kỳ trạng thái là:
Nó sẽ được viết lại trong script như sau:
var force[3];
var dist[3];
action move_me
{
while (1)
{
force.PAN = -10 * KEY_FORCE.X; // tính lực quay
my.SKILL14 = TIME*force.PAN + max(1-
TIME*0.7,0)*my.SKILL14; // vận tốc quay
my.PAN += TIME * my.SKILL14; // quay người chơi
force.X = 10 * KEY_FORCE.Y; // tính toán lực di chuyển
my.SKILL11 = TIME*force.X + max(1-TIME*0.7,0)*my.SKILL11; //
tính vận tốc
dist.X = TIME * my.SKILL11; // quãng đường đi được
dist.Y = 0;
dist.Z = 0;
move_mode = ignore_passable + glide;
ent_MOVE(dist,nullvector); // di chuyển người chơi
move_view(); // di chuyển camera theo người chơi
wait(1);
}
}
v -> v + dv
v -> v + (p - f * v) * d
Chương 4: Cài đặt
93
my.SKILL11 = my.skill11 + (force.X - 0.7 * my.SKILL11) * time;
và được thay đổi từng bước như sau:
my.SKILL11 = my.skill11 + TIME * force.X - time * 0.7 * my.SKILL11;
my.SKILL11 = TIME * force.X + (1-time*0.7) * my.SKILL11;
Cuối cùng cho ra một kết quả khá phức tạp:
my.SKILL11 = TIME * force.X + max(1-TIME*0.7,0) * my.SKILL11;
Như vậy, chúng ta đã hoàn thành script cho công thức tính vận tốc trên. Nhưng
chúng ta sử dụng hàm max ở đây để làm gì. Max(a.b) so sánh hai giá trị a và b,
và trả về giá trị nào lớn hơn. Khi sử dụng max(1-TIME*0.7,0), nó sẽ chỉ cho ra
kế quả dương, chúng ta phải làm như vậy, bởi vì trong các máy tính có tốc độ
khung quá thấp, và giá trị time quá lớn – TIME*0.7 có thể sẽ lớn hơn 1, cho ra
kết quả âm. Điều này làm cho vận tốc bị đảo chiều, và người chơi sẽ di chuyển
ngược ra sau.
b. Rơi từ trên xuống
Trong khi sự di chuyển theo chiều ngang của người chơi chủ yếu được tác
dụng từ các lực do người sử dụng ấn phím, thì sự di chuyển theo chiều dọc là
do tác dụng của trọng lực tác dụng vào người chơi. Nếu người chơi đang đứng
ở trên mặt đất, nó sẽ không cần di chuyển theo chiều dọc. Nhưng nếu người
chơi bỗng nhiên rơi vào không trung – như nếu nó tiến đến một vực thẳm, thì
nó nhất định phải rơi xuống. Để xác định người chơi có ở trạng thái này hay
không, cần phải xác định người chơi cách đất bao nhiêu. Chúng ta sẽ sử dụng
lệnh trace:
Chương 4: Cài đặt
94
Lệnh trace trả về khoảng cách đến chướng ngại vật đầu tiên mà một tia giữa 2
điểm (2 vector được đưa). Chúng ta đang sử dụng điểm trung tâm của người
chơi (my.x) là điểm thứ nhất, và điều chỉnh điểm temp để nó là điểm thứ 2 nằm
phía dưới người chơi khoảng 4000 quant. Bằng cách sử dụng chế độ use_box,
chúng ta đang sử dụng tia truy tìm có một bề dày là vỏ bao bên ngoài người
chơi, thông thường có đường kính là 32 quant – nó cũng trả về khoảng cách
đến điểm dưới cùng của hộp bao bên ngoài người chơi, không phải là trung tâm
action move_me
{
while (1)
{
force.PAN = -10 * KEY_FORCE.X; // tính lực quay
my.SKILL14 = TIME*force.PAN + max(1-TIME*0.7,0)*my.SKILL14; //
tính vận tốc quay
my.PAN += TIME * my.SKILL14; // quay người chơi
force.X = 10 * KEY_FORCE.Y;
my.SKILL11 = TIME*force.X + max(1-TIME*0.7,0)*my.SKILL11; // tính
vận tốc tiến về trước
dist.X = TIME * my.SKILL11; // quãng đường đi được về phía trước
dist.Y = 0;
vec_set(temp,my.x);
temp.z -= 4000; // một vị trí nằm dưới người chơi 4000 quants
// chọn các chế độ truy tìm các thực thể và bề mặt từ vị trí của người chơi
trace_mode =
ignore_me+ignore_sprites+IGNORE_MODELS+USE_BOX;
dist.z = -trace(my.x,temp); // trừ khoảng cách theo chiều dọc
move_mode = ignore_passable + glide;
ent_MOVE(dist,nullvector); // di chuyển người chơi
move_view(); // di chuyển camera
wait(1);
}
}
Chương 4: Cài đặt
95
của người chơi. Nếu chúng ta xem điểm dưới cùng của hộp bao bên ngoài là
chân của người chơi, thì lệnh trace sẽ tính chân người chơi đang cách mặt đất
là bao nhiêu. Nếu chân của nó đang ở dưới nền đất, lệnh trace sẽ trả về kết quả
âm. Vì thế dist.z được gán bằng phủ định của khoảng cách trả về từ lệnh trace.
Theo phương pháp này, người chơi có thể đi bộ giữa những vùng có độ cao
khác nhau, như lên hoặc xuống cầu thang. Chú ý để cho đơn giản chúng ta
dùng vector khoảng cách tương đối (dist) để di chuyển người chơi theo hướng
Z. Thông thường ở đây, nên sử dụng khoảng cách tương đối. Nhưng người chơi
sẽ điều chỉnh đến các độ cao khác nhau ngay lập tức. Cách di chuyển này rất
không tự nhiên. Để cho sự di chuyển được tự nhiên hơn, chúng ta sẽ tìm các
lực tác động đến người chơi theo hướng thẳng đứng:
- Khi người chơi là một chiếc máy bay thì lệnh trace trả về một giá trị lớn
hơn 0 - chỉ những lực hấp dẫn và ma sát mới tác dụng lên nó. Lực hấp
dẫn ở đây là trọng lực mà chúng ta đã đề cập, nó kéo người chơi xuống
phía dưới.
- cho đến khi người chơi tiến đến mặt đất hoặc chìm vào nó - lệnh trace
sẽ trả về một giá trí nhỏ hơn hoặc bằng 0. Trong trường hợp này thì lực
đàn hồi sẽ tác động. Đây là loại lực mới, nó càng mạnh khi người chơi
càng chìm sâu trong nền đất. Nó tạo ra cho người chơi một gia tốc
hướng lên. Hơn nữa gia tốc của người chơi sẽ tăng đáng kể khi người
chơi tiến vào mặt đất.
Sử dụng kĩ thuật này, và tùy theo trung tâm của thực thể người chơi, mà
chân của thực thể có thể đi xuyên qua bề mặt rắn, không thể qua được. Trong
thế giới thực loại bề mặt này dĩ nhiên không bao giờ đi qua được, nhưng với
đầu gối của người chơi, nó sẽ tạo ra cùng tác dụng. Vì thế sự xuất hiện của lực
đàn hồi là kết quả từ việc nhún của đầu gối - nếu người chơi là một động cơ –
thì đó là bộ giảm xóc. Cũng tương tự chúng ta có thể giải thích sự tăng lên của
Chương 4: Cài đặt
96
lực ma sát trên nền đất bằng lực ma sát được tạo ra bởi lực nhún của người chơi
hoặc bộ giảm xóc của xe.
var friction;
action move_me
{
while (1)
{
force.PAN = -10 * KEY_FORCE.X; // tính lực quay
my.SKILL14 = TIME*force.PAN + max(1-TIME*0.7,0)*my.SKILL14; //
vận tốc quay
my.PAN += TIME * my.SKILL14; // quay người chơi
vec_set(temp,my.x);
temp.z -= 4000; // một vị trí nằm dưới người chơi 4000 quants
// chọn các chế độ truy tìm các thực thể và bề mặt từ vị trí của người chơi
trace_mode =
ignore_me+ignore_sprites+IGNORE_MODELS+USE_BOX;
result = trace(my.x,temp); // subtract vertical distance to ground
if (RESULT > 5) // có phải đang ở trong không gian?
{
force.X = 0; // không có lực đẩy
force.Y = 0;
force.Z = -5; // trọng lực
friction = 0.1; // lực ma sát của không khí
}
Chương 4: Cài đặt
97
Bằng cách sử dụng lệnh if với kết quả truy tìm được, chúng ta có thể xác định
người chơi đang ở trong không khí hoặc cách mặt đất 5 quant. Trong trường
hợp đầu tiên, các lực được tạo ra từ bàn phím sẽ không có tác dụng, mà người
chơi sẽ rơi xuống dưới tác dụng của trọng lực. Trong trường hợp sau, xuất hiện
lực đàn hồi tương ứng với độ sâu khi thực thể chìm vào mặt đất, sẽ đẩy người
chơi ra khỏi mặt đất. Chúng ta đang sử dụng nhiều skill của thực thể, skill13 sẽ
lưu vận tốc theo phương thẳng đứng hiện tại của thực thể.
2. Cách di chuyển camera theo người chơi
2.1. Tầm nhìn của người thứ nhất
else // đang ở trên mặt đất
{
force.X = 10 * KEY_FORCE.Y; // lực quay
force.Y = 0;
force.Z = -0.5 * RESULT; // lực nẩy
friction = 0.7; // lực ma sát dưới nền đất
}
my.SKILL11 = TIME*force.X + max(1-TIME*friction,0)*my.SKILL11; //
tính vận tốc tiến về phía trước
my.SKILL13 = TIME*force.Z + max(1-TIME*friction,0)*my.SKILL13; //
tính vận tốc theo phương thẳng đứng
dist.X = TIME * my.SKILL11; // quãng đường tiến về phía trước
dist.y = 0;
dist.Z = TIME * my.SKILL13; // quãng đường rơi xuống
move_mode = ignore_passable + glide;
ent_MOVE(dist,nullvector); // di chuyển người chơi
move_view(); // di chuyển camera theo
wait(1);
}
}
Chương 4: Cài đặt
98
Hãy đặt viết mã nguồn như sau:
Và gọi hàm init_camera trong hàm main sau khi gọi hàm level_load. Lưu và
chạy ứng dụng. Khi đó camera sẽ di chuyển theo người chơi.
Chúng ta đã định nghĩa một khung nhìn mới. Hãy tượng tượng một khung nhìn
trong game. Nó chỉ là một cửa sổ. Chúng ta có thể xác định vị trí và kích thướt
của cửa sổ bằng cách điều chỉnh các thuộc tính pos_x, pos_y, size_x, size_y.
Như trên, chúng ta đã định nghĩa, góc trên bên trái của khung nhìn trùng với
góc trên bên trái của màn hình và có kích thướt của nó cũng bằng kích thướt
của màn hình.
view 1st_person
{
layer = 1;
pos_x = 0;
pos_y = 0;
}
function init_cameras()
{
camera.visible = off;
1st_person.size_x = screen_size.x;
1st_person.size_y = screen_size.y;
1st_person.genius = player;
1st_person.visible = on;
}
function update_views()
{
1st_person.x = player.x;
1st_person.y = player.y;
1st_person.z = player.z;
1st_person.pan = player.pan;
1st_person.roll = player.roll;
1st_person.tilt = player.tilt;
}
Chương 4: Cài đặt
99
Hàm update_views, sẽ được cập nhật sau mỗi trạng thái và thay đổi tọa độ x, y,
z của camera trong game. Ở đây, chúng ta thay đổi nó đến tọa độ của người
chơi, vì thế làm cho camera luôn luôn ở bên trong người chơi.
Đoạn mã vẫn chưa được hoàn hảo. Ví dụ, nếu camera được đặt ở điểm trung
tâm của mô hình người chơi, không ở trên đầu, là nguyên nhân làm cho khung
nhìn đặt quá gần nền đất. Như vậy chúng ta chưa thể nhìn lên hoặc xuống.
Chúng ta định nghĩa thêm một biến ở đầu đoạn mã.
var eye_height = 20;
và thay vì
1st_person.z = player.z;
chúng ta viết lại là:
1st_person.z = player.z + eye_height;
Nó sẽ điều chỉnh camera lên cao hơn 20 quant. Nếu giá trị này chưa được tốt,
có thể điều chỉnh lại trong lúc chơi game.
Bây giờ, chúng ta muốn người chơi có thể nhìn lên hoặc nhìn xuống. Để thực
hiện được, chúng ta cần các biến sau:
var tilt_1st = 0;
var cam_turnspeed = 2;
var max_tilt_1st = 40;
và thay đổi dòng mã:
1st_person.tilt = player.tilt;
thành:
1st_person.tilt = player.tilt + tilt_1st;
và thêm các hàm sau:
Chương 4: Cài đặt
100
Những hàm này phải được gọi trong lúc chơi game. Ví dụ, chúng ta có thể định
nghĩa như thế này:
on_pgup = look_up;
on_pgdn = look_down;
Hãy lưu lại và chạy thử. Không tồi, nhưng chưa có tác dụng như mong muốn.
Nếu ấn một phím và giữ nó, thì khung nhìn chỉ di chuyển một ít và sẽ không
thay đổi nữa. Chúng ta phải ấn nó nhiều lần để khung nhìn có thể di chuyển và
điều này quá chậm chạp.
Chúng ta sẽ thay đổi nó như thế nào? Thay đổi định nghĩa on_pageup và
on_pagedown như sau:
on_pgup = handle_pageup;
on_pgdn = handle_pagedown;
Và định nghĩa 2 hàm sau:
function look_up()
{
if (tilt_1st < max_tilt_1st) { tilt_1st += cam_turnspeed; }
}
function look_down()
{
if (tilt_1st > -max_tilt_1st) { tilt_1st -= cam_turnspeed; }
}
Chương 4: Cài đặt
101
Theo cách này các hàm của chúng ta sẽ được gọi trong mỗi trạng thái trong khi
các phím này đang được ấn. Nếu camera quay quá nhanh hoặc quá chậm, có
thể điều chỉnh giá trị cam_turnspeed. Nếu phạm vi của khung nhìn quá nhỏ và
để người chơi có thể thay đổi góc nhìn nhiều hơn, hãy thay đổi biến
max_tilt_1st. Giá trị 90 ở đây có nghĩa là: người chơi có thể nhìn thẳng lên
hoặc xuống. Giá trị trên 90 tức là người chơi có thể nhìn ngược ra sau.
2.2 Quay tự do tầm nhìn của người thứ 3
Bây giờ chúng ta muốn tạo ra một khung nhìn có thể quay của người thứ 3. Có
hai cách thực hiện: cách thứ nhất là tạo ra một camera ở bên ngoài người chơi
và không quay, ngay cả khi nó đi, luôn luôn đối diện với nó từ một hướng nào
đó. Cách thứ 2 là tạo ra một camera có thể rẽ khi người chơi rẽ, vì thế nó sẽ
luôn nằm ở đằng sau người chơi (hoặc trước, hoặc bên cạnh ).
Chúng ta sẽ làm cho camera này có thể rẽ và phóng to thu nho tự do. Để bắt
đầu, chúng ta sẽ tạo ra một khung nhìn của người thứ 3 luôn luôn đối mặt với
function handle_pageup()
{
while (key_pgup)
{
look_up();
wait(1);
}
}
function handle_pagedown()
{
while (key_pgdn)
{
look_down();
wait(1);
}
}
Chương 4: Cài đặt
102
người chơi từ một hướng và những thay đổi khi muốn khung nhìn quay cùng
với thực thể.
Định nghĩa khung nhìn thứ 2 như sau:
Chúng ta chưa làm cho nó có thể nhìn thấy được. Thay vì, chúng ta sẽ có thể
thay đổi camera trong lúc chơi game. Chúng ta sẽ định nghĩa thủ tục chuyển
đổi camera ngay bây giờ:
view 3rd_person
{
layer = 1;
pos_x = 0;
pos_y = 0;
}
Thêm dòng sau vào bên trong hàm "init_cameras":
...
3rd_person.size_x = screen_size.x;
3rd_person.size_y = screen_size.y;
...
var cam_mode = 0; // 0 cho người thứ nhất, 1 cho người thứ 3
function toggle_cams()
{
if (cam_mode == 0)
{ // Thay đổi đến người thứ 3
1st_person.visible = off;
3rd_person.visible = on;
cam_mode = 1;
}
else
{ // thay đổi đến người thứ nhất
3rd_person.visible = off;
1st_person.visible = on;
cam_mode = 0;
}
}
on f8 = toggle cams;
Chương 4: Cài đặt
103
Như vậy, bằng cách nhấn f8 ta có thể chuyển đổi giữa các khung nhìn. Tuy
nhiên, nó chưa có tác dụng, bởi vì các tọa độ x, y, z của người thứ 3 chưa được
định nghĩa. Chúng ta sẽ định nghĩa ngay giờ bằng cách thay đổi hàm
"update_views".
Nhưng chúng ta sẽ định nghĩa một camera quay quanh người chơi như thế nào?
Nó nên nằm trên cùng một mặt phẳng, vì thế giá trị z là giống nhau. Nhưng
chúng ta sẽ tính giá trị x và y như thế nào? Chúng ta cần một chút toán học.
Tưởng tượng người chơi được quan sát từ phía trên. Cách tốt nhất là lấy một tờ
báo và đặt một điểm trên nó, ở một nơi nào đó, để chỉ ra vị trí của người chơi
được thấy từ phía trên. Vẽ một đường tròn xung quanh điểm này. Đây là vòng
tròn mà camera sẽ di chuyển trên đó. Vòng tròn này có một bán kính nào đó.
Giả sử trên vòng tròn có một điểm là điểm gốc, khi đó chúng ta có thể xác định
một điểm P trên vòng tròn bằng một cung giữa đường thẳng vẽ từ gốc đến tâm
và từ P đến tâm của đường tròn.
Như vậy, khi có khoảng cách đến người chơi (bán kính của đường tròn) và một
góc trong mặt phẳng thì vị trí của camera sẽ được xác định.
Chương 4: Cài đặt
104
Lưu mã nguồn và chạy nó. Chọn f8 để chuyển đổi giữa các khung nhìn. Nên
xem người chơi trong khung nhìn của người thứ 3. Khi di chuyển, camera sẽ
luôn luôn di chuyển cùng khoảng cách với người chơi, và sẽ không thay đổi vị
trí khi người chơi rẽ. Nếu thay đổi giá trị của biến dist_planar thì camera sẽ tiến
lại gần hoặc lùi ra xa. Nếu thay đổi góc cam_angle thì nó sẽ quay xung quanh
người chơi, và luôn luôn đối diện với người chơi.
Tuy nhiên vẫn còn vấn đề khi người chơi ở gần các bức tường. Camera sẽ
thường xuyên đi xuyên qua các bức tường, và các chướng ngại vật sẽ chắn tầm
nhìn của người chơi. Chúng ta sẽ giải quyết vấn đề này trong phần sau. Bây giờ
chúng ta sẽ thay đổi mã nguồn một ítchúng ta muốn di chuyển camera lên
phía trên nhưng vẫn đối diện với người chơi. Và cũng cần phải giữ cùng
var dist_planar = 300; // khoảng cách đến người chơi
var cam_angle = 0;
function update_views()
{
if (cam_mode == 0)
{
1st_person.x = player.x;
1st_person.y = player.y;
1st_person.z = player.z + eye_height;
1st_person.pan = player.pan;
1st_person.roll = player.roll;
1st_person.tilt = player.tilt + tilt_1st;
}
else
{
3rd_person.x = player.x - cos (cam_angle) * dist_planar;
3rd_person.y = player.y - sin (cam_angle) * dist_planar;
3rd_person.z = player.z;
3rd_person.pan = cam_angle;
3rd_person.roll = 0;
3rd_person.tilt = 0;
}
}
Chương 4: Cài đặt
105
khoảng cách đến người chơi, vì thế sự di chuyển không còn theo đường tròn
nữa mà theo hình cầu.
Chúng ta sẽ thực hiện điều này như thế nào? Hãy tưởng tượng người chơi được
nhìn từ bên cạnh. Nếu camera nằm trên mặt phẳng XY của người chơi. Hãy vẽ
một đường thẳng từ nó đến người chơi, chúng ta sẽ nhận được một góc giữa
mặt phẳng XY và đường này. Góc này sẽ xác định chính xác vị trí của người
chơi.
Hình sau đây sẽ biểu diễn vị trí của camera trong trường hợp này:
Lúc này chúng ta cần chỉnh lại mã nguồn như sau:
Chương 4: Cài đặt
106
Bằng cách thay đổi giá trị của các biến tilt_3rd, cam_angle, dist_total, chúng ta
có thể di chuyển camera tự do xung quanh người chơi. Nó sẽ được di chuyển
trên một mặt cầu với bán kính có thể được thay đổi bằng cách thay đổi giá trị
của biến.
2.3 Cách để cho camera tránh chạm vào tường
Ý tưởng là gửi một tia từ người chơi đến vị trí mới của camera, nếu thấy có
một chướng ngại vật nằm trên tia này. Khi đó, khoảng cách giữa người chơi và
camera cần được thay đổi bằng khoảng cách giữa người chơi và chướng ngại
vật.
Thêm những dòng sau vào hàm update_views:
var dist_total = 300; // thay đổi giá trị này để tiến lại gần hoặc ra xa thực
thể
var tilt_3rd = 0;
function update_views()
{
...
else
{
dist_planar = cos (tilt_3rd) * dist_total;
3rd_person.x = player.x - cos (cam_angle) * dist_planar;
3rd_person.y = player.y - sin (cam_angle) * dist_planar;
3rd_person.z = player.z + sin (tilt_3rd) * dist_total;
3rd_person.pan = cam_angle;
3rd_person.roll = 0;
3rd_person.tilt = - tilt_3rd;
}
Chương 4: Cài đặt
107
Hàm này xác định vị trí của camera một cách hoàn toàn giống như cách trên,
nó chỉ sử dụng một khoảng cách mới đến người chơi, đó là khoảng cách từ
người chơi đến chướng ngại vật. Nó sẽ thay đổi từ từ để ngăn chặn việc camera
nằm bên trong bức tường.
Để đặt camera sau người chơi, chúng ta thay đổi những dòng:
3rd_person.x = player.x - cos (cam_angle) * dist_planar;
3rd_person.y = player.y - sin (cam_angle) * dist_planar;
thành:
function update_views()
{
...
3rd_person.roll = 0;
3rd_person.tilt = - tilt_3rd;
validate_view();
}
...
}
hàm trên sẽ được định nghĩa như sau:
var dist_traced;
function validate_view()
{
my = player;
trace_mode = ignore_me + ignore_passable;
dist_traced = trace (player.x, 3rd_person.x);
if (dist_traced == 0) { return; } // không chạm vào bất kì chướng ngại
vật nào
if (dist_traced < dist_total)
{
dist_traced -= 5; // Di chuyển ra ngoài bức tường
dist_planar = cos (tilt_3rd) * dist_traced;
3rd_person.x = player.x - cos (cam_angle) * dist_planar;
3rd_person.y = player.y - sin (cam_angle) * dist_planar;
3rd_person.z = player.z + sin (tilt_3rd) * dist_traced;
}
}
Chương 4: Cài đặt
108
3rd_person.x = player.x - cos (cam_angle + player.pan) * dist_planar;
3rd_person.y = player.y - sin (cam_angle + player.pan) * dist_planar;
chúng ta chỉ cần thêm góc quay của thực thể (player.pan) vào cam_angle.
II. Xe tự động
Tránh chướng ngại vật trên đường đi
Giả sử người chơi muốn di chuyển từ một điểm bắt đầu đến điểm kết thúc.
Tất nhiên nếu giữa nó không có chướng ngại vật nào hết thì rất đơn giản, chỉ
cần cho nó di chuyển theo một đường thẳng đi qua điểm bắt đầu và điểm kết
thúc.
Ở đây chúng ta đặc biệt chú ý đến trường hợp: giữa 2 điểm bắt đầu và kết
thúc có các chướng ngại vật: là các chiếc xe khác hoặc là các chướng ngại vật
tĩnh.
Hình 1
Chương 4: Cài đặt
109
Ví dụ ở đây: để người chơi di chuyển đến một vị trí nào đó ta có thể nhấp
chuột đến vị trí cần người chơi cần đến:
Lúc này điểm bắt đầu là vị trí của người chơi, điểm kết thúc là vị trí nút
nhất của chuột.
Có 8 hướng khác nhau xung quanh một người chơi, mỗi một hướng khác
nhau ta xem đó là một nút. Một nút có thể có độ rộng khác nhau tùy thuộc vào
chúng ta muốn chọn bao nhiêu.
Hình 2
Nếu một nút chứa một chướng ngại vật thì ta xem nút đó là nút không có
giá trị, sẽ không được chọn trong lúc tìm đường đến đích.
Hình 3
3 4 5 kt
2 v v
1 v v
bđ v V
Chương 4: Cài đặt
110
Giả sử từ nút bắt đầu bđ, muốn tìm một đường đi đi đến nút cần đến (nút kt).
Và các nút v là các chướng ngại vật:
Ở đây, mỗi nút trung gian (như các nút 0, 1 7), sẽ chứa 2 giá trị là chi phí
đường đi (waycost), và chi phí toàn bộ nút (nodecost).
Mỗi nút có một nút cha, và một nút cha có 8 nút con (trong trường hợp bình
thường), nằm xung quanh nút này.
Giả sử một nút có chi phí đường đi là waycost, thì các nút con của nó sẽ có
waycostcon=waycostcha+1;
Trong đó nút bắt đầu không có nút cha và ta cho waycost của nó là 0.
Ở đây ta sử dụng một heuristic, đó là khoảng cách từ nút đó đến nút đích (nút
kt), ta kí hiệu là goal_dist, thì chi phí của một nút sẽ là:
nodecost=waycost+goal_dist
Như vậy thuật toán sẽ gồm các bước sau:
Với thuật toán như vậy, trong hình 3 để tìm đường đi từ điểm bắt đầu (bd) đến
điểm kết thúc (kt), ta sẽ đi qua con đường đi qua các nút 1, 2, 3, 4, 5.
Bước 1:
Mở nút bắt đầu
Bước 2:
- Chọn trong danh sách các nút mở ra một nút có nodecost nhỏ nhất.
- Nếu không còn nút nào nữa thì kết thúc thuật toán.
Bước 3:
- Nếu nút này là nút đích thì thuật toán kết thúc.
- Nếu không thì:
+ Tạo ra các nút con từ nút này, với điều kiện các nút con không
phải là nút chứa các chướng ngại vật.
+ Đóng nút này lại và mở tất cả các nút con được tạo ra.
Bước 4:
Chương 4: Cài đặt
111
TÀI LIỆU THAM KHẢO
[1] Hướng dẫn có sẵn trong chương trình 3D Game Studio.
[2] Các tài liệu hướng dẫn trên trang web: www.3DGameStudio.com.
[3] Bạch Hưng Khang, Hoàng Kiếm, Trí tuệ nhân tạo, các phương pháp và
ứng dụng, Nhà xuất bản Khoa học và Kỹ thuật Hà Nội - 1999
Các file đính kèm theo tài liệu này:
- khoa_luan_ung_dung_tri_tue_nhan_tao_trong_xay_dung_game.pdf