Skip to content

Flying Enemy

NebSeniah edited this page Jul 22, 2026 · 7 revisions

Flying Enemy

System Summary

The Flying Enemy is a dynamic enemy type that moves between two points in space, a predictable traversal pattern for the player. Unlike Patrol enemies, Flying Enemies are not constrained to ground navigation and instead move freely in straight-line paths between two defined offsets.


Connected Systems

Connecting Systems:

Subsystems:

  • None

Bugs

  • None

Feature List / Breakdown of Features

Base Enemy (Inherited):

  • When landed on from above, the player will bounce on and KO the enemy.
  • Colliding from other directions damages the player.
  • Has variable health, which is auto-set to 1.
  • Inherits from BaseEnemyClass.gd.

Flying Enemy:

  • Flying Speed: Controls how fast the enemy travels between points. Higher values = faster movement.
  • Point B Offset: Defines the second movement point relative to the spawn position. X controls horizontal distance, Y controls vertical distance. Supports diagonal movement if both X and Y values aren't 0.
  • Moves in a straight line between Point A (spawn position) and Point B (Point A + Offset).
  • Automatically switches direction when reaching a point.
  • Uses normalized direction vector for smooth motion.
  • Uses direct velocity-based movement (no pathfinding).
  • Ignores gravity.
  • Can collide with level geometry.
  • Preview line demonstrates the way the flying enemy will move and is always visible in the editor.

Important Variables

propertyFile: Resource = Stores the currently assigned FlyingPreset resource.

pointA: Vector2 = Spawn position (set when enemy is placed).

pointB: Vector2 = Calculated endpoint based on offset.

targetPoint: Vector2 = Current movement destination.

speed: float = Movement speed of the enemy.

previewLine: Line2D = A UI graphic displaying the enemy's flight path while editing its properties.


Important Functions

  • func fly_behavior() -> void: Moves the enemy every frame.

  • func update_line_preview(x: int, y: int) -> void: Ensures the preview line matches the enemy's points and offset.

  • func assign_script(id: String, position: Vector2i) -> void: Assigns a FlyingPreset resource to the enemy based on a generated ID. Loads the correct .tres file from disk, assigns it to propertyFile, and sets the enemy's identity in the editor system.

  • func apply_script(file: Resource) -> void: Applies a FlyingPreset resource to the enemy instance. Reads stored data from the resource, updates movement behavior based on saved values, and recalculates patrol path (Point A and Point B). Does NOT reposition the enemy in world space; assumes enemy is already placed correctly by the editor.


Movement Logic

  1. Enemy spawns at Point A (editor placement)
  2. Point B is calculated using offset: Point B = Point A + Offset
  3. Enemy moves toward target point using normalized direction
  4. When close enough to target: switches target to the opposite point and repeats

Data Flow

  1. Editor places enemy
  2. assign_script()
  3. Resource created/saved (.tres)
  4. apply_script() on load
  5. Point A set = global position
  6. Point B calculated = A + offset
  7. Enemy begins patrol movement

Future Work / Risks

Future Work:

  1. Add support for variable movement patterns (e.g., sine wave, circular)
  2. Add visual indicators for patrol path in editor
  3. Add progress from moving platforms
  4. Add line visibility from moving platforms
  5. Add easing from moving platforms
  6. Add delay from moving platforms
  7. Make flying enemy and moving platforms have a child node that marks them as entities 'on rails' to avoid duplication

Risks:

  • None

Miscellaneous Notes

Offset-based system was chosen instead of absolute coordinates to:

  • Make enemy placement reusable
  • Simplify editing in property menu
  • Avoid dependency on world coordinates in resources

Clone this wiki locally