Author Topic: Interception  (Read 1398 times)

Galileo

  • Guest
Interception
« on: January 03, 2018, 11:36:45 AM »
New year, new codes.

Code: [Select]
// 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