0 votes

I'm making a little space shooter/bullet hell type game and am now constructing the movement AI for the 1st enemy. They are supposed to rotate around the player for a few seconds and then move in for a burst rush towards the player.
I have the burst movement working, but I have no clue as to how I would go about having the enemy move in a circular motion around the target body.

This is my code for the movement so far:

extends "res://MOB.gd"

onready var parent = get_parent()
var is_moving = false
export (float) var turn_speed
export (int) var detect_radius
export (int) var spd
export (int) var dmg
export (int) var burst

var target = null
var is_atborder = false
var switch = false
var def = true

func _ready():
   burst = 0
   $Wait.wait_time = 2
   $Detection/CollisionShape2D.shape.radius = detect_radius

 func control(delta):
   moving()
   if target and def:
    default_move()
   chase_move()

func moving():
   if is_moving == true:
        $AnimatedSprite.play("movement")
  else:
    $AnimatedSprite.play("default")

func _on_Detection_body_entered(body):
        if can_target:
            target = body

func _on_Detection_body_shape_exited(body_id, body, body_shape, area_shape):
       if body == target:
            target = null

func default_move():
      look_at(target.position)
      #position = target.position + (position - target.position).rotated(90)

func chase_move():
        if target and can_target:
         def = false
          is_moving = true
          var dir = global_position.direction_to(target.global_position)
          velocity = Vector2(speed, speed) * dir
          can_target = false
          burst += burst
          $Timer.start()
          if burst % 3 == 0:
            $Wait.start()

 func _on_Timer_timeout():
     can_target = true


 func _on_Wait_timeout():
      def =true
in Engine by (39 points)

2 Answers

0 votes

This will be long, Movement in video games is simply teleporting the sprite like 60 times a second small amounts to make it look like its moving, so for a straight line its simple, just teleport the sprite speed / 60(equals to speed * delta) in the movement direction, yet for a rotation object ( that goes around a point ) things get a bit problematic.
First, you have the introduction of angular momentum and angular speed, basically what angle he moves every second, and of course you need to have a middle point.
Physically speaking when an object goes around a center point in a fixed velocity, his acceleration is towards the middle of the circle(really interesting go check it out).

BUT

since we just teleport it every time using the physics equations wont result in a good visual, what you can in fact do is have angular speed ( what angle he covers every second ) and the center point ( the player for you ), so you can predict at which angle he will be in the next frame ( equals to angular_speed * delta) and multiply the unit vector that comes out from the new angle in the radius.
** unit vector is a vector which length is exactly 1 and is calculated using the cos and sin functions

Hope it helps, sorry for the long explanation

by (1,190 points)
0 votes

Something like this?

onready var target = get_node("<PathToPlayer>")
var radius = Vector2(100, 0)

func _physics_process(delta):
    # 1 full circle (i.e. 2 * PI) every second, clockwise
    radius = radius.rotated(2 * PI * delta)

    # 1 full circle (i.e. 2 * PI) every 4 seconds, counter-clockwise
    # radius = radius.rotated(2 * PI * delta * -0.25)

    global_position = target.global_position + radius

However, It might look weird (and not really circular) if the player is moving too fast.

by (10,315 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.