Help me with the code (nothing helps)

проблема в чем при запуске игры игрок зависает в воздухе а не понимаю в чем ошибка—the problem is that when starting the game, the player freezes in the air and I don’t understand what the error is

extends CharacterBody2D

enum {
MOVE,
ATTACK,
ATTACK2,
ATTACK3,
BLOCK,
SLIDE,
DAMAGE,
CAST,
DEATH
}

const SPEED = 150.0
const JUMP_VELOCITY = -400.0
const GRAVITY = 980
@onready var anim = $AnimatedSprite2D
@onready var animPlayer = $AnimationPlayer

var health = 100
var gold = 0
var state: = MOVE
var run_speed = 1
var combo = false
var attack_cooldown = false
var player_pos

func _ready() → void:
Signals.connect(“enemy_attack”, Callable (self, “_on_damage_received”))

func _physics_process(delta: float) → void:
velocity.y += GRAVITY * delta
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
if velocity.y > 0:
anim.play(“fall”)

match state:
	MOVE:
		move_state()
	ATTACK:
		attack_state()
	ATTACK2:
		attack2_state()
	ATTACK3:
		attack3_state()
	BLOCK:
		block_state()
	SLIDE:
		slide_state()
	DAMAGE:
		damage_state()
	DEATH:
		death_state()
	
	
if not is_on_floor():
	velocity += get_gravity() * delta

func death_state ():
if health <= 0:
health = 0
velocity.x = 0
animPlayer.play(“Death”)
await animPlayer.animation_finished
queue_free()
get_tree().change_scene_to_file(“res://menu.tscn”)

move_and_slide()

player_pos = self.position
Signals.emit_signal("player_position_update", player_pos)

func move_state ():
var direction := Input.get_axis(“left”, “right”)
if direction:
velocity.x = direction * SPEED * run_speed
if velocity.y == 0:
if run_speed == 1:
anim.play(“Walk”)
else:
anim.play(“Run”)
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
if velocity.y == 0:
animPlayer.play(“Idle”)
if direction == -1:
anim.flip_h = true

elif direction == 1:
	anim.flip_h = false
if Input.is_action_pressed("run"):
	run_speed = 2
else:
	run_speed = 1 
	
if Input.is_action_pressed("block"):
	if velocity.x == 0:
		state = BLOCK
	else:
		state = SLIDE
		
if Input.is_action_just_pressed("attack") and attack_cooldown == false:
	state = ATTACK

func block_state ():
velocity.x = 0
animPlayer.play(“Block”)
if Input.is_action_pressed(“block”):
state = MOVE

func slide_state():
animPlayer.play(“Slide”)
await animPlayer.animation_finished
state = MOVE

func attack_state():
if Input.is_action_just_pressed(“attack”) and combo == true:
state = ATTACK2
velocity.x = 0
animPlayer.play(“Attack”)
await animPlayer.animation_finished
attack_freeze()
state = MOVE

func attack2_state():
if Input.is_action_just_pressed(“attack”) and combo == true:
state = ATTACK3
animPlayer.play(“Attack2”)
await animPlayer.animation_finished
state = MOVE

func attack3_state():
animPlayer.play(“Attack3”)
await animPlayer.animation_finished
state = MOVE

func combo1 ():
combo = true
await animPlayer.animation_finished
combo = false

func attack_freeze ():
attack_cooldown = true
await get_tree().create_timer(0.5).timeout
attack_cooldown = false

func damage_state ():
velocity.x = 0
anim.play(“Damage”)
await anim.animation_finished
state = MOVE

func _on_damage_received (enemy_damage):
health -= enemy_damage
if health <= 0:
health = 0
state = DEATH
else:
state = DAMAGE

print(health)

этот был код игрока – This was the player’s code
сейчас будет код врага --The enemy’s code is coming up now
extends CharacterBody2D

enum {
IDLE,
ATTACK,
CHASE
}
var state: int = 0:
set (value):
state = value
match state:
IDLE:
idle_state()
ATTACK:
attack_state()

@onready var animPlayer = $AnimationPlayer
@onready var sprite = $AnimatedSprite2D

var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)
var player
var direction
var damage = 20

