Blitzkrieg
// Project: BlitzKrieg
// Created: 2019-01-14
// show all errors
SetErrorMode(2)
#constant KEY_SPACE 32
#constant KEY_LEFT 37
#constant KEY_UP 38
#constant KEY_RIGHT 39
#constant KEY_DOWN 40
type _bullet
ID as integer
time# as float //time to keep the bullet alive
endtype
type _enemy
ID as integer
direction as float
enemyType as String
speed as float
time# as float
hit as integer
endtype
type _player
ID as integer
ID2 as integer
hit as integer
time as float
ammoLeft as integer
endtype
// set window properties
SetWindowTitle( "BlitzKrieg" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
SetPhysicsScale(.025)
SetPhysicsGravity(0,.25)
SetPhysicsWallBottom(0)
SetPhysicsWallLeft(0)
SetPhysicsWallRight(0)
SetPhysicsWallTop(0)
global player as _player
player.hit=0
player.ammoLeft = 1000
player.ID=CreateSprite(0)
SetSpriteSize(player.ID,10,40)
SetSpritePosition(player.ID,500,700)
SetSpriteOffset(player.ID,5,40)
SetSpritePhysicsOn(player.ID,1)
baseImg=createBaseGun()
player.ID2=createSprite(baseImg)
SetSpriteScale(player.ID2,2,2)
SetSpritePosition(player.ID2,480,732)
SetSpritePhysicsOn(player.ID2,1)
planeLeftImg=createPlaneLeftFace()
planeRightImg=createPlaneRightFace()
global bullets as _bullet[]
global enemies as _enemy[]
global enemyBombs as _bullet[]
global bombersHit,bombersEscaped
global smallHit,smallEscaped
global mediumHit,mediumEscaped
global largeHit,largeEscaped
createEnemies(planeRightImg,planeLeftImg)
do
//rotate player anticlockwise
if GetRawKeyState(KEY_LEFT)
if makeNewAngle(GetSpriteAngle(player.ID),90)>15 then SetSpriteAngle(player.ID,GetSpriteAngle(player.ID)-1)
endif
//rotate player clockwise
if GetRawKeyState(KEY_RIGHT)
if makeNewAngle(GetSpriteAngle(player.ID),90)<165 then SetSpriteAngle(player.ID,GetSpriteAngle(player.ID)+1)
endif
//player shoots
if GetRawKeyState(KEY_SPACE)
if player.ammoLeft>0
SetSpriteOffset(player.ID,5,-10) //set the bullet position in front of gun
shoot(GetSpriteXByOffset(player.ID),GetSpriteYByOffset(player.ID),makeNewAngle(GetSpriteAngle(player.ID),90),185)
SetSpriteOffset(player.ID,5,40)
dec player.ammoLeft,1
endif
endif
//if players been hit do an explosion routine
if player.hit=1
alpha=GetSpriteColorAlpha(player.ID)
blue=GetSpriteColorBlue(player.ID)
green=GetSpriteColorGreen(player.ID)
alpha2=GetSpriteColorAlpha(player.ID2)
blue2=GetSpriteColorBlue(player.ID2)
green2=GetSpriteColorGreen(player.ID2)
if alpha>15 then SetSpriteColorAlpha(player.ID,alpha-10)
if blue>15 then SetSpriteColorBlue(player.ID,blue-10)
if green>15 then SetSpriteColorGreen(player.ID,green-10)
if alpha2>15 then SetSpriteColorAlpha(player.ID2,alpha2-10)
if blue2>15 then SetSpriteColorBlue(player.ID2,blue2-10)
if green2>15 then SetSpriteColorGreen(player.ID2,green2-10)
if player.time+3<timer()
removeSprites()
gameover()
player.hit=0
SetSpriteColor(player.ID,255,255,255,255)
SetSpriteColor(player.ID2,255,255,255,255)
createEnemies(planeRightImg,planeLeftImg)
player.ammoLeft=1000
bombersHit=0:bombersEscaped=0
smallHit=0:smallEscaped=0
mediumHit=0:mediumEscaped=0
largeHit=0:largeEscaped=0
endif
endif
if player.ammoLeft<=0
removeSprites()
gameover()
player.hit=0
SetSpriteColor(player.ID,255,255,255,255)
SetSpriteColor(player.ID2,255,255,255,255)
createEnemies(planeRightImg,planeLeftImg)
player.ammoLeft=1000
bombersHit=0:bombersEscaped=0
smallHit=0:smallEscaped=0
mediumHit=0:mediumEscaped=0
largeHit=0:largeEscaped=0
endif
moveEnemies(planeRightImg,planeLeftImg)
//////////////////////////////////////////////////////////////////////////////////
//check for player bullets and enemy collisions
for num=bullets.length to 0 step -1
for num2=enemies.length to 0 step -1
//print(GetSpriteCollision(bullets[num].ID,enemies[num2].ID))
hit=0
if enemies[num2].hit=0 then hit=checkContact(bullets[num].ID,enemies[num2].ID)
if hit=1 and enemies[num2].hit=0
Select enemies[num2].enemyType
case "Bomber":
inc bombersHit
endcase
Case "Small":
inc smallHit
endcase
case "Medium":
inc mediumHit
endcase
case "Large":
inc largeHit
endcase
endselect
//DeleteSprite(bullets[num].ID)
//bullets.remove(num)
//SetSpriteVisible(enemies[num2].ID,0)
enemies[num2].hit=1
endif
next num2
//endif
next num
//////////////////////////////////////////////////////////////////////////////////
//check if plane has crashed into player
for num=enemies.length to 0 step -1
if checkContact(enemies[num].ID,player.ID)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
if checkContact(enemies[num].ID,player.ID2)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
next
//check if shot yourself
for num=bullets.length to 0 step -1
if checkContact(bullets[num].ID,player.ID)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
if checkContact(bullets[num].ID,player.ID2)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
next
//check if been shot by bombers
for num=enemyBombs.length to 0 step -1
if checkContact(enemyBombs[num].ID,player.ID)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
if checkContact(enemyBombs[num].ID,player.ID2)
if player.hit=0 then player.time=timer() //set the explosion timer
player.hit=1
endif
next
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// Clean up bombs and bullets
for num = enemyBombs.length to 0 step-1
if enemyBombs[num].time#+6<timer()
DeleteSprite(enemyBombs[num].ID)
enemyBombs.remove(num)
endif
next num
for num = bullets.length to 0 step-1
if bullets[num].time#+6<timer()
DeleteSprite(bullets[num].ID)
bullets.remove(num)
endif
next num
//////////////////////////////////////////////////////////////////////////////////
Print("BlitzKrieg")
Print("========")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print(" Hit Escape")
Print("Bombers "+str(bombersHit)+" "+str(bombersEscaped))
Print("Small "+str(smallHit)+" "+str(smallEscaped))
Print("Medium "+str(mediumHit)+" "+str(mediumEscaped))
Print("Large "+str(largeHit)+" "+str(largeEscaped))
Print("Ammo left "+str(player.ammoLeft))
Print( ScreenFPS() )
StepPhysics(1)
Sync()
loop
function shoot(x# as float,y# as float,angle# as float, force# as float)
local bullet as _bullet
bullet.ID=CreateSprite(0)
SetSpritePosition(bullet.ID,x#,y#)
SetSpriteColor(bullet.ID,0,200,0,255)
SetSpriteSize(bullet.ID,5,5)
SetSpriteShape(bullet.ID,2)
SetSpritePhysicsOn(bullet.ID, 2) //2=dynamic
//SetSpriteAngle(bullet.ID, angle#)
SetSpritePhysicsIsBullet(bullet.ID, 1)
SetSpritePhysicsMass(bullet.ID,10)
vx#=cos(angle#)*force#
vy#=sin(angle#)*force#
SetSpritePhysicsImpulse(bullet.ID,x#,y#, -vx#, -vy# )
bullet.time#=timer()
bullets.insert(bullet)
endfunction
function dropBomb(x# as float,y# as float,direction as integer,force# as float)
local bomb as _bullet
local angle# as float
if direction=-1
angle#=275
else
angle#=180
endif
bomb.ID=CreateSprite(0)
SetSpritePosition(bomb.ID,x#,y#)
SetSpriteColor(bomb.ID,200,0,0,255)
SetSpriteSize(bomb.ID,5,5)
SetSpriteShape(bomb.ID,2)
SetSpritePhysicsOn(bomb.ID, 2) //2=dynamic
SetSpritePhysicsIsBullet(bomb.ID, 1)
SetSpritePhysicsMass(bomb.ID,10)
vx#=cos(angle#)*force#
vy#=sin(angle#)*force#
SetSpritePhysicsImpulse(bomb.ID,x#,y#,vx#,-vy#)
bomb.time#=timer()
enemyBombs.insert(bomb)
endfunction
function makeNewAngle(ang#,add#)
// add the new bit
ang# = ang# + add#
// check value
if ang# >= 0.0 and ang# <= 360.0 then exitfunction ang#
// adjust the value
while ang# < 0.0
ang# = ang# + 360.0
endwhile
while ang# > 360.0
ang# = ang# - 360.0
endwhile
endfunction ang#
function createBaseGun()
local data as integer [215] = [
0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0]
dataCount=0
ClearScreen()
for y = 0 to 8
for x = 0 to 23
if data[datacount]=1 then DrawLine(x,y,x,y,255,255,255)
inc dataCount,1
next x
next y
render()
img = getImage(0,0,24,10)
SetImageTransparentColor(img,0,0,0)
endfunction img
function createPlaneRightFace()
local data as integer [263] =[
0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,
0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0]
dataCount=0
ClearScreen()
for y = 0 to 10
for x = 0 to 23
if data[datacount]=1 then DrawLine(x,y,x,y,255,255,255)
inc dataCount,1
next x
next y
render()
img = getImage(0,0,24,12)
SetImageTransparentColor(img,0,0,0)
endfunction img
function createPlaneLeftFace()
local data as integer [263] =[
0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
dataCount=0
ClearScreen()
for y = 0 to 10
for x = 0 to 23
if data[datacount]=1 then DrawLine(x,y,x,y,255,255,255)
inc dataCount,1
next x
next y
render()
img = getImage(0,0,24,12)
SetImageTransparentColor(img,0,0,0)
endfunction img
function createEnemy(enemy ref as _enemy,faceRight as integer,faceleft as integer)
select enemy.enemyType
case "Bomber":
ran=random(1,2)
if ran= 1
enemy.ID=createSprite(faceLeft)
enemy.direction=-1.0
SetSpritePosition(enemy.ID,GetDeviceWidth()+random(1,GetDeviceWidth()/2),random(0,GetDeviceHeight()-300))
else
enemy.ID=createSprite(faceRight)
enemy.direction=1.0
SetSpritePosition(enemy.ID,-(random(1,GetDeviceWidth()/2)),random(0,GetDeviceHeight()-300))
endif
enemy.hit=0
enemy.speed=5/120.0
enemy.enemyType="Bomber"
//SetSpritePosition(enemy.ID,random(0,GetDeviceWidth()),random(0,GetDeviceHeight()-200))
SetSpriteShape(enemy.ID,3)
SetSpritePhysicsOn(enemy.ID,2)
SetSpritePhysicsIsSensor(enemy.ID,1)
SetSpritePhysicsMass(enemy.ID,1000)
SetSpritePhysicsRestitution(enemy.ID,0)
SetSpritePhysicsCanRotate(enemy.ID,0)
SetSpritePhysicsImpulse(enemy.ID,GetSpriteXByOffset(enemy.ID),GetSpriteYByOffset(enemy.ID),enemy.direction*enemy.speed,0)
SetSpriteScale(enemy.ID,3,3)
SetSpriteColor(enemy.ID,150,150,150,255)
//enemies.insert(enemy)
endcase
case "Small":
ran=random(1,2)
if ran= 1
enemy.ID=createSprite(faceLeft)
enemy.direction=-1.0
SetSpritePosition(enemy.ID,GetDeviceWidth()+random(1,GetDeviceWidth()/2),random(0,GetDeviceHeight()-300))
else
enemy.ID=createSprite(faceRight)
enemy.direction=1.0
SetSpritePosition(enemy.ID,-(random(1,GetDeviceWidth()/2)),random(0,GetDeviceHeight()-300))
endif
enemy.hit=0
enemy.speed=random(3,5)/120.0
enemy.enemyType="Small"
//SetSpritePosition(enemy.ID,random(0,GetDeviceWidth()),random(0,GetDeviceHeight()-200))
SetSpriteShape(enemy.ID,2)
SetSpritePhysicsOn(enemy.ID,2)
SetSpritePhysicsIsSensor(enemy.ID,1)
SetSpritePhysicsMass(enemy.ID,100)
SetSpritePhysicsRestitution(enemy.ID,0)
SetSpritePhysicsCanRotate(enemy.ID,0)
SetSpritePhysicsImpulse(enemy.ID,GetSpriteXByOffset(enemy.ID),GetSpriteYByOffset(enemy.ID),enemy.direction*enemy.speed,0)
SetSpriteScale(enemy.ID,2,2)
//enemies.insert(enemy)
endcase
case "Medium":
ran=random(1,2)
if ran= 1
enemy.ID=createSprite(faceLeft)
enemy.direction=-1.0
SetSpritePosition(enemy.ID,GetDeviceWidth()+random(1,GetDeviceWidth()/2),random(0,GetDeviceHeight()-300))
else
enemy.ID=createSprite(faceRight)
enemy.direction=1.0
SetSpritePosition(enemy.ID,-(random(1,GetDeviceWidth()/2)),random(0,GetDeviceHeight()-300))
endif
enemy.hit=0
enemy.speed=random(3,5)/120.0
enemy.enemyType="Medium"
//SetSpritePosition(enemy.ID,random(0,GetDeviceWidth()),random(0,GetDeviceHeight()-200))
SetSpriteShape(enemy.ID,2)
SetSpritePhysicsOn(enemy.ID,2)
SetSpritePhysicsMass(enemy.ID,1000)
SetSpritePhysicsRestitution(enemy.ID,0)
SetSpritePhysicsCanRotate(enemy.ID,0)
SetSpritePhysicsImpulse(enemy.ID,GetSpriteXByOffset(enemy.ID),GetSpriteYByOffset(enemy.ID),enemy.direction*enemy.speed,0)
SetSpriteScale(enemy.ID,3,3)
//enemies.insert(enemy)
endcase
case "Large":
ran=random(1,2)
if ran= 1
enemy.ID=createSprite(faceLeft)
enemy.direction=-1.0
SetSpritePosition(enemy.ID,GetDeviceWidth()+random(1,GetDeviceWidth()/2),random(0,GetDeviceHeight()-300))
else
enemy.ID=createSprite(faceRight)
enemy.direction=1.0
SetSpritePosition(enemy.ID,-(random(1,GetDeviceWidth()/2)),random(0,GetDeviceHeight()-300))
endif
enemy.speed=random(3,5)/120.0
enemy.enemyType="Large"
//SetSpritePosition(enemy.ID,random(0,GetDeviceWidth()),random(0,GetDeviceHeight()-200))
SetSpriteShape(enemy.ID,3)
SetSpritePhysicsOn(enemy.ID,2)
SetSpritePhysicsMass(enemy.ID,1000)
SetSpritePhysicsRestitution(enemy.ID,0)
SetSpritePhysicsCanRotate(enemy.ID,0)
SetSpritePhysicsImpulse(enemy.ID,GetSpriteXByOffset(enemy.ID),GetSpriteYByOffset(enemy.ID),enemy.direction*enemy.speed,0)
SetSpriteScale(enemy.ID,4,4)
//enemies.insert(enemy)
endcase
endselect
endfunction
function createEnemies(faceRight as integer,faceLeft as integer)
enemy as _enemy
for num = 1 to 5
enemy.enemyType="Bomber"
createEnemy(enemy,faceRight,faceLeft)
enemies.insert(enemy)
next num
for num = 1 to 5
enemy.enemyType="Small"
createEnemy(enemy,faceRight,faceLeft)
enemies.insert(enemy)
next num
for num = 1 to 5
enemy.enemyType="Medium"
createEnemy(enemy,faceRight,faceLeft)
enemies.insert(enemy)
next num
for num = 1 to 5
enemy.enemyType="Large"
createEnemy(enemy,faceRight,faceLeft)
enemies.insert(enemy)
next num
endfunction
function moveEnemies(faceRight as integer,faceLeft as integer)
for num=0 to enemies.length
SetSpritePhysicsImpulse(enemies[num].ID,GetSpriteXByOffset(enemies[num].ID),GetSpriteYByOffset(enemies[num].ID),enemies[num].direction*enemies[num].speed,-.025)
escapedCount=0
if GetSpriteX(enemies[num].ID)<-(GetDeviceWidth()/2)
SetSpritePhysicsDelete(enemies[num].ID)
DeleteSprite(enemies[num].id)
if enemies[num].hit=0 then escapedCount=1
createEnemy(enemies[num],faceRight,faceLeft)
endif
if GetSpriteX(enemies[num].ID)>(GetDeviceWidth()/2)+GetDeviceWidth()
SetSpritePhysicsDelete(enemies[num].ID)
DeleteSprite(enemies[num].id)
if enemies[num].hit=0 then escapedCount=1
createEnemy(enemies[num],faceRight,faceLeft)
endif
if enemies[num].enemyType="Bomber" and enemies[num].time#+0.75<timer() and enemies[num].hit=0
dropBomb(GetSpriteXByOffset(enemies[num].ID),GetSpriteYByOffset(enemies[num].ID),enemies[num].direction,85)
enemies[num].time#=timer()
endif
if escapedCount=1
Select enemies[num].enemyType
case "Bomber":
inc bombersEscaped
endcase
Case "Small":
inc smallEscaped
endcase
case "Medium":
inc mediumEscaped
endcase
case "Large":
inc largeEscaped
endcase
endselect
endif
if enemies[num].hit=1
alpha=GetSpriteColorAlpha(enemies[num].ID)
blue=GetSpriteColorBlue(enemies[num].ID)
green=GetSpriteColorGreen(enemies[num].ID)
if alpha>15 then SetSpriteColorAlpha(enemies[num].ID,alpha-10)
if blue>15 then SetSpriteColorBlue(enemies[num].ID,blue-10)
if green>15 then SetSpriteColorGreen(enemies[num].ID,green-10)
endif
next num
endfunction
function checkContact(spr as integer,spr2 as integer)
sprHit as integer
if GetSpriteFirstContact(spr)
sprHit=GetSpriteContactSpriteID2()
if spr2=sprHit then exitfunction 1
while GetSpriteNextContact()
sprHit=GetSpriteContactSpriteID2()
if spr2=sprHit then exitfunction 1
endwhile
//text$=str(sprHit)+" "+str(spr2)
//print (text$)
endif
endfunction 0
function removeSprites()
//remove all player bullets
for num=bullets.length to 0 step -1
deleteSprite(bullets[num].ID)
bullets.remove(num)
next num
//remove all enemies
for num=enemies.length to 0 step -1
deleteSprite(enemies[num].ID)
enemies.remove(num)
next num
//remove all enemy bombs
for num=enemyBombs.length to 0 step -1
deleteSprite(enemyBombs[num].ID)
enemyBombs.remove(num)
next num
endfunction
function gameover()
repeat
Print("BlitzKrieg")
Print("========")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print("")
Print(" GAME OVER")
Print("")
Print("")
Print("")
Print(" Hit Escape")
Print("Bombers "+str(bombersHit)+" "+str(bombersEscaped))
Print("Small "+str(smallHit)+" "+str(smallEscaped))
Print("Medium "+str(mediumHit)+" "+str(mediumEscaped))
Print("Large "+str(largeHit)+" "+str(largeEscaped))
Print("Ammo left "+str(player.ammoLeft))
Print("")
Print(" Press space key to play again")
sync()
until GetRawKeyPressed(KEY_SPACE)
removeSprites()
endfunction
Features
All media created with code
Uses 2D Physics
KEYS
Left Arrow =Rotate Left
Right Arrow=Rotate Right
Space Key =Shoot
Quote: "For those interested puzzler has started a thread for finished games with source at the below link"
https://forum.thegamecreators.com/thread/223468fubar