2024-09-11 15:42:46 +03:00
|
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../../../../_share/media/css/org-mode.css" />
|
|
|
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../../_share/media/css/godot.css" />
|
|
|
|
|
#+title: Lesson 12: Player-Enemy Collisions
|
|
|
|
|
|
|
|
|
|
|
2024-09-11 18:22:40 +03:00
|
|
|
* Links
|
|
|
|
|
- [[../../arpg/toc.org][< Back to Main TOC]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=UILX6fBQ_Zw1cZoK][Player-enemy collision]]
|
|
|
|
|
|
2024-09-11 15:42:46 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
* Notes
|
|
|
|
|
** add collision shape to enemy sprite
|
|
|
|
|
- add CollisionShape2D to sprite root
|
|
|
|
|
|
|
|
|
|
*** add shape
|
|
|
|
|
- select collision shape 2D node from Scene Panel
|
|
|
|
|
- Go to Inspector->CollisionShape2D->Shape
|
|
|
|
|
- select 'CapsuleShape2D' from dropdown
|
|
|
|
|
|
|
|
|
|
*** modify shape
|
2024-09-11 18:22:40 +03:00
|
|
|
- Inspector->CollisionShape2D->Node2D->Transform
|
2024-09-11 15:42:46 +03:00
|
|
|
- Go to Rotation and set to 90 degrees
|
|
|
|
|
- Modify shape via handles to adjust it over sprite
|
|
|
|
|
|
2024-09-11 18:22:40 +03:00
|
|
|
*** set the z-index
|
|
|
|
|
- in CollisionShape2D to 0
|
|
|
|
|
- in sprite root node to 1
|
|
|
|
|
|
|
|
|
|
*** make sure collision shape fits all the animation frames
|
|
|
|
|
- go to the AnimateSprit2D node
|
|
|
|
|
- Inspector->AnimatedSprite2D->Animation->Frame
|
|
|
|
|
- scroll through the frames to see if they fit the collision shape properly
|
|
|
|
|
|
2024-09-17 09:24:39 +03:00
|
|
|
** */method 1/*: using character bodies and collision shapes
|
2024-09-11 18:22:40 +03:00
|
|
|
|
|
|
|
|
*** default collision code
|
|
|
|
|
- default collision handling occurs between two CharacterBody2D nodes
|
|
|
|
|
- limits each others movements
|
|
|
|
|
- occurs after the =move_and_slide= function is called
|
|
|
|
|
|
2024-09-17 09:24:39 +03:00
|
|
|
*NOTE: you are not expected to put this into the script!!!*
|
|
|
|
|
|
2024-09-11 18:22:40 +03:00
|
|
|
#+begin_src godot
|
|
|
|
|
# Using move_and_collide.
|
|
|
|
|
var collision = move_and_collide(velocity * delta)
|
|
|
|
|
if collision:
|
|
|
|
|
print("I collided with ", collision.get_collider().name)
|
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
|
|
*** handle collisions (scaffolding)
|
|
|
|
|
- first get the number of collisions that occurred
|
|
|
|
|
- this is in =get_slide_collision_count()= function
|
|
|
|
|
- loop through the number with an index
|
|
|
|
|
- in each loop get the /collision info object/ for that index with =get_slide_collisions()=
|
|
|
|
|
- =get_slide_collision= takes an index
|
|
|
|
|
- to get the /collider/ call =get_collider()= on the /collision info object/
|
|
|
|
|
|
|
|
|
|
- the function scaffolding:
|
|
|
|
|
#+begin_src godot
|
|
|
|
|
# this is the basic function
|
|
|
|
|
func handleCollision():
|
|
|
|
|
for i in get_slide_collision_count():
|
|
|
|
|
var collision = get_slide_collision(i)
|
|
|
|
|
var collider = collision.get_collider()
|
|
|
|
|
priint_debug(collider.name)
|
|
|
|
|
#+end_src
|
2024-09-11 15:42:46 +03:00
|
|
|
|
2024-09-11 18:22:40 +03:00
|
|
|
- place this function in =func _physics_process(delta)=
|
|
|
|
|
- put it after =move_and_slide= but before =updateAnimation=
|
|
|
|
|
- example:
|
|
|
|
|
#+begin_src godot
|
|
|
|
|
func _physics_process(delta):
|
|
|
|
|
handleInput()
|
|
|
|
|
move_and_slide()
|
|
|
|
|
handleCollision()
|
|
|
|
|
updateAnimation()
|
|
|
|
|
#+end_src
|
2024-09-11 15:42:46 +03:00
|
|
|
|
2024-09-17 09:24:39 +03:00
|
|
|
*** problems
|
|
|
|
|
- the player sprite might only have the shape on the lower part of his body and not the upper
|
|
|
|
|
- this is to allow him to move the body against a tree or other object and only block by the feet
|
|
|
|
|
- this causes the enemy sprite to walk directly through the player
|
|
|
|
|
|
|
|
|
|
** layer and mask
|
|
|
|
|
|
|
|
|
|
*** change collision layer and mask for players
|
|
|
|
|
- [Player Root Node]->Inspector->CharacterBody2D->Layers
|
|
|
|
|
- How Layers work
|
|
|
|
|
- the numbers of the layers selected determines what he looks for
|
|
|
|
|
- you can change the name of the layer by clicking on the three dots to the right
|
|
|
|
|
- change the layers names
|
|
|
|
|
- Layer 1: 'player'
|
|
|
|
|
- Layer 2: 'enemy'
|
|
|
|
|
|
|
|
|
|
*** change the collision layer and mask for enemies
|
|
|
|
|
- [Enemy Sprite] -> [Enemy Root Node] -> Inspector -> CollisionObject2D -> Collision -> Layers
|
|
|
|
|
- move the sprites layer and mask to '2'
|
|
|
|
|
|
|
|
|
|
*** enabling enemy sprites to collide with tilemap
|
|
|
|
|
- make all enemy sprites children of the tilemap
|
|
|
|
|
- [Tilemap Node] -> Inspector -> TileMapLayer -> TILESET
|
|
|
|
|
- INSIDE the "tileset" dropdown, click on whatever element was selected
|
|
|
|
|
- this will open up the physics layer
|
|
|
|
|
- set the layers and masks to /*BOTH*/ "1" and "2"
|
|
|
|
|
|
|
|
|
|
** method2: hurt box and hit box
|
|
|
|
|
*** basic
|
|
|
|
|
- add hurt box to player
|
|
|
|
|
- add hit box to enemy
|
|
|
|
|
|
|
|
|
|
*** create hurt box
|
|
|
|
|
- add Area2D node to [Player Scene]
|
|
|
|
|
- you can rename it 'hurtBox'
|
|
|
|
|
- add a CollisionShape2D to the Area2D node
|
|
|
|
|
- [hurtBox node] -> CollisionsShape2D -> Inspector -> CollisionShape2D -> Shape
|
|
|
|
|
- select what shape you want from the dropdown box
|
|
|
|
|
- set the collision properties for the hurt box
|
|
|
|
|
- [hurtBox node] -> CollisionObject2D -> Collision
|
|
|
|
|
- set /*ONLY*/ the mask to "1" and "2"
|
|
|
|
|
|
|
|
|
|
*** create hit box
|
|
|
|
|
- go to NPC sprite
|
|
|
|
|
- add Area2D node
|
|
|
|
|
- rename 'hitBox'
|
|
|
|
|
- add CollisionShape2D to Area2D node
|
|
|
|
|
- rotate it 90
|
|
|
|
|
|
|
|
|
|
* in the case where animation frames change shape
|
|
|
|
|
|
|
|
|
|
** modify sprite scene
|
|
|
|
|
- add AnimationPlayer node to scene
|
|
|
|
|
- remove AnimatedSprite2D
|
|
|
|
|
- add regular Sprite2D node
|
|
|
|
|
- set texture on sprite
|
|
|
|
|
- drag sprite texture to Sprite2D->Inspector->Sprite2D->Texture
|
|
|
|
|
- set Hframes and Vframes correctly
|
|
|
|
|
- Sprite2D->Inspector->Sprite2D->Animation
|
|
|
|
|
|
|
|
|
|
- move sprite up over center of scene
|
|
|
|
|
|
|
|
|
|
** MOVE THE AREA2D FOR PROPER DRAWING
|
|
|
|
|
- area2D node must be lower than the Sprite2D node
|
|
|
|
|
- this will draw it on top of the sprite
|
|
|
|
|
- make it easier to animate properly
|
|
|
|
|
|
|
|
|
|
** modify AnimationPlayer node
|
|
|
|
|
- select node
|
|
|
|
|
- in lower pane, find "Animation" dropdown
|
|
|
|
|
- select "New"
|
|
|
|
|
- call it "walkDown"
|
|
|
|
|
#+attr_html: :width 400px
|
|
|
|
|
[[../../_share/media/img/ch12/g12_animation.png]]
|
|
|
|
|
|
|
|
|
|
- set snap to 0.2
|
|
|
|
|
#+attr_html: :width 400px
|
|
|
|
|
[[../../_share/media/img/ch12/animation_snap.png]]
|
|
|
|
|
|
|
|
|
|
** add sprite animations
|
|
|
|
|
- [Sprite2D node] -> Inspector -> Sprite2D -> Animation
|
|
|
|
|
- select the X and Y of Frame Coords
|
|
|
|
|
- click the key button
|
|
|
|
|
#+attr_html: :width 250px
|
|
|
|
|
[[../../_share/media/img/ch12/frame_coords.png]]
|
|
|
|
|
|
|
|
|
|
- screen should look like
|
|
|
|
|
#+attr_html: :width 600px
|
|
|
|
|
[[../../_share/media/img/ch12/animation_timeline.png]]
|
|
|
|
|
|
|
|
|
|
- set animation length to 0.8
|
|
|
|
|
- enable looping
|
|
|
|
|
#+attr_html: :width 600px
|
|
|
|
|
[[../../_share/media/img/ch12/length_looping.png]]
|
|
|
|
|
|
|
|
|
|
** add collision detection to the frames
|
|
|
|
|
- select Area2D->CollisionShape2D node
|
|
|
|
|
- Inspector-> Node2D-> Transform
|
|
|
|
|
- make sure the bottom animation panel is visible
|
|
|
|
|
- select the first frame
|
|
|
|
|
- lock properties to the frames using key buttons
|
|
|
|
|
- position
|
|
|
|
|
- scale
|
|
|
|
|
|
|
|
|
|
#+attr_html: :width 250px
|
|
|
|
|
[[../../_share/media/img/ch12/lock_properties.png]]
|
|
|
|
|
|
|
|
|
|
#+attr_html: :width 600px
|
|
|
|
|
[[../../_share/media/img/ch12/lock_animation.png]]
|
|
|
|
|
|
|
|
|
|
*** go to the next FRAME in the animation panel
|
|
|
|
|
- adjust the shape of the collision area
|
|
|
|
|
- lock the properties as before
|
|
|
|
|
|
|
|
|
|
*** changing shape
|
|
|
|
|
- changing shape is IMPOSSIBLE
|
|
|
|
|
- we must change scale
|
|
|
|
|
- click the chains to allow you to change x and y axis independently
|
|
|
|
|
- click on the text box for each to change it
|
|
|
|
|
|
|
|
|
|
*** discreate changes
|
|
|
|
|
- the shape will appear to not change properly with the sprite
|
|
|
|
|
- this is because it's update mode is set to 'continuous'
|
|
|
|
|
- change it to discrete on both scaling and positioning
|
|
|
|
|
#+attr_html: :width 300px
|
|
|
|
|
[[../../_share/media/img/ch12/discrete.png]]
|
|
|
|
|
|
|
|
|
|
*** update the rest of the animations
|
|
|
|
|
- duplicate the current animation
|
|
|
|
|
- modify and set whatever properties are necessary for each animation
|
|
|
|
|
|
|
|
|
|
** modify script
|
|
|
|
|
- set the animations variable from $AnimatedSprite2D to $AnimationPlayer
|
|
|
|
|
|
2024-09-11 15:42:46 +03:00
|
|
|
* Video Contents
|
|
|
|
|
|
|
|
|
|
[[https://www.youtube.com/watch?v=WVQkOWY3zxQ][Lesson Link]]
|
|
|
|
|
|
|
|
|
|
#+attr_html: :class content
|
|
|
|
|
- [[https://www.youtube.com/watch?v=WVQkOWY3zxQ][00:00 Introduction]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=vhyjv3xTfYhvAMmE&t=28][00:28 body-body collision]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=qLZquUVuAC-yYN1t&t=238][03:57 layer and mask]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=GqVUob9wQvm1YH_9&t=298][04:58 hurt boxy and hit box]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=rhqR5crCcWh7vgSH&t=394][06:34 hit box animation]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=DIBeG4TRZdhcds0g&t=711][11:51 fixing move animation]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=CTRznDX_bRokCO0d&t=751][12:31 hurt-hit box collisions]]
|
|
|
|
|
- [[https://youtu.be/WVQkOWY3zxQ?si=fUUy5KhrAFLzbWdA&t=827][13:47 outro]]
|