You are on page 1of 61

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG


──────── * ───────

BÀI TẬP LỚN


MÔN: LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG

Xây dựng một game nhập vai SimpleRGB

Sinh viên thực hiện: Nhóm 11

STT Họ và tên MSSV


1 Ngô Trọng Quân 20194144
2 Nguyễn Anh Tuấn 20194201
3 Ngô Đăng Hanh 20194042
4 Nguyễn Thanh Tùng 20194207
5 Lê Minh Hoàng 20194056

Lớp: Khoa học máy tính - khóa 64


Giáo viên hướng dẫn: ThS. Nguyễn Mạnh Tuấn
IT3100 – Lập trình hướng đối tượng 20202

Hà Nội, tháng 5 năm 2021

Nhóm 11 2
IT3100 – Lập trình hướng đối tượng 20202

MỤC LỤC
MỤC LỤC.................................................................................................................... 2

LỜI NÓI ĐẦU.............................................................................................................. 3

PHÂN CÔNG THÀNH VIÊN TRONG NHÓM.......................................................4

CHƯƠNG 1. KHẢO SÁT, ĐẶC TẢ YÊU CẦU BÀI TOÁN...............................5


1.1. Mô tả yêu cầu bài toán...................................................................................5
1.2. Biểu đồ use case..............................................................................................5
1.2.1. Biểu đồ use case tổng quan........................................................................5
1.2.2. Biểu đồ use case phân rã mức 2.................................................................5
1.3. Đặc tả use case................................................................................................5

CHƯƠNG 2. PHÂN TÍCH THIẾT KẾ BÀI TOÁN.............................................6


2.1. Thiết kế Cơ sở dữ liệu....................................................................................6
2.2. Biểu đồ trình tự...............................................................................................6
2.3. Biểu đồ lớp......................................................................................................6
2.4. Thiết kế chi tiết lớp.........................................................................................6

CHƯƠNG 3. CÔNG NGHỆ VÀ THUẬT TOÁN SỬ DỤNG...............................7

CHƯƠNG 4. XÂY DỰNG CHƯƠNG TRÌNH MINH HỌA................................8


4.1. Kết quả chương trình minh họa....................................................................8
4.2. Giao diện chương trình..................................................................................8

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN..................................................................9

TÀI LIỆU THAM KHẢO.........................................................................................10

PHỤ LỤC................................................................................................................... 11

Nhóm 11 3
IT3100 – Lập trình hướng đối tượng 20202

LỜI NÓI ĐẦU


<Nêu lý do chọn đề tài này, tầm quan trọng của đề tài này>
<Mô tả sơ qua về đề tài, quá trình tiếp cận và hoàn thiện đề tài>
Hiện nay chúng ta đang sống trong thời đại công nghệ 4.0 với nhiều sự mới mẻ
và phát triển tột bậc, những phát minh khoa học mới, nền kinh tế tăng trưởng vượt bậc,
dẫn đến nhu cầu vật chất và tinh thần của người dân cũng tăng cao, đặc biệt là nhu cầu
giải trí bằng game. Thật vậy, ở Việt Nam, một nước đang phát triển với dân số trẻ, nhu
cầu và độ tiếp nhận với game là rất lớn, vì vậy ngành game ở nước ta đang trải thảm
đỏ mời gọi nhân lực, đặc biệt là lập trình và thiết kế game. Việt Nam hiện mới chỉ có
khoảng 500 kỹ sư làm việc ở mảng game. Trong khi đó, theo báo cáo từ Appota, năm
2019, cả nước có khoảng 50 triệu người chơi game, tổng doanh thu ước đạt 500 triệu
USD. Còn theo dự báo của ông Lê Hồng Minh, Tổng giám đốc điều hành VNG, trong
5-10 năm tới, doanh thu ngành game sẽ đạt mốc 1 tỷ USD.
Việc thiếu thốn về nhân lực này tuy gây sự bất lợi trong cạch tranh với các tựa game
nước ngoài nhưng cũng tạo ra cơ hội để các bạn lập trình viên trong nước thử sức. Bên
cạnh đó thì cũng có nhiều thách thức đó là để tạo một game tốt hấp dẫn nhiều người
chơi cần rất nhiều công sức, chất xám của nhiều người và còn cần 1 ý tưởng tốt, hướng
đi tốt. Nhận thức được những cơ hội và thách thức đó, nhóm 11 bọn em đã chọn đề tài
làm game RGB cho dự án OOP lần này.
Sau khi các thành viên trong nhóm bàn bạc và quyết định đề tài này, bọn em bắt đầu
lập biểu đồ use case tổng quan dựa trên các yêu cầu cơ bản thầy đưa ra, cùng với
những chỉnh sửa theo ý tưởng của mỗi người mà cả nhóm thấy hợp lý, sau đó lập biểu
đồ use case phân rã cho các chức năng phức tạp, khi đã biết được các use case bọn em
tiến hành xây dựng các biểu đồ gói, biểu đồ lớp... sau đó lên ý tưởng cơ bản cho từng
gói, lớp và chia việc cho từng người. Công việc được chia thành các vòng lặp nhỏ lặp
lại mỗi 2,3 tuần: trả lời 1 vài câu hỏi như sản phẩm hiện tại đã đáp ứng được nhu cầu
của lần lặp trước chưa? Cần sửa, tối ưu những gì? Ý tưởng nào không khả thi? Có
những ý tưởng mới nào, sau đó lại vẽ và phân tích biểu đồ ưu case. Cứ như thế bọn em
đã dần tạo ra các phiên bản để code tối ưu hơn, dùng công nghệ mới hơn dễ nâng cấp
hơn cụ thể là chuyển từ code thuần JavaFx sang cải thiện giao diện hơn bằng FXML,
tận dụng thêm cả công cụ quản lý dự án Maven.
Do bọn em cũng chưa có nhiều kinh nghiệm trong làm game nói riêng và làm dự án
lập trình nói chung cùng với việc vừa học kiến thức vừa làm nên trong quá trình làm
việc xảy ra rất nhiều khó khăn. Nhưng dưới sự hướng dẫn của thầy Nguyễn Mạnh
Tuấn, cũng như mọi người trong nhóm đã giúp đỡ nhau vừa làm vừa học kiến thức
mới rất tích cực, chúng em đã hoàn thành được bài tập lớn này. Tuy còn nhỏ và chứa
nhiều thiếu sót, nhưng nhóm em đã rất cố gắng hoàn thiện sản phẩm này. Chúng em
Nhóm 11 4
IT3100 – Lập trình hướng đối tượng 20202
rất mong nhận được nhận xét của thầy, để có thể cải thiện các khuyết điểm cũng như
để bài tập này hoàn thiện hơn. Chúng em cảm ơn thầy.

Nhóm 11 5
IT3100 – Lập trình hướng đối tượng 20202
PHÂN CÔNG THÀNH VIÊN TRONG NHÓM
<Danh sách các thành viên trong nhóm>
<Phân công nhiệm vụ cụ thể của mỗi thành viên trong việc thực hiện bài tập
lớn môn học và đánh giá mức độ hoàn thành>
Họ và Email Điện thoại Công việc Đánh
tên thực hiện giá
Ngô Quan.nt194144@sis.hust.edu.vn 0367935764
Trọng
Quân
Nguyễn
Anh Tuấn
Ngô
Đăng
Hanh
Nguyễn
Thanh
Tùng
Lê Minh
Hoàng

Nhóm 11 6
IT3100 – Lập trình hướng đối tượng 20202

CHƯƠNG 1. KHẢO SÁT, ĐẶC TẢ YÊU CẦU BÀI TOÁN

<Trình bày, mô tả chi tiết về các kết quả khảo sát về bài toán – thông qua đề bài và
những yêu cầu từ giáo viên sau những lần trao đổi, gặp mặt>
<Đặc tả yêu cầu bài toán bao gồm:
- Biểu đồ use case tổng quan
- Biểu đồ use case phân rã cho các chức năng phức tạp.
- Đặc tả use case cho những use case chính, nghiệp vụ quan trọng của bài toán>

1.1. Mô tả yêu cầu bài toán


<Mô tả bằng lời về bài toán được giao>
 Người chơi điều khiển một hoặc nhiều nhân vật trong một bản đồ được
lưu trong một cấu trúc dữ liệu, ví dụ: mảng hai chiều như hình bên, trong
đó mỗi ô tương ứng với một dạng bản đồ khác nhau (đất, cỏ, nước…)
 Trên bản đồ có các quái vật có thể di chuyển được. Các nhân vật người
chơi điều khiển và quái vật có các chỉ số xác định tình trạng và thể lực (ví
dụ HP, MP, Attack, Defense, Speed…).
 Người chơi có thể tấn công quái vật và sử dụng các kỹ năng đặc biệt.
Tương tự, quái vật cũng có thể tìm đến và tấn công người chơi.
 Người chơi có thể di chuyển qua lại giữa các bản đồ khác nhau (ví dụ khi
đi vào vùng M0, M1, M2… trên bản đồ) hoặc đi đến kết thúc của trò chơi
(ví dụ khi đi vào vùng END trên bản đồ).
 Quái vật có khả năng di chuyển và tấn công người chơi (quái vật có thể
chia thành nhiều loại: tấn công gần, loại có thể tấn công/bắn đạn từ xa,
boss, …).
 Game có hai chế độ chơi dễ / khó theo mức độ “thông minh”, “di chuyển
nhanh” hoặc “lượng máu” của quái vật.

1.2. Biểu đồ use case


1.2.1. Biểu đồ use case tổng quan
<Vẽ và giới thiệu qua về biểu đồ use case tổng quan>

Nhóm 11 7
IT3100 – Lập trình hướng đối tượng 20202

1.2.2. Biểu đồ use case phân rã mức 2


<Vẽ và giới thiệu qua biểu đồ use case phân rã cho những use case phức tạp>

Nhóm 11 8
IT3100 – Lập trình hướng đối tượng 20202
1.3. Đặc tả use case
<Đặc tả cho 2-4 use case chính, biểu thị cho những nghiệp vụ quan trọng của bài toán>
<Có thể có phần này hoặc không; với những nghiệp vụ phức tạp, có thể vẽ thêm biểu
đồ hoạt động>
1.1.1. Use case Start.

