Với việc cho ra mắt iPhone 4 và chuẩn bị cho ra mắt iPhone 5 dường như cơn sốt iPhonevẫn sẽ tiếp tục sốt và những ứng dụng trên iPhone sẽ không ngừng tăng lên theo thời gian
Trang 1ĐẠI HỌC ĐÀ NẴNG TRƯỜNG ĐẠI HỌC BÁCH KHOA
KHOA CÔNG NGHỆ THÔNG TIN
Tel (84-511) 736 949, Fax (84-511) 842 771Website: itf.ud.edu.vn, E-mail: cntt@edu.ud.vn
ĐỒ ÁN TỐT NGHIỆP KỸ SƯ NGÀNH CÔNG NGHỆ THÔNG TIN
MÃ NGÀNH : 05115
ĐỀ TÀI : XÂY DỰNG GAME TRÊN HỆ ĐIỀU HÀNH iOS
SỬ DỤNG COCOS2D GAME ENGINE VÀ OPENFEINT API.
Mã số : 06T3-054 Ngày bảo vệ : 15/06/2011
SINH VIÊN : PHAN ĐINH VỸ
ĐÀ NẴNG, 05/2011
Trang 2LỜI CẢM ƠN
Đầu tiên em xin gửi lời cảm ơn chân thành nhất đến các thầy cô trong trường Đại học Bách Khoa Đà Nẵng nói chung và các thầy cô trong Khoa Công Nghệ Thông Tin, Bộ môn Công Nghệ Phần Mềm nói riêng đã tận tình giảng dạy truyền đạt cho em những kiến thức những kinh nghiệm quý báu trong suốt thời gian qua Trong thời gian làm việc với các thầy cô trong khoa Công Nghệ Thông Tin em đã được không ngừng tiếp thu thêm nhiều kiến thức mà còn được học tập tinh thần làm việc, thái độ nghiên cứu khoa học nghiêm túc, hiệu quả, những điều này rất cần thiết cho em trong quá trình học tập và công tác sau này
Em xin xin chân thành cảm ơn thầy Trần Quốc Chiến đã hết lòng hướng dẫn em thực hiện đề tài.
Sau cùng em xin gửi lời cảm ơn chân thành nhất đến gia đình bạn bè đã động viên, đóng góp ý kiến và giúp đỡ em trong quá trình thực hiện đồ án tốt nghiệp.
Trang 3LỜI CAM ĐOAN
Tôi xin cam đoan :
1 Những nội dung trong luận văn này là do tôi thực hiện dưới sự hướng dẫn trực tiếp của PGS-TSKH Trần Quốc Chiến.
2 Mọi tham khảo dùng trong luận văn đều được trích dẫn rõ ràng tên tác giả, tên công trình, thời gian, địa điểm công bố.
3 Mọi sao chép không hợp lệ, vi phạm quy chế đào tạo, hay gian trá,
tôi xin chịu hoàn toàn trách nhiệm.
Sinh viên, Phan Đinh Vy
Trang 4MỤC LỤC
MỞ ĐẦU 9
.I Giới thiệu bối cảnh đề tài: 9
.II Mục tiêu cần đạt được: 9
.III Ý nghĩa thực tiễn: 9
.IV Nội dung đề tài: 10
CƠ SỞ LÝ THUYẾT 11
.I Objective C: 11
.I.1 Lịch sử: 11
.I.2 Đặc điểm cơ bản: 11
.I.3 Cú pháp: 11
.I.3.1 Interface và implement: 11
.I.3.2 Category 12
.I.3.3 Kiểm soát Exception: 13
.I.3.4 Properties: 14
.I.3.5 Hàm tạo – Contructor: 14
.I.3.6 Quản lý bộ nhớ: 14
.II QUẢN LÝ BỘ NHỚ 15
.II.1 Cấu trúc bộ nhớ 15
.II.1.1 Cấu trúc của vùng nhớ Stack: 15
.II.1.2 Cấu trúc của vùng nhớ Heap: 16
.II.2 Rò rỉ bộ nhớ (Memory Leaks) 17
.II.2.1 Định nghĩa: 17
.II.2.2 Ảnh hưởng của rò rỉ bộ nhớ: 17
.II.2.3 Một số trường hợp rò rỉ bộ nhớ: 17
.II.3 Làm thế nào để tránh bị rò rỉ bộ nhớ: 20
.II.3.1 Nguyên tắc: 20
.II.3.2 Các cách phát hiện rò rỉ bộ nhớ: 20
.II.3.3 Sử dụng công cụ để kiểm tra 21
.III Cocos2D: 22
.III.1 Cocos2D là gì? 22
.III.2 Vì sao sử dụng Cocos2D: 22
.III.2.1 Hoàn toàn miễn phí: 22
.III.2.2 Mã nguồn mở: 22
.III.2.3 Được viết sử dụng ngôn ngữ Objective C: 22
.III.2.4 Ẩn đi các thành phần của OpenGL ES: 22
.III.2.5 Lập trình: 23
.III.2.6 Được sự ủng hộ của cộng đồng lập trình viên: 23
.III.3 Cơ bản về Cocos2D: 23
.III.3.1 Singleton: 23
.III.3.2 CCDirector: 24
.III.3.3 CCNode: 25
Trang 5.III.3.7 CCLabel: 28
.III.3.8 CCMenu: 28
.III.3.9 Lớp Actions: 29
.III.4 Quản lý bộ nhớ với Cocos2D: 29
.IV Open Feint: 30
.IV.1 Giới thiệu: 30
.IV.2 Tính năng: 31
.IV.3 Triển khai: 31
XÂY DỰNG GAME 32
.I Giới thiệu tổng quan: 32
.I.1 Game là gì? 32
.I.2 Qui trình làm game: 32
.I.3 Vòng đời của một game 33
.II Xây dựng game đua xe (Racing) 34
.II.1 Lịch sử game đua xe: 34
.II.2 Giới thiệu về game X-Racing: 35
.III Xây dựng game X-Racing: 36
.III.1 Xây dựng hệ thống điều khiển: 36
Tính toán vị trí của xe dựa vào vector vận tốc: 36
.III.1.1 Hệ thống vật lý cho xe: 37
.III.1.2 Thiết lập cho camera: 38
.III.1.3 Xét va chạm trong game: 38
.III.1.4 Tính thời gian hoàn thành vòng đua trong game 41
.III.2 Xây dựng hệ thống AI (trí thông minh nhân tạo) trong game: 42
.III.2.1 Các phương pháp dò đường: 42
.III.2.2 AI cho xe: 45
.IV Triển khai chương trình: 48
.IV.1 Phân tích thiết kế: 48
.IV.1.1 Sơ đồ hoạt động: 48
.IV.1.2 Biểu đồ lớp: 49
.IV.1.3 Biểu đồ tuần tự: 50
.IV.1.4 Các lớp trong X-Code: 51
.IV.2 Triển khai OpenFeint: 52
.IV.2.1 Đăng kí tài khoản: 52
.IV.2.2 Tích hợp OpenFeint API vào game: 54
CÀI ĐẶT VÀ THỬ NGHIỆM 56
.I Cài đặt: 56
.I.1 Hệ thống điều khiển của xe: 56
.I.1.1 Xe tăng tốc: 56
.I.1.2 Khi hãm phanh: 56
.I.1.3 Rẽ trái hoặc rẽ phải: 56
.I.1.4 Khi không có điều khiển: 57
.I.1.5 Cập nhật tọa độ sau mỗi lần tính toán: 57
.I.2 Thiết lập camera: 57
.I.3 Sử dụng ảnh để xét va chạm trong game: 57
Trang 6Mục lục iii
.I.4 Dữ liệu đường đua: 59
.I.5 Tính toán để cho xe tự chạy: 59
.I.5.1 Tính khoảng cách theo trục tọa độ X và Y giữa xe và điểm kiểm tra: 59
.I.5.2 Tính góc của xe và đường nối điểm checkpoint (điểm kiểm tra) 60
.I.5.3 Điều khiển xe: 60
.I.5.4 Chuyển sang checkpoint kế tiếp: 61
.I.6 Tính thời gian mỗi vòng đua: 61
.I.6.1 Kiểm tra điểm checkpoint 62
.I.6.2 Cập nhật thời gian: 62
.II Thử nghiệm chương trình: 63
.II.1.1 Menus: 63
.II.1.2 Bắt đầu cuộc đua: 65
.II.1.3 Leaderboard: 67
KẾT LUẬN 69
[1] David M Bourg, Gleen Seeman AI for Game Developers O’Reilly Publisher, Chương 14 71
[2] Sams Publishing, Programming in Objective-C, 2004 71
[3] Nguyễn Thanh Bình Phân tích và thiết kế hướng đối tượng Khoa CNTT Đại học Bách Khoa Đà Nẵng 71
[4] Trang web: http://developer.apple.com/library/ios 71
[5] Trang web: http://www.cocos2d-iphone.org/forum/ 71
Trang 7Mục lục iv
DANH MỤC HÌNH ẢNH
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT 9
HÌNH II.3-1: CÔNG CỤ LEAK 21
HÌNH II.3-2: DEBUG TRONG LEAK 21
HÌNH III.1-3: BIỂU TƯỢNG CỦA COCOS2D TRÊN NỀN TẢNG IOS22 HÌNH III.3-4: SƠ ĐỒ KẾ THỪA CÁC LỚP THÔNG DỤNG 25
HÌNH III.3-5: VỊ TRÍ SPRITE TRONG MÀN HÌNH 27
HÌNH III.3-6: MENU DƯỚI DẠNG TEXT 28
HÌNH IV.1-7: BIỂU TƯỢNG CỦA OPENFEINT 30
HÌNH IV.2-8: GIAO DIỆN OPENFEINT 31
HÌNH I.3-9: VÒNG ĐỜI CỦA MỘT ỨNG DỤNG 33
HÌNH II.1-10: GAME ĐUA XE ĐẦU TIÊN 34
HÌNH II.1-11: GAME POLE POSITION 34
HÌNH II.1-12: GAME MARIO KART 35
HÌNH II.1-13: GAME GRAM TURISMO 35
HÌNH III.1-14: VỊ TRÍ CỦA XE TRONG HỆ TRỤC TỌA ĐỘ 36
HÌNH III.1-15: TÍNH VỊ TRÍ CỦA XE 37
HÌNH III.1-16: VỊ TRÍ CANH GIỮA MÀN HÌNH 38
HÌNH III.1-17: HÌNH ẢNH THỰC VÀ HÌNH ẢNH CHỨC NĂNG CỦA ĐƯỜNG ĐUA 39
HÌNH III.1-18: MÔ TẢ ĐƯỜNG ĐUA 39
HÌNH III.1-19: VA CHẠM CỦA XE VỚI BÊN NGOÀI ĐƯỜNG ĐUA 40 HÌNH III.1-20: ĐIỂM CHECKPOINT TRONG GAME 41
HÌNH III.2-21: ĐƯỜNG CHẠY CỦA XE 42
HÌNH III.2-22: SỬ DỤNG ĐIỂM CHECKPOINT 43
HÌNH III.2-23: SỬ DỤNG DÒ ĐƯỜNG 44
HÌNH III.2-24: MÔ PHỎNG ĐƯỜNG ĐUA 44
HÌNH III.2-25: NHỮNG VỊ TRÍ CỦA XE 45
HÌNH III.2-26: GÓC XOAY CỦA XE 46
Trang 8Mục lục v
HÌNH IV.1-29: SƠ ĐỒ LỚP 49
HÌNH IV.1-30: SƠ ĐỒ TUẦN TỰ 50
HÌNH IV.1-31: CÁC LỚP SCENE 51
HÌNH IV.1-34 51
HÌNH IV.1-32: CÁC LỚP LAYER 51
HÌNH IV.1-33: CÁC LỚP CHÍNH TRONG GAME 51
HÌNH IV.2-35: THÔNG TIN GAME TRÊN OPENFEINT 52
HÌNH IV.2-36: GIAO DIỆN TẠO LEADERBOARD 53
HÌNH IV.2-37: GIAO DIỆN QUẢN LÝ LEADERBOARD 53
HÌNH IV.2-38: FRAMEWORK CHO OPENFEINT 54
HÌNH IV.2-39: THIẾT LẬP CHO PROJECT 54
HÌNH IV.2-40: PHƯƠNG THỨC TRONG FILE HEADER 55
HÌNH IV.2-41: KHỞI TẠO OPENFEINT 55
HÌNH I.5-42: TỌA ĐỘ TRONG COCOS2D VÀ PHOTOSHOP 60
HÌNH I.6-43: MENU CHÍNH 63
HÌNH I.6-44: MENU TÙY CHỌN 63
HÌNH I.6-45: THÔNG TIN GAME 64
HÌNH I.6-46: LỰA CHỌN ĐƯỜNG ĐUA 64
HÌNH I.6-47: KẾT QUẢ CUỘC ĐUA 65
HÌNH I.6-48: BẮT ĐẦU GAME 65
HÌNH I.6-49: ĐUA XE VỚI BOT 66
HÌNH I.6-50: ĐUA MỘT NGƯỜI 66
HÌNH I.6-51: KẾT NỐI BẠN BÈ 67
HÌNH I.6-52: DANH SÁCH ĐƯỜNG ĐUA 67
HÌNH I.6-53: DANH SÁCH NGƯỜI ĐIỂM CAO 68
HÌNH I.6-54: GAME CHANNEL 68
Trang 9Mục lục vi
DANH MỤC VIẾT TẮT VÀ THUẬT NGỮ
AI Artificial Intelligence – Trí
thông minh nhân tạo
CCSprite Lớp để tạo ra nhân vật trong
CCScene Lớp để hiển thị tất cả các đối
tượng ra màn hình
CCLabel Lớp để tạo ra một nhãn trong
Cocos2D
iOSDashboard Bảng điều khiển của một
người chơi trong OpenFeint
Framework Là tập thư viện hoặc lớp để
lập trình viên sử dụng
khung hình trên một giây
id Kiểu trả về mặc định của
Objective C Tương đương với void* ơC++iOS Hệ điều hành trên các thiết
bị iPhone, iPod Touch, iPadcủa Apple
không được phép đi vào
Trang 10Mục lục vii
dòng máy của Apple
OpenFeint Dịch vụ chia sẻ thông tin
giữa người chơi
Leaderboard Bảng tổng kết những người
có số điểm cao
SDK Software Development Kit Tập hợp những công cụ để
lập trình trên thiết bị hay nềntảng nào đó
Singleton Một mẫu trong Design
Pattern
X-Code Chương trình để viết ứng
dụng trên dòng máy MAC
Trang 11MỞ ĐẦU
.I Giới thiệu bối cảnh đề tài:
Trong một thập kỉ gần đây Apple nổi lên như là một công ty công nghệ chuyên sản xuấtnhững thiết bị CNTT hàng đầu thế giới Nổi tiếng nhất có lẽ là dòng máy nghe nhạc iPodhuyền thoại và gần đây là dòng điện thoại iPhone Một chiếc điện thoại kết hợp gần nhưhoàn hảo giữa thời trang và công nghệ Nhưng điều làm cho iPhone nổi tiếng không nằm ơtính năng nổi trội hay kiểu dáng sành điệu mà chính là ơ nội dung phần mềm phong phúdành chon nó Với gian hàng App Store của Apple với vô số những ứng dụng miễn phí cũngnhư giá cả chỉ ơ mức 0.99$ người sử dụng iPhone đã có thể trải nghiệm điện thoại iPhonemà không hề cảm thấy chán
iPhone có một màn hình độ phân giải cao kết hợp với màn hình đa điểm đã trơ thànhmảnh đất màu mỡ cho các nhà phát triển game di động Với những chiếc smart phone caocấp hiện nay người dùng có thể chơi mọi lúc mọi nơi những game được đầu tư công phu với
đồ họa đẹp mắt Không những thế gian hàng App Store đã trơ thành nơi kiếm tiền cho rấtnhiều lập trình viên trên toàn thế giới
Với việc cho ra mắt iPhone 4 và chuẩn bị cho ra mắt iPhone 5 dường như cơn sốt iPhonevẫn sẽ tiếp tục sốt và những ứng dụng trên iPhone sẽ không ngừng tăng lên theo thời gian.Cùng với nhu cầu ngày càng tăng về các ứng dụng mang tính giải trí cao như game,những game engine cũng bắt đầu phát triển và đến bây giờ cũng đã có rất nhiều gameengine khác nhau cả 2D lẫn 3D Game engine 2D như: Cocos2D, Sparrow, iTorque… 3Dnhư: Unity, SIO2, Irrlicht3D…
Đồ án lần này ứng dụng Cocos2D game engine để viết game đua xe trên iPhone kết hợpvới OpenFeint để nâng cao khả năng giao tiếp giữa những người chơi với nhau
.II Mục tiêu cần đạt được:
Sử dụng thành thạo Objective C để viết ứng dụng trên các dòng máy của Apple
Ứng dụng Cocos2D để xây dựng game
Tích hợp OpenFeint API để mơ rộng khả năng kết nối của game
Tìm hiểu về cấu trúc cũng như qui trình làm game
.III Ý nghĩa thực tiễn:
Trang 12Ứng dụng game framework sẵn có cũng như hoàn thiện phát triển game framework phụcvụ mục đích cá nhân.
.IV Nội dung đề tài:
Đề tài gồm có 3 chương:
− Chương 1: Cơ sơ lý thuyết
Lý thuyết về ngôn ngữ lập trình Objective C, Cocos2D và OpenFeint
− Chương 2: Xây dựng game
Giới thiệu quá trình xây dựng một ứng dụng trên iOS và từng bước xây dựng gameRacing
− Chương 3: Cài đặt và thử nghiệm
Triển khai những thuật toán, thiết kế và hình ảnh chạy chương trình
Trang 13Xây dựng game Racing trên hệ điều hành iOS
Hơn một thập kỉ sau năm 1996 sau một thời kì khủng hoảng tồi tệ, Apple mới nhận ratầm quan trọng không thể thay thế của Steve Jobs và đã mời ông trơ lại làm CEO Applecũng đồng thời mua lại NeXT và tiếp tục sử dụng ngôn ngữ Objective C để phát triển hệđiều hành MAC và xây dựng một loạt các công cụ phát triển như XCode, InterfaceBuilder… Chính vì thế mà khi nhắc tới Mac, nhắc tới iOS thì người ta sẽ nghĩ ngay đếnObjective C chứ không phải là một ngôn ngữ hướng đối tượng nào khác
.I.2 Đặc điểm cơ bản:
o Là ngôn ngữ lập trình hướng đối tượng - OOPL
o Mơ rộng từ C
o Mềm dẻo, có thể sử dụng cấu trúc của C để viết
.I.3 Cu pháp:
.I.3.1 Interface và implement:
Lập trình trong Objective C yêu cầu phải đặt interface và cài đặt của nó trên 2 file khácnhau Cũng giống như trong C++, trong Objective C file header được đặt tên với đuôi h vàfile cài đặt được đặt tên với đuôi m
Interface:
Interface của một lớp thường được định nghĩa trong file header Có cấu trúc như sau:
@interface classname : superclassname
{
// instance variables
}
Trang 14Xây dựng game Racing trên hệ điều hành iOS
Dấu – biểu thị phạm vi hoạt động của phương thức là ơ object
Các thuộc tính được khai báo trong cặp { } và khai báo phương thức ơ bên ngoài
Sử dụng #import để thay thế cho #include
Cũng giống như Java, Objective C chỉ cho phép đơn kế thừa Mặc định tất cả các lớp sẽ
kế thừa từ NSObject
Các phạm vi truy xuất public,protected và private giống như C++ mặc định là protected
Để truy cập đến phương thức của một đối tượng ta dùng cú pháp [obj method:argument];
Kiểu trả về của một hàm trong Objective C có thể là bất kì kiểu nào trong C hoặc là contrỏ trỏ đến những kiểu đặc biệt như NSArray *, NSImage *, hay NSString * Kiểu trả vềmặc định của Objective C là id
Lấy ví dụ đơn giản như sau:
• File integer.h
#import <objc/Object.h>
Trang 15Xây dựng game Racing trên hệ điều hành iOS
@interface Integer (Arithmetic)
- ( id ) add: (Integer *) addend;
- ( id ) sub: (Integer *) subtrahend;
@end
• File arithmetic.m
#import "Arithmetic.h"
@implementation Integer (Arithmetic)
- ( id ) add: (Integer *) addend
Lưu ý khi sử dụng category:
Có thể thêm bao nhiêu lần mơ rộng lớp từ category là không giới hạn nhưng không đượctrùng lặp tên
.I.3.3 Kiểm soát Exception:
Objective C cũng hỗ trợ cấu trúc try-catch-throw-finally, cách dùng hoàn toàn tương tựnhư C++
Trang 16Xây dựng game Racing trên hệ điều hành iOS
.I.3.4 Properties:
Hầu như bất kì ngôn ngữ lập trình hiện đại nào cũng hỗ trợ khái niệm này Đây là kháiniệm bảo toàn tính đóng gói của OOP
Trong file h ta phải khai báo sử dụng bằng từ khóa @property
@property ( readwrite ) int _value;
Một property có thể khai báo là readonly, readwrite, assign, copy hay retain Mặc địnhproperty sẽ có thuộc tính là atomic, giá trị sẽ được khóa không cho nhiều thread thay đổicùng một thời điểm Thuộc tính nếu là nonatomic thì sẽ bỏ đi khóa này
Trong file m chỉ thị @synthesize phải được thêm vào trước implement một lớp để báocho trình biên dịch biết là phải khơi tạo ra hàm get và set cho giá trị
@synthesize _value;
.I.3.5 Hàm tạo – Contructor:
Không giống như C++ hàm tạo phải có quy luật về khơi tạo đối tượng thì trong Objective
C ta có thể tự tạo ra một hàm tạo của riêng mình, tất nhiên theo thói quen và để cho dễ nhớ
ta nên đặt hàm tạo với những tên như init hoặc tương tự…
Một số lưu ý:
• Từ khóa super để tham chiếu tới lớp cha
• Từ khóa self tác dụng tương đương như this trong C++ (chính bản thân đang thể hiện của lớp - object hiện tại)
• Kết thúc hàm khơi tạo (init) sẽ trả về chính đối tượng được tạo ra thông qua từ khóa self
• Mặc định trong Objective C hàm khỏi tạo là - (id) init;
• Trong Objective C hàm khơi tạo chỉ có ý nghĩa về mặt tư duy, nó không được đối
xử đặc biết giống như C++
Trang 17Xây dựng game Racing trên hệ điều hành iOS
.II QUẢN LÝ BỘ NHỚ.
.II.1 Cấu truc bộ nhớ
− Code segment: nơi chứa chương trình sau khi được biên dịch
− Global area: nơi chứa biến toàn cục
− Stack segment: nơi các biến cục bộ (local variables) và tham số (parameter)được cấp phát
− Heap segment: nơi các biến cấp phát động được cấp phát vùng nhớ
.II.1.1 Cấu trúc của vùng nhớ Stack:
− Vùng nhớ sử dụng trong stack là tạm thời và được tự động giải phóng
Trang 18Xây dựng game Racing trên hệ điều hành iOS
.II.1.2 Cấu trúc của vùng nhớ Heap:
Trang 19.II.2 Rò rỉ bộ nhớ (Memory Leaks)
.II.2.1 Định nghĩa:
Là trường hợp vùng nhớ không còn sử dụng nữa nhưng không thể được giải phóng điềunày đồng nghĩa với việc bộ nhớ sẽ tăng một cách không thể kiểm soát được
.II.2.2 Ảnh hưởng của rò rỉ bộ nhớ:
• FPS (Frame Per Second – Số khung hình trên 1 giây)
FPS của ứng dụng sẽ rất thấp điều này rất quan trọng trong việc viết ứng dụng đặc biệt làgame, người dùng sẽ không chấp nhận tình trạng game bị giật khựng hay đứng hình
− Thoát bất chợt (Crashed)
Khi không đủ bộ nhớ để sử dụng thì những thiết bị có hệ điều hành thường được hệ điềuhành quản lý việc giải phóng tất cả vùng nhớ không cần thiết bằng cách tắt ngay ứng dụngđang tiêu tốn vùng nhớ đồng thời giải phóng tất cả vùng nhớ mà ứng dụng gây ra lỗi tạo ra.Điều này đồng nghĩa với việc ứng dụng đang chạy sẽ bị thoát một cách bất chợt mà khônghề có thông báo cũng như không có một sự đảm bảo nào cho việc dữ liệu đang xử lý sẽđược lưu trữ
− Đứng thiết bị (freeze), khơi động lại (restart):
Một số thiết bị không có hệ điều hành hoặc hệ điều hành quản lý bộ nhớ không được tốtthì tình trạng này rất phổ biến, khi không còn đủ bộ nhớ sử dụng cho thiết bị, thiết bị sẽkhông thể hoạt động được nữa Khi đó để giải phóng một số thiết bị sẽ tự khơi động lại đểgiải phóng toàn bộ vùng nhớ đã bị chiếm dụng
Trang 20Sử dụng auto release
− Không giải phóng hết:
Ví dụ:
Giải pháp:
Xóa hết tất cả các phần tử:
Sử dụng đối tượng mảng (chỉ dùng với Objective C):
Trang 21Xây dựng game Racing trên hệ điều hành iOS
− Sử dụng kiểu trả về là con trỏ:
Ví dụ:
Giải pháp:
Tránh gọi trực tiếp hàm trả về kiểu con trỏ
Giải phóng ngay sau khi sử dụng
− Sử dụng con trỏ làm tham chiếu:
Trang 22Xây dựng game Racing trên hệ điều hành iOS
• Bằng cách chạy trực tiếp trên thiết bị
Cách này không hẳn chính xác, trong thực tế thiết bị xảy ra nhiều “triệu chứng” khácnhau Chẳng hạn khi thiết bị bị đứng hoặc khơi động lại không phải nhất thiết thiết bị bị hếtbộ nhớ mà có thể đó là lỗi hệ điều hành, firmware hay thậm chí là lỗi phần cứng
− Bằng cách kiểm tra mã nguồn từ đầu đến cuối
Việc này tốn rất nhiều thời gian để đọc cũng như hiểu được mã nguồn xử lý gì bên trong,nếu không phải là người viết nên mã nguồn thì biện pháp này không khả thi
− Bằng cách sử dụng các công cụ debug để kiểm tra
Trong X-Code có thể sử dụng công cụ Leak để kiểm tra có rò rỉ bộ nhớ trong quá trìnhthực thi chương trình hay là không
Trang 23Xây dựng game Racing trên hệ điều hành iOS
.II.3.3 Sử dụng công cụ để kiểm tra.
Hình II.3-1: Công cụ Leak.
Hình II.3-2: Debug trong Leak.
Trang 24Xây dựng game Racing trên hệ điều hành iOS
.III Cocos2D:
.III.1 Cocos2D là gì?
Hình III.1-3: Biểu tượng của Cocos2D trên nền tảng iOS
Cocos2D là một game engine (công cụ phát triển game) trên nền tảng iOS của các thiết
bị iPhone / iPod Touch / iPad và gần đây nhất là trên nền tảng OSX của Mac được phát triểnbơi Ricardo Quesada Cocos2D đang phát triển mạnh mẽ và được hỗ trợ bơi cộng đồng lậptrình viên hết sức đông đảo Cocos2D mang đến cho lập trình viên rất nhiều thành phần đểcó thể viết game trong thời gian nhanh nhất có thể và rất nhiều game nằm trong “top” hiệnnay đều được viết sử dụng Cocos2D engine
.III.2 Vì sao sử dụng Cocos2D:
Một lập trình viên khi tìm kiếm một game engine để lập trình thường cân nhắc trên mộtsố yếu tố quan trọng và Cocos2D phần nào đã đáp ứng được những yếu tố quan trọng nhất.Đó là:
.III.2.1 Hoàn toàn miễn phí:
Lập trình viên được phép sử dụng Cocos2D để viết game và phân phối cả bản miễn phívà thương mại mà không cần phải trả bất kì một khoản tiền nào
.III.2.2 Mã nguồn mở:
Mọi mã nguồn thư viện của Cocos2D đều “mơ” Điều này đồng nghĩa với việc người sửdụng có thể “jump” vào sâu bên trong mã nguồn để xem xét cũng như chỉnh sửa cho phùhợp với nhu cầu sử dụng
.III.2.3 Được viết sử dụng ngôn ngữ Objective C:
Mã nguồn của Cocos2D được viết bằng ngôn ngữ Objective C, ngôn ngữ “chính thức”của Apple sử dụng để lập trình trên tất cả các hệ máy của hãng
Cocos2D làm cho việc ứng dụng iPhone SDK trơ nên linh hoạt hơn rất nhiều
Các APIs thông dụng như OpenFeint, Facebook, hay GameCenter cũng được viết trênngôn ngữ Objective-C vì thế nên Cocos2D dễ dàng được tích hợp để sử dụng những APInày
.III.2.4 Ẩn đi các thành phần của OpenGL ES:
Đây là điều mà lập trình viên rất thích khi sử dụng Cocos2D Chẳng hạn như để vẽ một
Trang 25Xây dựng game Racing trên hệ điều hành iOS
Nhưng đồng thời Cocos2D vẫn cho phép lập trình viên sử dụng OpenGL ES trong mãnguồn của mình Điều này rất hữu ích khi cần viết lại một lớp nào đó của Cocos2D
.III.2.5 Lập trình:
Về cơ bản sử dụng Cocos2D sẽ làm cho việc viết game trên nền tảng iOS dễ dàng hơnnhưng không phải là lập trình viên có thể tạo ra một game mà không phải lập trình Một sốgame engine khác như Unity, iTorque… tạo ra một bộ công cụ để giảm thiểu đi việc lậptrình Điều này làm giảm thời gian và công sức lập trình như khi có lỗi xảy ra thì rất khó đểbảo trì và sửa chữa
.III.2.6 Được sự ủng hộ của cộng đồng lập trình viên:
Điều này cũng rất quan trọng đối với người lập trình Khi mới tiếp cận thì không phảimọi câu hỏi đều có thể tự thân người lập trình tìm ra câu trả lời Mọi câu hỏi đều được trảlời nhanh chóng trên forum của Cocos2D
Lập trình viên sử dụng Cocos2D chia sẽ rất nhiều mã nguồn cũng như hướng dẫn thựchiện với Cocos2D
Và vì Cocos2D hoàn toàn mơ nên nó càng ngày càng hoàn thiện bơi cộng đồng lập trìnhviên đông đảo trên iOS
.III.3 Cơ bản về Cocos2D:
Trong phần này sẽ giới thiệu những thành phần cơ bản, những lớp thường sử dụng trongCocos2D cũng như cấu trúc của Cocos2D engine
.III.3.1 Singleton:
Mẫu Singleton trong thiết kế mẫu (Design Pattern) là một lớp thông thường nhưng chỉ códuy nhất một thể hiện (chỉ có duy nhất một đối tượng được tạo ra) trong suốt cả quá trìnhthực thi chương trình Để đảm bảo điều này thì luôn có một phương thức static được sửdụng trong suốt quá trình tạo và truy cập đến đối tượng được tạo ra
Trong Cocos2D thay vì sử dụng alloc/init thì để truy cập đến đối tượng singleton ta dùng
phương thức bắt đầu bằng shared.
Một số lớp thông dụng nhất sử dụng singleton trong Cocos2D là:
CCActionManager* sharedManager = [CCActionManager sharedManager];
CCDirector* sharedDirector = [CCDirector sharedDirector];
CCSpriteFrameCache* sharedCache = [CCSpriteFrameCache sharedSpriteFrameCache];
CCTextureCache* sharedTexCache = [CCTextureCache sharedTextureCache];
CCTouchDispatcher* sharedDispatcher = [CCTouchDispatcher sharedDispatcher];
CDAudioManager* sharedManager = [CDAudioManager sharedManager];
SimpleAudioEngine* sharedEngine = [SimpleAudioEngine sharedEngine];
Ưu điểm của sử dụng singleton:
Trang 26Xây dựng game Racing trên hệ điều hành iOS
Singleton có thể sử dụng trong bất cứ đâu, bất cứ lúc nào trong mọi lớp khác, giống nhưmột biến toàn cục Điều này đặc biệt có ý nghĩa khi cần phải sử dụng chung dữ liệu cũngnhư phương thức trong nhiều nơi khác nhau
Ví dụ như sử dụng âm thanh trong game, âm thanh thường có ơ bất kì đâu từ menu đếngame đến nhưng đoạn hiệu ứng cắt cảnh (cutscene) Lập trình viên không cần phải tạo mớilại đối tượng player mỗi lần phát nhạc, hoặc lập trình viên có thể khơi tạo một lần dữ liệunhạc mà có thể sử dụng nhiều lần trong suốt game
Nhược điểm của sử dụng singleton:
Singleton chỉ tạo ra một đối tượng duy nhất đó cũng chính là nhược điểm
Ví dụ như trong game có nhiều level khác nhau, mỗi lần chuyển level thì thông tin ngườichơi sẽ được giữ nguyên từ level này qua level khác Để khơi tạo lại thì lập trình viên phảicó một phương thức để “reset” lại thông tin đó, giả sử như người chơi có rất rất nhiều biếnkhác nhau thì việc reset lại sẽ tốn nhiều thời gian Hoặc giả sử như lập trình viên muốn tạo
ra một game nhiều người chơi (multiplayer) nhưng nếu dùng kiểu singleton thì một lần chỉcó duy nhất một người chơi, như vậy thì vấn đề đặt ra bây giờ là phải viết lại code hoặc bỏ
đi chế độ multiplayer
Vì thế nên khi sử dụng singleton phải xem xét có nên sử dụng duy nhất một đối tượnghay là không, phải tùy mục đích sử dụng mà áp dụng singleton
.III.3.2 CCDirector:
Đây là thành phần cơ bản nhất của Cocos2D CCDirector là singleton vì mục đích củađối tượng này là lưu trữ các thiết lập trong Cocos2D đồng thời cũng để quản lý các Scenetrong Cocos2D Mục đích của CCDirector gồm:
− Truy cập và thay đổi Scene
− Lưu trữ các thiết lập của Cocos2D
− Thay đổi trạng thái của game (Pause, resume hoặc end)
− Chuyển đổi giữa tọa độ
Ví dụ:
Lấy kích thước màn hình trong Objective-C
CGSize* winsize = [[CCDirector sharedDirector] winSize];
Chuyển đổi giữa các Scene:
[[Director sharedDirector] replaceScene:[MenuScene node]];
Trang 27Xây dựng game Racing trên hệ điều hành iOS
Cấu trúc của màn hình game:
Những đối tượng dùng để vẽ lên màn hình trong Cocos2D gọi là một node lớp cha củatất cả các node là CCNode Tất cả các node đều có duy nhất một node chứa nó trừ Scene, vàcó thể có nhiều node con
1 Một màn hình game sẽ theo cấu trúc:
2 Khơi tạo đối tượng Scene
3 Trên Scene có một hoặc nhiều Layer
4 Các đối tượng hiển thị sẽ được đặt trên Layer như Sprite, Menu, Label…
.III.3.3 CCNode:
Hình III.3-4: Sơ đồ kế thừa các lớp thông dụng.
Một số phương thức thường dùng:
• Tạo một node mới:
CCNode* childNode = [CCNode node];
• Thêm node và node cha:
[myNode addChild:childNode z:0 tag:123];
• Lấy node con từ node cha:
CCNode* retrievedNode = [myNode getChildByTag:123];
• Xóa node con theo tag:
[myNode removeChildByTag:123 cleanup:YES];
• Xóa node con:
Trang 28Xây dựng game Racing trên hệ điều hành iOS
[myNode removeAllChildrenWithCleanup:YES];
• Node xóa chính nó trong lớp cha:
[myNode removeFromParentAndCleanup:YES];
CCNode là lớp cha của tất cả các lớp khác trong Cocos2D CCNode có các phương thức
để thêm, lấy và xóa node con Mỗi node con trong node cha đều được đánh số (tag) và sắpxếp theo một thứ tự z (z order) Node có giá trị z thấp nhất thì sẽ được vẽ đầu tiên cao nhất
vẽ sau cùng Nếu như có cùng giá trị z thì sẽ tính theo tứ tự node con được thêm vào nodecha, thêm trước vẽ trước và ngược lại Nếu các node có cùng tag thì khi sử dụng phươngthức getChildByTag sẽ lấy ra node đầu tiên có giá trị tag
.III.3.4 CCScene:
CCScene là node đầu tiên trong một màn hình game CCScene dùng để chứa không phải
để vẽ lên màn hình Thông thường chỉ chứa một đối tượng dẫn xuất từ lớp CCLayer
Khi một Scene được thay thế bảo một scene khác thì Scene mới sẽ được load vào bộ nhớtrước khi Scene cũ được xóa đi Vì thế sẽ sử dụng nhiều bộ nhớ hơn lúc chuyển Scene Nếugame lớn dùng nhiều bộ nhớ thì có thể sẽ bị đứng lúc chuyển Scene
Một số phương thức thường dùng:
• Khơi chạy một Scene:
[[CCDirector sharedDirector] runWithScene:[HelloWorld scene]];
• Thay một Scene đã có bơi một Scene khác:
[[CCDirector sharedDirector] replaceScene:[HelloWorld scene]];
.III.3.5 CClayer:
CCLayer cũng là lớp dùng để chứa các đối tượng khác chứ bản thân nó không có gì để
vẽ lên màn hình
Thông thường một Scene chỉ chứa một Layer nhưng cũng có thể chứa nhiều Layer,trường hợp chứa nhiều Layer trong giao diện người dùng khi dùng chức năng kéo (slide) đểthay đổi hiển thị Lúc có nhiều Layer được thêm vào Scene thì nó sẽ được sắp xếp bơi giátrị z Layer đầu tiên hiển thị là Layer có z thấp nhất
Layer sẽ chứa các đối tượng khác như Sprite, Label hay Menu
Không nên dùng quá nhiều Layer trên một Scene, nếu dùng quá nhiều Layer sẽ gây khóhiểu cũng như làm game chậm đi Đặc biệt khi Layer có sử dụng màn hình cảm ứng (touch)hay là sử dụng gia tốc kế (accelerometer)
Trang 29Xây dựng game Racing trên hệ điều hành iOS
CCLayer được thiết kế để nhận sự kiện touch từ người dùng Kể bật chức năng touch thìcần phải thiết lập biết isTouchEnabled bằng YES
self.isTouchEnabled = YES;
Đồng thời cần phải cài đặt những hàm phục vụ sự kiện touch, khi touch vào thì sẽ xử lýnhững gì thì phải cài đặt trong những hàm sau:
• Được gọi khi bắt đầu touch vào màn hình:
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
• Được gọi khi ngón tay di chuyển trên màn hình:
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
• Được gọi khi thả ngón tay ra khỏi màn hình:
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
Hình III.3-5: Vị trí Sprite trong màn hình.
Nếu không xét vị trí thì sprite mặc định nằm ơ vị trí (0, 0) tức là góc dưới bên trái màn hình
Trang 30Xây dựng game Racing trên hệ điều hành iOS
Điểm neo (anchor point) là vị trí mà khi ta thêm Sprite vào trong layer thì điểm đó sẽ tươngứng với vị trí sprite trong Layer mà ta chỉ định Mặc định điểm neo nằm giữa sprite nhưng
ta có thể xét cho nó nằm ơ bất kì đâu trong giới hạn hình ảnh
Ví dụ:
Xét anchor point nằm ơ góc dưới bên trái:
sprite.anchorPoint = CGPointMake(0, 0);
Xét anchor point nằm ơ góc trên bên phải:
sprite.anchorPoint = CGPointMake(sprite.contentSize.width / 2, sprite.contentSize.height / 2);
.III.3.7 CCLabel:
Sử dụng CCLabel là cách đơn giản nhất để hiển thị nội dung text ra màn hình
Sử dụng label cũng như sử dụng sprite nhưng với Label thì điểm anchor point sẽ khác Cụthể:
• Canh label về bên phải:
CCMenu cho phép ta tạo một menu một cách nhanh chóng
CCMenu nhận node con là CCMenuItem
Hình III.3-6: Menu dưới dạng text.
Trang 31Xây dựng game Racing trên hệ điều hành iOS
CCMenuItemImage: tạo ra một menu hình ảnh
CCMenuItemToggle: tạo ra menu chức năng tắt / bật
.III.3.9 Lớp Actions:
Actions là những lớp cho phép lập trình viên di chuyển, xoay, phóng to thu nhỏ… mộtnode trên màn hình Những lớp này làm việc với tất cả các node vì thế có thể sử dụng trênsprite, label, menu hay thậm chí trên cả một scene
Có nhiều loại Action nhưng phổ biến gồm:
Ví dụ: Xoay hình một góc 360 độ trong 2 giây và lặp đi lặp lại mãi
CCRotateBy* rotateBy = [CCRotateBy actionWithDuration:2 angle:360];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:rotateBy];
[myNode runAction:repeat];
Theo chuỗi (Sequences):
Khi cần thực hiện nhiều action trong một node nhưng theo thứ tự trước sau Thực hiệnxong một action rồi mới tới action tiếp theo
Ví dụ: Thay đổi màu của một Label từ đỏ sang xanh da trời sang xanh lá cây:
CCTintTo* tint1 = [CCTintTo actionWithDuration:4 red:255 green:0 blue:0];
CCTintTo* tint2 = [CCTintTo actionWithDuration:4 red:0 green:0 blue:255];
CCTintTo* tint3 = [CCTintTo actionWithDuration:4 red:0 green:255 blue:0];
CCSequence* sequence = [CCSequence actions:tint1, tint2, tint3, nil];
[label runAction:sequence];
Chuỗi các action phải được kết thúc bằng nil (tức NULL ơ C hay Java) để cho hàm nhậnbiết phải kết thúc
.III.4 Quản lý bộ nhớ với Cocos2D:
Thông thường để tạo mới một đối tượng trong Objective-C thì ta cần dùng alloc để cấpphát vùng nhớ cho đối tượng đó Và sau khi dùng xong phải giải phóng vùng nhớ bằng cách
Trang 32Xây dựng game Racing trên hệ điều hành iOS
NSObject* myObject = [[[NSObject alloc] init] autorelease];
Với cách này thì không cần phải quan tâm đến việc phải giải phóng vùng nhớ nữa vìchương trình đã tự làm
Với Cocos2D cũng tương tự nhưng ơ đây Cocos2D luôn cung cấp một phương thứcstatic để lấy đối tượng tự giải phóng (autorelease object), chính điều này làm cho việc lậptrình trơ nên dễ dàng hơn và không cần phải luôn luôn ghi nhớ việc giải phóng vùng nhớ saukhi sử dụng
.IV Open Feint:
.IV.1 Giới thiệu:
Trang 33Xây dựng game Racing trên hệ điều hành iOS
chỉ để chia sẽ điểm số trong trò chơi với nhau mà lập trình viên còn có thể cho phép ngườidùng có thể đạt được những thành tích nhất định trong game hoặc thậm chí có thể thách đấunhau
Không những thế người dùng còn có thể chat với nhau qua OpenFeint hoặc tìm kiếmnhững game khác ngoài game mình đang chơi
− Máy chủ ổn định, tốc độ cao
− Có thể giao tiếp giữa iOS và
Android và ngược lại
− Hoàn toàn miễn phí
Hình IV.2-8: Giao diện OpenFeint
.IV.3 Triển khai:
OpenFeint dễ dàng được tích hợp vào trong game Để tích hợp OpenFeint vào game lậptrình viên cần đăng kí tài khoản trên trang web của hãng và tải OpenFeint API
Trang 34Xây dựng game Racing trên hệ điều hành iOS
CHƯƠNG 2
XÂY DỰNG GAME
.I Giới thiệu tổng quan:
.I.1 Game là gì?
Game hay video game là một ứng dụng nhưng mang tính giải trí Game là ứng dụngmang tính tương tác cao giữa người với thiết bị Thông thường thiết bị sẽ tương tác ngaylập tức đối với những tác động của người dùng bằng âm thanh hay hình ảnh động Game cóthể xem như một đoạn phim vì cũng đều xử lý theo cách cho máy tính vẽ lại những hình ảnhtĩnh một cách liên tục, nhưng không giống như phim Game cho phép người chơi tương tác,người chơi có thể điều khiển nhân vật theo ý muốn của mình trong một kịch bản game chosẵn
.I.2 Qui trình làm game:
Trên thực tế để làm được một game có chất lượng cần phải trải qua rất nhiều khâu,nhiều công đoạn khác nhau Một công ty sản xuất ra một sản phẩm game có chất lượng caokhi từng công đoạn được chuyên môn hóa cao và giữa các bộ phận sản xuất có sự gắn kếtchặt chẽ với nhau
Thông thường một game sẽ trải qua 4 công đoạn trước khi đến được tay người dùng, đólà:
Ý tương: công đoạn này do một nhóm những người thiết kế game (Game Designers)thực hiện Những người thiết kế game là những người có nhiều kinh nghiệm về game về ýtương mới cho game Người thiết kế game sẽ đưa ra một kịch bản game (Game Scenrano).Kịch bản game tóm gọn những ý tương của người thiết kế chẳng hạn game gì, cách chơi,gồm có những thành phần nào…
Thiết kế: công đoạn này do những họa sĩ đồ họa (Graphic Artist) thực hiện Ở giai đoạnnày thiết kế game sẽ đưa ý tương của mình cho họa sĩ và họa sĩ chịu trách nhiệm làm ranhững hình ảnh, đồ họa cho game theo những thiết kế có sẵn
Mã hóa: công đoạn này do lập trình viên (Progammer) thực hiện Lập trình viên sẽ chịutrách nhiệm hiện thực hóa những ý tương và thiết kế mà thiết kế game và họa sĩ đồ họa thựchiện Lập trình viên sẽ liên kết những hình ảnh đồ họa mà họa sĩ vẽ ra và làm cho nhữnghình ảnh trơ nên sinh động Lập trình viên phải tuân thủ đúng những ý tương trong thiết kếđã định Đây có thể xem là công việc nặng nhất trong quá trình sản xuất ra một game.Kiểm thử: công đoạn này do những nhân viên kiểm thử (Game Tester) thực hiện Ở đâyviệc kiểm thử không giống với việc kiểm thử những hệ thống lớn, việc kiểm thử không dựatrên những test case định sẵn mà sẽ thực hiện theo nguyên tắc “tìm càng nhiều lỗi càng tốt”.Nhân viên kiểm thử sẽ chơi game và trong quá trình chơi sẽ cố gắng tìm hết ra tất cả những
Trang 35Xây dựng game Racing trên hệ điều hành iOS
Và dĩ nhiên không thể thiếu trách nhiệm của Quản lý dự án (Project Manager) người sẽquản lý cũng như điều phối thời gian cho từng giai đoạn phát triển của một game
.I.3 Vòng đời của một game.
Hình I.3-9: Vòng đời của một ứng dụng.
Game sẽ bắt đầu khi thực hiện lời gọi hàm didFinishLauchingOptions
Khi xảy ra interrupt như là SMS hay cuộc gọi đến… hàm applicationWillResignActive sẽ được gọi
Khi người dùng bấm phím Home thì hàm applicationDidEnterBackground được gọi, lúc nàyứng dụng sẽ được chuyển về trạng thái nền (background) có thể sẽ tiếp tục chạy nhưng không hiển thị giao diện (như ứng dụng nghe nhạc), hoặc có thể lưu lại trạng thái trước đó rồi “đóng băng” không tiếp tục chạy nữa
Trang 36Xây dựng game Racing trên hệ điều hành iOS
.II Xây dựng game đua xe (Racing)
.II.1 Lịch sử game đua xe:
Game đua xe đầu tiên được giới thiệu vào năm 1974 có tên là Gran Trak 10 là thể loại game một người chơi (single player) và không hề có AI
Hình II.1-10: Game đua xe đầu tiên.
Năm 1982 Namco cho ra đời game Pole Position là game đầu tiên có AI thuộc thể loại game một người chơi
Hình II.1-11: Game Pole Position.
Đến năm 1992, Nitendo cho ra đời game Super Mario Kart là game đầu tiên được bổ sung thêm hệ thống vật phẩm nhằm tăng tính hấp dẫn của game