Godot Version
Replace this line with your Godot version
Question
How would you go about doing that? Would it be with vectors or raycasting?
Replace this line with your Godot version
How would you go about doing that? Would it be with vectors or raycasting?
What are your own thoughts on how to solve this problem? You seem to have narrowed down the solution to one that includes either “vectors” or “raycasting”. What makes you think you need to use these?
On a sidenote, a statement saying that a solution needs to use “vectors” in gamedev is kinda as abstract as it gets. You can’t get around using vectors. So, could you elaborate a bit?
Well I was thinking of making a collision box on the top of the enemy and using Vectors for the player to collide with that box, but I’m struggling how to do that. I could be wrong, I am new to this engine.
I see. Let’s wait for @yesko’s response since he seems to be conjuring up a solution for you.
As far as I know, Super Mario basically does it like this:
Of course, that’s not the only way to do it.
As @Sweatix said, using vectors is kind of essential in gamedev so it’s hard to tell what you mean with the phrase…
But I assume you mean the solution I described but “in reverse”, so the player has a collision shape that covers their entire body and the enemy has a collision shape at their head checking for collision. For this to work you would also need to check if the player has a downward velocity (so they can’t just walk into an enemy to kill them) but other than that it’s a valid solution.
Here is what I would do to implement it:
Thanks, can it by physics process or just regular process?
And, how do I check under the function if the enemies area is colliding with the players areas?
Yeah sorry, physics process is actually better in this case because you’re interacting with the physics engine. Both theoretically work though
Area2D has a function has_overlapping_areas with which you can detect if there are any intersecting areas and with get_overlapping_areas you can get those areas
Can the script be in the main node or should i make a script for the area2d child node?
Basically, was doing Brackeys tutorial and maybe the enemies just being generic 2D nodes was not a good idea?
I use Area Collision shapes for this above the player.
extends CharacterBody2D
const SPEED = 100.0
const JUMP_VELOCITY = -300.0
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var collision = get_slide_collision
@onready var collision_shape_bottom = $Area2D/CollisionShapeBottom
@onready var animated_sprite = $AnimatedSprite2D
@onready var grunt = $"../Grunt"
@onready var collision_shape = $Area2D/CollisionShape2D
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
if collision_shape_bottom = direction
# Handle Jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
$Jump.play()
velocity.y = JUMP_VELOCITY
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var direction = Input.get_axis("move_left", "move_right")
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
# Animates the Player
if is_on_floor():
if direction == 0:
animated_sprite.play("Idle")
else:
animated_sprite.play("Walk")
else:
animated_sprite.play("Jump")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
Here’s my code for the player character, honestly, still getting stumped, maybe I should just do more tutorials, was doing Brackeys and the 2D Dodge the creeps and learned some stuff, but some of this connecting signals and learning what each function does and reading the documentation just frustrates me, maybe I should just go back to Game Maker lol.
It usually works okay to have them just be Node2Ds, but if you feel like it’s achievable for you it’s better to give them their own class that has methods like kill or damage or something. This just makes them more independent from the rest of the game and prevents the main script from getting bloated with many different systems.
In my opinion, you should have the the Area2D’s be handled by their respective scene roots, so the player handles their own areas.
You can do this easily by getting a reference to the area in the script (e.g. @onready var area: Area2D = $Area2D) and then managing the reference.
I don’t think tutorials are the best way to learn, they are good for learning the absolute basics, but from there, (when possible) you should try to solve every “large” problem yourself and ask, research, or watch tutorials about the smaller things that are holding you back. This will inevitably lead to “imperfect” code or architecture but no one is ever perfect at game development and you will learn a lot more trying to find a solution than watching someone find the best solution and copying them.
I’ll include some code snippets that should hopefully help you put the feature in place
# in the player script
@onready var area: Area2D = $Area2D # replace this with the actual node path to the Area2D
# in the player script
# function to handle the player bouncing on enemies
func _handle_enemy_bouncing() -> void:
# player needs to be falling to bounce on enemies, so if they're not we just cancel the function
if velocity.y <= 0:
return
# if there are no enemies' areas overlapping with "area", there are no enemies that the player can bounce on
if not area.has_overlapping_areas():
return
# get one of the enemy areas that are overlapping with "area"
var enemy_area: Area2D = area.get_overlapping_areas()[0]
# to get the scene root call get_owner() on the area. This assumes that you have an enemy scene
var enemy: Node2D = enemy_area.get_owner()
# whatever happens when the player bounces on an enemy goes in the following lines!
enemy.queue_free() # e.g. destroy the enemy
velocity.y = JUMP_VELOCITY # make the player bounce upward
# at the top of _physics_process in the player script
_handle_enemy_bouncing()
By the way, you might be wondering what’s up with the colon and type I put after var variable_name (e.g. var enemy: Node2D = enemy_area.get_owner()). It’s called “static typing” and it means telling the engine what a variable is supposed to store. Without the static types, something like this is possible:
var test = 1
test = "Hello, world!"
test is first assigned an integer and then a string without any errors.
This seems pretty handy at first, but it’s a lot more error-prone than its alternative and you don’t get much code completion with this.
var test: int = 1
test = "Hello, world!" # the engine will complain about this line because "Hello, world" isn't an int
With static typing every variable can only have one type, which prevent a lot of very annoying bugs because you can’t accidentally assign a variable the wrong value anymore. It also makes it clearer what a variable does. A variable just called var position could be an int, a float, a Vector2, or a Vector3, depending on context. But if you use var position: Vector2 instead, everyone immediately knows what position is
Looks good, just put it in, getting an error with the area part of the line, going to try and figure that out.
Line 59:Identifier "area" not declared in the current scope.
Line 63:Identifier "area" not declared in the current scope.
EDIT: NVM, fixed it, it works! Thanks so much! Going to look more into this code to understand it more.
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.