Tên Use-Case Start

Mô tả Khởi động một lần chơi mới của game

Sự kiện kích hoạt Người dùng chọn vào biểu tượng Start trên giao diện Menu chính

Actors Người dùng

Use-Case liên quan Choose Character, Difficulty, Play game.

Thiết bị của người dùng đã cài đặt game và thỏa mãn những yêu
Tiền điều kiện
cầu về phần cứng.

Lần lượt giao diện chọn nhân vật và chọn độ khó hiện ra để
Hậu điều kiện
người dùng thiết lập, sau đó giao diện Game hiện ra.

- Người chơi lựa chọn một trong các nhân vật đã sở hữu.
Biến thể - Người chơi lựa chọn một trong các độ khó có sẵn.
- Người chơi mở khóa nhân vật chưa sở hữu.

- Người chơi muốn chọn nhân vật chưa sở hữu.


Ngoại lệ
- Người chơi chọn “Back” để hủy lệnh Start.

1.1.2. Use Case Load game

Tên Use-Case Load game

Mô tả Người chơi muốn tiếp tục phần chơi cũ đã được lưu.


Người dùng chọn vào biểu tượng Load game trên giao diện
Sự kiện kích hoạt
Menu chính
Actors Người dùng

Use-Case liên quan Play game, Save game

Nhóm 11 9
IT3100 – Lập trình hướng đối tượng 20202

Thiết bị của người dùng đã cài đặt game và thỏa mãn những yêu
Tiền điều kiện cầu về phần cứng, có ít nhất một bản lưu mà người chơi đã lưu
lại trong quá trình chơi trước.

Giao diện Game hiện ra với thông tin nhân vật cũng như các
Hậu điều kiện
thuộc tính cũ của nhân vật có được từ lần chơi trước đó.

- Người chơi lựa chọn một trong các bản lưu game mà người
Biến thể
chơi lưu lại từ những lần chơi trước.

- Không có bản lưu game nào.


Ngoại lệ
- Người chơi chọn “Back” để hủy lệnh Load game.

1.1.3. Use Case Play Game

Tên Use-Case Play Game

Là chế độ chơi chính của game. Ở Use-case này, người dùng sẽ


Mô tả
điều khiển nhân vật để thực hiện thử thách của trò chơi
Người dùng chọn chế độ Start để tạo một màn chơi mới.
Sự kiện kích hoạt
Người dùng chọn chế độ Load game để quay lại màn chơi cũ.
Actors Người dùng

Use-Case liên quan Choose Character, Difficulty, Load game, Save Game, Exit

Thiết bị của người dùng đã cài đặt game và thỏa mãn những yêu
Tiền điều kiện cầu về phần cứng. Người dùng đã thiết lập nhân vật và độ khó từ
trước.

Màn hình trò chơi hiện ra các hoạt ảnh của trò chơi, người dùng
Hậu điều kiện có thể điều khiển nhân vật chính, sử dụng các kỹ năng, tiêu diệt
quái vật, thực hiện thử thách.

- Người chơi đã thiết lập các dữ liệu về nhân vật và độ khó của
trò chơi.
- Người dùng sử dụng giao diện Pause để thiết lập các tùy chọn
Biến thể
về âm thanh và tiến hành Save Game.
- Người chơi mở giao diện kho đồ để kiểm tra số lượng và sử
dụng item.
Nhóm 11 10
IT3100 – Lập trình hướng đối tượng 20202

- Người chơi tiêu diệt quái vật và hoàn thành game.


Ngoại lệ - Người chơi của nhân vật có lượng HP bị giảm về 0.
- Người chơi chọn về giao diện Menu chính.

Nhóm 11 11
IT3100 – Lập trình hướng đối tượng 20202

CHƯƠNG 2. PHÂN TÍCH THIẾT KẾ BÀI TOÁN

2.1. Thiết kế Cơ sở dữ liệu hoặc Cấu trúc tệp dữ liệu


2.1.1. Dữ liệu hình ảnh
Các hệ thống tương tác như Menu chính, Menu pause, Menu win, hệ thống chọn
độ khó, chọn nhân vật được xây dựng dựa trên các ảnh và background có sẵn
được tải từ OpenGameArt.org. Các giao diện này được tạo bằng các in các lớp
ảnh theo thứ tự lên sân khấu của JavaFX dựa trên thiết kế ban đầu và các chỉnh
sửa trong quá trình phát triển. Các file ảnh để tạo các hệ thống tương tác này
được lưu riêng vào một thư mục giúp dễ dàng tìm kiếm và chỉnh sửa trong quá
trình phát triển game The Lone Avenger.

Về việc xây dựng bản đồ cho game The Lone Avenger là một quá trình kì công
và mang đầy tính sáng tạo. Chúng em tải các tileset game 32x32 được chia sẻ
miễn phí trên OpenGameArt.org sau đó sử dụng ứng dụng phầm mềm thiết kế
bản đồ game Tiled để ghép những mảnh bản đồ này với nhau theo sự sáng tạo
riêng để tạo thành 4 bản đồ cho game của mình.

Nhóm 11 12
IT3100 – Lập trình hướng đối tượng 20202

Nhóm 11 13
IT3100 – Lập trình hướng đối tượng 20202

Về nhân vật, hệ thống NPC, boss, quái vật, hiển thị hình ảnh các kỹ năng, …
Chúng em sử dụng các tấm ảnh dạng sprite để tạo ra các animation chuyển động
của các thực thể trên.

2.1.2 Dữ liệu âm thanh


Tất cả các âm thanh được sử dụng trong game được tải từ nhiều nguồn khác
nhau. Các file âm thanh được sử dụng đều có định dạng .wav và được quản lý ở
Nhóm 11 14
IT3100 – Lập trình hướng đối tượng 20202
tệp sounds. Có nhạc nền game, nhạc nền menu, âm thanh khi chiến thắng, âm
thanh khi thua trận, âm thanh kỹ năng, … Âm nhạc là một phần không thể thiếu
của game, nó giúp game thêm thú vị, sinh động và giúp người chơi thư giãn.

2.2. Biểu đồ trình tự


<Vẽ và giới thiệu qua về biểu đồ trình tự cho 1-2 use case chính, biểu thị nghiệp vụ
quan trọng của bài toán>
Phải làm
Trong game The Lone Avenger, 2 use case chính mà mọi người chơi sẽ trải qua nhiều
nhất đó chính là việc chơi game mới và chơi game đã được lưu.

Nhóm 11 15
IT3100 – Lập trình hướng đối tượng 20202

Fig...biểu đồ tuần tự mô tả quá trình từ lúc player bật game đến lúc chơi game

Khi người chơi muốn chơi game mới, người chơi cần phải chọn nút start game, sau đó
chọn character và độ khó qua 2 scene đó là CharacterScene và DifficultyScene được
điều khiển bới các controller của chúng. Hệ thống sẽ tạo ra game mới dựa vào
character và độ khó được chọn sau đó hiển thị trên GameScene được điều khiển bới
GameController. Sau đó game sẽ bắt đầu vòng lặp, mỗi vòng lặp , hệ thống sẽ lắng
nghe những chỉ thị của người chơi để điều chỉnh những thuộc tính trong game, đồng
thời màn hình sẽ được xóa đi vẽ lại.

Nhóm 11 16
IT3100 – Lập trình hướng đối tượng 20202

Fig: biểu đồ tuần tự miêu tả quá trình player chọn phần game mình đã save đến lúc
chơi game
Quá trình người chơi muốn chọn phần đã lưu chơi tiếp cơ chế giống với quá trình trên
chỉ khác là lần này người chơi phải chọn vào nút load game để mở cửa sổ load game
ứng với LoadScene, người chơi chọn vào phần game mình đã lưu sau và chọn nút
continue, lúc này hệ thống sẽ nạp những thuộc tính của nhân vật như character,cấp,
máu, phòng thủ.... cùng với thuộc tính của map như difficulty, để tạo thành 1 thực thể
game mới.

2.3. Biểu đồ gói và biểu đồ lớp


<Vẽ và giới thiệu về gói, các lớp, mối quan hệ trong Biểu đồ lớp>
<Chỉ rõ mỗi lớp nằm ở tầng nào: cơ sở dữ liệu/nghiệp vụ/giao diện. Nếu cần, tách làm
nhiều biểu đồ lớp một cách hợp lý để trình bày tốt hơn>

2.3.1. Hệ thống các package


 Class Laucher và class StartApp: class Laucher chứa lệnh main là class thực thi
của chương trình có nhiệm vụ tạo ra 1 instance của class StartApp để bắt đầu
game, việc chia ra 2 class nhằm giúp code gọn hơn và thuận lợi trong việc test.

Nhóm 11 17
IT3100 – Lập trình hướng đối tượng 20202
 Package scene: chứa các cảnh của chương trình ứng với từng scene class khi
người chơi điều hướng.
 Package controller: chưa các class controller, mỗi controller ứng với 1 scene ở
trong package scene, giúp thu nhận những tín hiệu, thao tác của người chơi để
vận hành chương trình.
 Package setting: package này chỉ chứa 1 class đó là class Setting, hiện tại class
này chỉ có tác dụng lưu trữ giá tiền của các skin trong game, nhưng bọn em vẫn
để ở đó cho những mục đích phát triển sau này.
 Package sounds: package này chứa các class lưu trữ và điều phối âm thanh,
thay đổi, bật tắt của cả game.
 Package game: package này chứa các tài nguyên game khi ta chơi, chứa vòng
lặp và chịu trách nghiệm xử lý các sự kiện khi ta chơi.
 Package util: chứa 2 class Util và HandlerApp, Util chứa các lệnh tĩnh hay được
dùng ở các class khác như nhập xuất nhằm tránh việc lặp lại code, HandlerApp
giúp các class trong chương trình có thể giao tiếp tốt được với nhau

2.3.2. Biểu đồ lớp

2.4. Thiết kế chi tiết lớp


2.4.1. Class Laucher và class Game

