Untitled

 avatar
unknown
plain_text
10 months ago
1.6 kB
19
Indexable
extends Node2D

@export var gun: Sprite2D
@export var target: Node2D
@export var proj_speed: float = 100
@export var proj: PackedScene

# obviously we wouldnt hardcode this.
var gravity: float = 300
@export var angle: float = 0:
	set(value):
		if value != angle:
			angle = value
			update_gun_angle()

func _process(delta: float) -> void:
	if target == null:
		return
	adjustAim()
	
func update_gun_angle():
	var v = Vector2(sin(angle), cos(angle))
	gun.position = v * 100


func fire():
	var p = proj.instantiate()
	p.vel = Vector2(sin(angle), cos(angle)) * proj_speed
	add_child(p)

func adjustAim():	
	# get target offest
	var offset = global_position - target.global_position
	
	# solve quadradic equation for angle
	var disc = pow(proj_speed, 4) - gravity * (gravity * pow(offset.x, 2) + 2 * offset.y * pow(proj_speed, 2))
	if disc < 0:
		print("target unreachable - out of range")
		return null  # unreachable
	
	# solve for each possible angle 
	var t1 = (pow(proj_speed, 2) + pow(disc, .5)) / (gravity * abs(offset.x))
	var t2 = (pow(proj_speed, 2) - pow(disc, .5)) / (gravity * abs(offset.x))
	
	var a1 = atan(t1)
	var a2 = atan(t2)
	
	# adjust angles to match godot standards
	if offset.x > 0:
		a1 = PI - a1
		a2 = PI - a2
		
	a1 = a1 + PI * 0.5
	a2 = a2 + PI * 0.5
	
	# check time of flight for each angle. shorter one is the more direct shot angle
	var tof1 = offset.x / (proj_speed * sin(a1))
	var tof2 = offset.x / (proj_speed * sin(a2))
	
	if tof1 > tof2:
		angle = a1
		return
		
	angle = a2


func _on_button_down() -> void:
	fire()
Editor is loading...
Leave a Comment