Tiếp nối phần 12 trong phần này mình sẽ hướng dẫn các bạn về:
- Tấn công kẻ thù (attack enemy)
- Kẻ thù tấn công
- Spritesheet
- AnimationPlayer
- Mask/Layer
Đầu tiên các bạn tải cho mình animation slash tức là animation chém vì trong asset kia không có animation tấn công nên chúng ta sẽ lấy cái khác.
Bạn có thể download ở dưới:
Hoặc save ảnh này
Note: Trước khi đi vào bài thì ở bài tạo menu chỗ trò chơi mới thì mình sơ suất code lỗi 1 dòng
Ở PackedSence các bạn đổi lại thành:
export(String,FILE,"*.tscn") var BoSenceVao
Và cùng bắt đầu thôi.
Animation
Đầu tiên chúng ta sẽ setup animation cho nó. Ở sence Player chúng ta sẽ xài Node AnimationPlayer. Đây là nút dùng để chứa và chạy tài nguyên (animation) giải thích thì khó hiểu nhưng mà khi làm thì sẽ hiểu nhé.
Các bạn tạo node animation và tạo 1 cái animation mới
Mình sẽ để tên nó là chem
Và ở đây chúng ta vẫn chưa có 1 nút nào chứa tài ngyên chém (animation chém) vì vậy chúng ta phải tạo 1 nút để AnimationPlayer có thể chạy cái tài nguyên đó(chạy animation). Ở đây mình sẽ tạo 1 cái nút là sprite rồi bỏ ảnh chém vào.
Ở đây các bạn có thể thấy nó là dạng sprite sheet
Chúng ta sẽ vào bảng Inspector của nút mới tạo.
Và ở Animation thì có 4 cái:
- Vframes: Chiều dọc của frame
- Hframes: Chiều ngang của frame
- Frame: Số frame đang ở hiện tại
- FrameCoord: Khi bạn thay đổi chỉ số tọa độ thì frame sẽ tự động điều chỉnh đến số tọa độ mà bạn chỉnh sửa
À ai chưa biết frame là gì thì frame là: Khung
Vd thì nhìn dưới ảnh những số mình vẽ = 1 frame nhé.
Tiếp đến chúng ta sẽ set frame cho nó.
VFrame là chiều dọc vậy chúng ta sẽ đếm frame theo chiều dọc và Hframe là chiều ngang thì chúng ta cũng đếm từ chiều ngang đếm được bao nhiều thì điền vào bấy nhiêu.
Vậy :
- Vframes của mình là 6
- Hframes là 5
Lưu ý: Nếu frame của bạn bị lệch không theo thứ tự tức là:
- Bạn set Vframes và Hframse chưa chính xác
- Spritesheet sai vị trí
Rồi sau đó bạn nhấn hide cái nút chém đi nhé, biều tưởng mắt bên phải nút
Vậy là đã xong và tiếp theo chúng ta sẽ sử dụng AnimationPlayer để chạy animation chém
Đầu tiên:
Ở Animation chem vừa tạo các bạn nhấn Add Track > Poperty Track
Chọn cho mình cái nút mà chúng ta vừa tạo ở trên
Rồi tìm cho mình cái frame
Ở đây nghĩa là AnimationPlayer sẽ truy cập vào nút animation chém và sẽ lấy tài nguyên từ đó tạo thành 1 animation hoặc có thể hiểu là AnimationPlayer sẽ chạy frame theo cách mà bạn muốn từ frame 0-5 hoặc 5-1 hoặc 5-10 v.v…
Ở đây mình sẽ giải thích cho các bạn 1 số tool trong AnimationPlayer
- Màu đỏ: Thời Gian chạy Frame
- Màu Xanh Sáng: Chỉnh độ nhìn thời gian
- Màu Xanh Lá Cây: Chỉnh kiểu chạy Frame liên tục hay cắt đứt,vv
- Mà Đen: Lặp lại Animation
- Mà Xanh Đậm: Chạy Animation khi bắt đầu
Rồi tiếp đến các bạn nhấn chuột phải vào Track mới tạo nhấn insert key
Ở đây mình sẽ Insert 5 cái Keys tức là 5 cái frame đầu tiên.
Lưu Ý: Frame đầu tiên sẽ là = 0
Các bạn nhấn vô Keys rồi bên bảng Inspector ở cái Value là giá trị frame nhé.Muốn chạy frame nào thì điền vô và nhớ cái đầu tiên sẽ = 0
ở mấy cái tiếp theo các bạn chỉnh lên 0-5 nghĩa là sẽ chạy 5 cái frame đầu tiên trong ảnh chém
Ở đây mình set thời gian lại thành 0.5 cho ngắn à và khi set time với cái này thì các bạn nên chọn từ 0.1-1 giây thôi nhé đừng có chọn 1-10 giây
Tiếp đến chúng ta sẽ phải unhide nó nghĩa là phải hiện nó lên khi chém và ẩn khi kết thúc
Vì vậy các bạn Add thêm Track cho mình là Visible, đây là chức năng ẩn hiện trong inspector phần Canvas Item của nút
Ở đây mình sẽ Insert 2 Keys 1 keys là lúc bắt đầu chém tức là 0.1 thì nó sẽ hiện lên và 1 keys ở cuối tức là 0.4 sau khi chém xong sẽ ẩn
Ở Keys đầu tiên sẽ tick vào ô value là On và Keys cuối thì không tick
Tiếp đến các bạn nhấn nút Play để xem Animation
Nó sẽ biến mất 1 cách hoàn hảo, nhưng nhược điểm ở đây là frame thứ 5 sẽ không xuất hiện vì cùng khoản thời gian là 0.4 nó đã bị ẩn bởi Track Visible vì vậy bạn có thể chỉnh thời gian lên 0.6 và để cái keys mà Frame ẩn đi lên 0.5 là sẽ chạy đầy đủ frame.
Vậy là đã xong phần setup Animation tiếp theo chúng ta sẽ làm phần “Tấn công kẻ thù”
Attack Enemy Và Layer/Mask
Và đến phần tiếp theo và trong phần này sẽ có những cái phải làm như sau.
- Hitbox Player: cái này sẽ là cái mà dùng để kiếm tra player sẽ tấn công vào cái gì đó.Ở trong đây thì nó sẽ kiểm tra player tấn công vào hurtbox enemy.Nghĩa là chúng ta dùng nút Hitbox Player để xác nhận rằng nó có va chạm với Hurtbox cuả Quái nếu nó xác nhận rằng hitbox của player có va chạm với hurtbox của Quái thì nó sẽ gây ra sát thương cho quái
- Hurtbox Player:Kiểm tra nếu hitbox của Quái va chạm vào thì sẽ gây sát thương cho player
- Hitbox Enemy: Dùng để va chạm với Hurtbox của Player để gây damage
- Hurtbox Enemy: Kiểm tra xem hitbox của player có va chạm không.Có thể hiểu là kiểm tra xem Player có đánh trúng quái không -_-.
- Đó là Layer và Mask:
Layer và Mask là 2 cái dùng để chọn cái nào va chạm với cái nào.
– Layer = Tên Layer
– Mask = Chọn cái layer mà bạn muốn nó va chạmVD: Ở Player mình sẽ để là Layer 2 và Mask 2
Và Quái sẽ là Layer 3 và Mask 3.
Ở đây mình cả 2 cái đều ko liên quan tới nhau vậy nghĩa là 2 cái sẽ không va chạm mà đi qa nhau.Bây giờ mình muốn 2 cái khi chạm nhau sẽ không đi qua nhau và sẽ va chạm với nhau thì mình chỉ cần đổi lại mask thành mục tiêu muốn va chạm.
Player thì mình sẽ chọn Mask 3 tức là Layer 3 là Enemy
Quái thì chọn Mask 2 tức là Layer 2 là Player
Khi đó nó sẽ va chạm với nhau mà không bước qua đời nhau
Tiếp:
Các bạn tạo 1 sence mới và nút root là Area2D đổi tên thành hitbox và nút con là collsion2D và ko set collsionshape cho nó nhé rồi lưu lại. Vậy là xong cái hitbox
Tiếp đến cái Hurtbox làm tương tự
À và chúng ta set mask layer cho nó nữa
Các bạn vô Project > Project Setting > Layer Names> 2D Render % & 2D Physic thì Render = Layer, Physic = Mask và tên cả 2 cái phải giống nhau để dễ phân biệt nhé.
Ở đây mình sẽ set là
Set 2 cái giống hệt nhau nha.
Tới cái hitbox thì đổi layer/mask lại thành không có cái nào nha
Rồi tiếp đó vô Sence Player và Instance 2 nút là Hitbox và HurtBox
Ở Hitbox và Hurtbox chuột phải chọn editable as children nghĩa là cho phép bạn chỉnh sử nút này như 1 nút con mà không ảnh hướng tới nút chính
Ở Hurtbox thì chọn collsion2D và setcollsion shape cho mình nhé
Và ở Hitbox & Hurtbox các bạn set Layer cho nó nhé
Còn cái mask thì Hitbox Player -> Hurtbox Enemy
HurtBoxPlayer thì để layer là Hurtbox Player ko set mask vì hurt box không va chạm với cái gì cả nhiệm vụ của nó chỉ là nhận chứ không làm
Rồi đến Quái chúng ta cũng làm tương tự nhưng layer là enemy
Ở enemy các bạn set collion shape hit box & hurt box giống CollsionShape của nó đều đc
Tiếp đến sẽ set collsion shape hitbox cho Player:
Các bạn nhấn Add track > Poperty track > Hitbox > CollisionShape2D > Disabled
Disabled là chức năng vô hiệu hóa collsion ở đây chúng ta sẽ dùng chức năng này để tạo hitbox cho player.
À ở đây Keys frame của mình từ 20-24 và nút chém thì Flip H = True nhé.
Các bạn sẽ căn cho mình khi nào chém thì collsionshape sẽ kích hoạt và khi nào không kích hoạt nhé
Vậy là đã xong phần hitbox & hurtbox tiếp đến là code
Ở hitbox tạo cho mình 1 cái script là HitboxPlayer
Ở đây chúng ta sẽ code phần biến là export damage để đưa giá trị ra bên ngoài inspector cho dễ edit ~
export (int) var damage = 10
Tiếp đến chúng ta sẽ kết nối tín hiệu cho nó để biết rằng nó có va chạm hay không còn cái mask/layer là để cái này va chạm với cái kia,
Ở đây chúng ta sẽ xài area enterd thay vì body bởi vì hitbox sẽ và chạm với hurtbox và cả 2 đều là area2d nên sẽ xài area enterd.
Ở phần code chúng ta sẽ code để nhận biết kẻ thù va chạm với chúng ta và gây sát thương cho nó.
Đến phần sence của con quái ở cái hurtbox các bạn kết nối tín hiệu là area enter để nhận biết hitbox của player va chạm với nó kết nối vào kinematicbody ý
Ở phần trước mình đã hướng dẫn các bạn tạo máu cho quái rồi.
Tiếp đến phần hàm mới kết nối gõ:
health -= area.damage
if health <= 0:
queue_free()
health = máu và -= area.damage là gọi cái damage của player sẽ trừ đi máu của Quái dòng if health <= 0 nghĩa là nếu máu <= 0 thì biến mất queue_free là lệnh giúp bạn làm điều đó ngoài ra còn 1 số lệnh giống queue_free() là:
- queue_free()
- free()
- remove_child
Mỗi cái đều có cách dùng riêng và không phải cái nào cũng giống nhau đâu nhé ^^
Tiếp đến là con Quái tấn công. Các bạn tạo damage cho nó rồi sau đó qua sence player
Ở cái hurtbox thì các bạn cũng connect như ở Enemy Sence
À ở cái hitbox á, các bạn cũng có thể xài chung 1 script nha cho cả 2 cái đều được nó sẽ không thay đổi giá trị nếu bạn thay đổi giá trị ở ngoài bảng Inspector, thêm script vào hitbox enemy nha vì enemy chưa có damage ở cái hitbox.
Tiếp đến code cái hàm mới connect
health -= area.damage
if health <= 0:
get_tree().change_scene("res://tscn/title screen/TitleMenu.tscn")
ở đây cũng như vừa nãy nhưng khác ở cái là get_tree().change_sence() ở cái Player chúng ta sẽ không dùng queue_free() hay cái gì mà:
- Đưa về màn hình chính sau khi chết
- Làm 1 cái màn hình end game sau đó tạo 2 nút vè màn hình chính hoặc chơi lại
Ở đây mình sẽ làm tạm 1 cái label để xem cái máu là bao nhiêu.
Tạo node mới > Canvas layer > Label
Canvaslayer là nút giúp bạn hiện thị mấy cái như label trên màn hình, theo màn hình ý
Label thì là cái label :v
Rồi vô code tạo hàm func _process(delta):
Rồi dùng $ gọi nút $CanvasLayer/Label.set_text() .
Set_text() dùng để set ký tự cho label hoặc mấy cái tương tự. Nếu bạn set_text(health) thì nó sẽ báo lỗi là không thể convert int to string nghĩa là không thể chuyển đổi giá trị interger sang string.
Để hiển thị máu các bạn làm như sau:
$CanvasLayer/Label.set_text(str(health))
Str() giúp bạn đổi giá trị số sang chữ.
Vậy đến đây là hết rồi hẹn gặp lại tỏng bài tiếp theo nhé!