Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | amaou310 |
I am very new to godot and making 2d platformer zombie game.
I have made an enemy that can do following things when collide with player.
(1) Disable player movement, disable player visibility, lock player’s position
(2) Play enemy grab attack animation, show button mashing progress bar
(3)-(1) If cleared, enable player visibility, unlock player’s position, enemy return to chase state
(3)-(2) After few sec, enable player movement
(4)-(1) If failed, play enemy execution animation
(4)-(2) when animation finished, enable player visibility, unlock player’s position
(4)-(3) After few sec, enable player movement
Everything works perfectly fine except, when I duplicated enemy, duplicated one is synchronized with original one. So when I collide with duplicated enemy, the button mashing progress bar will also be shown upon original one.
I would appreciate if you could kindly teach me how to fix this problem.
When it is not duplicated:
When it is duplicated (Left is duplicated one, and Right is original one):
Player Script: Sorry if my code is messy and annoyingly hard to see
class_name Player
extends KinematicBody2D
var speed = 200
var acceleration = 30
var friction = 15
var gravity = 1500
var air_jump = true
var jump_strength = 570
var air_jump_strength := 550
var air_friction = 1
var can_move = true
var player_in_hitbox: bool = false
var max_hp = 100
var current_hp
var _velocity := Vector2.ZERO
onready var position2D = $Position2D
onready var _animation_player: AnimationPlayer = $Position2D/PlayerSkinIK/AnimationPlayer
onready var hurtbox_collision = $HurtboxPlayer/CollisionShape2D and $HurtboxPlayer/CollisionShape2D2
onready var player_grab_finished = get_node("../Mushroom")
onready var label = get_node("Label")
signal player_in_hitbox_false() #signal for player movement disable
signal player_in_hitbox_true() #signal for player movement disable
func _ready():
player_grab_finished.connect("grab_finished", self, "grab_finished_signal_received") #connect mushroom
current_hp = max_hp
func get_input_direction() -> float:
if player_in_hitbox: #disable player movement if true
return 0.0
var _horizontal_direction = ( #player movement direction
Input.get_action_strength("move_right")
- Input.get_action_strength("move_left")
)
return _horizontal_direction
func _process(delta: float) -> void:
if get_global_mouse_position().x > $Position2D/PlayerSkinIK.global_position.x: #flip player sprite
position2D.scale.x=1
else:
position2D.scale.x=-1
if can_move == false: #lock player position when in Grab Attack
self.position = get_node("../Mushroom/HitPosition").global_position
func grab_finished_signal_received(): #Grab Finished
print("Grab Finished!")
label.text="CAN'T MOVE"
_animation_player.play("Player-Damaged IK")
can_move = true
_velocity.x = 1 * -250
self.visible = true
$player_in_hitboxTimer.start()
func _on_player_in_hitboxTimer_timeout(): #After Grab Finished
print("FREE!")
label.text="CAN MOVE"
player_in_hitbox = false
$player_in_hitboxTimer.is_stopped()
emit_signal("player_in_hitbox_true")
func _on_HurtboxPlayer_area_entered(area: Area2D): #When Player Enter Enemy Hitbox
if area.name == "HitboxMushroom":
label.text="CAN'T MOVE"
player_in_hitbox = true #Disable Movement
can_move = false #Lock Position
self.visible = true #Disable Visibility
emit_signal("player_in_hitbox_false") #Emit Signal to Disable Shooting
pass
Enemy Script:
extends KinematicBody2D
var max_hp = 100
var current_hp= max_hp
var defense = 0
var speed = 100
var chase_speed = 100
var gravity = 10
var direction = -1
var velocity = Vector2.ZERO
onready var _animation_player: AnimationPlayer = $Position2D/Node2D/AnimationPlayer
onready var sprite = get_node("Position2D/Node2D")
onready var flashTimer = $flashTimer
onready var player = get_node("../Player")
onready var enemy_collision = get_node("EnemyCollision")
onready var label = get_node("Label")
signal button_mashing_start()
signal grab_finished()
enum state {IDLE, CHASE, GRAB, FINISH, DEATH}
var enemy_state = state.IDLE
func _ready():
enter_state(state.IDLE)
$Position2D/Node2D/AnimationPlayer.connect("animation_finisehd", self, "on_animation_finished")
current_hp = max_hp
pass
func _physics_process(delta):
process_state()
pass
func enter_state(pass_state):
if(enemy_state != pass_state):
leave_state(enemy_state)
enemy_state = pass_state
if(pass_state == state.IDLE):
_animation_player.play("Mushroom-Idle")
label.text="IDLE"
if(pass_state == state.CHASE):
_animation_player.play("Mushroom-Idle")
label.text="CHASE"
if(pass_state == state.GRAB):
_animation_player.play("Mushroom-Grab")
label.text="GRAB01"
if(pass_state == state.FINISH):
_animation_player.play("Mushroom-Execution")
label.text="GRAB02"
if(pass_state == state.DEATH):
_animation_player.play("Mushroom-Idle")
label.text="DEATH"
func process_state():
if(enemy_state == state.IDLE):
process_idle()
if(enemy_state == state.CHASE):
process_chase()
if(enemy_state == state.GRAB):
process_grab()
if(enemy_state == state.FINISH):
process_finish()
if(enemy_state == state.DEATH):
process_death()
func leave_state(pass_state):
pass
func process_idle():
if is_on_wall() or not $Position2D/FloorRay.is_colliding() and is_on_floor():
print("turn around")
direction = direction * -1
flip()
velocity.y += gravity
velocity.x = speed * direction
velocity = move_and_slide(velocity, Vector2.UP)
if enemy_collision.is_colliding():
velocity += enemy_collision.get_push_vector() * 2.5
func process_chase():
if velocity.x>0:
$Position2D.scale.x=-1
elif velocity.x<0:
$Position2D.scale.x=1
velocity = (player.position - position).normalized()
if not is_on_floor():
velocity.y += gravity
if enemy_collision.is_colliding():
velocity += enemy_collision.get_push_vector() * 2.5
velocity = move_and_slide(velocity * chase_speed)
func process_grab():
velocity.y += 0
velocity.x = 0 * direction
velocity = move_and_slide(velocity, Vector2.UP)
emit_signal("button_mashing_start")
func process_finish():
velocity.y += 0
velocity.x = 0 * direction
velocity = move_and_slide(velocity, Vector2.UP)
func process_death():
velocity.x = 0 * direction
velocity.y += gravity
velocity = move_and_slide(velocity, Vector2.UP)
set_collision_mask_bit(0, false)
func _on_AnimationPlayer_animation_finished(anim_name):
print("Grab02 End!")
emit_signal("grab_finished")
enter_state(state.CHASE)
func flip(): #Flip Sprite
if direction>0:
$Position2D.scale.x=-1
elif direction<0:
$Position2D.scale.x=1
func _on_HitboxMushroom_area_entered(area):
if !area.name == "HurtboxPlayer":
enter_state(state.CHASE)
if area.name == "HurtboxPlayer":
print("Grab01!")
enter_state(state.GRAB)
func _on_PlayerDetector_area_entered(area: Area2D): #Player Search Area. Chase when Player entered
if area.name == "HurtboxPlayer":
print("found you !")
enter_state(state.CHASE)
pass
func _on_PlayerDetector_area_exited(area: Area2D): #Player Search Area. Stop Chase when Player exited
if area.name == "HurtboxPlayer":
print("lost you !")
enter_state(state.IDLE)
pass
func _on_ProgressBar_button_mashing_cleared():
enter_state(state.CHASE)
emit_signal("grab_finished")
print("Return Chase!")
pass
func _on_ProgressBar_button_mashing_failed():
enter_state(state.FINISH)
print("Grab02!")
pass
Progress Bar Script:
extends ProgressBar
var start = false
signal button_mashing_cleared()
signal button_mashing_failed()
func _ready():
set_visible(false)
func set_bar_value(value_to_set):
value = value_to_set
func _physics_process(delta):
if not start == false:
set_visible(true)
value -= 15 * delta
if Input.is_action_just_pressed("jump"):
set_bar_value(value + 5)
if(value <= 0):
print("Bar Failed!")
start = false
set_visible(false)
set_bar_value(50)
emit_signal("button_mashing_failed")
elif(value >= 100):
print("Bar Cleared!")
start = false
set_visible(false)
set_bar_value(50)
emit_signal("button_mashing_cleared")
func _on_Mushroom_button_mashing_start():
start = true
Try to expaind the method you use to duplicate the enemy.
I think this will solve the problem.
mrfatalo | 2022-08-21 17:41
I simply right clicked enemy node, and duplicated.
amaou310 | 2022-08-22 10:57