func _ready():
Signals.connect(“player_position_update”, Callable (self, “_on_player_position_update”))

func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta

if state == CHASE:
	chase_state()

move_and_slide()

func _on_player_position_update (player_pos):
player = player_pos

func _on_attack_range_body_entered(body):
state = ATTACK

func idle_state ():
animPlayer.play(“Idle”)
await get_tree().create_timer(1).timeout
$AttackDirection/AttackRange/CollisionShape2D2.disabled = false
state = CHASE

func attack_state ():
animPlayer.play(“Attack”)
await animPlayer.animation_finished
$AttackDirection/AttackRange/CollisionShape2D2.disabled = true
state = IDLE

func chase_state():
direction = (player.position - global_position).normalized()
if direction.x < 0:
sprite.flip_h = true
$AttackDirection.rotation_degrees = 180
else:
sprite.flip_h = false
$AttackDirection.rotation_degrees = 0

func _on_hit_box_area_entered(area):
Signals.emit_signal(“enemy_attack”, damage)

In its current state your code is almost impossible to read.

Please edit your post and place a line with three (3) backticks (`) above and below the two code sections (like shown in the following paragraph). That lets the forum software format those blocks correctly.

```
your code should be placed like this
```

From what I can see in your post it seems that in your player code the call to move_and_slide() is not in the _physics_process() function but in the death_state() function.

You must call move_and_slide() every physics frame for the player to move.

где я должен заменить move_and_slide() на это в коде врага или коде игрока,и написать немного код где примеряется строка move_and_slide(),я больше недели не могу ничего сделать я еще новичок – where should I replace move_and_slide() with this in the enemy’s code or the player’s code, and write some code where the move_and_slide() string is being tried on, I haven’t been able to do anything for more than a week, I’m still a beginner

You usually put move_and_slide() at the end of _physics_process(). The enemy already has that, so you only need to add it in the player’s code.

And currently, you’re applying gravity three times on the player (probably from trying to fix this issue), so you should remove two of these.

1 Like

Part of your player code seems to be like this:

func _physics_process(delta: float) -> void:
	velocity.y += GRAVITY * delta
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta
	if velocity.y > 0:
		anim.play(“fall”)
	
	match state:
		MOVE:
			move_state()
		ATTACK:
			attack_state()
		ATTACK2:
			attack2_state()
		ATTACK3:
			attack3_state()
		BLOCK:
			block_state()
		SLIDE:
			slide_state()
		DAMAGE:
			damage_state()
		DEATH:
			death_state()
	
	
	if not is_on_floor():
		velocity += get_gravity() * delta


func death_state ():
	if health <= 0:
		health = 0
		velocity.x = 0
		animPlayer.play(“Death”)
		await animPlayer.animation_finished
		queue_free()
		get_tree().change_scene_to_file(“res://menu.tscn”)

	move_and_slide()

	player_pos = self.position
	Signals.emit_signal("player_position_update", player_pos)

The last three lines (that are currently part of the death_state() function belong to the _physics_process() function like this:

func _physics_process(delta: float) -> void:
	velocity.y += GRAVITY * delta
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta
	if velocity.y > 0:
		anim.play(“fall”)
	
	match state:
		MOVE:
			move_state()
		ATTACK:
			attack_state()
		ATTACK2:
			attack2_state()
		ATTACK3:
			attack3_state()
		BLOCK:
			block_state()
		SLIDE:
			slide_state()
		DAMAGE:
			damage_state()
		DEATH:
			death_state()
	
	
	if not is_on_floor():
		velocity += get_gravity() * delta

	move_and_slide()

	player_pos = self.position
	Signals.emit_signal("player_position_update", player_pos)


func death_state ():
	if health <= 0:
		health = 0
		velocity.x = 0
		animPlayer.play(“Death”)
		await animPlayer.animation_finished
		queue_free()
		get_tree().change_scene_to_file(“res://menu.tscn”)

1 Like

я понял у меня не прописано анимация падение,у врага показывает строчку на эту
direction = (player.position - global_position).normalized() потом сказали поменять на эту
direction = ($Player.position - global_position).normalized()
ошибка
сейчас скину весь код
и ошибка возникает сейчас напишу ----chase_state: Invalid access to property or key ‘position’ on a base object of type ‘null instance’.

I realized I didn’t have a drop animation, the enemy shows a line on this one.
direction = (player.position - global_position).normalized() Then they said to change it to this one
direction = ($Player.position - global_position).normalized()
error
I’m going to upload the entire code now
and the error occurs now I will write
----chase_state: Invalid access to property or key ‘position’ on a base object of type ‘null instance’.

extends CharacterBody2D

enum {
IDLE,
ATTACK,
CHASE
}
var state: int = 0:
set (value):
state = value
match state:
IDLE:
idle_state()
ATTACK:
attack_state()

@onready var animPlayer = $AnimationPlayer
@onready var sprite = $AnimatedSprite2D

var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)
var player
var direction
var damage = 20

func _ready():
Signals.connect(“player_position_update”, Callable (self, “_on_player_position_update”))

func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta

if state == CHASE:
	chase_state()

move_and_slide()

func _on_player_position_update (player_pos):
player = player_pos

func _on_attack_range_body_entered(body):
state = ATTACK

func idle_state ():
animPlayer.play(“Idle”)
await get_tree().create_timer(1).timeout
$AttackDirection/AttackRange/CollisionShape2D2.disabled = false
state = CHASE

func attack_state ():
animPlayer.play(“Attack”)
await animPlayer.animation_finished
$AttackDirection/AttackRange/CollisionShape2D2.disabled = true
state = IDLE

func chase_state():
direction = ($Player.position - global_position).normalized()
if direction.x < 0:
sprite.flip_h = true
$AttackDirection.rotation_degrees = 180
else:
sprite.flip_h = false
$AttackDirection.rotation_degrees = 0

func _on_hit_box_area_entered(area):
Signals.emit_signal(“enemy_attack”, damage)

I don’t think that you have the player as a child node of your enemies and therefore accessing $Player.position will never work. Using the $ notation allows you to easily access the child nodes of the current scene - where the current scene in your case means the enemy scene.

Your previous approach (using player.position) also did not work.

That is because it seems that your variable player does not contain a reference to the player node. It seems that it already contains the players position according to the following code:

func _on_player_position_update (player_pos):
	player = player_pos

Therefore in the code that uses the players position you should use that player variable directly:

func chase_state():
	direction = (player - global_position).normalized()
	if direction.x < 0:
		sprite.flip_h = true
		$AttackDirection.rotation_degrees = 180
	else:
		sprite.flip_h = false
		$AttackDirection.rotation_degrees = 0

Maybe you should rename that player variable to better represent it’s purpose: to contain the players position:

var player_position: Vector2

func _on_player_position_update (player_pos: Vector2):
	player_position = player_pos

func chase_state():
	direction = (player_position - global_position).normalized()
	if direction.x < 0:
		sprite.flip_h = true
		$AttackDirection.rotation_degrees = 180
	else:
		sprite.flip_h = false
		$AttackDirection.rotation_degrees = 0

func _on_player_position_update(player_pos: Vector2) → void:
print("Player position updated: ", player_pos)
я добавил другое , что ты написал не работает и возникает ошибку,
игрок в воздухе вроде ошибок нет а проблема если убрать анимацию падение то игрок в воздухе ходить не умеет аттаковать и скользить , я так понял что нету гравитации как мне ее добавить? — I added something else that you wrote doesn’t work and an error occurs,
the player in the air doesn’t seem to have any errors, but the problem is if you remove the falling animation, then the player in the air can’t walk, attack and slide, I understand that there is no gravity, how do I add it?

сейчас скину проект , если не сложно сможешь там поправить или исправить и мне обратно отправить, пожалуйста помоги–I’ll send the project now, if it’s not difficult, you can fix it or fix it and send it back to me, please help

I changed the following things:

player.gd:

  • I removed the player position variables from the script. These are unnecessary. The script is attached to the player node and the position can be directly accessed.
  • I removed a duplicate gravity calculation from the _physics_process function.
  • I moved two lines (move_and_slide() and Signals.emit_signal("...") from the end of the death_state() function to the end of the _physics_process function where they belong.
  • I removed an extraneous move_and_slide() call from the _on_damage_received() function.
  • I added some code so that the death_state() function only executes once. See separate remarks below.

mushroom.gd

  • I changed the _on_player_position_update() function so that it updates the player_position variable in that script.

Remarks regarding the death_state:

If the player diese the function death_state() is called from the _physics_process() function 60 times per second. Every time this function is called it does reset some values, makes sure that the “Death” animation is played and then registers a piece of code that should run once the animation finishes.

It seems that this leads to problems if you call get_tree().change_scene_to_file("res://menu.tscn") within that code block after the await.

Changing that code to get_tree().change_scene_to_file.call_deferred("res://menu.tscn") solves the problem.


(I hope this automatic translation is usable)
Я изменил следующее:

player.gd:

  • Я удалил переменные положения игрока из скрипта. Они не нужны. Скрипт привязан к узлу игрока, и к положению можно получить прямой доступ.
  • Я удалил дубликат вычисления силы тяжести из функции _physics_process.
  • Я переместил две строки (move_and_slide() и Signals.emit_signal(«...») из конца функции death_state() в конец функции _physics_process, где они и должны быть.
  • Я удалил лишний вызов move_and_slide() из функции _on_damage_received().
  • Я добавил код, чтобы функция death_state() выполнялась только один раз. См. отдельные замечания ниже.

mushroom.gd

  • Я изменил функцию _on_player_position_update(), чтобы она обновляла переменную player_position в этом скрипте.

Примечания относительно death_state:

Если игрок умирает, функция death_state() вызывается из функции _physics_process() 60 раз в секунду. Каждый раз, когда вызывается эта функция, она сбрасывает некоторые значения, обеспечивает воспроизведение анимации «Смерть», а затем регистрирует фрагмент кода, который должен выполняться по окончании анимации.

Похоже, что это приводит к проблемам, если вы вызываете get_tree().change_scene_to_file(«res://menu.tscn») в этом блоке кода после await.

Изменение этого кода на get_tree().change_scene_to_file.call_deferred(«res://menu.tscn») решает проблему.

Переведено с помощью DeepL.com (бесплатная версия)


player.gd
extends CharacterBody2D

enum {
	MOVE,
	ATTACK,
	ATTACK2,
	ATTACK3,
	BLOCK,
	SLIDE,
	DAMAGE,
	CAST,
	DEATH
}

const SPEED = 150.0
const JUMP_VELOCITY = -400.0
const GRAVITY = 980
@onready var anim = $AnimatedSprite2D
@onready var animPlayer = $AnimationPlayer

var health = 100
var gold = 0
var state: = MOVE
var run_speed = 1
var combo = false
var attack_cooldown = false

func _ready() -> void:
	Signals.connect("enemy_attack", Callable (self, "_on_damage_received"))

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta
	if velocity.y > 0:
		anim.play("Fall")
		
	match state:
		MOVE:
			move_state()
		ATTACK:
			attack_state()
		ATTACK2:
			attack2_state()
		ATTACK3:
			attack3_state()
		BLOCK:
			block_state()
		SLIDE:
			slide_state()
		DAMAGE:
			damage_state()
		DEATH:
			death_state()
	
	move_and_slide()
	Signals.emit_signal("player_position_update", self.position)
		
func death_state ():
	if health <= 0:
		health = 0 
		velocity.x = 0 
		animPlayer.play("Death")
		await animPlayer.animation_finished
		get_tree().change_scene_to_file.call_deferred("res://menu.tscn")

func move_state ():
	var direction := Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * SPEED * run_speed
		if velocity.y == 0:  
			if run_speed == 1:     
				anim.play("Walk")
			else:
				anim.play("Run")
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		if velocity.y == 0:
			animPlayer.play("Idle")
	if direction == -1:
		anim.flip_h = true
		
	elif direction == 1:
		anim.flip_h = false
	if Input.is_action_pressed("run"):
		run_speed = 2
	else:
		run_speed = 1 
		
	if Input.is_action_pressed("block"):
		if velocity.x == 0:
			state = BLOCK
		else:
			state = SLIDE
			
	if Input.is_action_just_pressed("attack") and attack_cooldown == false:
		state = ATTACK

func block_state ():
	velocity.x = 0
	animPlayer.play("Block")
	if Input.is_action_pressed("block"):
		state = MOVE
	
func slide_state():
	animPlayer.play("Slide")
	await animPlayer.animation_finished
	state = MOVE
	
func attack_state():
	if Input.is_action_just_pressed("attack") and combo == true:
		state = ATTACK2
	velocity.x = 0
	animPlayer.play("Attack")
	await animPlayer.animation_finished
	attack_freeze()
	state = MOVE
	
func attack2_state():
	if Input.is_action_just_pressed("attack") and combo == true:
		state = ATTACK3
	animPlayer.play("Attack2")
	await animPlayer.animation_finished
	state = MOVE
	
func attack3_state():
	animPlayer.play("Attack3")
	await animPlayer.animation_finished
	state = MOVE
	
func combo1 ():
	combo = true 
	await animPlayer.animation_finished
	combo = false 
	
func attack_freeze ():
	attack_cooldown = true 
	await get_tree().create_timer(0.5).timeout
	attack_cooldown = false 
	
func damage_state ():
	velocity.x = 0
	anim.play("Damage")
	await anim.animation_finished
	state = MOVE

func _on_damage_received (enemy_damage):
	health -= enemy_damage
	if health <= 0:
		health = 0 
		state = DEATH
	else:
		state = DAMAGE
	
	print(health)
mushroom.gd
extends CharacterBody2D

enum {
	IDLE,
	ATTACK,
	CHASE
}
var state: int = 0:
	set (value):
		state = value
		match state:
			IDLE:
				idle_state()
			ATTACK:
				attack_state()

@onready var animPlayer = $AnimationPlayer
@onready var sprite = $AnimatedSprite2D

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var direction
var damage = 20
var player_position: Vector2

func _ready():
	Signals.connect("player_position_update", Callable (self, "_on_player_position_update"))

func _physics_process(delta):
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta
		
	if state == CHASE:
		chase_state()
	
	move_and_slide()
	
func _on_player_position_update (player_pos):
	player_position = player_pos

func _on_attack_range_body_entered(body):
	state = ATTACK 
	
func idle_state ():
	animPlayer.play("Idle")
	await get_tree().create_timer(1).timeout
	$AttackDirection/AttackRange/CollisionShape2D2.disabled = false
	state = CHASE
	
func attack_state ():
	animPlayer.play("Attack")
	await animPlayer.animation_finished
	$AttackDirection/AttackRange/CollisionShape2D2.disabled = true
	state = IDLE

func chase_state():
	direction = (player_position - global_position).normalized()
	if direction.x < 0:
		sprite.flip_h = true
		$AttackDirection.rotation_degrees = 180
	else:
		sprite.flip_h = false
		$AttackDirection.rotation_degrees = 0

func _on_hit_box_area_entered(area):
	Signals.emit_signal("enemy_attack", damage)

Появилась новая проблема я создал глобальный скрипт везде поменял у игрока и тут при запуске игры перекидывает на уровень скрипт показывает строку — A new problem has appeared, I created a global script, changed it everywhere for the player, and then when the game starts, it throws the script to the level and shows the line

как мне исправить эту ошибку снизу закреплю материал — how do I fix this error? I’ll fix the material from below

я там поменял в скобках global.player_health ---- я там поменял global.player_health в скобках.

ошибка — _process: недопустимый доступ к свойству или ключу «Global» базового объекта типа «CharacterBody2D (player.gd)».

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.