07-15-2023, 07:32 PM
I'm attempting to recreate the look and feel of the original BattleStar Galactica lasers that the Colonial Vipers (red lasers) and the Cylon Raiders (white/blue lasers) produced. Below you can see a montage of screen shots showing the various lasers in action. There's also a link to a short 4 minute clip of the show showing the two ships shooting at each other.
I've tried to recreate this effect a number of different ways using image files, rotozoom and_PUTIMAGE, shading using alpha blends, and other various things that always look like crap. I'm horrible when it comes to custom graphics.
So here's the challenge if you choose to accept it: Create this laser effect on a 2D screen where the laser can be pointed and shot in any one of 360 degrees. I've posted an early attempt of my code to give you and idea of what to shoot for. I'm working on a game based on the old BG series and I really want to get the lasers looking as authentic as possible.
YouTube clip: https://www.youtube.com/watch?v=E2BJodHVGT8
I've tried to recreate this effect a number of different ways using image files, rotozoom and_PUTIMAGE, shading using alpha blends, and other various things that always look like crap. I'm horrible when it comes to custom graphics.
So here's the challenge if you choose to accept it: Create this laser effect on a 2D screen where the laser can be pointed and shot in any one of 360 degrees. I've posted an early attempt of my code to give you and idea of what to shoot for. I'm working on a game based on the old BG series and I really want to get the lasers looking as authentic as possible.
YouTube clip: https://www.youtube.com/watch?v=E2BJodHVGT8
Code: (Select All)
OPTION _EXPLICIT
CONST SWIDTH = 1280
CONST SHEIGHT = 720
TYPE TYPE_VECTOR
x AS SINGLE ' x vector/coordinate
y AS SINGLE ' y vector/coordinate
END TYPE
TYPE TYPE_LINE
Start AS TYPE_VECTOR ' start coordinate of laser beam line
Finish AS TYPE_VECTOR ' end coordinate of laser beam line
'Center AS TYPE_VECTOR ' center coordinate of laser beam line
END TYPE
TYPE TYPE_LASER
Origin AS TYPE_VECTOR
Head AS TYPE_LINE ' overall rectangle
Tail AS TYPE_LINE
Beam AS TYPE_LINE ' center beam
HeadSpeed AS SINGLE
TailSpeed AS SINGLE
MaxSpeed AS SINGLE
Vector AS TYPE_VECTOR ' vector direction of laser
Degree AS INTEGER ' degree direction of laser
Speed AS SINGLE ' speed of laser
LaserColor AS _UNSIGNED LONG
GlowColor AS _UNSIGNED LONG
Active AS INTEGER ' laser is active (t/f)
END TYPE
REDIM Laser(0) AS TYPE_LASER
DIM Vec(359) AS TYPE_VECTOR
'DIM i AS INTEGER
DIM Degree AS INTEGER
DIM Origin AS TYPE_VECTOR
DIM Colour AS INTEGER
DIM Speed AS SINGLE
DIM RapidFire AS INTEGER
'DIM Size AS SINGLE
Degree = 0 ' precalculate degree vectors
DO
Vec(Degree).x = SIN(_D2R(Degree))
Vec(Degree).y = -COS(_D2R(Degree))
Degree = Degree + 1
LOOP UNTIL Degree = 360
SCREEN _NEWIMAGE(SWIDTH, SHEIGHT, 32)
CLS
Origin.x = 100
Origin.y = 359
Degree = 90
Colour = 4
Speed = 15
'Size = 1
DO
_LIMIT 60
CLS
IF _KEYDOWN(32) AND RapidFire = 0 THEN
SHOOT_LASER Origin, Degree, Speed, Colour
Degree = FIX_DEGREE(Degree + 2)
RapidFire = 10
ELSE
IF RapidFire THEN RapidFire = RapidFire - 1
END IF
UPDATE_LASER
_DISPLAY
LOOP UNTIL _KEYDOWN(27)
SUB SHOOT_LASER (Origin AS TYPE_VECTOR, Degree AS INTEGER, Speed AS SINGLE, Colour AS INTEGER)
SHARED Laser() AS TYPE_LASER
SHARED Vec() AS TYPE_VECTOR
DIM Index AS INTEGER
Index = -1 ' reset index counter
DO ' begin free index search
Index = Index + 1 ' increment index counter
IF Laser(Index).Active = 0 THEN EXIT DO ' is this index free?
LOOP UNTIL Index = UBOUND(Laser) ' leave when all indexes checked
IF Laser(Index).Active THEN ' were all indexes checked?
Index = Index + 1 ' yes, no free indexes, increment index
REDIM _PRESERVE Laser(Index) AS TYPE_LASER ' create a new index in array
END IF
Degree = FIX_DEGREE(Degree)
Laser(Index).Active = -1
Laser(Index).Origin = Origin
Laser(Index).Vector = Vec(Degree)
Laser(Index).Degree = Degree
Laser(Index).HeadSpeed = Speed
Laser(Index).TailSpeed = Speed * .5
Laser(Index).Speed = Speed
Laser(Index).LaserColor = _RGB32((Colour AND 4) * 64, (Colour AND 2) * 128, (Colour AND 1) * 256)
Laser(Index).Beam.Start = Origin
Laser(Index).Beam.Finish = Origin
Laser(Index).Head.Start.x = Origin.x - 2
Laser(Index).Head.Start.y = Origin.y
Laser(Index).Head.Finish.x = Origin.x + 2
Laser(Index).Head.Finish.y = Origin.y
Rotate Laser(Index).Head.Start, Degree, Origin ' rotate line
Rotate Laser(Index).Head.Finish, Degree, Origin
Laser(Index).Tail = Laser(Index).Head
SELECT CASE Colour
CASE 4
Laser(Index).GlowColor = _RGB32(255, 211, 80)
CASE 7
Laser(Index).GlowColor = _RGB32(0, 128, 255)
END SELECT
END SUB
SUB UPDATE_LASER ()
SHARED Laser() AS TYPE_LASER
DIM Index AS INTEGER
DIM NoActive AS INTEGER
NoActive = -1
Index = -1
DO
Index = Index + 1
IF Laser(Index).Active THEN
NoActive = 0
Laser(Index).Head.Start.x = Laser(Index).Head.Start.x + Laser(Index).Vector.x * Laser(Index).HeadSpeed
Laser(Index).Head.Start.y = Laser(Index).Head.Start.y + Laser(Index).Vector.y * Laser(Index).HeadSpeed
Laser(Index).Head.Finish.x = Laser(Index).Head.Finish.x + Laser(Index).Vector.x * Laser(Index).HeadSpeed
Laser(Index).Head.Finish.y = Laser(Index).Head.Finish.y + Laser(Index).Vector.y * Laser(Index).HeadSpeed
Laser(Index).Tail.Start.x = Laser(Index).Tail.Start.x + Laser(Index).Vector.x * Laser(Index).TailSpeed
Laser(Index).Tail.Start.y = Laser(Index).Tail.Start.y + Laser(Index).Vector.y * Laser(Index).TailSpeed
Laser(Index).Tail.Finish.x = Laser(Index).Tail.Finish.x + Laser(Index).Vector.x * Laser(Index).TailSpeed
Laser(Index).Tail.Finish.y = Laser(Index).Tail.Finish.y + Laser(Index).Vector.y * Laser(Index).TailSpeed
Laser(Index).Beam.Start.x = Laser(Index).Beam.Start.x + Laser(Index).Vector.x * Laser(Index).HeadSpeed
Laser(Index).Beam.Start.y = Laser(Index).Beam.Start.y + Laser(Index).Vector.y * Laser(Index).HeadSpeed
Laser(Index).Beam.Finish.x = Laser(Index).Beam.Finish.x + Laser(Index).Vector.x * Laser(Index).TailSpeed
Laser(Index).Beam.Finish.y = Laser(Index).Beam.Finish.y + Laser(Index).Vector.y * Laser(Index).TailSpeed
Laser(Index).HeadSpeed = Laser(Index).HeadSpeed * 1.04
Laser(Index).TailSpeed = Laser(Index).TailSpeed * 1.07
LINE (Laser(Index).Tail.Start.x, Laser(Index).Tail.Start.y)-(Laser(Index).Tail.Finish.x, Laser(Index).Tail.Finish.y), Laser(Index).LaserColor
LINE -(Laser(Index).Head.Finish.x, Laser(Index).Head.Finish.y), Laser(Index).LaserColor
LINE -(Laser(Index).Head.Start.x, Laser(Index).Head.Start.y), Laser(Index).LaserColor
LINE -(Laser(Index).Tail.Start.x, Laser(Index).Tail.Start.y), Laser(Index).LaserColor
PAINT (Laser(Index).Beam.Finish.x + Laser(Index).Vector.x * 2, Laser(Index).Beam.Finish.y + Laser(Index).Vector.y), Laser(Index).LaserColor, Laser(Index).LaserColor
LINE (Laser(Index).Tail.Start.x, Laser(Index).Tail.Start.y)-(Laser(Index).Tail.Finish.x, Laser(Index).Tail.Finish.y), Laser(Index).GlowColor
LINE -(Laser(Index).Head.Finish.x, Laser(Index).Head.Finish.y), Laser(Index).GlowColor
LINE -(Laser(Index).Head.Start.x, Laser(Index).Head.Start.y), Laser(Index).GlowColor
LINE -(Laser(Index).Tail.Start.x, Laser(Index).Tail.Start.y), Laser(Index).GlowColor
'LINE (Laser(Index).Beam.Start.x, Laser(Index).Beam.Start.y)-(Laser(Index).Beam.Finish.x, Laser(Index).Beam.Finish.y), Laser(Index).LaserColor
IF Laser(Index).Tail.Start.x < 0 OR Laser(Index).Tail.Start.x > SWIDTH THEN Laser(Index).Active = 0
IF Laser(Index).Tail.Start.y < 0 OR Laser(Index).Tail.Start.y > SHEIGHT THEN Laser(Index).Active = 0
END IF
LOOP UNTIL Index = UBOUND(Laser)
IF NoActive AND UBOUND(Laser) > 0 THEN REDIM Laser(0) AS TYPE_LASER: BEEP
END SUB
SUB Rotate (vec AS TYPE_VECTOR, angleDeg AS SINGLE, origin AS TYPE_VECTOR)
' Rotate a point around an origin using linear transformations.
DIM x AS SINGLE
DIM y AS SINGLE
DIM __cos AS SINGLE
DIM __sin AS SINGLE
DIM xPrime AS SINGLE
DIM yPrime AS SINGLE
x = vec.x - origin.x ' move rotation vector origin to 0
y = vec.y - origin.y
__cos = COS(_D2R(angleDeg)) ' get cosine and sine of angle
__sin = SIN(_D2R(angleDeg))
xPrime = (x * __cos) - (y * __sin) ' calculate rotated location of vector
yPrime = (x * __sin) + (y * __cos)
xPrime = xPrime + origin.x ' move back to original origin
yPrime = yPrime + origin.y
vec.x = xPrime ' pass back rotated vector
vec.y = yPrime
END SUB
' ______________________________________________________________________________________________________________________________________________
'/ \
FUNCTION FIX_DEGREE (Degree AS INTEGER) ' __FIX_DEGREE |
' __________________________________________________________________________________________________________________________________________|____
'/ \
'| Normalizes degree to between 0 and 359. |
'| |
'| Degree = FIX_DEGREE(-270) |
'\_______________________________________________________________________________________________________________________________________________/
DIM Deg AS INTEGER ' degree value passed in
Deg = Degree ' get passed in degree value
IF Deg < 0 OR Degree > 359 THEN ' degree out of range?
Deg = Deg MOD 360 ' yes, get remainder of modulus 360
IF Deg < 0 THEN Deg = Deg + 360 ' add 360 if less than 0
END IF
FIX_DEGREE = Deg ' return degree
END FUNCTION