yet another space console game made during classes... but this time with more action!
#include "fbgfx.bi"
#include "crt.bi"
'#define UseConsole
'#define GfxScale
#if defined(__FB_DOS__) andalso defined(UseConsole)
const ConWid=80 , ConHei=50 'minimum size!
#else
const ConWid=80 , ConHei=60
#endif
const ConMidLin = ConHei\2-1 , ConMidCol = ConWid\2
#ifdef UseConsole
#ifndef __FB_DOS__
#include "MyTDT\ConsoleAuxiliar.bas"
ConsoleFonte(8,8) 'otherwise, be aware of font size :)
ConsolePalette(8,64,64,64)
#endif
#else
#ifdef GfxScale
#include "MyTdt\GfxResize.bas"
Gfx.PreResize()
#endif
screenres ConWid*8,ConHei*8
palette 1,0,0,85
#ifdef GfxScale
Gfx.Resize(ConWid*8,ConHei*8)
#endif
#endif
sub Cleanup() destructor
#ifndef UseConsole
screen 0
#endif
color 7,0 : cls
end sub
'#include "MyTDT\ConsoleBigFont.bas" ======================================================================
static shared as string sUpper(3),sLower(3),sDigit(3),sSymbl(3)
sub InitBigFont() constructor
' =====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====
sUpper(0) = " / \ _ _ __ __ ___ __ ___ ___ ___ _ _ ___ __ __ __ __ __ ___ ___"
sUpper(1) = " / ___ \ ~ ) / \ | | | \ | | \ | | | | | | | | / | | | | | | | | | | | | | | | | | | | | | \ / \ / /"
sUpper(2) = " , \ ___ / | |a/ |--| |--< | | | |--- |-- | -- |--| | | |< | |\/| |\| | | |-- | | |-- -- | | | | | | | X | / "
sUpper(3) = " / \ / . \__/ | | |__/ |___ |__/ |___ | |__/ | | _|_ \_/ | \ |__ | | | | |__| | |_\| | \ __| | |__| \/ |/\| / \ | /__"
sLower(0) = " __ __ __ __ ___ __ ___ ___ ___ _ _ ___ __ __ __ __ __ ___ ___"
sLower(1) = " | \ | /\ \ | | | \ | | \ | | | | | | | | / | | | | | | | | | | | | | | | | | | | | | \ / \ / /"
sLower(2) = " | \ | |--| |--< | | | |--- |-- | -- |--| | | |< | |\/| |\| | | |-- | | |-- -- | | | | | | | X | / "
sLower(3) = " |__ \ __| ____ | | |__/ |___ |__/ |___ | |__/ | | _|_ \_/ | \ |__ | | | | |__| | |_\| | \ __| | |__| \/ |/\| / \ | /__"
sDigit(0) = " _._ ___ __ . __ __ __ __ ___ __ __ "
sDigit(1) = " | || _||_ ( | 0/ \ / | / \ \ / | / | /| /| | | | | | | / | | | | ' "
sDigit(2) = " | _||_ -+- /0 X ( ) -|- -+- --- / | | | -- --| --| `-\ |-- / |--| --| "
sDigit(3) = " . || _|_) C_< \ / / \ | / o / |/_| _|_ |__ __| | \_/ |__| / |__| __| ' "
' =====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====|||||=====
for N as long = 0 to 3
dim as zstring ptr pzArr(...) = {strptr(sLower(N)),strptr(sUpper(N)),strptr(sDigit(N))}
for A as long = 0 to ubound(pzArr)
#define pzRow (*pzArr(A))
for I as long = 0 to len(pzRow)-1
select case pzRow[I]
case asc("*"): pzRow[I] = 250
case asc("~"): pzRow[I] = 239
case asc("+"): pzRow[I] = 197
case asc("o"): pzRow[I] = 254
end select
next I
next A
next N
end sub
sub PrintBig(sText as string)
var iLin = csrlin() , iCol = pos()
for iL as long = 3 to 0 step -1
dim as string sLine
for N as long = 1 to len(sText)
var iChar = asc(sText,N)
select case iChar
case asc(";") to asc("Z")
sLine += mid(sUpper(iL),(iChar-asc(";"))*5+1,5)
case asc("[") to asc("z")
sLine += mid(sLower(iL),(iChar-asc("["))*5+1,5)
case asc("!") to asc("@")
sLine += mid(sDigit(iL),(iChar-asc("!"))*5+1,5)
case else
sLine += space(5)
end select
next N
locate iLin+iL,iCol : print sLine;
next iL
end sub
'==========================================================================================================
const cMaxShield = 1024+15
type Shot
as Long Lin,Col
as long DiffLin,DiffCol
as Long Erro,Cor
end type
static shared as long StarLin(127),StarCol(127)
static shared as single Ang(34),AngSpd(34)
dim shared as long ShieldHit, AlienHit, StationHit
dim shared as long ScoreStation , ScoreAlien
dim shared as Shot tShotAlien , tShotStation(8)
dim shared as byte Shield(3)
dim shared as long iShield=cMaxShield,iTicks
dim shared as long iTickCharge=0
dim shared as long AlienLin=2,AlienCol=1
function DistFromStation( iLin as long , iCol as long ) as single
dim as long DistLin = iLin-ConMidLin , DistCol = iCol-ConMidCol
return sqr(DistLin*DistLIn + DistCol*DistCol)
end function
sub DrawShield( Quadrant as long )
select case Quadrant
case 0
locate ConMidLin-9 , ConMidCol+1 : print "***";
locate ConMidLin-8 , ConMidCol+4 : print "**";
locate ConMidLin-7 , ConMidCol+6 : print "*";
locate ConMidLin-6 , ConMidCol+7 : print "*";
locate ConMidLin-5 , ConMidCol+8 : print "*";
locate ConMidLin-4 , ConMidCol+8 : print "*";
locate ConMidLin-3 , ConMidCol+9 : print "*";
locate ConMidLin-2 , ConMidCol+9 : print "*";
locate ConMidLin-1 , ConMidCol+9 : print "*";
case 1
locate ConMidLin+1 , ConMidCol+9 : print "*";
locate ConMidLin+2 , ConMidCol+9 : print "*";
locate ConMidLin+3 , ConMidCol+9 : print "*";
locate ConMidLin+4 , ConMidCol+8 : print "*";
locate ConMidLin+5 , ConMidCol+8 : print "*";
locate ConMidLin+6 , ConMidCol+7 : print "*";
locate ConMidLin+7 , ConMidCol+6 : print "*";
locate ConMidLin+8 , ConMidCol+4 : print "**";
locate ConMidLin+9 , ConMidCol+1 : print "***";
case 2
locate ConMidLin+1 , ConMidCol-9 : print "*";
locate ConMidLin+2 , ConMidCol-9 : print "*";
locate ConMidLin+3 , ConMidCol-9 : print "*";
locate ConMidLin+4 , ConMidCol-8 : print "*";
locate ConMidLin+5 , ConMidCol-8 : print "*";
locate ConMidLin+6 , ConMidCol-7 : print "*";
locate ConMidLin+7 , ConMidCol-6 : print "*";
locate ConMidLin+8 , ConMidCol-5 : print "**";
locate ConMidLin+9 , ConMidCol-3 : print "***";
case 3
locate ConMidLin-9 , ConMidCol-3 : print "***";
locate ConMidLin-8 , ConMidCol-5 : print "**";
locate ConMidLin-7 , ConMidCol-6 : print "*";
locate ConMidLin-6 , ConMidCol-7 : print "*";
locate ConMidLin-5 , ConMidCol-8 : print "*";
locate ConMidLin-4 , ConMidCol-8 : print "*";
locate ConMidLin-3 , ConMidCol-9 : print "*";
locate ConMidLin-2 , ConMidCol-9 : print "*";
locate ConMidLin-1 , ConMidCol-9 : print "*";
end select
end sub
sub DrawStation()
color 15
locate ConMidLin-2 ,ConMidCol-7 : print chr(&hC9,&hCD,&hCB,&hCD,&hBB, 32 );"/ \";chr( 32 ,&hC9,&hCD,&hCB,&hCD,&hBB);
locate ConMidLin-1 ,ConMidCol-7 : print chr(&hCC,&hC5,&hC5,&hC5,&hB9,&hC4);" ";chr(&hC4,&hCC,&hC5,&hC5,&hC5,&hB9);
locate ConMidLin-0 ,ConMidCol-7 : print chr(&hC8,&hCD,&hCA,&hCD,&hBC, 32 );"\ /";chr( 32 ,&hC8,&hCD,&hCA,&hCD,&hBC);
locate ConMidLin+1 ,ConMidCol-1 : print " _ ";
locate ConMidLin+2 ,ConMidCol-1 : print " . ";
locate ConMidLin+3 ,ConMidCol-1 : print "...";
end sub
sub DrawShieldBar()
if iShield < cMaxShield andalso abs(iTickCharge-iTicks)>30 andalso (iTicks mod 2)=0 then iShield += 1
locate 1,2: color 11,0 : print "Shield: ";
if iShield>(cMaxShield\2) then color 10,8 else if iShield >(cMaxShield\8) then color 14,8 else color 12,8
const cAdjShield = ConWid/80
print string((iShield\16)*cAdjShield,219);
if iShield > 0 then
#ifdef UseConsole
print chr( iif( (iShield mod 16)<12 , 176+((iShield mod 16)\4) , 219 ) );
#else
print chr( iif((iShield mod 16) >= 8 , 219 , 221 ) );
#endif
end if
color 8,0 : print string((64-((iShield+1)\16))*cAdjShield,219);
end sub
sub InitStars()
for N as long = 0 to 127
dim as long Lin=2+rnd*(ConHei-3) , Col = 1+rnd*(ConWid-1)
if DistFromStation(Lin,Col)<10 then N=N-1:continue for
StarLin(N) = Lin : StarCol(N) = Col
next N
end sub
sub DrawStars(iForce as long=1)
static as long iStarBase=0
for N as long =iStarBase to iStarBase+15
dim as integer iChar = iif(iForce,32,screen(StarLin(N),StarCol(N)))
if iChar=32 or iChar=250 then
color 2+rnd*8 : locate StarLin(N),StarCol(N) : print chr(250);
end if
next N
iStarBase = (iStarBase+16) and 127
end sub
sub SyncFps()
static as double dFPS
static as double dSync
static as long iFps : iFps += 1
if abs(timer-dFPS)>=1 then
dFPS = timer
locate 1,ConWid-4: color 15 : print iFps
iFps=0
end if
if abs(timer-dSync)>1 then dSync = timer
while (timer-dSync) < 1/60
sleep 1,1
wend
dSync += 1/60
end sub
sub IntroScreen()
for N as long = 0 to 3
color 10+N : DrawShield(N)
DrawStars()
next N
for N as long = -1 to 0
color (N and 14)
locate ConMidLin-23,ConMidCol-34 : PrintBig("Use The Shield")
locate ConMidLin-18,ConMidCol-28 : PrintBig("To Defend...")
color (N and 10) : locate ConMidLin-11,ConMidCol+ 9 : PrintBig("E")
color (N and 11) : locate ConMidLin+ 7,ConMidCol+ 9 : PrintBig("C")
color (N and 12) : locate ConMidLin+ 7,ConMidCol-12 : PrintBig("Z")
color (N and 13) : locate ConMidLin-11,ConMidCol-12 : PrintBig("Q")
color (N and 12) : locate ConMidLin+14,ConMidCol-38 : PrintBig("The SpaceStation")
if N = -1 then
do
color (N and 3) : locate ConMidLin+21,ConMidCol-38 : PrintBig("Any Key to Start")
for N as long = 0 to (400/16)
DrawStars(0)
SyncFps()
next N
color 0 : locate ConMidLin+21,ConMidCol-38 : PrintBig("Any Key to Start")
for N as long = 0 to (200/16)
DrawStars(0)
if len(inkey) then exit do
SyncFps()
next N
loop
end if
next N
end sub
sub InitAlien()
const PI=atn(1)*8
for N as long = 0 to ubound(Ang)
AngSpd(N) = (rnd*2-1)/256
Ang(N) = rnd*PI
next N
end sub
sub DrawAlien()
const PI=atn(1)*8
dim as single fLin,fCol
static as long OldLin,OldCol
static as long iMove = 60
dim as long Lin=any,Col=any
if rnd<(1/60) then iMove += 30
if iMove orelse (iTicks and 7)=0 then
if iMove then
iMove -= 1
elseif rnd<(1/15) then
for N as long = 0 to ubound(Ang)
Ang(N) = fmod(Ang(N)+rnd*PI,PI)
next N
end if
do
fLin=0:fCol=0
for N as long = 0 to ubound(Ang)
Ang(N) = fmod(Ang(N)+AngSpd(N)+PI,PI)
fLin += sin(Ang(N))*(ConHei/20) : fCol += cos(Ang(N))*(ConWid/20)
next N
if abs(fLin)>(ConMidLin\2) then fLin = sgn(fLin)*(ConMidLin\2)
if abs(fCol)>(ConMidCol\2) then fCol = sgn(fCol)*(ConMidCol\2)
var fDist = 14+sqr(fLin*fLin + fCol*fCol)')\2
var fAng = atan2(fLin,fCol)
Lin = ConMidLin+sin(fAng)*fDist : Col = ConMidCol+cos(fAng)*fDist
if Lin<2 then Lin=2-(Lin-2) else if Lin>(ConHei-4) then Lin=(ConHei-4)-(Lin-(ConHei-4))
if Col<1 then Col=1-(Col-1) else if Col>(ConWid-3) then Col=(ConWid-3)-(Col-(ConWid-3))
if OldLin<>Lin or OldCol<>Col then
OldLin=Lin : OldCol=Col
exit do
end if
loop
color 0
locate AlienLin+0,AlienCol+1 : print "#" ;
locate AlienLin+1,AlienCol+0 : print "#O#";
locate AlienLin+2,AlienCol+1 : print "#" ;
AlienLin = Lin : AlienCol = Col
color 10
locate AlienLin+0,AlienCol+1 : print "#" ;
locate AlienLin+1,AlienCol+0 : print "#O#";
locate AlienLin+2,AlienCol+1 : print "#" ;
end if
end sub
sub Shoot( tShot as Shot , LinFrom as long , ColFrom as long , LinTo as long , ColTo as long , Cor as long )
with tShot
.Lin = LinFrom : .Col = ColFrom
.DiffLin = LinTo-.Lin
.DiffCol = ColTo-.Col
.Erro = 0 : .Cor = Cor
end with
end sub
sub KillShot( tShot as Shot )
with tShot
locate .Lin,.Col : Print " ";
.Lin = 0
end with
end sub
sub MoveShot( tShot as Shot )
with tShot
locate .Lin,.Col : Print " ";
if abs(.DiffLin) > abs(.DiffCol) then
'bigger difference is row
.Lin = .Lin+sgn(.DiffLin)
.Erro = .Erro+abs(.DiffCol)
if .Erro > abs(.DiffLin) then
.Col = .Col+sgn(.DiffCol)
.Erro = .Erro-abs(.DiffLin)
end if
else
'bigger or equal difference is column
.Col = .Col+sgn(.DiffCol)
.Erro = .Erro+abs(.Difflin)
if .Erro > abs(.Diffcol) then
.Lin = .Lin+sgn(.Difflin)
.Erro = .Erro-abs(.DiffCol)
end if
end if
if .Lin<3 or .Lin>(ConHei-2) or .Col<1 or .Col>ConWid then
KillShot( tShot ) : exit sub
end if
locate .Lin,.Col
color .Cor : Print chr(&hFE);
end with
end sub
sub ProcessShooting()
with tShotAlien
if .Lin=0 then 'if not shooting there's 1/60 chance to shoot
if rnd<(1/60) then
Shoot( tShotAlien , AlienLin+1 , AlienCol+1 , ConMidLin,ConMidCol , 14 )
ShieldHit= iif(.DiffLin<0,1,0) xor (iif(.DiffCol>0,3,0))
end if
else
if (iTicks mod 4)=0 then
MoveShot( tShotAlien )
'shot entered shield area?
dim as single fDist = DistFromStation(.Lin,.Col)
if StationHit=0 andalso fDist<10 then
if Shield(ShieldHit)=0 then 'Shield Shutdown... lose
StationHit = 1
else 'Shield on. REFLECT
const PI90 = atn(1)*2
'add 1 buller every 10° of each reflected Quadrant
if ShieldHit=0 or ShieldHit=2 then ShieldHit xor= 2
for N as long = 0 to 8
dim as double Ang = ShieldHit*PI90 + ((N+.5)*(PI90/9))
dim as long DeLin = ConMidLin+sin(Ang)*9 , DeCol = ConMidCol-cos(Ang)*9
dim as long ParaLin = ConMidLin+sin(Ang)*ConWid , ParaCol = ConMidCol-cos(Ang)*ConWid
Shoot( tShotStation(N) , DeLin,DeCol , ParaLin,ParaCol , 11 )
next N
AlienHit=0 : KillShot(tShotAlien)
end if
end if
if StationHit andalso fDist<4 then
color 12 : locate ConMidLin+6,ConMidCol-15 : print "Your Station has been Destroyed!";
do
var sKey = inkey
if len(sKey) then
select case sKey[0]
case asc("Q"),asc("q"),asc("E"),asc("e"),asc("Z"),asc("z"),asc("C"),asc("c")
rem ignore keys that might be pressed before this point
case else : exit do
end select
end if
color 9+rnd*6 : locate ConMidLin-2,ConMidCol-11 : PrintBig("Bang!")
SyncFps()
loop
locate ConMidLin+6,ConMidCol-15 : print space(32);
color 0 : locate ConMidLin-2,ConMidCol-11 : PrintBig("Bang!")
ScoreAlien = ScoreAlien + 1 : StationHit = 0
color 14 : locate ConHei,ConWid-10: print "Alien: ";ScoreAlien;
DrawStation() : KillShot(tShotAlien)
end if
end if
end if
end with
'move our shots if enabled
for N as long = 0 to 8
with tShotStation(N)
if .Lin <> 0 then
MoveShot( tShotStation(N) )
if AlienHit<>0 then continue for
'check if shot hit alien
if abs(.Lin-(AlienLin+1)) < 3 and abs(.Col-(AlienCol+1)) < 3 then
for N as long = 0 to 19
locate AlienLin-1 , AlienCol-1
Color 8+rnd*4 : PrintBig("*")
SyncFps()
next N
ScoreStation = ScoreStation + 1
color 11 : locate ConHei,2 : print "You: " ;ScoreStation;
locate AlienLin-1 , AlienCol-1 : PrintBig(" ")
KillShot( tShotStation(N) )
AlienHit=1
end if
end if
end with
next N
end sub
sub ProcessKeys()
'process Keys
static as byte Teclas(3) = { fb.SC_E , fb.SC_C , fb.SC_Z , fb.SC_Q }
for N as long = 0 to 3
Shield(N) = (iShield>0 andalso multikey(Teclas(N)))
if Shield(N) then
iShield -= 1 : iTickCharge = iTicks
if iShield>(cMaxShield\3) orelse (iTicks mod 2) then color 10+N else color 1
else
color 1
end if
DrawShield(N)
next N
do
var sKey = inkey
if len(sKey)=0 then exit do
select case sKey[0]
case 27 : end
end select
loop
end sub
Width ConWid,ConHei : locate ,,0
randomize()
InitStars()
InitAlien()
DrawStation()
IntroScreen()
color 11 : locate ConHei,2 : print "You: " ;ScoreStation;
color 14 : locate ConHei,ConWid-10: print "Alien: ";ScoreAlien;
do
iTicks += 1
DrawStars()
DrawShieldBar()
DrawAlien()
ProcessShooting()
ProcessKeys()
SyncFps()
loop
linux users... to run this using console, you need to set your console to 80x50 (as seem freebasic width may not work with all terminals... and you need to set the console codepage to be IBM-850 or the classic US-437).
(https://i.imgur.com/E1F6jnO.png)
(https://i.imgur.com/Kp4feuD.png)