diff options
author | Daniel Weipert <code@drogueronin.de> | 2023-08-10 11:48:05 +0200 |
---|---|---|
committer | Daniel Weipert <code@drogueronin.de> | 2023-08-10 11:48:05 +0200 |
commit | 46556d864b9685c3b09a0038f5de83966fe7ff94 (patch) | |
tree | c68082eacd35559e14565d1598dd694972fb8e0e /Scenes/Entities/Bombs/Bomb.gd |
Initial commit
Diffstat (limited to 'Scenes/Entities/Bombs/Bomb.gd')
-rw-r--r-- | Scenes/Entities/Bombs/Bomb.gd | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/Scenes/Entities/Bombs/Bomb.gd b/Scenes/Entities/Bombs/Bomb.gd new file mode 100644 index 0000000..96a5e62 --- /dev/null +++ b/Scenes/Entities/Bombs/Bomb.gd @@ -0,0 +1,165 @@ +extends CharacterBody2D + +class_name Bomb + + +signal body_exited +signal exploded + + +var Explosion = preload("res://Scenes/Entities/Bombs/Explosion.tscn") +var power = 2 + + +func _ready(): + add_to_group("bombs") + + var collision_area = Utilities.Collision.Area.new(self, $CollisionShape2D) + collision_area.connect("collided", Callable(self, "_collide")) + collision_area.connect("body_exited", Callable(self, "_body_exited")) + add_child(collision_area) + + $AnimatedSprite2D.play() + + +func _process(delta): + var collision = move_and_collide(velocity * delta) + if collision: + velocity = Vector2(0, 0) + + +func explode(): + $CollisionShape2D.disabled = true + + # explode on the spot + var explosion = self.spawn_explosion(self.global_position) + + # explode in all directions + var directions = [ + Vector2.UP, + Vector2.RIGHT, + Vector2.DOWN, + Vector2.LEFT, + ] + + for j in range(directions.size()): + var direction = directions[j] + + for i in range(self.get_power()): + var to = Utilities.from_grid_to_position( + Utilities.from_position_to_grid(self.global_position) + (direction * (i + 1)) + ) + + var query = PhysicsPointQueryParameters2D.new() + query.set_position(to) + query.set_collision_mask(explosion.collision_mask) + + var explosion_intersection = get_world_2d().direct_space_state.intersect_point(query) + if explosion_intersection: + var collider = explosion_intersection[0].collider + + # call collision function and get collision type + var collision_type + if collider.is_in_group("player"): + collision_type = self._on_collide_group_player() + elif collider.is_in_group("enemies"): + collision_type = self._on_collide_group_enemies() + elif collider.is_in_group("explosions"): + collision_type = self._on_collide_group_explosions() + elif collider.is_in_group("bombs"): + collision_type = self._on_collide_group_bombs() + elif collider.is_in_group("breakables"): + collision_type = self._on_collide_group_breakables() + else: + collision_type = self._on_collide_group_else() + + # progress loop based on collision type + if collision_type == EXPLOSION_COLLISION_TYPE.STOP: + break + if collision_type == EXPLOSION_COLLISION_TYPE.SPAWN_AND_STOP: + self.spawn_explosion(to) + break + elif collision_type == EXPLOSION_COLLISION_TYPE.SKIP: + continue + elif collision_type == EXPLOSION_COLLISION_TYPE.CONTINUE: + pass + elif collision_type == EXPLOSION_COLLISION_TYPE.HIT_STOP: + if collider.has_method("hit_by_explosion"): + collider.hit_by_explosion() + break + elif collision_type == EXPLOSION_COLLISION_TYPE.HIT_CONTINUE: + if collider.has_method("hit_by_explosion"): + collider.hit_by_explosion() + continue + + self.spawn_explosion(to) + + emit_signal("exploded", self) + + queue_free() + + +func get_power(): + return self.power + + +func spawn_explosion(spawn_position: Vector2): + var explosion = Explosion.instantiate() + explosion.position = spawn_position + get_tree().get_current_scene().add_child(explosion) + + return explosion + + +func hit_by_explosion(): + call_deferred("explode") + + +func _collide(area: Area2D): + if area.is_in_group("explosions"): + call_deferred("explode") + + +func _on_Timer_timeout(): + self.explode() + + +func _body_exited(body): + emit_signal("body_exited", body) + + +### Explosion Collision ### + + +enum EXPLOSION_COLLISION_TYPE { + STOP, + SKIP, + CONTINUE, + SPAWN_AND_STOP, + HIT_STOP, + HIT_CONTINUE, +} + + +func _on_collide_group_player(): + return EXPLOSION_COLLISION_TYPE.CONTINUE + + +func _on_collide_group_enemies(): + return EXPLOSION_COLLISION_TYPE.CONTINUE + + +func _on_collide_group_explosions(): + return EXPLOSION_COLLISION_TYPE.SKIP + + +func _on_collide_group_bombs(): + return EXPLOSION_COLLISION_TYPE.HIT_STOP + + +func _on_collide_group_breakables(): + return EXPLOSION_COLLISION_TYPE.HIT_STOP + + +func _on_collide_group_else(): + return EXPLOSION_COLLISION_TYPE.STOP |