Nhóm 11 18
IT3100 – Lập trình hướng đối tượng 20202

Game được chạy từ hàm main() trong class Launcher, trong hàm main, 1 instance của
class StartApp sẽ được khởi tạo sau đó sẽ gọi đến hàm launchGame của StartApp.
Do đây là ứng dụng sử dụng javafx nên class StartApp sẽ extend Application. Khi hàm
lauchGame được gọi sẽ làm hàm init() bắt đầu, các tài nguyên như hình ảnh âm thanh,
các file được lưu sẽ nạp vào game khiến quá trình chơi game sẽ mượt mà hơn. Khi
hàm init() gọi xong, hàm start() sẽ được gọi kế tiếp, với tham số nhận vào là object
stage, cảnh đầu của game (startScene) sẽ dược tạo và được gán cho stage để hiển thị.

2.4.2. Package game


2.4.2.1: Class GameManager

Nhóm 11 19
IT3100 – Lập trình hướng đối tượng 20202

Về cơ bản, game của chúng em hoạt động dựa trên một vòng lặp để cập nhật tất cả
các chỉ số và vẽ ra màn hình, mỗi khung hình của game sẽ là một lần lặp. Khi người
chơi bắt đầu chơi, phương thức start() sẽ được gọi. Trong phương thức start(), đầu tiên,
sẽ gọi tới phương thức init() để khởi tạo hình ảnh bản đồ, khởi tạo các đối tượng trong
game, sau đó khởi tạo đối tượng myTimer của class AnimationTimer để bắt đầu vòng
lặp. Class AnimationTimer là một class có sẵn trong JavaFX, khi sử dụng cần override
lại phương thức handle(long l), đây chính là nơi vòng lặp diễn ra. Trong vòng lặp sẽ có
2 phương thức chính cần gọi đi gọi lại, cũng là 2 phương thức cần thiết để game có thể
hoạt động được: tick() và render().
- Về phương thức tick(): Tick() là phương thức không thể thiếu của mọi đối
tượng trong game, từ người chơi, quái, cho đến những đối tượng khác như bản
đồ, các world, đối tượng quản lý input của người chơi,… Tất cả đều phải có
phương thức này để cập nhật lại thông số của nó trong game, từ đó vẽ ra màn
hình trong khung hình kế tiếp. Phương thức này có nhiệm vụ gọi tới tick() của
GameState, từ đó gọi tới các tick() của đối tượng khác để xử lý.

- Về phương thức render(): Tương tự như tick(), phương thức này là một trong
hai phương thức quan trọng của mọi đối tượng trong game. Sau khi cập nhật
các thông số bằng tick(), từ các thông số ấy mà render() in ra màn hình bằng
cách vẽ lên Node Canvas. Node Canvas là một Node trong JavaFX, với width,
height bằng width, height của game, nó giống như một tờ giấy trắng và mỗi
frame tương tự như một bức tranh. Sau khi các thông số được khởi tạo trong
RAM, nó sẽ thể hiện các thông số lên Canvas tạo thành một frame, rồi lại xoá
đi vẽ frame kế tiếp thông qua vòng lặp. Ví dụ như tại một thời điểm sau khi cập
nhật bằng tick(), nhân vật đang ở vị trí A, nó sẽ vẽ nhân vật ra vị trí có toạ độ là
A, tương tự như quái, map,… Tất cả sẽ được vẽ ra tạo thành một frame của
game.
Nhóm 11 20
IT3100 – Lập trình hướng đối tượng 20202

Nhóm 11 21
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.2: Class Handler

Để có thể get/set các thuộc tính một cách thuận tiện nhất, chúng em tạo ra class
Handler. Đây là một class chứa các getter và setter để có thể truy cập dễ dàng mà
không cần phải nhớ xem một thuộc tính nằm ở class nào, mà chỉ cần gọi tới đối tượng
handler và gọi tới thuộc tính cần sử dụng.

2.4.2.3: Package state

GameState là một state chính của game. Đây là một class để khởi tạo các World
ứng với các tầng. Chúng em tạo một mảng World, trong đó có world[0] chính là world
chỉ tầng hiện tại. Bên cạnh đó, GameState còn khởi tạo các class quản lý thực thể là
EntityManager ứng với các World. Mỗi World sẽ có một EntityManager tương ứng, và
con các quái cũng được tạo ra, đặt vị trí và thêm vào các EntityManger tương ứng tại
class này. Phương thức tick() gọi tới tick() của world[0] là world hiện tại để cập nhật
các thông số của nhân vật, quái trong entityManger tương ứng. Sau đó từ thông số trên
mà vẽ ra màn hình thông qua phương thức render(). Đây cũng chính là nơi vẽ giao
diện chính cho game như: Vị trí các button, thanh máu của nhân vật, bảng kỹ năng của
nhân vật và chỉ số vàng kiếm được.

2.4.2.4: Package worlds

Nhóm 11 22
IT3100 – Lập trình hướng đối tượng 20202

World là class chịu trách nhiệm quản lý các thực thể, các đồ vật tại world mà
nhân vật đang ở. Vị trí world nhân vật đang ở được đánh dấu bởi countWorld, thông
qua đây mà xác định được chỉ số của world trong mảng World[] được tạo trong
GameState. Mỗi World sẽ có một EntityManger, ItemManger khởi tạo trong
constructor dùng để quản lý các nhân vật, quái, các đồ vật như bình máu, bình tốc độ,
… Phương thức tick() sẽ gọi tới tick() của EntityManager, ItemManger, qua đó cập
nhật lại List các nhân vật, quái, kiểm tra xem nhân vật hay quái đã chết chưa rồi in ra
thông qua render(). Phương thức getTile() sẽ trả về Tile mà vị trí xác định nằm trong,
từ đó đặt ra các block dùng để ngăn nhân vật không thể đi vào được. Phương thức
loadWorld() sẽ đọc giá trị từ file txt chứa width, height là chiều dài, độ cao của map, vị
trí mà nhân vật xuất hiện khi bắt đầu vào World và vị trí của các vật trang trí cho map.

Nhóm 11 23
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.5: Package maps

Package này chính là nơi in ra toàn bộ bản đồ của game. Trong đó có Class Tile
được hiểu như một ô trong maps, nó chứa biến image là hình ảnh của ô, và id để đánh
id cho ảnh tương ứng. Class này chứa phương thức init() để khởi tạo tất cả các đối
tượng cho map: từng hình ảnh, vị trí RockTile hay gọi là block. Vì các thông số này
không có sự thay đổi nên phương thức tick() không làm gì cả, còn render() sẽ in các
hình ảnh ra màn hình. Bên cạnh đó còn có isSolid() mặc định trả về false để báo nhân
vật có thể đi vào ô này, và isCheckPoint() mặc định trả về false để báo đây không phải
điểm dịch chuyển giữa các World.
Kế thừa Class Tile gồm các class:
- CheckPoint: Với image là một điểm dịch chuyển, giá trị isCheckPoint() trả về
true. Khi nhân vật đi tới ô này, nhân vật sẽ dịch chuyển sang world tương ứng.
- RockTile: Với image là một ảnh trong suốt dùng để đè lên map, giá trị isSolid()
trả về true để báo rằng nhân vật không thể đi vào ô này.
- Các class ArchitectureMap1, 2, 3, 4: Đây là class gồm tập hợp tất cả các ô để
tạo nên một Map cho World. Ở đây chúng em sử dụng phần mềm Tiled, dựa
trên một sheet ảnh gồm các ô có sẵn trên mạng để ghép thành một map của
riêng mình.

Nhóm 11 24
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.6: Package items

- Class Item: Class định nghĩa các vật phẩm trong game như bình máu, bình tốc
độ, bình sức mạnh. Các vật phẩm này được rơi ngẫu nhiên sau khi nhân vật giết
quái. Các phương thức tick(), render() để cập nhật và in ra màn hình các vật
phẩm. Phương thức createNew() tạo ra vật phẩm với id tương ứng để thêm vào
List các vật phẩm trong ItemManager. Bên cạnh đó còn có phương thức use()
để dựa vào id mà xác định tác dụng của vật phẩm. Tác dụng của vật phẩm cũng
có thể được xem chi tiết thông qua phương thức printDetail().
- Class ItemManager: Class này dùng để quản lý các vật phẩm khi game được bắt
đầu. Các vật phẩm được quản lý bằng ArrayList<Item>, chứa các vật phẩm để
tick() và render() lần lượt các phần tử. Nếu một vật phẩm được nhặt thì biến
pickedUp sẽ được set thành true, và xoá khỏi List thông qua tick(). Mỗi khi
quái chết thì một vật phẩm sẽ xuất hiện ngẫu nhiên và được thêm vào List thông
qua phương thức addItem().

Nhóm 11 25
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.7: Package inventory

Class Inventory dùng để quản lý các vật phẩm mà nhân vật hiện có trong game.
Bên cạnh đó, class cũng quản lý một phần giao diện túi vật phẩm khi người chơi bấm
nút F. Với các thuộc tính invX, invY, invWidth, intHeight dùng để xác định vị trí giao
diện của túi để in ra màn hình. Biến selectedItem dùng để chỉ ra vật phẩm mà người
chơi đang trỏ tới, từ đó có thể sử dụng vật phẩm thông qua nút Enter. Phương thức
tick() và render() dùng để cập nhật các chỉ số và in ra màn hình giao diện của túi vật
phẩm. Phương thức scrollUp(), scrollDown() là 2 phương thức xử lý logic khi người
chơi chọn các vật phẩm trong túi. Ví dụ khi đang ở đầu danh sách mà người chơi bấm
mũi tên lên để chọn vật phẩm trên thì con trỏ sẽ chỉ tới vật phẩm ở cuối cùng danh
sách và ngược lại. Còn nếu không ở đầu hay cuối danh sách thì con trỏ di chuyển bình
thường theo input của người chơi. Phương thức addItem() để thêm vật phẩm vào List
quản lý và tăng số lượng vật phẩm trong túi lên mỗi khi nhân vật nhặt vật phẩm. Còn
phương thức useItem() sẽ xác định số lượng vật phẩm còn lại, khi người chơi dùng
một vật phẩm thì số vật phẩm còn lại trừ đi 1, đến khi về 0 thì sẽ không thể dùng được
nữa.

