compsci-godot-arpg/ch01/lesson-12.org
2024-11-27 05:20:17 +02:00

7.6 KiB

Lesson 12: Player-Enemy Collisions

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

  • Inspector->CollisionShape2D->Node2D->Transform
  • Go to Rotation and set to 90 degrees
  • Modify shape via handles to adjust it over sprite

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

method 1: using character bodies and collision shapes

default collision code

  • default collision handling occurs between two CharacterBody2D nodes
  • limits each others movements
  • occurs after the move_and_slide function is called

NOTE: you are not expected to put this into the script!!!

# Using move_and_collide.
var collision = move_and_collide(velocity * delta)
if collision:
    print("I collided with ", collision.get_collider().name)

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:
# 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)
  • place this function in func _physics_process(delta)

    • put it after move_and_slide but before updateAnimation
    • example:
func _physics_process(delta):
    handleInput()
    move_and_slide()
    handleCollision()
    updateAnimation()

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"
/notes/compsci-godot-arpg/media/commit/_share/media/img/ch12/g12_animation.png
  • set snap to 0.2

    /notes/compsci-godot-arpg/media/commit/_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

    /notes/compsci-godot-arpg/media/commit/_share/media/img/ch12/frame_coords.png
  • screen should look like

    /notes/compsci-godot-arpg/media/commit/_share/media/img/ch12/animation_timeline.png
  • set animation length to 0.8
  • enable looping

    /notes/compsci-godot-arpg/media/commit/_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

      /notes/compsci-godot-arpg/media/commit/_share/media/img/ch12/lock_properties.png /notes/compsci-godot-arpg/media/commit/_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

    /notes/compsci-godot-arpg/media/commit/_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

adding hurt to hit box collision

hit box

  • Player->hurtBox->Node Tab (not Inspector!)->Area2D->area_entered(area: Area2D)