class_name WrappingManager extends Node @export var sprite: AnimatedSprite2D @export var shape: Node # FIXME (also in refactor see below) this is bad. # Mirrored sprites for periodic boundary var mirrors: Array # Called when the node enters the scene tree for the first time. func _ready() -> void: await owner.ready mirrors.append(Area2D.new()) mirrors.append(Area2D.new()) mirrors.append(Area2D.new()) # TODO: npc overhaul; make npc2d (and child classes) inherit from Node instead of Area2d. # Each entity should have Area2d -> collisionshape2d + animatedsprite2d. We then duplicate this area2d instead of the bullshit thats happening here # note taht the below bs also does not work, as the (freshly instantiated) area2ds have none of the signals connected. The above refactor will fix this. for m in mirrors: for i in owner.get_groups(): if not str(i).begins_with("_"): m.add_to_group(i) m.set_collision_layer(owner.get_collision_layer()) m.set_collision_mask(owner.get_collision_mask()) m.add_child(sprite.duplicate()) m.add_child(shape.duplicate()) owner.add_child(m) _handle_wrapping() func play_sprite(anim: String) -> void: mirrors[0].get_node("AnimatedSprite2D").play(anim) mirrors[1].get_node("AnimatedSprite2D").play(anim) mirrors[2].get_node("AnimatedSprite2D").play(anim) func _process(delta: float) -> void: _handle_wrapping() # Mirroring table: # |---|---|---|---| # | 4 | 3 | 4 | 3 | # |---|===|===|---| # | 1 ǁ 2 | 1 ǁ 2 | # |---ǁ---|---ǁ---| # | 4 ǁ 3 | 4 ǁ 3 | # |---|===|===|---| # | 1 | 2 | 1 | 2 | # |---|---|---|---| # If less than viewport size away from an edge, mirror over that edge (for seamless boundary) # NOTE: For this to look correctly the camera size should be smaller than half the screen port (in # any one dimension. Ideally, the difference between camera size and half the screen port is # at least the size of the prey sprite) func _handle_wrapping(): # TODO: Assume viewport size << screen size and only draw according to GameManager.viewport_size # Find corresponding section of the screen if owner.position.x < GameManager.screen_size.x/2 and owner.position.y < GameManager.screen_size.y/2: # Right mirrors[0].global_position = owner.global_position + Vector2(GameManager.screen_size.x, 0) # Diag mirrors[2].global_position = owner.global_position + Vector2(GameManager.screen_size.x, GameManager.screen_size.y) # Bottom mirrors[1].global_position = owner.global_position + Vector2(0, GameManager.screen_size.y) elif owner.position.x < GameManager.screen_size.x/2: # Top mirrors[0].global_position = owner.global_position + Vector2(0, - GameManager.screen_size.y) # Diag mirrors[1].global_position = owner.global_position + Vector2(GameManager.screen_size.x, - GameManager.screen_size.y) # Right mirrors[2].global_position = owner.global_position + Vector2(GameManager.screen_size.x, 0) elif owner.position.y < GameManager.screen_size.y/2: # Left mirrors[0].global_position = owner.global_position + Vector2(- GameManager.screen_size.x, 0) # Bottom mirrors[1].global_position = owner.global_position + Vector2(0, GameManager.screen_size.y) # Diag mirrors[2].global_position = owner.global_position + Vector2(- GameManager.screen_size.x, GameManager.screen_size.y) else: # Left mirrors[0].global_position = owner.global_position + Vector2(- GameManager.screen_size.x, 0) # Diag mirrors[1].global_position = owner.global_position + Vector2(- GameManager.screen_size.x, - GameManager.screen_size.y) # Top mirrors[2].global_position = owner.global_position + Vector2(0, - GameManager.screen_size.y)