Nhóm 11 26
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.8: Package input

Đây là package chứa 2 class xử lý sự kiện của game với nhiệm vụ: xử lý việc
người chơi nhập từ bàn phím và xử lý các thao tác của người chơi tới chuột.
- KeyManager: Class này với nhiệm vụ quản lý việc người chơi sử dụng bàn
phím. Ví dụ như khi người chơi bấm phím Q, thì một giá trị boolean trong
HashMap của phím Q tương ứng sẽ trả về true. Từ đó trong class kỹ năng của
nhân vật, điều kiện if(Q được nhấn) thoả mãn, nhân vật sẽ sử dụng kỹ năng
được gán cho phím Q. Để làm được điều ấy, class KeyManager sẽ có một
HashMap<KeyCode, Boolean> là keys để lưu trữ giá trị theo cặp: KeyCode –
Boolean. Lý do chúng em sử dụng HashMap để lưu trữ là vì HashMap có một
method getOrDefault(). Method này là của Map interface, được implemented
bởi HashMap có nhiệm vụ lấy giá trị đã gán với một key nhất định, ở đây là
Boolean. Nếu chưa có giá trị nào được gán thì giá trị mặc định (false) sẽ được
trả về. Từ đó xác định ra người chơi đã nhấn phím hay chưa. Để có thể gắn
KeyManager vào game, chúng em sử dụng phương thức addListener() với tham
số truyền là scene game, gắn vào scene game thông qua addEventFilter() là một
phương thức do JavaFX cung cấp. Trong method addListener() sẽ thêm hai sự
kiện là: nhấn phím và thả phím. Khi nhấn phím, chúng em đưa KeyCode của
phím và giá trị true vào HashMap, và với sự kiện thả phím, chúng em đưa
KeyCode của phím và giá trị false vào trong HashMap.

- Class MouseManager: Tương tự như cơ chế xử lý của Class KeyManger. Class


MouseManager có nhiệm vụ quản lý việc người chơi sử dụng chuột. Cụ thể là
người chơi đã bấm phím chuột trái, phải chưa, con trỏ chuột đã di tới đâu,…
Tất cả đều được xử lý trong class này. Do chuột chỉ có 2 nút nên ở đây chúng
em quyết định không sử dụng HashMap nữa, thay vào đó chỉ sử dụng 2 biến
leftPressed và rightPressed. Còn lại cơ chế tương tự trong phương thức
addListener() của KeyManager: Khi nhấn phím chuột trái thì set giá trị
leftPressed là true, khi thả ra thì set giá trị leftPressed là false.

Nhóm 11 27
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.9: Package gfx


Đây là package xử lý đồ hoạ chính của game: Từ các đơn vị nhỏ nhất như ảnh
của các ô, cho tới hệ thống ảnh của nhân vật, quái, chuyển động của nhân vật, quái, và
cả xử lý camera sao cho nhân vật phải ở giữa màn hình của game.
- Class Assets, ImageLoader, SpriteSheet

Ba class này phụ trách chứa toàn bộ ảnh để có thể sử dụng trong game. Class
ImageLoader chỉ chứa phương thức loadImage(), dùng để load ảnh từ đường dẫn
String là một tham số đầu vào. Bên cạnh đó, với những ảnh ở dạng một sheet (dùng
cho chuyển động của nhân vật) thì class SpriteSheet này với nhiệm vụ xử lý với
phương thức crop() để cắt ảnh tuỳ theo toạ độ, Sau đó, class Assets sẽ khởi tạo đối
tượng ảnh cần thiết như player, mobs, các buttons,… và lưu dưới dạng một đối tượng
static để có thể truy cập trực tiếp thông qua class này.
- Class SpriteAnimation, ImageAnimation

Hai class này phụ trách việc tạo ra chuyển động cho nhân vật. Dựa trên cơ chế
như chuyển động của hoạt hình trên phim, nhân vật sẽ có các ảnh lặp nối tiếp nhau,
mỗi khung hình của game sẽ hiển thị một ảnh, liên tục như vậy sẽ tạo ra chuyển
động cho nhân vật cũng như hệ thống quái của game. Thường thì các ảnh của nhân
vật như vậy sẽ được đặt trong một tấm duy nhất tạo thành Spritesheet. Để tạo ra
chuyển động, chúng em tạo class SpriteAnimation kế thừa class Transition với
nhiệm vụ chỉ hiển thị một góc của Spritesheet, và liên tục di chuyển góc hiển thị
thông qua phương thức interpolate() là một phương thức phải override khi kế thừa
Transition. Chúng em sẽ lấy view port là một hình chữ nhật với width, height bằng

Nhóm 11 28
IT3100 – Lập trình hướng đối tượng 20202
width, height của nhân vật, sau đó view port sẽ được liên tục dịch chuyển dựa trên
offsetX và offsetY.
Tuy nhiên, do dữ liệu ảnh các nhân vật chúng em lấy từ trên mạng, thì bên cạnh
cách lưu trữ ảnh theo Spritesheet, còn có một kiểu nữa là lưu dưới dạng một folder
gồm rất nhiều ảnh tương ứng với một view port. Do do chúng em tạo thêm một
class nữa song song với SpriteAnimation là class ImageAnimation. Về cơ chế thì
class này sẽ lấy các ảnh của nhân vật từ class Assets, các ảnh này được lưu dưới
một mảng các ảnh. Mảng này sẽ được duyệt liên tục, từ đó dựa trên tốc độ khung
hình mà phương thức getCurrentFrame() sẽ liên tục trả về một ảnh với index tương
ứng trong mảng ảnh đã tạo.

Nhóm 11 29
IT3100 – Lập trình hướng đối tượng 20202

2.4.2.10: Package entities

Đây là package chứa hệ thống tất các nhân vật, quái, NPCs, hay những cây cối,
đá, vũ khí, đạn… trong game. Về cơ bản, các thuộc tính mặc định của mọi thực thể
như máu, giáp, hay trạng thái sống/chết active sẽ nằm trong lớp trừu tượng Entity, từ
đó, các lớp khác sẽ kế thừa lớp này và thêm thuộc tính đặc trưng khác.
- Class Entity: Lớp trừu tượng này dùng để định nghĩa một thực thể một cách
tổng quát nhất với các thuộc tính là máu, giáp, trạng thái sống/chết. Class này có
phương thức trừu tượng tick(), render(), die() bắt buộc các class kế thừa phải override.
Nhóm 11 30
IT3100 – Lập trình hướng đối tượng 20202
Bên cạnh đó class này còn có phương thức takeDamage() với tham số đầu vào là một
giá trị amount. Ví dụ khi một đối tượng thuộc class con của class Entity va chạm với
đạn bắn ra, thì takeDamage() sẽ nhận tham số là damage của viên đạn, từ đó trừ vào
máu của đối tượng ấy, đến khi về 0 thì sẽ set active thành false đồng nghĩa với đối
tượng đã chết. Hai phương thức dùng để kiểm tra va chạm là getCollisionBounds() và
checkEntityCollision(). Cụ thể là mỗi thực thể sẽ có một bounds là hình chứ nhật bao
quanh, và phương thức getCollisionBounds() sẽ trả về bounds này. Việc sử dụng
bounds này sẽ khiến cho kiểm tra va chạm giữa 2 thực thể dễ dàng hơn. Thay vì phải
kiểm tra xem lọn tóc này va chạm với cái gì, ngón tay này chạm tới đạn chưa,… chúng
em quy về kiểm tra các hình chữ nhật đã va chạm, hay là đã đè lên nhau chưa. Để
kiểm tra va chạm giữa 2 hình chữ nhật, JavaFX đã cung cấp phương thức intersects().
Do đó trong phương thức checkEntityCollision() chúng em chỉ cần lấy bounds thông
qua getCollisionBounds() và lần lượt kiểm tra với các đối tượng trong List nhân vật.
- Package creatures: Package này sẽ chứa các lớp định nghĩa các thực thể có thể
chuyển động như người chơi, quái, hay những viên đạn, vũ khí.
+ Class Creature: Lớp trừu tượng này dùng để định nghĩa các Entity có thể di
chuyển và gây damage với các thuộc tính là speed, damage và direction chỉ
hướng di chuyển. Class này có phương thức move(), với xMove và yMove là 2
gia tốc đối với toạ độ x và y. Tuỳ theo mục đích mà tăng giảm xMove, yMove
để nhân vật thay đổi toạ độ, từ đó tạo thành hành động di chuyển. Các đối
tượng của lớp Creature có thể gây sát thương thông qua phương thức
checkAttacks(), cụ thể khi trong vòng tấn công thì phương thức takeDamage()
của đối tượng bị tấn công sẽ gọi tới với tham số là damage của đối tượng tấn
công.
+ Class Player: Kế thừa class Creature là class Player, class định nghĩa nhân vật
của người chơi. Bên cạnh những thuộc tính được kế thừa, class Player có thêm
thuộc tính mới là skillManager để quản lý các kỹ năng của nhân vật. Phương
thức getInput() sẽ kiểm tra phím nào được nhấn, từ đó set các giá trị cho
direction, xMove, yMove để di chuyển nhân vật. Do chúng em tạo ra các World
khác nhau, và chỉ có nhân vật mới có thể di chuyển qua lại giữa các World nên
class Player có thêm phương thức checkPointMove(), kiểm tra xem đã đi vào ô
CheckPoint chưa, nếu rồi thì sẽ thay đổi toàn bộ bản đồ, quái sang World mới.
Để sử dụng các kỹ năng của mình, chúng em sẽ lấy input từ bàn phím để kiểm
tra xem người chơi đã nhấn phím kỹ năng Q, W, E, R chưa, nếu rồi thì kích
hoạt kỹ năng trong List và tính thời gian cool down để tái kích hoạt.
+ Class Enemy: Đây là một lớp trừu tượng kế thừa class Creature với nhiệm vụ
định nghĩa ra các con quái. Việc tạo di chuyển cho quái thì chúng em tạo 2
phương thức: chasePlayerMove() và backHomeMove(). Do thời gian không đủ
nên chúng em chưa áp dụng các giải thuật tìm đường cho quái, dẫn đến việc
nếu đứng cách nhau một bức tường thì quái không thể đi đường vòng để đến
chỗ người chơi. Cụ thể phương thức chasePlayerMove() sẽ kiểm tra khoảng
cách giữa người – quái, các vùng trong khoảng cách này tạo thành một zone.
Nếu nhân vật nằm trong zone của quái thì quái sẽ di chuyển tới vị trí của nhân
vật. Còn nếu nhân vật không nằm trong zone của quái thì quái sẽ trở về toạ độ
sinh của nó (homeX, homeY) và thực hiện phương thức selfRecovery() để hồi
lại máu nếu máu của quái bé hơn máu tối đa. Ngoài ra, class Enemy còn có một
phương thức nữa là respawn(). Phương thức này sẽ kiểm tra khi active = false,
sẽ tạo ra một Thread. Thread vừa tạo sẽ sleep trong một thời gian gọi là

