Logic Advice on Player Action

G4.3

What I have, Scene Powerbox, Wire and Player.

Node2D - Powerbox
-AnimatedSprite
-Area2D
–Collision

StaticBody2D - Wire

  • Animatedsprite
  • CollisionStatic
  • Area2D
  • –CollisionArea

What I want to do is when the wire breaks the player can walk over to the broken wire and press an input and activate a fixing function. The wire will then be fixed.

Conditions - The wire can only be fixed while the player holds down the input and can only work if the player is on the wire collision box. This will then trigger animation and when animation is finished the wire is fixed. If the player lets go of input or moves outside the wire collsion it will stop fixing which will then have the player start again.

Powerbox has an export which the wire scene is attached to within the inspector.

When the player moves over the wire the script on powerbox knows its the player. After this point I get logic lost.

Any ideas please???

This is a pretty complicated task but the system you want to use is pretty well developed. Ill try and write some stuff based on my code.

extends StaticBody2D

signal wire_fixed

enum WireState {FIXED, BROKEN, BEING_FIXED}

# you can use a global Enums for this if you want to as well
# But I just used enums here cause its only for wires.

export var fix_time = 3.0
var current_state = WireState.FIXED
var player_in_area = false
var fix_progress = 0.0
var animation_player = null

func _ready():
    if has_node("AnimationPlayer"):
        animation_player = $AnimationPlayer

    $Area2D.connect("body_entered", self, "_on_Area2D_body_entered")
    $Area2D.connect("body_exited", self, "_on_Area2D_body_exited")

func _process(delta):
    if current_state == WireState.BROKEN and player_in_area:
        if Input.is_action_pressed("fix_wire"):
            fix_progress += delta
            if animation_player:
                animation_player.play("fixing")
            
            if fix_progress >= fix_time:
                complete_fix()
        else:
            reset_fix_progress()
    
func break_wire():
    current_state = WireState.BROKEN

    if animation_player:
        animation_player.play("broken")

func complete_fix():
    current_state = WireState.FIXED
    fix_progress = 0.0
    if animation_player:
        animation_player.play("fixed")
    emit_signal("wire_fixed")

func reset_fix_progress():
    fix_progress = 0.0
    if current_state == WireState.BEING_FIXED:
        current_state = WireState.BROKEN
    if animation_player:
        animation_player.stop()

func _on_Area2D_body_entered(body):
    if body.is_in_group("player"):
        player_in_area = true

func _on_Area2D_body_exited(body):
    if body.is_in_group("player"):
        player_in_area = false
        reset_fix_progress()

Then use something like this script for your Powerbox that references the wire:

extends Node2D

export(NodePath) var wire_path
var wire = null

func _ready():
    if wire_path:
        wire = get_node(wire_path)
        wire.connect("wire_fixed", self, "_on_Wire_fixed")

# Called when the wire is fixed
func _on_Wire_fixed():
    $AnimatedSprite.play("powered")

Couple of things I want to add on to this, Because I’m writing all of this in code. I’m ref’ing nodes by hard coding them. DONT DO THIS IN YOU CODE. Do something that more versatile like an @export with the correct node reference as a var for Wire or the Powerbox.

Also make sure to create a group for the player and add it to that group that I made in the code. Name it whatever you wanna.

Also you can use more complicated signals or custom signals. I can suggest a vid for that if you want to. Those can be hard to get down.

1 Like

@noaht5.1999 Thanks for this! Just had a wee hour looking over this and applying it to my situation. Obviously not intended to be plug and play but this did get me out of a jam!

Made me rethink a number of things and I seem to be back on track! Aprreciate your time.

1 Like