New year, new codes.
// Ported from FreeBASIC to Yabasic by Galileo, 01/2018
// Original code in https://www.freebasic.net/forum/viewtopic.php?f=7&t=1857&sid=ede02092a49e9af4ca8a0bbfe0166104
clear screen
SCR_W = 640
SCR_H = 480
BULLET_SPEED = 3.7
PLAYER_SPEED = 2.4
PLAYER_ACCEL = 0.15
active = 1 : x = 2 : y = 3 : vx = 4 : vy = 5
turret = 1 : bullet = 2 : player = 3
export sub atan2(dx, dy)
local a, half_pi
half_pi = pi / 2
if abs(dx) > abs(dy) then
a = atan(dy / dx)
else
a = atan(dx / dy)
if a < 0 then
a = -half_pi - a
else
a = half_pi - a
end if
end if
if dx < 0 then
if dy < 0 then
a = a - pi
else
a = a + pi
end if
end if
return a
end sub
sub get_fire_angle(src, dest, speed)
local t, dx, dy, delta, cosine, sine
speed = speed * speed
dx = OBJECTB(dest, x) - OBJECTB(src, x)
dy = OBJECTB(dest, y) - OBJECTB(src, y)
delta = speed * (dx * dx + dy * dy) - (OBJECTB(dest, vx) * dy - OBJECTB(dest, vy) * dx) * (OBJECTB(dest, vx) * dy - OBJECTB(dest, vy) * dx)
t = -OBJECTB(dest, vx) * dx - OBJECTB(dest, vy) * dy - sqrt(delta)
t = t / (OBJECTB(dest, vx) * OBJECTB(dest, vx) + OBJECTB(dest, vy) * OBJECTB(dest, vy) - speed)
cosine = dx + OBJECTB(dest, vx) * t
sine = dy + OBJECTB(dest, vy) * t
return atan2(cosine, -sine)
end sub
dim OBJECTB(3, 5)
open window SCR_W, SCR_H
backcolor 0,0,0
OBJECTB(player, x) = ran(SCR_W)
OBJECTB(player, y) = ran(SCR_H)
OBJECTB(turret, x) = SCR_W / 2
OBJECTB(turret, y) = SCR_H / 2
do
clear window
color 255, 255, 255 : fill circle OBJECTB(player, x), OBJECTB(player, y), 4
color 255, 128, 0 : fill circle OBJECTB(turret, x), OBJECTB(turret, y), 4
color 128, 0, 0 : line OBJECTB(turret, x), OBJECTB(turret, y), OBJECTB(turret, x) + cos(angle) * SCR_W, OBJECTB(turret, y) - sin(angle) * SCR_W
if OBJECTB(bullet, active) then
color 255, 0, 0 : fill circle OBJECTB(bullet, x), OBJECTB(bullet, y), 4
OBJECTB(bullet, x) = OBJECTB(bullet, x) + OBJECTB(bullet, vx)
OBJECTB(bullet, y) = OBJECTB(bullet, y) + OBJECTB(bullet, vy)
end if
switch key$
case "left": if OBJECTB(player, vx) > -PLAYER_SPEED OBJECTB(player, vx) = OBJECTB(player, vx) - PLAYER_ACCEL : break
case "right": if OBJECTB(player, vx) < PLAYER_SPEED OBJECTB(player, vx) = OBJECTB(player, vx) + PLAYER_ACCEL : break
case "up": if OBJECTB(player, vy) > -PLAYER_SPEED OBJECTB(player, vy) = OBJECTB(player, vy) - PLAYER_ACCEL : break
case "down": if OBJECTB(player, vy) < PLAYER_SPEED OBJECTB(player, vy) = OBJECTB(player, vy) + PLAYER_ACCEL : break
case " ": OBJECTB(bullet, x) = OBJECTB(turret, x)
OBJECTB(bullet, y) = OBJECTB(turret, y)
OBJECTB(bullet, vx) = cos(angle) * BULLET_SPEED
OBJECTB(bullet, vy) = -sin(angle) * BULLET_SPEED
OBJECTB(bullet, active) = true : break
case "q": end
end switch
OBJECTB(player, x) = OBJECTB(player, x) + OBJECTB(player, vx)
OBJECTB(player, y) = OBJECTB(player, y) + OBJECTB(player, vy)
angle = get_fire_angle(turret, player, BULLET_SPEED)
key$ = inkey$(0.02)
loop