Nhóm 11 31
IT3100 – Lập trình hướng đối tượng 20202
respawn cool down. Sau khi cool down xong thì Thread này sẽ chạy dòng lệnh
tạo một đối tượng quái mới tại vị trí (homeX, homeY), từ đó quái được hồi
sinh. Ở đây, mỗi khi quái hồi sinh, chúng em gặp phải một lỗi
ConcurrentModificationException khi remove/add vào ArrayList. Đây là một
lỗi thường gặp khi con trỏ List đang duyệt thì bị thay đổi kích thước của List.
Để khắc phục vấn đề này, chúng em tạo thêm một List tạm trong
EntityManager, để cho quái mới hồi sinh thêm vào List tạm sau đó mới thêm
vào List quản lý sau khi List quản lý duyệt xong.
+ Class Skeleton, Slime, Witch, Boss: Đây là các class thể hiện quái: quái
xương, quái slime, phù thuỷ và boss. Để phân biệt cũng như tăng độ đa dạng
cho quái, chúng em cho quái xương và slime sẽ chỉ có thể đánh gần, còn phù
thuỷ và boss sẽ bắn được đạn. Thêm nữa vòng tấn công của boss
+ Package weapons: Đây là package chứa các vũ khí, các chưởng của nhân vật
cũng như của quái. Trong đó có lớp trừu tượng Weapon, với các biến xLong,
yLong dùng để xác định quãng đường đạn, kiếm,... đi được. Nếu đi quá xLong,
yLong thì sẽ set active = false để xoá đạn, kiếm,… ra khỏi List. Class Weapon
sẽ override lại phương thức move(), thêm vào đó là khi va chạm với vật cản,
hay tấn công trúng nhân vật, quái thì sẽ set active = false và dừng move(), tránh
hiện tượng đạn đâm vào tường nhưng không biến mất. Thể hiện của lớp
Weapon là các lớp con Bullet, FireRing, Spell, Sword với hình ảnh, xLong,
yLong, sát thường khác nhau.
+ Package skills: Đây là package thiết kế kỹ năng cho nhân vật cũng như quái,
boss. Với lớp trừu tượng Skill có phương thức trừu tượng attack() và
showCountDown() sẽ thiết kế phương thức gây sát thương cùng với thời gian
hồi chiêu của kỹ năng. Để quản lý các kỹ năng này, chúng em tạo thêm một lớp
nữa là class SkillManager. Class này có nhiệm vụ quản lý các kỹ năng, các thể
hiện của kỹ năng như đối tượng của class Bullet, Sword,… các buff nhân vật,…
trong một List gọi là skillArray. Cuối cùng là các class kỹ năng chi tiết như
BulletSkill, SaydaSkill, SwordSkill sẽ được thiết kế bằng cách override lại
phương thức attack().
+ Package npc: Đây là package thiết kế các NPCs trong game. Các NPCs này
chỉ có nhiệm vụ làm game thêm sinh động và tạo cốt truyện cho game. Để cụ
thể hoá việc này, chúng em tạo ra lớp NPC. Lớp này có biến dialogue là những
câu nói của NPCs, khi nhân vật hỏi, những câu nói này sẽ được in ra màn hình
trong khoảng thời gian ngắn, thể hiện các nhân vật nói chuyện với nhau. Về
việc thiết lập di chuyển cho các NPCs, chúng em sử dụng Thread bằng cách tạo
một biến random nhận giá trị từ 1 đến 4 tương ứng với các hướng lên, xuống,
trái, phải. Từ các hướng tương ứng sẽ set giá trị xMove, yMove phù hợp. Sau
khi random được một số thì sẽ tạm dừng bằng Thread.sleep(). Từ đó tạo ra việc
chuyển động liên tục của các NPCs. Thêm vào đó, mỗi khi đứng gần nhân vật,
chúng em sẽ có NPCs ngưng random, tạm dừng chuyển động để đứng nói
chuyện cùng nhân vật bằng phương thức playDialogue(). Các class NPCs kế
thừa lớp trừu tượng NPC sẽ có hình ảnh các nhân vật khác nhau, tạo sự đa dạng
cho trò chơi.

2.4.3. Package sounds

Nhóm 11 32
IT3100 – Lập trình hướng đối tượng 20202

Bên cạnh hệ thống hình ảnh, chúng em cũng thiết kế thêm phần âm thanh cho
game của mình. JavaFX đã cung cấp rất đầy đủ các phương thức cần thiết cho âm
thanh này. Ở đây chúng em tạo class Sound chứa toàn bộ âm thanh dưới type Media.
Khi cần phát một file âm thanh, chúng em sẽ phát đối tượng âm thanh thích hợp đã
khởi tạo trong class Sound thông qua phương thức playSound(). JavaFX cũng cung
cấp phương thức play() để phát file âm thanh, tuy nhiên khi muốn phát lại âm thanh đã
phát thì sẽ không thể phát được nữa, do đó chúng em tạo phương thức này để khắc
phục vấn đề ấy. Sau khi phát xong thì sử dụng phương thức dispose() sẵn có để giải
phóng bộ nhớ.
Để lưu âm thanh dưới type Media mà JavaFX đã cung cấp, chúng em tạo thêm
một class SoudLoader với phương thức loadSound() để khởi tạo âm thanh. Cụ thể là
với tham số là đường dẫn tới file .wav để trong thư mục resources, thông qua phương
thức này sẽ trả về đối tượng Media từ đường dẫn này.
Sau đó các âm thanh sẽ được quản lý bằng List sounds trong class
SoundManager với các phương thức quản lý: addSounds() để thêm âm vào List,
soundOff() để tắt âm, muteAll() để tắt toàn bộ âm thành của game, unMuteAll() để bỏ
tắt toàn bộ âm.

2.4.4. Package scene và package controller

Nhóm 11 33
IT3100 – Lập trình hướng đối tượng 20202

Nhóm 11 34
IT3100 – Lập trình hướng đối tượng 20202
Trong game, chúng em sử dung hệ thống scene cho mỗi menu mà người chơi đang ở,
ví dụ như menu chọn nhân vật, giao diện khởi đầu.... Mỗi scene sẽ được kết hợp với 1
class controller, 1 file fxml, 1 file css tương ứng giúp cho người chơi có trải nghiệm
tốt nhất, scene hiển thị dựa trên fxml và css, controller điều khiển những tác vụ bên
trong.
Mỗi controller sẽ gồm contructor, các thuộc tính như Button, ProgressBar,.. có tên lấy
từ id của thuộc tính đó trong file fxml.
 Class SceneFx: là 1 class abstract, nó bao gồm các thuộc tính handlerApp,
scene, fxml, sceneSound đồng thời định nghĩa các hàm getScene(),
playSound(), stopSound() để các class con của nó có thể kế thừa. Thuộc tính
scene đại diện cho menu đó , khi chuyển cảnh hàm getScene sẽ được gọi, String
fxml là tên file fxml để ta load file này và kết hợp với scene hiện có. Thuộc tính
sceneSound là thuộc tính đại diện cho nhạc nền của mỗi scene tắt bật được điều
khiển bởi 2 hàm playSound(), stopSound().
 Interface FxController: là 1 interface để các controller khác implement, dùng để
phân loại các controller với class bình thường.
 Class StartScene có vai trò hiển thị giao diện menu chính với các thao tác sự
kiện được sử lý bởi StartMenuController, đây là giao diện mở ra khi người
chơi vào game, cũng là nơi chung gian để điều hướng tới các menu khác qua
các button đã được định nghĩa sẵn trong file fxml tích hợp với thuộc scene
trong StartScene và được thêm các listener trong controller, từ đây bạn có thể
thoát game, hoặc di chuyển sang menu load, menu credits, menu setting, hoặc
menu chọn skin.
 Class SettingScene là một class nhỏ có vai trò hiển thị menu setting có các chức
năng bật tắt âm thanh hoặc là reset toàn bộ data trong game, các hoạt động này
được xử lý bởi SettingSceneController, menu này có điều đặc biệt đó là nó sẽ
được mở ở 1 cửa sổ khác(trên 1 stage phụ), khi ta chọn reset, hệ thống sẽ gọi
đến hàm static resetGame() trong class Utils, và game sẽ trở lại như mặc định
ban đầu.
 Class ChooseCharacterScene có vai trò hiển thị menu chọn skin cho game mới,
với các thao tác sử lý sự kiện bởi ChooseCharacterController, trong menu này,
người chơi sẽ được chọn skin mong muốn, di chuyển giữa các skin qua 2 nút
pre, next, quay lại menu start ấn nút back và khi đã chọn xong thì ấn next,
nhưng nếu bạn không sở hữu skin đó bạn phải mất gold để mua (gold kiếm
được khi đánh quái) và nút next sẽ bị ẩn đi thay bằng nút giá tiền hiện ra.
 Class DifficultyScene có vai trò hiển thị menu chọn độ khó game, các event
