Thay đổi font chữ hiển thị trong game
Ở phần trước mình có hướng dẫn các bạn sử dụng hàm draw_text() để ghi thông tin về điểm số và level lên màn hình, nhưng nếu chỉ sử dụng hàm này không mà chưa cài đặt font thì dòng chữ hiển thị ra GUI sẽ rất xấu và nhìn không bắt mắt, đó cũng là lý do mình hướng dẫn các bạn cách đổi font chữ trong game.
1. Thêm font chữ (ẤN ALT+F)
Thêm và tùy chỉnh font chữ cho hợp lý
2. Sử dụng các hàm build-in để thay đổi font chữ hiển thị thành font vừa cài đặt, ở ví dụ bên dưới mình sẽ chỉnh sửa lại font cho màn hình oGameOver mà chúng ta đã làm ở phần 2
draw_set_halign(fa_center);
draw_set_font(gameFont2);
draw_set_color(c_red);
draw_text(360,310,"GAME OVER");
draw_set_font(gameFont1);
draw_set_color(c_white);
draw_text(360,510,"FINAL SCORE \n"+string(oCircle.myscore));
3. Chạy thử
Sau khi chỉnh màu, kiểu chữ trong game và chạy trên PC sẽ ra kết quả như thế này
Thêm âm thanh cho trò chơi
Một thành phần quan trọng không kém trong game đó là âm thanh, các bạn có thể tự thiết kế âm thanh cho game hoặc tải các âm thanh đã được tạo sẵn miễn phí tại đây (không bản quyền)
1. Thêm sound (ẤN ALT+U)
Import âm thanh của các bạn tại vùng khoanh đỏ, sau đó hãy đặt tên cho phù hợp
2. Sau khi thêm âm thanh, để phát âm thanh khi xảy ra một event nào đó (vd: ấn nút, va chạm, nhạc nền, ...) các bạn hãy sử dụng hàm audio_play_sound(<TÊN sound>,<ĐỘ ƯU TIÊN>,<LẶP LẠI>)
. Ở ví dụ bên dưới mình sẽ thêm dòng lệnh sau vào Collision Event của oCircle (quả bóng)
audio_play_sound(overSound,1,false);
3. Tương tự các bạn có thể chèn dòng lệnh như trên vào bất kỳ event nào các bạn muốn phát ra âm thanh
Làm cho chướng ngại vật trở nên đa dạng hơn
Các bạn biết rằng, đối tượng oWall của chúng ta chỉ sử dụng duy nhất 1 sprite và lúc nào nó cũng xuất hiện với kích thước như nhau, như vậy thì thật là nhàm chán đúng không? Vậy làm thế nào để object oWall của chúng ta mang nhiều màu sắc trong game để người chơi hứng thú hơn.
1. Import tất cả các hình ảnh (sprite) mà bạn muốn chướng ngại vật sử dụng, chuyển tốc độ khung hình (Speed) về 0
.
Ở đây mình sử dụng 9 hình ảnh (kích thước như nhau) để làm những chướng ngại vật khác nhau
2. Chỉnh sửa Step Event của oFunction (nếu bạn không biết oFunction là gì, xem lại phần 2)
level=floor(oCircle.myscore/1000)+1;
levelSpeed=8+level*1.3;
if (delay==0){
delay=max(40,100-level*10);
var xx=random_range(0,520);
with (instance_create_layer(xx,-200,"Instances",oWall)){
image_index=random_range(0,8);
image_xscale=random_range(0.3+oFunction.level/10,0.8+oFunction .level/10);
image_yscale=image_xscale;
speed=oFunction.levelSpeed;
direction=point_direction(0,0,0,1);
}
} else delay--;
3. Mỗi khi khởi động trò chơi, GMS2 sẽ cung cấp cho chúng ta một seed, những hàm random ở bước 2 sẽ dựa vào seed để trả về những giá trị ngẫu nhiên. Tuy nhiên seed này sẽ không thay đổi ngay cả khi bạn thoát trò chơi và vào lại, vì vậy những giá trị ngẫu nhiên là như nhau ở mọi thời điểm chơi trò chơi này. Nhằm tránh hiện tượng trên, tại Create Event của oFunction, các bạn hãy thêm dòng randomize();
randomize() sẽ đảm nhiệm chức năng thay đổi seed mỗi khi trò chơi bắt đầu.
4. Chạy thử
Các vật thể được sinh ra với kích thước và hình dạng ngẫu nhiên
Nhập tên người chơi
Phần này sử dụng hàm get_string_async(<Title>,<DefaultName>)
để tạo cửa sổ cho người dùng nhập dữ liệu trên cả PC và android và trả về một danh sách gần như là Map trong Java. Chính vì vậy chúng ta sử dụng một Event mới: Async - Dialog nhằm phân tích danh sách này và trả về đúng dữ liệu mà người dùng nhập vào, các bạn có thể tìm hiểu sâu hơn tại đây.
1. Tạo thêm 1 nút (object) oChangeName (xem cách tạo nút tại phần 1), và thêm vào đó 4 event như sau
2. Create Event: Tạo 2 biến, một biến lưu trữ tên người chơi, một biến tạm lưu trữ giá trị trả về
global.name="Defaut";
msg="";
3. Draw Event: In thông tin người chơi ra màn hình
draw_self();
draw_set_halign(fa_center);
draw_set_font(gameFont1);
draw_text(360,y-80,"Welcome, "+string(global.name));
4. Left Pressed Event: Hiển thị cửa sổ nhập tên khi ấn chuột trái
msg=get_string_async("Type your name: ","Defaut name");
5. Xử lí dữ liệu trả về của Map (Nâng cao nên không cần hiểu rõ)
var mapId = ds_map_find_value(async_load, "id");
if mapId == msg
if ds_map_find_value(async_load, "status")
if ds_map_find_value(async_load, "result") != ""
global.name = ds_map_find_value(async_load, "result");
Thành quả chạy thử trên Android
Bảng điểm
GMS2 hỗ trợ một hàm build-in cho phép bạn lưu các giá trị tên người chơi và điểm số vào một table, và nó sẽ tự động sắp xếp từ điểm cao tới thấp, để hiển thị table
1. Tạo một object để hiển thị table chứa danh sách người chơi đứng top, sau khi tạo xong kéo thả object này vào room HighScore
Create Event để đọc danh sách người chơi mỗi khi truy cập room HighScore
Draw Event để vẽ bảng điểm trong room HighScore
2. Tạo một object để lưu danh sách người chơi đứng top vào file, object này sẽ được tạo mỗi khi trò chơi kết thúc nhằm lưu lại điểm của người chơi hiện tại
Tạo object SaveHighScore (không dùng Sprite)
Cuối cùng, trong Collision Event của oCircle khi va chạm với oWall, hãy thêm dòng kiểm tra sau để lưu điểm số của người chơi
if (!instance_exists(SaveHighScore))
instance_create_layer(0,0,"GameOver",SaveHighScore);
Thành quả chạy thử trên Android khi ấn vào room HighScore
Tạm Kết
Qua phần này, các bạn đã có thể hiểu thêm được một số thành phần trong GMS2 và dựa vào đó để bổ sung những tính năng còn thiếu trong game của mình, nếu các bạn thấy chủ đề hay, hãy chia sẽ bài viết và đánh giá 5 sao để mình có thêm động lực hướng dẫn các bạn nhiều tính năng chuyên nghiệp hơn nữa. Cuối cùng, cảm ơn các bạn đã đọc bài viết và chúc các bạn thành công.
Demo phần 4 (phần cuối): giới thiệu về shader, nâng cấp trò chơi để quả bóng có thể bắn vỡ chướng ngại vật, hiển thị thanh máu như thế nào, ...
Game đã hoàn chỉnh: Android PC
Tài nguyên sử dụng trong game (Đã update phần 1+2+3): Resource
Project (GMS2_ProjectFile): Part 1+2 (5000 views phần 4 mình sẽ update Project cuối cùng_bản đầy đủ tính năng)