#+HTML_HEAD: #+HTML_HEAD: #+title: Lesson 12: Player-Enemy Collisions * Links - [[../../arpg/toc.org][< Back to Main TOC]] - [[https://youtu.be/WVQkOWY3zxQ?si=UILX6fBQ_Zw1cZoK][Player-enemy collision]] * 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!!!* #+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 - 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 *** 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 * 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]]