2018-05-20 11:16:50 +02:00
unit GameTutorial3;
{$mode objfpc} {$H+}
//step3:
//a platformer where everything is 1 hit kill
2018-05-22 12:40:25 +02:00
//Warning: While it's tempting to read through the code to find out how to beat this, try it first without
2018-05-20 11:16:50 +02:00
interface
uses
windows, Classes, SysUtils, gamepanel, guitextobject, staticguiobject, gamebase,
2018-05-22 12:40:25 +02:00
target, bullet, Dialogs, Graphics, playerwithhealth, math, gl, glext, glu,
2018-05-22 15:48:39 +02:00
gamecube, platformenemy, platformplayer;
2018-05-20 11:16:50 +02:00
type
2018-05-22 12:40:25 +02:00
Tdoor= class( TObject)
private
w: single ;
h: single ;
fx, fy: single ;
flocked: boolean ;
door: TStaticGUIObject;
lock: TStaticGUIObject;
public
function isinside( _x, _y: single ) : boolean ;
procedure render;
constructor create;
destructor destroy; override ;
property locked: boolean read flocked write flocked;
property x: single read fx write fx;
property y: single read fy write fy;
end ;
2018-05-20 11:16:50 +02:00
TGame3= class( TGameBase)
private
fpanel: Tgamepanel;
2018-05-22 15:48:39 +02:00
pplayer: TPlatformPlayer;
2018-05-20 11:16:50 +02:00
platforms: array of TgameCube;
2018-05-22 12:40:25 +02:00
enemies: array of TPlatformEnemy; //change from gamecube to gameobject after testing
2018-05-20 11:16:50 +02:00
info: TGUITextObject;
infobutton: TStaticGUIObject;
pausescreen: TGUITextObject;
pausebutton: TStaticGUIObject;
2018-05-22 12:40:25 +02:00
door: Tdoor;
2018-05-20 11:16:50 +02:00
gametime: qword;
walkdirection: single ;
2018-05-22 12:40:25 +02:00
jumpkeydown: boolean ;
2018-05-20 11:16:50 +02:00
yvelocity: single ;
falling: boolean ;
2018-05-22 12:40:25 +02:00
fuckplayer: boolean ; //when true the platformenemies will move to form a barrier around the door
fuckplayertime: qword;
procedure fuckplayercode; //code to call each gametick when the game has been won
2018-05-20 11:16:50 +02:00
function pauseclick( sender: tobject) : boolean ;
function infoPopup( sender: tobject) : boolean ;
function HideInfo( sender: tobject) : boolean ;
procedure spawnPlayer;
2018-05-22 15:48:39 +02:00
procedure resetgame;
2018-05-20 11:16:50 +02:00
public
2018-05-22 12:40:25 +02:00
greencount: integer ;
2018-05-20 11:16:50 +02:00
procedure gametick( currentTime: qword; diff: integer ) ; override ;
procedure render; override ;
function KeyHandler( TGamePanel: TObject; keventtype: integer ; Key: Word ; Shift: TShiftState) : boolean ; override ;
constructor create( p: TGamePanel) ;
destructor destroy; override ;
end ;
implementation
2018-12-08 00:05:26 +01:00
uses registry;
2018-05-22 12:40:25 +02:00
function TDoor. isinside( _x, _y: single ) : boolean ;
begin
result : = ( _x> x - w/ 2 ) and
( _x< x + w/ 2 ) and
( _y> y - h/ 2 ) and
( _y< y + h/ 2 ) ;
end ;
procedure TDoor. render;
begin
door. x: = fx;
door. y: = fy;
lock. x: = fx;
lock. y: = fy;
door. render;
if flocked then lock. render;
end ;
destructor TDoor. destroy;
begin
freeandnil( door) ;
freeandnil( lock) ;
inherited destroy;
end ;
constructor TDoor. create;
begin
flocked: = true ;
w: = 0.08 ;
h: = 0.18 ;
door: = TStaticGUIObject. create( nil , 'door.png' , h, w) ;
lock: = TStaticGUIObject. create( nil , 'lock.png' , h, w) ;
door. rotationpoint. x: = 0 ;
door. rotationpoint. y: = 0 ;
lock. rotationpoint. x: = 0 ;
lock. rotationpoint. y: = 0 ;
x: = 1 - ( w/ 2 ) ;
y: = 1 - ( h/ 2 ) - 0.05 ;
end ;
2018-05-20 11:16:50 +02:00
function TGame3. KeyHandler( TGamePanel: TObject; keventtype: integer ; Key: Word ; Shift: TShiftState) : boolean ;
var
x: boolean ;
i: integer ;
bulletpos: integer ;
ct: qword;
begin
2018-05-22 15:48:39 +02:00
if ( pplayer= nil ) or ( pplayer. blownup) then exit;
2018-05-20 11:16:50 +02:00
if iskeydown( VK_W) and iskeydown( VK_I) and iskeydown( VK_N) then
begin
usedcheats: = true ;
2018-05-22 12:40:25 +02:00
for i: = 0 to length( enemies) - 1 do
enemies[ i] . explode;
door. locked: = false ;
2018-05-20 11:16:50 +02:00
exit;
end ;
if iskeydown( VK_D) and iskeydown( VK_I) and iskeydown( VK_E) then
begin
pplayer. explode;
exit;
end ;
2018-05-22 12:40:25 +02:00
if iskeydown( VK_F) and iskeydown( VK_C) and iskeydown( VK_K) then
begin
2018-05-22 15:48:39 +02:00
door. locked: = false ;
2018-05-22 12:40:25 +02:00
fuckplayer: = true ;
fuckplayertime: = gametime;
exit;
end ;
2018-05-20 11:16:50 +02:00
// if player.isdead then exit;
if keventtype= 0 then
begin
ct: = GetTickCount64;
case key of
2018-05-22 12:40:25 +02:00
VK_P: pauseclick( nil ) ;
2018-05-20 11:16:50 +02:00
VK_LEFT, VK_A: if walkdirection> = 0 then walkdirection: = - 0.1 ; //starts with a lot of inertia
VK_RIGHT, VK_D: if walkdirection< = 0 then walkdirection: = 0.1 ;
VK_SPACE, VK_W, VK_UP:
begin
2018-05-22 12:40:25 +02:00
jumpkeydown: = true ; //makes mountaingoating easier
2018-05-20 11:16:50 +02:00
if falling= false then
begin
yvelocity: = 1.45 ;
end ;
end ;
end ;
end
else
begin
case key of
VK_LEFT, VK_A: if walkdirection< 0 then walkdirection: = 0 ;
VK_RIGHT, VK_D: if walkdirection> 0 then walkdirection: = 0 ;
2018-05-22 12:40:25 +02:00
VK_SPACE, VK_W, VK_UP:
begin
jumpkeydown: = false ;
end ;
2018-05-20 11:16:50 +02:00
end ;
end ;
result : = false ;
end ;
procedure TGame3. render;
var i: integer ;
begin
for i: = 0 to length( platforms) - 1 do
platforms[ i] . render;
if info< > nil then
info. render
else
begin
if infobutton< > nil then
infobutton. render;
end ;
pausebutton. render;
if pausescreen< > nil then
pausescreen. render;
if pplayer< > nil then
pplayer. render;
2018-05-22 12:40:25 +02:00
for i: = 0 to length( enemies) - 1 do
begin
if enemies[ i] < > nil then
enemies[ i] . render;
end ;
if door< > nil then
door. render;
end ;
procedure TGame3. fuckplayercode;
//in 2 seconds take positions
var
t: qword;
pos: single ;
targetx, targety: single ;
distance: single ;
begin
t: = gametime- fuckplayertime;
pos: = t/ 2 0 0 0 ;
if length( enemies) > = 3 then
begin
if enemies[ 0 ] < > nil then
begin
//move it to the bottom left rotated 45 degress to the left
//take 2 seconds to rotate
targetx: = door. x- ( door. w/ 2 ) - ( enemies[ 0 ] . width/ 2 ) ;
if pos> = 1 then
begin
enemies[ 0 ] . rotation: = 3 6 0 - 9 0 ;
enemies[ 0 ] . x: = targetx;
end
else
begin
enemies[ 0 ] . rotation: = 3 6 0 - ( 9 0 * pos) ;
distance: = targetx- enemies[ 0 ] . x;
enemies[ 0 ] . x: = enemies[ 0 ] . x+ distance* pos;
end ;
end ;
if enemies[ 1 ] < > nil then
begin
//move it to the topleft rotated 45 degrees to the left
targetx: = door. x- ( door. w/ 2 ) - ( enemies[ 0 ] . width/ 2 ) ;
targety: = enemies[ 0 ] . y- ( enemies[ 0 ] . height/ 2 ) - ( enemies[ 1 ] . height/ 2 ) ;
if pos> = 1 then
begin
enemies[ 1 ] . rotation: = 3 6 0 - 9 0 ;
enemies[ 1 ] . x: = targetx;
enemies[ 1 ] . y: = targety;
end
else
begin
enemies[ 1 ] . rotation: = 3 6 0 - ( 9 0 * pos) ;
distance: = targetx- enemies[ 1 ] . x;
enemies[ 1 ] . x: = enemies[ 1 ] . x+ distance* pos;
distance: = targety- enemies[ 1 ] . y;
enemies[ 1 ] . y: = enemies[ 1 ] . y+ distance* pos;
end ;
end ;
if enemies[ 2 ] < > nil then
begin
//move it to the topright
targetx: = door. x;
targety: = door. y- ( door. h/ 2 ) - ( enemies[ 2 ] . width/ 2 ) ;
if pos> = 1 then
begin
enemies[ 2 ] . x: = targetx;
enemies[ 2 ] . y: = targety;
end
else
begin
distance: = targetx- enemies[ 2 ] . x;
enemies[ 2 ] . x: = enemies[ 2 ] . x+ distance* pos;
distance: = targety- enemies[ 2 ] . y;
enemies[ 2 ] . y: = enemies[ 2 ] . y+ distance* pos;
end ;
end ;
end ;
2018-05-20 11:16:50 +02:00
end ;
procedure TGame3. gametick( currentTime: qword; diff: integer ) ;
var
i, j: integer ;
oldx, oldy: single ;
newx, newy: single ;
oldplayerfeet, newplayerfeet: single ;
platformwalky: single ;
2018-05-22 12:40:25 +02:00
2018-05-20 11:16:50 +02:00
begin
if ticking= false then exit;
if pausescreen< > nil then
exit;
inc( gametime, diff) ;
oldx: = pplayer. x;
oldy: = pplayer. y;
newy: = pplayer. y- ( yvelocity* ( diff/ 1 0 0 0 ) ) ;
oldplayerfeet: = oldy+ pplayer. height/ 2 ;
newplayerfeet: = newy+ pplayer. height/ 2 ;
pplayer. y: = newy;
if yvelocity< 0 then
begin
//falling down
//check the platforms that are between oldy and pplayer.y
for i: = 0 to length( platforms) - 1 do
begin
platformwalky: = platforms[ i] . y- ( platforms[ i] . height/ 2 ) ;
if ( oldplayerfeet< = platformwalky) and
( newplayerfeet> = platformwalky) then
begin
//it passed this platform. Check if the width is good enough
if ( pplayer. x> platforms[ i] . x- platforms[ i] . width/ 2 ) and
( pplayer. x< platforms[ i] . x+ platforms[ i] . width/ 2 ) then
begin
//yes, it landed on top
2018-05-22 12:40:25 +02:00
if platforms[ i] . color. g= 0 then
inc( greencount) ; //I could of course check if all are green, but this provides an easy hackable spot to speed things up
2018-05-20 11:16:50 +02:00
platforms[ i] . color. r: = 0 ;
platforms[ i] . color. g: = 1 ;
falling: = false ;
yvelocity: = 0 ;
pplayer. y: = platformwalky- pplayer. height/ 2 ; //put it on top of the platform
break;
end ;
end ;
end ;
end ;
if yvelocity< > 0 then
falling: = true ;
2018-05-22 12:40:25 +02:00
if jumpkeydown and not falling then
begin
yvelocity: = 1.45
end
else
yvelocity: = yvelocity- 0.1 ;
2018-05-20 11:16:50 +02:00
if walkdirection< > 0 then
walkdirection: = walkdirection* 1.035 ;
if walkdirection< - 0.7 then walkdirection: = - 0.7 ;
if walkdirection> 0.7 then walkdirection: = 0.7 ;
if ( pplayer< > nil ) and ( walkdirection< > 0 ) then
begin
pplayer. x: = pplayer. x+ ( walkdirection* ( diff/ 1 0 0 0 ) ) ;
end ;
if pplayer. x> ( 1 - pplayer. width/ 2 ) then pplayer. x: = ( 1 - pplayer. width/ 2 ) ;
if pplayer. x< ( - 1 + pplayer. width/ 2 ) then pplayer. x: = ( - 1 + pplayer. width/ 2 ) ;
2018-05-22 12:40:25 +02:00
if fuckplayer then
fuckplayercode
else
2018-05-20 11:16:50 +02:00
begin
2018-05-22 12:40:25 +02:00
for i: = 0 to length( enemies) - 1 do
2018-05-20 11:16:50 +02:00
begin
2018-05-22 12:40:25 +02:00
if enemies[ i] < > nil then
enemies[ i] . travel( diff) ;
2018-05-20 11:16:50 +02:00
end ;
2018-05-22 12:40:25 +02:00
end ;
for i: = 0 to length( enemies) - 1 do
begin
if ( enemies[ i] < > nil ) then
begin
if ( not enemies[ i] . exploding) and enemies[ i] . checkCollision( pplayer) then
2018-05-22 15:48:39 +02:00
pplayer. explode;
2018-05-22 12:40:25 +02:00
if enemies[ i] . blownup then
freeandnil( enemies[ i] ) ;
end ;
end ;
if ( door. locked) and ( greencount> = length( platforms) ) then
begin
door. locked: = false ;
fuckplayer: = true ; //what happens when you nop this out ?
fuckplayertime: = gametime; //another point of attack
end ;
//I 'could' do a constant check for door.unlocked and then enter the fuckplayer mode, but just being nice and making it possible to unlock the door without having to mark all green
2018-05-20 11:16:50 +02:00
2018-05-22 15:48:39 +02:00
if ( pplayer< > nil ) and ( not pplayer. exploding) and ( door. locked= false ) and door. isinside( pplayer. x, pplayer. y) then
2018-05-22 12:40:25 +02:00
begin
ticking: = false ;
showmessage( 'well done' ) ;
2018-12-08 00:05:26 +01:00
with tregistry. create do
begin
if OpenKey( '\Software\Cheat Engine\GTutorial' , true ) then
WriteBool( 'This does not count as a solution for tutorial 3' , True ) ;
free;
end ;
2018-05-22 12:40:25 +02:00
gamewon;
end ;
2018-05-20 11:16:50 +02:00
if ( pplayer< > nil ) and ( pplayer. blownup) then
begin
//recreate the player
//game over, restart
freeandnil( pplayer) ;
2018-05-22 15:48:39 +02:00
resetgame;
2018-05-20 11:16:50 +02:00
end ;
end ;
function TGame3. pauseclick( sender: tobject) : boolean ;
begin
if pausescreen< > nil then
freeandnil( pausescreen)
else
begin
pausescreen: = TGUITextObject. create( fpanel) ;
pausescreen. firstTextBecomesMinWidth: = true ;
pausescreen. width: = 0.8 ;
pausescreen. height: = 0.8 ;
pausescreen. x: = 0 ;
pausescreen. y: = 0 ;
pausescreen. rotationpoint. x: = 0 ;
pausescreen. rotationpoint. y: = 0 ;
pausescreen. color: = clRED;
pausescreen. bcolor: = clWhite;
pausescreen. font. Size: = 1 8 ;
pausescreen. text : = '!PAUSED!' ;
end ;
result : = true ;
end ;
function TGame3. infoPopup( sender: tobject) : boolean ;
begin
if info< > nil then exit( false ) ;
info: = TGUITextObject. create( fpanel) ;
info. firstTextBecomesMinWidth: = true ;
info. width: = 0.8 ;
info. height: = 0.8 ;
info. x: = 0 ;
info. y: = 0 ;
info. rotationpoint. x: = 0 ;
info. rotationpoint. y: = 0 ;
info. color: = clBlack;
info. bcolor: = clWhite;
info. backgroundAlpha: = 1 9 0 ;
info. font. Size: = 9 ;
info. text : = 'Step 3:' #13 #10 +
2018-05-22 12:40:25 +02:00
'Mark all platforms green to' #13 #10 +
'unlock the door' #13 #10 +
' ' #13 #10 +
'Beware: Enemies are 1 hit kill' #13 #10 +
' (and bad losers)' #13 #10 +
' ' #13 #10 +
' ' #13 #10 +
2018-05-20 11:16:50 +02:00
'Have fun!' #13 #10 +
2018-05-22 12:40:25 +02:00
' ' #13 #10 +
2018-05-20 11:16:50 +02:00
'Hint: There are multiple solutions' #13 #10 +
2018-05-22 12:40:25 +02:00
' e.g: Find collisiton detect with ' #13 #10 +
' enemies, or teleport, or fly' #13 #10 +
2018-05-20 11:16:50 +02:00
' or ....' #13 #10 ;
info. OnClick: = @ HideInfo;
result : = true ;
end ;
function TGame3. HideInfo( sender: tobject) : boolean ;
begin
freeandnil( info) ;
result : = true ;
end ;
procedure TGame3. spawnPlayer;
begin
2018-05-22 15:48:39 +02:00
if pplayer= nil then
pplayer: = tplatformplayer. create; //temporary holder
2018-05-20 11:16:50 +02:00
pplayer. x: = - 1 + 0.1 ;
pplayer. y: = 1 - 0.05 - 0.15 / 2 ;
end ;
2018-05-22 15:48:39 +02:00
procedure TGame3. resetgame;
2018-05-20 11:16:50 +02:00
var i: integer ;
begin
2018-05-22 15:48:39 +02:00
spawnplayer;
2018-05-20 11:16:50 +02:00
2018-05-22 15:48:39 +02:00
if length( platforms) < 1 2 then
setlength( platforms, 1 2 ) ;
2018-05-20 11:16:50 +02:00
for i: = 0 to length( platforms) - 1 do
begin
2018-05-22 15:48:39 +02:00
if platforms[ i] = nil then
platforms[ i] : = Tgamecube. create;
2018-05-20 11:16:50 +02:00
platforms[ i] . color. b: = 0 ;
platforms[ i] . color. r: = 0.8 ;
2018-05-22 12:40:25 +02:00
platforms[ i] . color. g: = 0 ;
2018-05-20 11:16:50 +02:00
end ;
//ground
platforms[ 0 ] . width: = 2 ;
platforms[ 0 ] . height: = 0.05 ;
platforms[ 0 ] . x: = 0 ;
platforms[ 0 ] . y: = 0.975 ;
//p1
platforms[ 1 ] . width: = 0.3 ;
platforms[ 1 ] . height: = 0.05 ;
platforms[ 1 ] . x: = - 0.4 ;
platforms[ 1 ] . y: = 0.7 ;
platforms[ 2 ] . width: = 0.3 ;
platforms[ 2 ] . height: = 0.05 ;
platforms[ 2 ] . x: = 0.1 ;
platforms[ 2 ] . y: = 0.7 ;
platforms[ 3 ] . width: = 0.2 ;
platforms[ 3 ] . height: = 0.05 ;
platforms[ 3 ] . x: = 0 ;
platforms[ 3 ] . y: = 0.42 ;
platforms[ 4 ] . width: = 0.2 ;
platforms[ 4 ] . height: = 0.05 ;
platforms[ 4 ] . x: = 0.4 ;
platforms[ 4 ] . y: = 0.2 ;
platforms[ 5 ] . width: = 0.2 ;
platforms[ 5 ] . height: = 0.05 ;
platforms[ 5 ] . x: = 0.6 ;
platforms[ 5 ] . y: = - 0.05 ;
platforms[ 6 ] . width: = 0.4 ;
platforms[ 6 ] . height: = 0.05 ;
platforms[ 6 ] . x: = 0.75 ;
platforms[ 6 ] . y: = - 0.3 ;
platforms[ 7 ] . width: = 0.1 ;
platforms[ 7 ] . height: = 0.05 ;
platforms[ 7 ] . x: = 0.0 ;
platforms[ 7 ] . y: = - 0.3 ;
2018-05-22 12:40:25 +02:00
platforms[ 8 ] . width: = 0.4 ;
2018-05-20 11:16:50 +02:00
platforms[ 8 ] . height: = 0.05 ;
2018-05-22 12:40:25 +02:00
platforms[ 8 ] . x: = - 0.3 ;
2018-05-20 11:16:50 +02:00
platforms[ 8 ] . y: = - 0.5 ;
platforms[ 9 ] . width: = 0.2 ;
platforms[ 9 ] . height: = 0.05 ;
platforms[ 9 ] . x: = - 0.4 ;
platforms[ 9 ] . y: = - 0.7 ;
platforms[ 1 0 ] . width: = 0.2 ;
platforms[ 1 0 ] . height: = 0.05 ;
platforms[ 1 0 ] . x: = - 0.8 ;
platforms[ 1 0 ] . y: = - 0.7 ;
2018-05-22 12:40:25 +02:00
platforms[ 1 1 ] . width: = 0.1 ;
platforms[ 1 1 ] . height: = 0.05 ;
platforms[ 1 1 ] . x: = - 0.8 ;
platforms[ 1 1 ] . y: = 0 ;
2018-05-22 15:48:39 +02:00
fuckplayer: = false ;
if length( enemies) < 3 then
setlength( enemies, 3 ) ;
if enemies[ 0 ] = nil then
enemies[ 0 ] : = TPlatformEnemy. create;
2018-05-22 12:40:25 +02:00
enemies[ 0 ] . x: = - 0.5 ;
enemies[ 0 ] . y: = 1 - enemies[ 0 ] . height/ 2 - platforms[ 0 ] . height;
enemies[ 0 ] . minx: = - 0.6 ;
enemies[ 0 ] . maxx: = 0 - enemies[ 0 ] . width/ 2 ;
2018-05-22 15:48:39 +02:00
enemies[ 0 ] . rotation: = 0 ;
2018-05-22 12:40:25 +02:00
2018-05-22 15:48:39 +02:00
if enemies[ 1 ] = nil then
enemies[ 1 ] : = TPlatformEnemy. create;
2018-05-22 12:40:25 +02:00
enemies[ 1 ] . x: = 0 + enemies[ 0 ] . width/ 2 ;
enemies[ 1 ] . y: = 1 - enemies[ 1 ] . height/ 2 - platforms[ 2 ] . height;
enemies[ 1 ] . minx: = 0 ;
enemies[ 1 ] . maxx: = 0.9 ;
2018-05-22 15:48:39 +02:00
enemies[ 1 ] . rotation: = 0 ;
if enemies[ 2 ] = nil then
enemies[ 2 ] : = TPlatformEnemy. create;
2018-05-22 12:40:25 +02:00
enemies[ 2 ] . x: = 0 + enemies[ 0 ] . width/ 2 ;
enemies[ 2 ] . y: = platforms[ 8 ] . y- ( enemies[ 2 ] . height/ 2 ) - ( platforms[ 8 ] . height/ 2 ) ;
enemies[ 2 ] . minx: = platforms[ 8 ] . x- platforms[ 8 ] . width/ 2 ;
enemies[ 2 ] . maxx: = platforms[ 8 ] . x+ platforms[ 8 ] . width/ 2 ;
2018-05-29 15:10:22 +02:00
enemies[ 2 ] . speed: = enemies[ 1 ] . speed/ 2 ; //got to keep the illusion the player can potentially win
2018-05-22 12:40:25 +02:00
2018-05-22 15:48:39 +02:00
greencount: = 0 ;
door. locked: = true ;
end ;
destructor TGame3. destroy;
begin
if pplayer< > nil then
freeandnil( pplayer) ;
if infobutton< > nil then
freeandnil( infobutton) ;
if info< > nil then
freeandnil( info) ;
inherited destroy;
end ;
constructor TGame3. create( p: TGamePanel) ;
var i: integer ;
begin
fpanel: = p;
infobutton: = TStaticGUIObject. create( p, 'infobutton.png' , 0.1 , 0.1 ) ;
infobutton. rotationpoint. y: = 1 ; //so the bottom will be the y pos
infobutton. x: = - 1 ;
infobutton. y: = 1 - 0.05 ;
infobutton. OnClick: = @ infopopup;
2018-05-22 12:40:25 +02:00
2018-05-22 15:48:39 +02:00
pausebutton: = TStaticGUIObject. create( p, 'pausebutton.png' , 0.1 , 0.1 ) ;
pausebutton. rotationpoint. y: = 1 ;
pausebutton. x: = - 1 + 0.1 ;
pausebutton. y: = 1 - 0.05 ;
pausebutton. OnClick: = @ pauseclick;
2018-05-22 12:40:25 +02:00
door: = Tdoor. create;
2018-05-22 15:48:39 +02:00
resetgame;
2018-05-20 11:16:50 +02:00
infopopup( infobutton) ;
ticking: = true ;
{ p. background. r: = 0 ;
p. background. g: = 0 ;
p. background. b: = 1 ; }
end ;
end .