Professional Documents
Culture Documents
Mau Bao Cao
Mau Bao Cao
Nhóm 11 2
IT3100 – Lập trình hướng đối tượng 20202
MỤC LỤC
MỤC LỤC.................................................................................................................... 2
PHỤ LỤC................................................................................................................... 11
Nhóm 11 3
IT3100 – Lập trình hướng đối tượng 20202
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
<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>
Nhóm 11 7
IT3100 – Lập trình hướng đối tượng 20202
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.
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
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.
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.
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
Nhóm 11 11
IT3100 – Lập trình hướng đối tượng 20202
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.
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.
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
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ị.
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
Để 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.
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.
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
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
- 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
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
Đâ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.
Nhóm 11 27
IT3100 – Lập trình hướng đối tượng 20202
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
Đâ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.
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.
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.
Đâ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
<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.
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
Nhóm 11 43
IT3100 – Lập trình hướng đối tượng 20202
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.
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.
Nhóm 11 46
IT3100 – Lập trình hướng đối tượng 20202
Nhóm 11 47
IT3100 – Lập trình hướng đối tượng 20202
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.
Nhóm 11 52
IT3100 – Lập trình hướng đối tượng 20202
lần chơi mới.
Nhóm 11 53
IT3100 – Lập trình hướng đối tượng 20202
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.
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.
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.
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
Nhóm 11 58
IT3100 – Lập trình hướng đối tượng 20202
[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