được điều khiển bới DifficultySceneController, ở menu này người chơi sẽ có 3
độ khó để chọn.
 Class CreditScene có vai trò hiển thị menu ghi lại nhưng thành viên tham gia
nhóm, lời cảm ơn đến nguồn ảnh , asset có trong game, menu này được điều
khiển bởi CreditController
 Class LoadScene có vai trò hiển thị menu chứa các game đã được lưu, được
điều khiển bởi LoadController, tại đây có 9 ô, người chơi có thể lưu tối đa 9
game, hết slot thì không thể lưu thêm nữa, mỗi ô là 1 ImageView, nếu có dữ
liệu được lưu thì nó sẽ lấy ảnh character tương ứng để show ra.
 Class GameScene có vai trò hiển thị vòng lặp game khi người chơi bắt đầu chơi
game, được điều khiển bởi GameController, khi người chơi đã chọn được chế
độ thích hợp, game mới hoặc load game, thì game scene bắt đầu làm việc, các
Nhóm 11 35
IT3100 – Lập trình hướng đối tượng 20202
hình ảnh sẽ được vẽ trên canvas của scene. Ở góc trái có nút resume khi người
chơi click vào sẽ chuyển tới ResumeScene và vòng lặp ngừng lại. Ở giữa bên
dưới có 1 bảng ghi các thuộc tính các chưởng mà người chơi có trong game.
 Class GameOverScene có vai trò hiển thị menu thua cuộc khi người chơi máu
nhỏ hơn hoặc bằng 0, menu tương ứng được điều khiển bới
GameOverController, từ đây người chơi có thể quay về màn hình chính hoặc
thoát app.
 Class VictoryScene vai trò hiển thị menu thắng cuộc khi người chơi giết được
boss, menu tương ứng được điều khiển bới VictoryController, từ đây người
chơi có thể quay về màn hình chính hoặc thoát app.
 Class ResumeScene vai trò hiển thị menu resume khi bạn muốn dừng lại để
thoát hoặc để lưu khi đang chơi, điều khiển bới ResumeSceneController, tại đây
bạn có những sự lựa chọn đó là quay lại chơi tiếp, bật tắt nhạc, save game này,
hoặc đi đến menu để chơi game mới.

2.4.6. Package setting

Đây là một package nhỏ chỉ có 1 class đó là Setting, và nó chỉ có 1 thuộc tính duy nhất
đó là priceCharacter quy định giá của các skin (hay character) trong game, nhóm em
cố tình để nó trong 1 class như vậy để tăng tính mạnh lạc và cho những tiềm năng phát
triển sau này.
2.4.7. Package save

Nhóm 11 36
IT3100 – Lập trình hướng đối tượng 20202

Đây là package chuyện phụ trách việc lưu trữ của app game, dữ liệu trong game sẽ
được lưu trữ vào trong object là instance của SaveData(1 class đã implement class
Serializable nên có thể ghi được ra file binary) sau đó sẽ được ghi ra file binary trong
thư mục save ở resource.
 Class ResourceManager bao gồm 2 method giúp ích cho việc lưu object ra file,
hàm save() lấy object và tên file để lưu ra, hàm load() lấy tên file để đọc và trả
về object tương ứng.
 Class SaveDataGame là class để lưu các thuộc tính của player mỗi game khác
nhau như máu, kinh nghiệm,chưởng, đồ dùng.... cùng với đó là độ khó của màn
chơi, thuộc tính serialVersionUID giúp ích cho việc giải mã file binary ra
object.
 Class SaveData là class chính lưu trữ, trong class chứa 1 chuỗi các
SaveDataGame đã được lưu, bên cạnh đó là thuộc tính serialVersionUID, gold
để mua skin.
2.4.8. package util

Nhóm 11 37
IT3100 – Lập trình hướng đối tượng 20202

Package này chứa các class HandlerApp và Utils có nhiều tác dụng trong việc điều
phối game, lưu trữ các hàm tiện ích dùng nhiều trong game để tránh lặp lại code.
 HandlerApp là class có vai trò lớn trong game, nó giúp lưu trữ các instance của
các scene, đẻ khi chuyển scene ta chỉ cần gọi đến nó để lấy các instance đó và
đưa vào stage để nó hiển thị.
 Utils là class hỗ trợ chứa các static method tiên ích, được sử dụng nhiều, như
loadFileAsString có tác dụng đọc file và trả lại là String của file đó, parseInt()
lấy vào số dạng String và trả về dạng int, loadData() được gọi ngay từ đầu với
mục đích load data đã lưu vào một object, saveData() lấy tham số là 1 instance
của SaveData và lưu instance đó vào trong file binary, resetGame() là method
gọi khi người chơi muốn reset game, nó sẽ tạo ra 1 instance của SaveData mới
và lưu đè lên file lưu cũ.

Nhóm 11 38
IT3100 – Lập trình hướng đối tượng 20202

CHƯƠNG 3. CÔNG NGHỆ VÀ THUẬT TOÁN SỬ DỤNG

<Trình bày các công nghệ, kiến thức và thuật toán liên quan đã sử dụng để làm bài tập
lớn>
3.1. Ngôn ngữ lập trình và các nền tảng công nghệ
Điều đầu tiên để tạo được một phần mềm đó là việc lựa chọn một ngôn ngữ lập
trình phù hợp. Với chủ đề lựa chọn là tạo một game 2D nhập vai dành cho desktop
Window thì nhóm đã quyết định sử dụng ngôn ngữ lập trình JavaFx để xây dụng game
“The Lone Avenger”. JavaFx là một thư viện Java bao gồm các lớp và các giao diện
được viết bằng mã Java nguyên gốc nên giống như Java nó cũng là một ngôn ngữ lập
trình hướng đối tượng.Và vẫn trên cơ sở là ngôn ngữ Java, JavaFx có thêm các nền
tảng thích hợp cho việc xây dựng và thiết kế ứng dụng, việc kết hợp các âm thanh,
hình ảnh, đồ họa, văn bản cũng dễ dàng hơn rất nhiều. Vì các ưu điểm của JavaFx
cùng với việc cả nhóm đều đã làm quen với Java từ trước nên việc làm quen với
JavaFx cũng dễ dàng hơn vậy nên JavaFx đã được lựa chọn để làm giải pháp phát triển
phân mềm. Và để hỗ trợ cho việc lập trình chúng em đã sử dụng công cụ lập trình
IntelliJ IDEA.
Khi lập trình game “The Lone Avenger” theo ý tưởng là giao diện hiển thị 2D,
chúng em đã sử dụng thêm FXML là một ngôn ngữ khai báo và CSS cả hai đều là các
tính năng được JavaFx hỗ trợ giúp dễ dàng định nghĩa và thiết kế giao diện người dùng
trong ứng dụng, ngoài ra chúng em còn sử dụng công cụ JavaFx Scene Builder cho
phép kéo thả khi thiết kế giao diện đồ họa (GUI). Cùng với các tính năng mà JavaFx
hỗ trợ để lập trình và thao tác với giao diện, ta còn có các bộ thư viện hỗ trợ đầy đủ
cho lập trình viên, để quản lý thư viện trở nên đơn giản hơn chúng em đã kết hợp thêm
công cụ Maven để liên kết đến các thư viện mà không phải copy thư viện vào Project
và khai báo Classpath như truyền thống, ta sẽ chỉ cần khai báo thư viện JavaFx cần sử
dụng trên file pom.xml, sau khi save file pom.xml sẽ kiểm tra thư viện và tự động tải
thư viện tư Internet xuống nên trên máy chưa có, cuối cùng Maven sẽ tự động khai báo
Classpath cho Project tới vị trí file jar được download về. Trong phần mềm của mình
thì các thư viện JavaFx được chúng em sử dụng bao gồm:
javafx.scene.Scene;
javafx.scene.image.Image;
javafx.scene.image.ImageView;
javafx.scene.media.MediaPlayer;
javafx.scene.control.Button;
javafx.scene.text.Text;
javafx.scene.input.MouseEvent;
javafx.scene.input.KeyCode;
javafx.scene.input.MouseButton;
javafx.scene.paint.Color;
javafx.scene.shape.Rectangle;
javafx.scene.paint.Color;
javafx.scene.canvas.GraphicsContext;
javafx.application.Application;
javafx.application.Platform;

Nhóm 11 39
IT3100 – Lập trình hướng đối tượng 20202
javafx.stage.Modality;
javafx.stage.Stage;
javafx.stage.WindowEvent;
javafx.scene.canvas.GraphicsContext;
javafx.event.EventHandler;
javafx.event.ActionEvent;
javafx.fxml.FXML;
javafx.geometry.Rectangle2D;
javafx.util.Duration;

Ngoài ra còn có một số thư viện của Java vẫn được chúng em sử dụng như:
java.io.BufferedReader;
java.io.FileReader;
java.io.IOException;
java.io.FileInputStream;
java.io.ObjectInputStream;
java.io.ObjectOutputStream;
java.io.Serializable;
java.nio.file.Files;
java.nio.file.Paths;
java.util.ArrayList;
java.util.Iterator;

Với các bộ thư viện này, cụ thể là các phương thức đã được cung cấp sẵn việc
triển khai phần mềm sẽ dễ dàng hơn rất nhiều đặc biệt là việc xây dụng giao diện đồ
họa thì các thư việc của JavaFx đã hỗ trợ rất tốt, ví dụ như các hàm trong thư viện
javafx.scene.Scene giúp trong tạo các khung hình, các class trong thư viện
javafx.scene.image giúp trong việc tạo các phương thức giúp đọc và sử dụng file hình
ảnh, âm thanh,…. Các thư viện của Java cũng có được sử dụng trong việc lưu trữ dữ
liệu, đối tượng của game trong quá trình chạy trong các Buffer và các Array,…. Nhờ
đó hệ thống phần mềm sẽ trở nên hoàn thiện.

3.2. Kỹ thuật, cấu trúc dữ liệu và thuật toán


