3 | 20 LẬP TRÌNH GAME BẰNG FRAMEWORK libGDX libGDX là một framework phát triển game miễn phí và có mã nguồn mở, được viết chủ yếu bằng ngôn ngữ Java và một số thành phần bằng C và C++ đ
Trang 11 | 20
ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
BÁO CÁO BÀI TẬP MÔN ĐỒ HOẠ VÀ HIỆN THỰC ẢO
ĐỀ TÀI LẬP TRÌNH GAME BẰNG FRAMEWORK libGDX
Giảng viên hướng dẫn: ThS Lê Tấn Hùng
Nhóm sinh viên thực hiện:
Nguyễn Văn Sơn - MSSV 20143863 Trương Quang Toàn - MSSV 20134028
Lớp KSTN CNTT K59
Hà Nội ngày 15 tháng 05 năm 2018
Trang 22 | 20
MỤC LỤC
I GIỚI THIỆU VỀ libGDX 3
1 Lịch sử phát triển libGDX 3
2 Các đặc điểm của libGDX 5
3 Kiến trúc libGDX 6
4 Các game nổi tiếng được viết bằng libGDX 7
II CÁC KHÁI NIỆM CƠ BẢN TRONG libGDX 8
1 Vẽ đồ họa lên màn hình 8
2 Hệ tọa độ trong libGDX 11
2.1 Hệ tọa độ tiếp xúc 11
2.2 Hệ tọa độ màn hình hoặc ảnh 12
2.3 Hệ tọa độ hiển thị chuẩn hóa 12
2.4 Hệ tọa độ UV 13
2.5 Hệ tọa độ thế giới thực 14
3 Camera và Viewport 14
4 Box 2D 16
III XÂY DỰNG TRÒ CHƠI FUNNY BUNNY BẰNG libGDX 17
1 Ý tưởng trò chơi 17
2 Thể loại 17
3 Đối tượng hướng đến của trò chơi 17
4 Tóm tắt diến biến trò chơi 17
5 Thế giới vật lý trong trò chơi 18
6 Đồ họa trong trò chơi 18
7 Logic trò chơi 20
IV KẾT LUẬN 20
Trang 33 | 20
LẬP TRÌNH GAME BẰNG FRAMEWORK libGDX
libGDX là một framework phát triển game miễn phí và có mã nguồn mở, được viết chủ yếu bằng ngôn ngữ Java và một số thành phần bằng C và C++ để tăng hiệu năng libGDX cho phép lập trình viên phát triển game trên nhiều nền tảng như Windows, Linux, Mac OS, Android, iOS, BlackBerry, và nền tảng web
1 Lịch sử phát triển libGDX
Năm 2009, chiếc điện thoại Android đầu tiên được ra mắt trên thị trường Mario Zechner, một lập trình viên với niềm đam mê làm game, quyết định rằng mình sẽ làm game cho loại điện thoại mới ra mắt này Zechner bắt đầu bằng việc tìm hiểu về Android SDK (1.x) và OpenGL ES, sau đó anh viết game framework AFX (Android Effects) để phục
vụ cho việc làm game của mình Tuy nhiên, việc cài đặt phần mềm trên Android lại là một thách thức đối với những phiên bản Android ban đầu, do đó Zechner quyết định chỉnh sửa AFX để game được viết ra có thẻ chạy được trên nền tảng desktop Đó chính
là khởi đầu của libGDX mà ta biết ngày nay
Bước ngoặt thứ hai của libGDX là vào tháng 3 năm 2010, Zechner đưa AFX trở thành mã nguồn mở trên Google Code với giấy phép GNU Lesser General Public License (LGPL) Quyêt định này được đưa ra một phần bởi Google tặng anh một chiếc Nexus One do những đóng góp đối với nền tảng Android Tuy nhiên, lúc đó Zechner cũng nói rằng AFX được viết ra không phải để làm game cho desktop mà đối tượng chính vẫn là game trên nền tảng Android Vào tháng 4, dự án có người đóng góp đầu tiên
Đến tháng 5 năm 2010, libGDX có bước phát triển lớn khi được tích hợp thêm Box2D JNI wrapper Từ đó, những nhà phát triển game bằng libGDX có thể làm các game với hiệu ứng vật lý như trong thế giới thật Việc tích hợp này cũng lôi cuối nhiều người
sử dụng và đóng góp hơn cho dự án mã nguồn mở này, nhờ đó dự án phát triển nhanh hơn và ổn định hơn
libGDX tiếp tục có những bước phát triển vững chắc trong năm 2011.Cuối tháng 2 năm 2011, phiên bản 0.9 được phát hành với rất nhiều tính năng và nhận được sự đón nhận của cộng đồng Các game được viết bằng libGDX bắt đầu trở thành hiện tượng trên cửa hàng Android Nổi bật nhất là game Appratus, bán được 500 nghìn bản, một
Trang 44 | 20
con số đáng mơ ước đối với những game trả phí trên di động Cũng trong tháng 2, Zechner xuất bản cuốn sách đầu tiền về libGDX (700 trang!) Tháng 9 năm đó, phiên bản libGDX 0.9.2 được phát hành
libGDX vẫn tiếp tục phát triển với tốc độ nhanh chóng Zechner viết gdx-jnigen nhằm giúp cho việc mở rộng framework được dễ dàng hơn
Cột mốc tiếp theo của libGDX đến khi Zechner bắt đầu thấy hứng thú với PlayN, một framework phát triển game đa nền tảng được phát hành bởi Google PlayN này có thể sử dụng để làm game cho máy tính, điện thoại Android và nền tảng web Điểm thú vị nhất của PlayN là nó có thể được sử dụng để làm game trên nền web mà không cần dùng đến applet Thay vào đó, code Java được biên dịch thành Javascript bằng GWT Zechner tin rằng anh có thể tạo ra điều tương tự với libGDX Tuy nhiên, libGDX phức tạp hơn PlayN rất nhiều và có nhiều tính năng mà GWT không hỗ trợ, do đó Zechner và các lập trình viên khác đã phải rất nhiều việc để hoàn thành được chức năng tương tự PlayN cho libGDX Sau này, Zechner thừa nhận rằng phát triển nền tảng web cho libGDX là một trong những phần thích thú nhất, nhưng cũng đáng sợ nhất của dự án
Tháng 4 năm 2012, phiên bản 0.9.3 được phát hành Cũng vào khoảng thời gian
đó, một báo cáo tiết lộ rằng 1.24% số lượng ứng dụng Android được viết bằng libGDX libGDX là framework làm game phổ biến nhất thời điểm đó, vượt lên cả Unity
Tháng 6 năm 2012, thay đổi lớn tiếp theo diễn ra Nhóm lập trình viên nòng cốt của libGDX quyết định mở rộng framework để hỗ trợ iOS Tháng 8, dự án được chuyển đến Github và hỗ trợ Maven Có thời điểm, libGDX là ứng dụng Java lớn thứ 4 trên Github, có trên 1300 pull requests và 200 người đóng góp Cuối năm 2012, game đầu tiên được xây dựng bằng libGDX được phát hành trên iOS store, phiên bản 0.9.7 được phát hành Thậm chí, Google cũng bắt đầu sử dụng libGDX
Từ tháng 3 đến tháng 5 năm 2013, phần xử lý 3D được viết lại và tích hợp vào thư viện Vào tháng 6, website chính thức của libGDX được viết lại để người dùng có thể đưa các game mà họ viết bằng libGDX lên Cho đến tháng 1 năm 2016, hơn 3000 games đã được đưa lên trang này
Ngày 20 tháng 4 năm 2014, sau 4 năm phát triển, phiên bản 1.0 của libGDX được phát hành
Các mốc phát triển của libGDX:
Trang 55 | 20
Version Release date
1.0 20 April 2014[1]
1.1 23 May 2014[37]
1.2 22 June 2014[38]
1.3 9 August 2014[39]
1.4 10 October 2014[40]
1.5 8 December 2014[41]
1.6 6 May 2015[42]
1.7 21 September 2015[43]
1.8 5 January 2016[44]
1.9 24 January 2016[45]
2 Các đặc điểm của libGDX
❖ Mã nguồn mở
libGDX là một framework làm game mã nguồn mở được đăng kí dưới giấy phép Apache 2.0 Giấy phép này cho phép người dùng chỉnh sửa và phân phối game được viết bằng libGDX miễn phí miễn là người dùng thêm giấy phép này vào dự án của họ Người
Trang 66 | 20
dùng cũng có thể sử dụng libGDX cho các dự án thương mại mà không cần phải trả phí hay đóng góp gì cho những người đã phát triển libGDX
❖ Đa nền tảng
Đặc điểm quan trọng nhất của libGDX là tính đa nền tảng Mục tiêu của libGDX, như Mario Zechner phát biểu là: “hoàn thành lời hứa của Java “viêt một lần, chạy khắp nơi”, đặc biệt là cho quá trình phát triển game” Người dùng chỉ cần viết các phần chính của trò chơi một lần, và với rất ít thao tác có thể đưa trò chơi chạy trên các nền tảng iOS, Android, HTML Windos, Linux, Mac OS
❖ Tính mở rộng
Các lập trình viên sử dụng libGDX có thể thêm rất nhiều phần mở rộng ngoài các cài đặt mặc định Những mở rộng này gồm các xử lý vật lý 2D, AI… Ví dụ nếu lập trình viên muốn viết một game 3D có sử dụng các hiệu ứng vật lý, họ chỉ cần thêm thư viện Bullet vào chương trình mà không cần phải xây dựng lại từ đầu
Các thư viện mở rộng đáng chú ý của libGDX bao gồm:
- gdxAI: hỗ trợ lập trình viên sử dụng AI với libGDX
- gdx freetype: hỗ trợ các font freetype
- Box2D: hỗ trợ các hiệu ứng vật lý trong game 2D
- packr: công cụ đóng gói JRE với game giúp cho người dùng không phải cài đặt JRE
3 Kiến trúc libGDX
libGDX cho phép lập trình viên viết, thử nghiệm và gỡ lỗi trò chơi trên máy tính PC và
sử dụng cùng code đó để tạo game trên Android Lập trình viên cảm thấy không còn rào cản giữa các nền tảng máy tình như Window, Mac OS, Linux với các thiết bị di động Để làm được điều đó, thư viện này sử dụng các thư viện khác để xử lý chuyên biệt trên mỗi nền tảng Bằng việc sử dụng các thư viện chuyên biệt này, lập trình viên không cần phải viết code cho các nền tảng khác nhau ngoại trừ phần code khởi động game Các thư viện
đó bao gồm:
- Lightweight Java Game Library được sử dụng để xây dựng game trên máy tính PC
- Google Web Toolkit được sử dụng để biên dịch mã nguồn Java thành Javascript
Mã nguồn sau khi được biên dịch có thể chạy trên nền trình duyệt
Trang 77 | 20
- Trên nền tảng Android, libGDX sử dụng mã nguồn Java được biên dịch cho Android bằng Android SDK
- Trên nền tảng iOS, một phiên bản chỉnh sửa của RoboVM được sử dụng để biên dịch mã nguồn Java thành lệnh trên iOS
4 Các game nổi tiếng được viết bằng libGDX
a) Paperama
Đây là trò chơi xếp giấy Origami nổi tiếng trên cửa hàng ứng dụng của Android Đã có trên 10 triệu lượt tải về, trên 2 triệu lượt đánh giá với điểm trung bình là 4.4 Trò chơi yêu cầu bạn phải ghép giấy theo các hình cho trước với độ khó tăng dần Với hiệu ứng 3D hấp dẫn và hơn 70 level khác nhau, đây chắc chắn là trò chơi được yêu thích nhất của những người yêu thích nghệ thuật xếp giấy Origami nói riêng và những người yêu cái đẹp nói chung
Một số hình ảnh về trò chơi
Figure 1: Logo trò chơi paperama
Figure 2: Một level trong trò chơi paperama
Trang 88 | 20
b) Tap Tap Dash
Trò chơi này có cách chơi cực kì đơn giản Bạn phải chạm vào màn hình để thay đổi hướng của nhân vật trong game khi đến các lối rẽ Tuy cách chơi đơn giản như vậy nhưng đây là trò chơi có tính gây nghiện cao khi có đến hơn 50 triệu lượt tải trên Android store Với hơn 1000 màn chơi, người chơi sẽ thấy mình không thể rời mắt khỏi màn hình một khi đã chơi
Figure 3: Một số hình ảnh trong trò chơi Tap Tap Dash
1 Vẽ đồ họa lên màn hình
Một hình ảnh sau khi được giải mã từ định dạng ban đầu (ví dụ như PNG) và đưa vào GPU được gọi là một texture Mỗi texture có một hình dạng hình học khác nhau, thường là hình chữ nhật Để vẽ một texture ra màn hình, ta phải tìm các đỉnh texture rồi
vẽ texture dựa trên những đỉnh đã được xác định đó Vị trí và kích thước của texture trên màn hình được xác định bởi dạng hình học và cấu hình khung nhìn của OpenGL Rất nhiều trò chơi 2D cấu hình khung nhìn có kích thước bằng kích thước của màn hình Trong thực tế, việc vẽ một texture hoặc các khu vực khác nhau của một texture nhiều lần là rất phổ biến trong trường hợp này, nếu cứ mỗi lần vẽ cùng một texture hoặc các khu vực của cùng một texture, ta phải tính toán lại từ đầu thì sẽ rất hạn chế đến hiệu năng của trò chơi Để giải quyết vấn đề này, ta sử dụng SpriteBatch Với cùng một texture, SpriteBatch sẽ tính toán trước tất cả các vùng cần vẽ đối với một texture rồi gửi
Trang 99 | 20
những giá trị đó cho GPU xử lý khi có một texture mới đến yêu cầu vẽ ra màn hình Do thao tác gửi khá tốn kém, và các giá trị được SpriteBatch gửi đi khi có một texture mới đến, do đó trong libGDX, các hình ảnh nhân vật hoặc đối tượng trong trò chơi thường được vẽ thành một vùng nhỏ trong một bức ảnh lớn Ví dụ dưới đây là bức ảnh chứa các đối tượng trong trò chơi Super Jumper
Figure 4: Ảnh chứa các đối tượng trong game
Các đối tượng là các vùng trong bức ảnh để tiết kiệm năng lực tính toán
Để sử dụng SpriteBatch, ta phải gọi thủ tục begin, sau đó vẽ các hình ảnh ra màn hình Khi kết thúc quá trình vẽ, ta gọi thủ tục end
Trang 1010 | 20
Figure 5: Cách sử dụng SpriteBatch trong libGDX
Để thao tác với các texture, trong libGDX ta sử dụng lớp Texture
Figure 6: Sử dụng Texture trong libGDX
Trong ví dụ ở hình 6, ta khai báo một đối tượng texture tương ứng với bức ảnh
“image.png” trong thư mục assets, sau đó sử dụng một đối tượng SpriteBatch để vẽ
texture ra màn hình
Ngoài lớp Texture, libGDX còn hỗ trợ lớp TextureRegion để thao tác với các vùng con trong một texture Sau đó ta có thể dùng SpriteBatch để vẽ các đối tượng TextureRegion này
Figure 7: Ví dụ sử dụng TextureRegion trong libGDX
Để làm việc với các vùng con trong một texture, libGDX còn cung cấp lớp Sprite Lớp này không chỉ lưu thông tin về vùng con trong texture như TextureRegion, nó còn lưu các thông tin khác như vị trí, màu sắc… của vùng đó khi hiển thị ra màn hình
Figure 8: Ví dụ về lớp Sprite
Trang 1111 | 20
Trong ví dụ trên, lớp Sprite cắt ra vùng hình chữ nhật có vị trí (20, 20) trong texture với chiều rộng và chiều dài là 50, sau đó quay 45 độ và hiển thị ra trên màn hình ở vị trí (10,10)
2 Hệ tọa độ trong libGDX
Khi lập trình bằng libGDX hoặc bất kì hệ thống nào dựa trên OpenGL, lập trình viên cần phải làm việc với nhiều hệ tọa độ khác nhau Nguyên nhân của việc này là OpenGL
cố gắng đưa ra một hệ tọa độ không phụ thuộc vào độ phân giải của từng thiết bị riêng biệt Hệ tọa độ này có thể được áp dụng với mọi loại thiết bị và chỉ phụ thuộc vào logic của game Phần này sẽ giới thiệu các hệ tọa độ khi phát triển game bằng libGDX
2.1 Hệ tọa độ tiếp xúc
- Đơn vị: pixels
- Hướng của trục y: hướng xuống dưới
- Tọa độ: số nguyên
- Miền giá trị: (0,0), góc trên bên trái, đến
(Gdx.graphics.getWidth() -1, Gdx.graphics.getHeight()-1) , góc dưới bên phải
- Sử dụng: xác định điểm tiếp xúc trên thiết bị di động, điểm click chuột trên máy tính
- Giá trị phụ thuộc vào từng loại thiết bị
Figure 9: Hệ tọa độ tiếp xúc
Mỗi điểm trên hệ tọa độ là chỉ số của một mảng hai chiều, biểu diễn một điểm trên màn hình Do đó, các giá trị biểu diễn tọa độ luôn là số nguyên Khi muốn biết vị trí click
Trang 1212 | 20
chuột hoặc vị trí chạm của màn hình di động, lập trình đều phải sử dụng hệ tọa độ này Libgdx cung cấp các phương thức để chuyển đổi giá trị trong hệ tọa độ này thành giá trị trong các hệ tọa độ khác dễ sử dụng hơn
Ví dụ camera.unproject hoặc viewport.unproject
2.2 Hệ tọa độ màn hình hoặc ảnh
- Đơn vị: pixels
- Hướng của trục y: hướng lên trên
- Tọa độ: số nguyên
- Miền giá trị: (0, 0), góc dưới bên trái, đến
(Gdx.graphics.getWidth()-1, Gdx.graphics.getHeight()-1), góc trên bên phải
- Sử dụng: viewport, scissors, pixmap
- Giá trị phụ thuộc vào từng loại màn hình, vào hình ảnh hiển thị
Hệ tọa độ này thường được sử dụng để xác định khu vực của màn hình mà hình ảnh được vẽ ra Tuy nhiên trong thực tế hệ tọa độ này ít được sử dụng
2.3 Hệ tọa độ hiển thị chuẩn hóa
- Đơn vị: 1
- Hướng trục y: hướng lên trên
- Tọa độ: số thực
- Miền giá trị: (-1, -1) góc dưới bên trái đến (+1, +1) góc trên bên phải
- Sử dụng: shader
- Hệ tọa độ này không phụ thuộc vào thiết bị
Trang 1313 | 20
Figure 10: Hệ tọa độ hiển thị chuẩn hóa
Hai hệ tọa độ giới thiệu ở trên có một nhược điểm lớn là chúng đều phụ thuộc vào thiết bị Để giải quyết vấn đề đó, OpenGL cho phép lập trình viên sử dụng một hệ tọa độ độc lập với thiết bị Hệ tọa độ này sẽ tự chuyển đổi sang hệ tọa độ màn hình khi hiển thị hình ảnh ra màn hình Giá trị của các vị trí trong hệ tọa độ này nằm tỏng khoảng từ [1, -1] đến [+1, +-1] với gốc tọa độ (0, 0) nằm chính giữa màn hình Hệ tọa độ này cũng ít được sử dụng trong thực tế Chú ý rằng mặc dù kích thước chiều cao và chiều rộng của màn hình thiết bị có thể không giống nhau, miền giá trị theo chiều cao và chiều rộng trong hệ tọa độ này luôn nằm trong khoảng [-1, +1], do đó lập trình viên phải xử lý tình huống này trong ứng dụng
2.4 Hệ tọa độ UV
- Đơn vị: 1
- Hướng của trục y: hướng lên trên
- Tọa độ: số thực
- Miền giá trị: (0, 0) góc dưới bên trái đến (1, 1) góc trên bên phải
- Sử dụng: shader, mesh, texture regions, sprite
- Không phụ thuộc vào màn hình
Điểm khác biệt duy nhất giữa hệ tọa độ UV và hệ tọa độ hiển thị chuẩn hóa là hệ tọa độ
UV sử dụng miền giá trị từ [0, 0] đến [1, 1]