4.4
So when my dizzy state finishes, it switches to the run state.
extends State
var dizzytimed: bool = false
func enter():
super.enter()
dizzytimer.start()
animation.play("dizzy")
func transition():
if dizzytimed:
get_parent().change_state("Run")
func _on_dizzy_countdown_timeout() -> void:
dizzytimed = true
But the problem is my Run state script, it switches to the Dizzy state when the boss touches the wall,
extends State
#
func enter():
super.enter()
owner.set_physics_process(true)
animation.play("default")
func exit():
super.exit()
owner.set_physics_process(false)
# Called when the node enters the scene tree for the first time.
#func _ready() -> void:
#pass # Replace with function body.
func transition():
var wallnorm = owner.get_wall_normal()
var distance = owner.direction.length()
if wallnorm:
get_parent().change_state("Dizzy")
And since the run state switches to dizzy when it touches the wall, and dizzy switches to run state when the timer ends, its gonna be a loop.
So i want it to flip, and stop touching the wall, and look the other direction and run to the player again
There are multiple solutions, and one of them would be to add a new state that the boss transitions into after exiting the dizzy
state. Then in the new state, only go to the ārunā state if the boss is not near a wall.
Another idea that does not involve adding a new state: throw the boss back a few pixels in the opposite direction it was traveling when it enters the dizzy state. It wouldnāt even be physically implausible, because in reality if you throw something against a wall and it doesnāt break or deform, it tends to bounce back.
1 Like
Can you write down an example for the new state script? ( i chose the solution: making a new state) and I dont know how to āturnā and make it go a few pixels away from the wall left or right
I donāt know what the rest of your code looks like or how your nodes are organized, so Iām not sure how helpful any code would be.
My suggestion: add two RayCast2D
s to your boss scene: one going in the direction of the positive x-axis, the other in the direction of the negative x-axis. These will help your boss sense if anything is nearby. Make them longer to detect things at greater distance, or shorter to reduce detection distance. Then add a Node2D
(or whatever), and add this script:
extends Node2D
signal not_near_wall()
@export var ray_left : RayCast2D = null
@export var ray_right RayBast2D = null
func _physics_process(delta : float)->void:
if not (ray_left.is_colliding() and ray_right.is_colliding()):
not_near_wall.emit()
Add both ray nodes to the script via the inspector. Then at the root node of your boss scene, listen to the signal:
...
func _ready()->void:
$path/to/your/new/node.not_near_wall(_on_not_near_wall.bind())
...
func _on_not_near_wall()->void:
$path/to/your/new/state/scene.transition_to_run_state()
transition_to_run_state()
should be a method in your new state that transitions to the ārunā state.
I donāt know what your tree looks like, so this almost certainly wonāt work right out of the box.
1 Like
So heres the code i made for my new state:
extends State
@onready var Rayleft: RayCast2D = $"../../Rayleft"
@onready var Rayright: RayCast2D = $"../../Rayright"
func enter():
super.enter()
owner.set_physics_process(false)
#if Rayleft.is_colliding():
#owner.position.x += 1
#elif Rayright.is_colliding():
#owner.position.x -= 1
func transition():
if Rayleft.is_colliding():
owner.position.x += 3
owner.animatedsprite.flip_h = true
get_parent().change_state("Run")
elif Rayright.is_colliding():
owner.position.x -= 3
owner.animatedsprite.flip_h = false
get_parent().change_state("Run")
Very simple, just checks if rayleft is colliding, if it is, just move the bossās position by right (its the same for rayright too).
But, since my code in the Run state only does direction.x = player.position.x - position.x in the: func area_2d_body_entered instead of the process function, it will keep moving left or right because the last time the player touched the area2d was left or right so it doesnt reset and will keep moving left or right everytime the boss switches to run state
extends State
#
func enter():
super.enter()
owner.set_physics_process(true)
animation.play("default")
func exit():
super.exit()
owner.set_physics_process(false)
# Called when the node enters the scene tree for the first time.
#func _ready() -> void:
#pass # Replace with function body.
func transition():
var wallnorm = owner.get_wall_normal()
var distance = owner.direction.length()
if wallnorm:
get_parent().change_state("Turn")
I dont want to move the direction.x = player.position.x - position.x to the process function because it will keep following where the player is, i only want it to dash one spot only.
Hereās the clip if you dont get what i mean
I dont know why my code has some # but okay
As you can see, in the video it shows that my Turn state js moving the boss by right but my run is still hitting the same wall and isnt turning to the opposite side, and since its hitting the wall, it will switch to the turn state and turn will switch to run and⦠it just loops (i removed the dizzy state for testing purposes)
This is a tough one to crack, mostly because I suspect the question has become one of game design rather than a strict programming issue. As you say, the boss immediately tries to rush the player once it gets back inside the ārunā state, and then immediately crashes into the wall. To make things even more difficult, he ends up in a pit.
During this boss fight, what should happen if the boss ends up in the pit? Itās a bit of an open-ended question. Does he jump out, climb out, or maybe teleport? At any rate, going back to the ārunā state might not be optional.
1 Like
Oh i get what you mean, first: this isnt a room for a boss, its a test room so no, pits arent in the boss room lol, the only thing i want is the boss to flip, i dont know how to write the code for that
That probably simplifies things.
From your other thread I gather that the boss has some sort of collision shape that detects the player, right? What does that look like? Is is a big rectangle that stretches out in both directions, or just one?
I think that, personally, I would center this rectangle on the boss and also make it much wider than the boss. Then on exiting the ārunā state, I would set the direction
vector to Vector2(0, 0)
. That way the boss would not move until the player enters the collision shape again. (And would even run in the correct direction without any extra code.)
1 Like
But i want the boss to flip when it hits a wall, i dont want it to have to detect the player again⦠and there are more things i want the boss to do but ofcourse i cant explain everything in one topic
Skip to 3:03, if you dont know what i mean when i said flip
Hi so i figured out how to flip and stuff i just used Vector.RIGHT or LEFT, iāll show my whole code after i fix this one annoying problem
1 Like