Để thực thi một giải pháp phần mềm cho một ý tưởng thì không thể thiếu các kỹ
thuật, cấu trúc dữ liệu và các giải thuật được áp dụng. Và phần mềm The Lone
Avenger trong quá trình tạo dựng cũng cần rất nhiều những kỹ thuật lập trình và nổi
bật là kỹ thuật hướng đối tượng và kỹ thuật xử lý dữ liệu đầu vào.
Đầu tiên ta cần nói về kỹ thuật hướng đối tượng. Một phần mềm hay cụ thể là
một trò chơi cần có giao diện và các tính năng cho người chơi, sẽ rất phức tạp và khó
kiểm soát nếu như ta thiết kế từng phần một mà không có cách kiểm soát. Qua việc
học môn lập trình hướng đối tượng chúng ta có được phương pháp thiết kế quản lý
bằng việc chia thành các nhóm tính năng, công việc thành rồi đưa vào thành các
package, class để vừa dễ dàng trong việc xây dụng và phát triển mà nguồn, vừa dễ cho
việc phân chia công việc cho các thành viên trong nhóm. Với việc sử dụng JavaFx trên
nền tảng là ngôn ngữ Java là một ngôn ngữ thuần hướng đối tượng cũng giúp cho việc
tổ chức và lập trình đơn giản hơn rất nhiều. Nhờ vào lập trình hướng đối tượng các
thực thể mà ta muốn xuất hiện trong game được chuyển thành các đối tượng rồi bằng
Nhóm 11 40
IT3100 – Lập trình hướng đối tượng 20202
JavaFx chúng sẽ được xỷ lý để tạo thành giao diện được thể hiện trên máy tính. Các
package và các class cụ thể cũng như việc vận dụng kỹ thuật hướng đối tượng ra sao
đã được trình bày cụ thể ở mục 2, ta có thể tổng kết thành các kỹ thuật chủ yếu:
Encapsulation (tính đóng gói của 1 class), Inheritance (tính kế thừa của một class),
Overriding (tái định nghĩa hàm của class), và Polymorphism (tính đa hình của một đối
tượng).
Bên cạnh kỹ thuật hướng đối tượng, còn có một kỹ thuật sử dụng xuyên suốt
quá trình ta chạy phần mềm đó là xử lý dữ liệu đầu vào. Với một phần mềm là một trò
chơi, thì tất nhiên phần hình ảnh là rất quan trọng, với các dữ liệu đưa vào là các hình
ảnh ta cần tạo nên giao diện cho trò chơi với bản đồ, các nhân vật trong trò chơi vơi
các chuyển động và tương tác trong trò chơi. Về ý tưởng sơ bộ, chúng ta sẽ vẽ liên tục
các hình ảnh(được lấy từ file nguồn) của các đối tượng(object) lên màn hình với mỗi
chuyển động thì ta sẽ có một hình ảnh khác nhau và sẽ xuất hiện trong một khoảng
thời gian rồi chuyển sang hình ảnh khác nếu được yêu cầu tạo nên hiệu ứng chuyển
động, điều này cũng giống như nguyên lý hoạt động của video – mỗi một đoạn video
là một tập các khung hình được chiếu liên tiếp nhau.
Và để các nhân vật, các đối tượng trong game di chuyển và tương tác với
nhau thì ta cần tọa độ hóa để tính toán. Dựa vào đó ta có thể kiểm tra được sự tương
tác giữa các nhân vật trong trò chơi, đưa ra chuyển động đúng với yêu cầu của người
chơi,….
Một khía cạnh quan trọng không thể thiếu để chương trình có thể chạy đó là
các cấu trúc dữ liệu và giải thuật. Về cơ bản trong chương trình thì các cấu trúc dữ liêu
và thuật toán cơ bản quen thuộc được sử dụng xuyên suốt như các biến, các cấu trúc
lặp, rẽ nhánh ,… và bên cạnh đó có một số cấu trúc đặc biệt được sử dụng như
ArrayList (java.util.ArrayList) và Iterator (java.util.Iterator) để xây dựng giao diện cho
các đối tượng trong trò chơi như Player, Weapon, Skill,… các cấu trúc liên quan đến
đồ họa và âm thanh như MediaPlayer (javafx.scene.media), Image
(javafx.scene.image) để khởi tạo và sử dụng các thành phần âm thanh và hình ảnh mà
người lập trình thiết kế. Còn về phía giải thuật thì nổi trội và được sử dụng nhiều trong
trò chơi là thuật toán checkEntityCollision và thuật toán doHandle.
Về việc xây dựng ý tưởng và vận dụng thuật toán checkEntityCollision -
mục tiêu là để kiểm tra các va chạm vật lý giữa các thực thể được mô tả trong gme.
Việc va chạm này là muốn thể hiện một cách thực tế nhất có thể rằng nhân vật, cây
cối, tường,... là những thứ có khả năng va chạm vật lý, có thể ngăn cản nhau trong các
bước di chuyển. Về ý tưởng thì chỉ đơn giản là chúng ta sử dụng tọa độ hiện tại trong
map và kích thước của nhân vật để tính ra được một hitbox có dạng dữ liệu là
Rectangle của nhân vật đó. Sau đó, với mỗi tile không thể đi sang được hoặc với mỗi
nhân vật khác trong map, chúng ta cũng dựa vào tọa độ và kích thước để tính ra hitbox
của chúng. Sau đó, nhờ vào hàm coolisionWithTile của Rectangle mà chúng ta có thể
biết được hai Rectangle có giao nhau hay không. Nếu có tức là hai vật thể đó collide
(đè?) lên nhau, từ đó có thể ngăn chặn không cho nhân vật đi vào những khu vực
không thể đi được, hoặc đi xuyên qua các nhân vật khác.
Khi chạy trò chơi, các khung hình được gọi ra mỗi khi chương trình chạy,
trong một số trường hợp do vấn đề về chất lượng phần cứng hoặc khi lập trình, các
hình ảnh không được vẽ liên tục trên màn hình dẫn đến hiện tượng giật, lag. Do đó
chúng ta sử dụng thuật toán doHandle để điều chỉnh số khung hình được vẽ trên màn
hình một cách cố định, tạo cảm giác mượt mà khi chạy. Mô tả ý tưởng của thuật toán
này như sau: ta cần 3 biến xác định thời gian, start – ghi giá trị thời gian bắt đầu xuất

Nhóm 11 41
IT3100 – Lập trình hướng đối tượng 20202
hiện , timePerUpDate – đưa ra thời gian xuất hiện của một khung hình, và now – lấy
giá trị thời gian thực mỗi lần chạy thuật toán. Ở trò chơi này chúng em cố định số
khung hình trên 1 giây là một hằng số FPS = 40, trò chơi chỉ mượt mà khi FPS hiện tại
của trò chơi lớn hơn 40 do đó timePerUpdate =1000000000 / FPS, với mỗi một khung
hình trên màn hình để vẽ khung hình tiếp theo thì (now – start) phải lớn hơn
timePerUpDate và sẽ tiếp tục thuật toán với các khung hình tiếp theo.

Nhóm 11 42
IT3100 – Lập trình hướng đối tượng 20202

CHƯƠNG 4. XÂY DỰNG CHƯƠNG TRÌNH MINH HỌA

4.1. Kết quả chương trình minh họa


<Trình bày tổng quan về kết quả đạt được trong quá trình làm bài tập lớn trong chương
trình minh họa, nêu qua những chức năng chính đã thực hiện được>
 Kết quả đạt được:
- Học được kỹ năng phân tích bài toán, phân chia công việc, tăng cường kỹ năng
làm việc nhóm.
- Đạt được khả năng phát triển, thiết kế game đơn giản, làm quen với các khái
niệm cơ bản về UI/UX.
- Phát triển tư duy lập trình hướng đối tượng và lập trình Java, xây dựng giao
diện với JavaFx.
- Phát triển kỹ năng thiết kế đồ họa cơ bản.
 Những chức năng chính:
- Thể hiện được các nhân vật, bản đồ cùng với hình ảnh kỹ năng trên giao diện
màn hình.
- Xây dựng hệ thống bản đồ bằng Tiled.
- Chức năng chọn nhân vật, chọn độ khó.
- Phát triển hệ thống xác định va chạm vào vật cản tĩnh và động.
- Phát triển hệ thống item giúp trò chơi trở lên thú vị hơn.
- Chức năng bật/tắt âm thanh.
- Chức năng Save/Load game.
- Xây dựng hệ thống level và kỹ năng mở theo level.

Nhóm 11 43
IT3100 – Lập trình hướng đối tượng 20202

4.2. Giao diện chương trình


4.2.1. Giao diện Menu:
- Giao diện Menu chính:

- Giao diện Credits:

- Giao diện “Load game”:


Màn hình sẽ hiện lên quá trình chơi game và các màn đã qua mà người
chơi lưu từ những lần chơi trước, nếu là lần chơi đầu tiên thì tất cả các màn

Nhóm 11 44
IT3100 – Lập trình hướng đối tượng 20202
chơi sẽ khóa lại. Người chơi sẽ click chuột vào màn được mở khóa để quay lại
quá trình chơi trước ở từng màn chơi. Tính năng sẽ hữu dụng hơn khi game
được nâng cấp với nhiều màn chơi hơn sau này.

- Giao diện chọn nhân vật.


Người chơi click chuột phải vào “Pre” hoặc “Next” để thay đổi nhân vật mình
điều khiển.

Nhóm 11 45
IT3100 – Lập trình hướng đối tượng 20202
Ở giao diện này, người chơi có thể nhìn thấy số tiền của mình theo đơn vị tiền
tệ trong game là “Gold”. Người chơi có thể tăng số tiền này lên trong quá trình
chơi game trước đó. Dùng lượng “Gold” này để mở khóa các nhân vật đặc sắc
hơn.

- Giao diện chọn độ khó:


Trò chơi có 3 mức độ khó là: Dễ, Trung bình và Khó. Lựa chọn độ khó phù
hợp để bắt đầu trò chơi.

Nhóm 11 46
IT3100 – Lập trình hướng đối tượng 20202

- Giao diện “Setting”:


Setting cho người chơi khả năng thay đổi các chức năng cần thiết trước khi bắt
đầu trò chơi như âm thành hay xóa đi thông tin của lần chơi trước.

- Giao diện “Pause”:


Giao diện được sử dụng khi bạn muốn tạm dừng trò chơi để thực hiện những
cài đặt trong quá trình chơi. Các chức năng của giao diện “Pause” bao gồm
bật/tắt âm thanh, lưu lại quá trình chơi, quay lại menu chính. Khi muốn quay
lại trò chơi, người chơi chọn “Back”.

Nhóm 11 47
IT3100 – Lập trình hướng đối tượng 20202

4.2.2. Giao diện trò chơi.


Trò chơi gồm 4 khu vực tương ứng với 4 map mô phỏng thế giới trong game:
- Khu vực 1: Khu vực 1 hay còn gọi là khu vực khởi đầu là khu vực mà người
chơi xuất hiện khi bắt đầu trò chơi. Khu vực này mô phỏng một ngôi làng nhỏ
yên bình. Khu vực này chỉ bao gồm các NPC.

Nhóm 11 48
IT3100 – Lập trình hướng đối tượng 20202

Hệ thống cổng dịch chuyển phía giúp người chơi di chuyển sang các khu vực
khác.

- Khu vực 2: Khu vực 2 là khu vực đầu tiên xuất hiện quái vật. Khu vực này mô
phỏng cho vùng ranh giới giữa nơi ở của con người và nơi ở của quái vật. Quái

Nhóm 11 49
IT3100 – Lập trình hướng đối tượng 20202
vật ở nơi này là loại quái cận chiến khá dễ tiêu diệt để người chơi có thể bắt
đầu một cách dễ dàng.

Tiêu diệt quái để tăng level giúp mở khóa kỹ năng, nhận được item có ích.

- Khu vực 3: Khu vực 3 mô phỏng một khu rừng bóng tối. Khu vực này bao
gồm những loại quái mạnh hơn với khả năng tấn công tầm xa cùng với số

Nhóm 11 50
IT3100 – Lập trình hướng đối tượng 20202
lượng quái lớn hơn. Thêm vào đó là kinh nghiệm đạt được cùng với tỷ lệ rơi
vật phẩm lớn hơn khu vực 2. Di chuyển vào cổng dịch chuyển ở góc phía trên
bên phải khu vực 2 để tới khu vực này.

- Khu vực 4: Khu vực 4 là khu vực cuối cùng của game ở hiện tại, nó là nơi ở
của Boss cuối cùng của game. Khu vực 4 được lấy ý tưởng là một tế đàn
khổng lồ nằm giữa thiên đàng và địa ngục. Di chuyển vào cánh cổng ở góc
phía trên bên phải khu vực 3 để tới khu vực này.

Nhóm 11 51
IT3100 – Lập trình hướng đối tượng 20202

Khi đạt đủ sức mạnh, người chơi sẽ đến đây để thách đấu với Boss. Tiêu diệt
Boss để chiến thắng trò chơi.

- Giao diện “Win game”:


Giao diện này xuất hiện khi người chơi tiêu diệt thành công Boss. Lúc này
người chơi có 2 lựa chọn là “Exit” để thoát trò chơi hoặc “Restart” để bắt đầu

Nhóm 11 52
IT3100 – Lập trình hướng đối tượng 20202
lần chơi mới.

- Giao diện “Game Over”:


Giao diện này khi lượng HP của người chơi giảm xuống 0. Lúc này người chơi
có 2 lựa chọn là “Exit” để thoát trò chơi hoặc “Restart” để bắt đầu lần chơi
mới.

Nhóm 11 53
IT3100 – Lập trình hướng đối tượng 20202

- Giao diện túi đồ:


Giao diện túi đồ là nơi người chơi kiểm tra và sử dụng các item mà mình nhận
được trong quá trình tiêu diệt quái vật. Trong quá trình chơi, để mở giao diện
kho đồ, người chơi bấm phím “F”.

4.2.3. Hệ thống nhân vật trong game:

Nhóm 11 54
IT3100 – Lập trình hướng đối tượng 20202
Các nhân vật trong game được vẽ theo phong cách pixel art, kích thước 32x32 (ngoại trừ
Boss). Nhân vật được chia làm 3 loại: Player, Enemy, NPC. Player và các Enemy có HP
và có khả năng tấn công còn NPC thì không.

4.3. Kiểm thử các chức năng đã thực hiện


Các chức năng đã xây dựng trong chương trình:
 Thể hiện bản đồ và các đối tượng trên bản đồ trên giao diện đồ họa.
 Di chuyển và phát hiện va chạm.
 Hệ thống skill, HP.
 Save Game và Load Game.

4.3.1. Kiểm thử cho chức năng 1

Chức năng: Thể hiện bản đồ và các đối tượng trên bản đồ trên giao diện đồ họa.
Kết quả kiểm thử:
 Giao diện bản đồ cùng với các nhân vật được thể hiện trên giao diện đồ họa một
cách rõ nét và mượt mà.
 Vì các lớp giao diện được in ra màn hình dưới các lớp khác nhau nên nhiều lúc sẽ
xuất hiện các giao diện bị chồng lấn bất hợp lý.
VD: Lớp NPC được in ra màn hình sau lớp Player khiến giao diện nhân vật NPC
chồng bất hợp lý lên Player.

4.3.2. Kiểm thử cho chức năng 2

Chức năng: Di chuyển và phát hiện va chạm.


Kết quả kiểm thử:

Nhóm 11 55
IT3100 – Lập trình hướng đối tượng 20202
 Việc di chuyển của nhân vật khá mượt mà, không mắc lỗi không nhận bàn
phím.
 Vùng xử lý va chạm vật thể tạo nên địa hình bản đồ không theo hình ảnh
của vật thể mà theo ô vuông nơi chứa vật thể, nên xung quanh vật thể này
có các vùng trống xung quanh, người chơi không thể di chuyển vào các
vùng trống này. Thêm vào đó, khi item rơi vào vị trí các vật thể này, ta
không thể tiến vào khu vực để thu hồi item cũng như hiệu ứng kỹ năng bị
hủy khi va chạm với các vùng này tuy rằng dưới mắt thường của người chơi
thì trên đường đi không hề có vật cản.

4.3.3. Kiểm thử cho chức năng 3

Chức năng: Hệ thống skill, HP.


Kết quả kiểm thử:
 Hệ thống skill của người chơi và quái vật hoạt động ổn định, HP bị trừ khi
nhân vật tấn công quái vật và ngược lại.
 Khi người chơi lên cấp độ cũng như sử dụng item, các skill được tăng sức
mạnh.
 Vì khi skill va chạm vào quái vật thì animation sẽ biến mất nên khi tấn
công cận chiến, nếu đứng quá gần quái vật sẽ không hiển thị animation khi
sử dụng skill tấn công.

4.3.4. Kiểm thử cho chức năng 4

Chức năng: Save Game và Load Game.


Kết quả kiểm thử:
 Chức năng Save Game, Load Game hoạt động, giữ được level cũng như
item từ lần chơi trước đó.
 Quá trình Save Game phải được thực hiện thủ công, nếu game bị tắt quá đột
ngột thì quá trình chơi trước đó không được lưu.
 Khi thực hiện Load Game, nhân vật của người chơi sẽ xuất hiện ở khu vực
1 chứ không phải vị trí khi thực hiện Save Game.

Nhóm 11 56
IT3100 – Lập trình hướng đối tượng 20202
4.3.5. Kết luận

Sau khi hoàn thành bài tập lớn, chúng em nhận thấy quá trình thực hiện đề tài còn tồn tại
một số ưu điểm và nhược điểm sau:
 Ưu điểm: Hoàn thành, đáp ứng đủ các yêu cầu của đề tài giao cho, xây dựng
nhiều tính năng ưu hóa, nâng cao ngoài yêu cầu giúp nâng cao trải nghiệm của
người chơi, trò chơi chạy ổn định, không xuất hiện lỗi quá lớn, lối chơi của trò
chơi hấp dẫn, dễ nâng cấp, giao diện đẹp mắt, trực quan.
 Nhược điểm: Trò chơi yêu cầu lượng tài nguyên lớn. Giao diện được mượn từ
nhiều nơi khác nhau dẫn tới việc không ăn khớp, không phù hợp. Các tính năng
tương tác với NPC chưa được xây dựng. Mặt khác, do thời gian bị hạn chế nên
code chưa được tối ưu, vẫn còn xuất hiện nhiều lỗi nhỏ.
Sau khi hoàn thành bài tập lớn này, chúng em đã học được rất nhiều điều về phát triển
phần mềm và tư duy lập trình hướng đối tượng. Với tất cá thành viên trong nhóm thì đây
chính là sản phẩm phần mềm đầu tiên của mình nên ai cũng rất hăng hái học hỏi. Code
của phầm mềm được xây dựng để dễ dàng được nâng cấp, hứa hẹn cho một trò chơi tốt
hơn trong tương lai.

Nhóm 11 57
IT3100 – Lập trình hướng đối tượng 20202

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN


<Phần này nêu kết luận đã làm được gì trong lần quá trình thực hiện bài tập lớn.
Ưu, nhược điểm. Sau đó đưa ra hướng phát triển cho đề tài, chủ yếu để khắc phục các
nhược điểm đã nêu>

Nhóm 11 58
IT3100 – Lập trình hướng đối tượng 20202

TÀI LIỆU THAM KHẢO


<Liệt kê thông tin chi tiết về các tài liệu tham khảo đã sử dụng trong quá trình làm bài
tập lớn – kể cả tài liệu tiếng Anh, tiếng Việt, trên Internet hay sách, báo…>

[1] Phân tích và thiết kế hệ thống thông tin - Nguyễn Văn Ba - 2003.
[2] Vở ghi môn Phân tích thiết kế hệ thống do thầy Đỗ Văn Uy giảng dạy.

Nhóm 11 59
IT3100 – Lập trình hướng đối tượng 20202

PHỤ LỤC
<Phần này đưa ra hướng dẫn cài đặt, hướng dẫn sử dụng của chương trình, một số các
vấn đề khác muốn trình bày…>

Nhóm 11 60
IT3100 – Lập trình hướng đối tượng 20202

Nhóm 11 61

You might also like