Ok then, here you go; my entry.
It's the epic tale of a primitive animal's agonizing days, being punched in the face by a vicious camera while being held down by the evil power of a malfunctioning collision system.
No media required;
rem ********************
rem * Rudolpho's entry *
rem * 2009-04-06 *
rem ********************
#constant true 1
#constant false 0
#constant _n chr$(13) + chr$(10)
#constant SYNC_FREQUENCY 50 ` This is essentially the desired FPS
#constant SEGMENT_FLOOR 1
#constant SEGMENT_WALL 2
#constant TEX_FLOOR 1001
#constant TEX_WALL 1002
#constant TEX_COIN 1100
#constant TEX_SKY 1999
#constant IMG_WIN_BG 2001
#constant IMG_WIN_FRONT 2002
#constant IMG_LOOSE_BG 2003
#constant IMG_LOOSE_FRONT 2004
#constant OBJ_SKY 9998
` Structures
type levelData
width as dword
height as dword
segSize as double float
coins as dword
endtype
type levelArrayData
exist as boolean
seg as byte
obj as dword
endtype
type coord
x as dword
y as dword
endtype
type vector
x as double float
y as double float
z as double float
endtype
type playerData
obj as dword
pos as vector
oldpos as vector
size as vector ` Used for collision checking
tile as coord
angle as vector ` Room for all angles allthough just y
oldangle as vector ` is used here
score as dword ` Number of coins taken
endtype
type coins
isTaken as boolean
obj as dword
pos as vector
size as vector
angle as double float
endtype
type timerType
round as dword ` Time (in seconds, not ms) to complete level
remaining as dword
last as dword
endtype
type masterTimerType ` Used for timer-based movement
last as dword
delta as dword
force as double float
endtype
` Variables
global level as levelData
level.segsize = 100.0 ` The size (square) of each level segment
global player as playerData
global time as timerType
time.round = 120 ` 2 minutes
time.remaining = time.round
time.last = timer()
global masterTime as masterTimerType
masterTime.delta = 1000 / SYNC_FREQUENCY
masterTime.last = timer()
` Setup engine
sync on
autocam off
set camera range 1.0, 10000.0
color backdrop 0x000000
gosub generateMedia
gosub prepareLevelData
gosub buildLevel
gosub setupPlayer
setupCoins(50) ` This will place 50 coins randomly around the level
assembleSkybox(OBJ_SKY, TEX_SKY)
position camera player.pos.x, 251.0, player.pos.z + 500.0
yrotate camera 180.0
set text size 24
set text to bold
ink 0xee9900, 0x000001
` Main loop
while not escapekey()
masterTime.force = getTimeForce()
handlePlayer()
handleCoins()
if returnkey() then text 0, 50, "Segment type: " + str$(level(player.tile.x, player.tile.y).seg)
text 0, 0, "Tile: " + str$(player.tile.x) + "x" + str$(player.tile.y)
text coin(0).pos.x + 20, coin(0).pos.y, str$(player.score) + " / " + str$(level.coins)
set camera to follow player.pos.x, player.pos.y, player.pos.z, object angle y(player.obj), level.segSize * 2.0, level.segSize * 0.75, 31.0, true
updateTimer()
updateMasterTimer()
sync
endwhile
end
generateMedia:
createWallTexture(TEX_WALL)
createFloorTexture(TEX_FLOOR)
createCoinTexture(TEX_COIN)
createSkyTexture(TEX_SKY)
createWinScreen(IMG_WIN_BG)
createWinScreen2(IMG_WIN_FRONT)
createGameOverScreen(IMG_LOOSE_BG)
createGameOverScreen2(IMG_LOOSE_FRONT)
return
prepareLevelData:
` For simplicity and independence of any external files, we use the data commands to
` create the level layout here.
restore
data 25, 25 ` The dimensions of the level; width x height
` Actual level segment data follows; the digits used are corresponding to the declared
` constants above. (Zeroes represent empty space).
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ` First
data 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0
data 2, 1, 1, 2, 2, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0
data 2, 1, 1, 2, 2, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0
data 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0
data 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 1, 1, 2, 2, 2, 2, 2, 2, 0, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ` S
data 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
data 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ` Last
`S
` Set the starting tile for the player as column x row
` (Columns are counted from left to right and rows from top to bottom; count is
` zero-based). The S's up above pinpoint the starting position that is set below:
data 11, 22
return
buildLevel:
` Read level data and create the level out of simple bodies for visually representing it
restore
read level.width
read level.height
tw = level.width - 1 ` This will save some time in the for loop
th = level.height - 1 ` (It will hardly be noticeable in this context though)
dim level(tw, th) as levelArrayData
for y = 0 to th
for x = 0 to tw
read level(x, y).seg
level(x, y).obj = 2000 + (y * level.width) + x
select level(x, y).seg
case SEGMENT_FLOOR:
make object plain level(x, y).obj, level.segSize, level.segSize, true
xrotate object level(x, y).obj, 90
if image exist(TEX_FLOOR)
texture object level(x, y).obj, TEX_FLOOR
endif
level(x, y).exist = true ` This will be quicker than calling object exist()
endcase
case SEGMENT_WALL:
make object box level(x, y).obj, level.segSize, level.segSize * 1.5, level.segSize
` The standard box object (as well as all other primitives) are by default
` oriented around its center on the Y-axis. Therefore we need to offset it
` properly in order to have it based around its bottom instead:
offset limb level(x, y).obj, 0, 0.0, level.segSize * 0.75, 0.0
if image exist(TEX_WALL)
texture object level(x, y).obj, TEX_WALL
endif
level(x, y).exist = true
` Setup a static collision box for easy handling of the "set camera to follow" routine
make static collision box (x - 1) * level.segSize, 0.0, (y - 1) * level.segSize, x * level.segSize, level.segSize * 1.5, y * level.segSize
endcase
` This approach makes the code readily modable; you can easily add in your
` own segments here.
endselect
if level(x, y).exist
position object level(x, y).obj, x * level.segSize, 0.0, y * level.segSize
endif
next y
next x
` Read the starting position
read sx
read sy
player.pos.x = (sx + 0.5) * level.segsize
player.pos.z = (sy - 0.5) * level.segsize
return
setupPlayer:
` This looks rather messy; all it does is create the player object from some primitives
player.obj = 999
tmpObj = 998
make object sphere player.obj, 30.0, 16, 16
scale object player.obj, 100.0, 100.0, 250.0
make object sphere tmpObj, 10.0, 6, 6
scale object tmpObj, 50.0, 100.0, 100.0
make mesh from object tmpObj, tmpObj
add limb player.obj, 1, tmpObj
delete object tmpObj : delete mesh tmpObj
offset limb player.obj, 1, 0.0, 9.0, 15.0
make object triangle tmpObj, -5.0, 0.0, 0.0, 0.0, -5.0, 0.0, 5.0, 0.0, 5.0
make mesh from object tmpObj, tmpObj
add limb player.obj, 2, tmpObj
add limb player.obj, 3, tmpObj
add limb player.obj, 4, tmpObj
add limb player.obj, 5, tmpObj
delete object tmpObj : delete mesh tmpObj
offset limb player.obj, 2, -10.0, -15.0, -10.0
offset limb player.obj, 3, 10.0, -15.0, -10.0
offset limb player.obj, 4, -10.0, -15.0, 10.0
offset limb player.obj, 5, 10.0, -15.0, 10.0
make object sphere tmpObj, 5.0, 8, 8
scale object tmpObj, 100.0, 100.0, 650.0
make mesh from object tmpObj, tmpObj
add limb player.obj, 6, tmpObj
delete object tmpObj : delete mesh tmpObj
offset limb player.obj, 6, 0.0, 5.0, -14.5
rotate limb player.obj, 6, 51.0, 0.0, 0.0
set object cull player.obj, false
color object player.obj, 0xfeaa00
position object player.obj, player.pos.x, 51.0, player.pos.z
yrotate object player.obj, 180.0
player.size.x = object size x(player.obj, true)
player.size.y = object size y(player.obj, true) ` This is actually not used in this implementation
player.size.z = object size z(player.obj, true)
return
` This will add 'count' coins, randomly spread over the level. Coins will only spawn on
` floor segments.
function setupCoins(count as dword)
local continue as boolean
dim coin(count) as coins
level.coins = count
player.score = 0
coin(0).obj = 10000
make object sphere coin(0).obj, 20, 4, 4 ` Give them that edge-ish look
scale object coin(0).obj, 100.0, 100.0, 10.0
set object cull coin(0).obj, false
texture object coin(0).obj, TEX_COIN
coin(0).size.x = object size x(coin(0).obj, true)
coin(0).size.y = object size y(coin(0).obj, true)
coin(0).size.z = object size z(coin(0).obj, true)
for c = 1 to count
coin(c).obj = 10000 + c
instance object coin(c).obj, coin(0).obj
coin(c).size.x = coin(0).size.x
coin(c).size.y = coin(0).size.y
coin(c).size.z = coin(0).size.z
` Find a proper spot to spawn (that is, a floor segment and no other coins in such an
` immediate area that they would intersect this one).
continue = false ` Reset
while not continue ` Repeat until a proper position is found
tx = rnd(level.width - 1)
ty = rnd(level.height - 1)
if level(tx, ty).seg = SEGMENT_FLOOR
tmpX# = ((tx - 0.5) * level.segSize) + rnd(level.segSize - coin(c).size.x) + (coin(c).size.x / 2.0)
tmpZ# = ((ty - 0.5) * level.segSize) + rnd(level.segSize - coin(c).size.z) + (coin(c).size.z / 2.0)
if not coinAtPos(tmpX#, tmpZ#, c)
coin(c).pos.x = tmpX#
coin(c).pos.y = 20.0
coin(c).pos.z = tmpZ#
position object coin(c).obj, coin(c).pos.x, coin(c).pos.y, coin(c).pos.z
scale object coin(c).obj, 100.0, 100.0, 20.0
set object cull coin(c).obj, false
continue = true
endif
endif
endwhile
next c
` Use the coin(0) object as an icon / whatever to call it
position camera 0, 251.0, 500.0
scale object coin(0).obj, 300.0, 300.0, 20.0 ` Enlarge now that the instances have been created
position object coin(0).obj, camera position x() + 150.0, camera position y() + 5.0, camera position z() + 20.0
lock object on coin(0).obj
coin(0).pos.x = 460 ` Assumes 640x480 resolution
coin(0).pos.y = 30
endfunction
` Returns true if a coin is already present at the given location; counts from 1 to the
` value specified.
function coinAtPos(x as double float, z as double float, count as dword)
local x1 as double float
local x2 as double float
local z1 as double float
local z2 as double float
for c = 1 to count
x1 = coin(c).pos.x - (coin(c).size.x / 2.0)
x2 = coin(c).pos.x + (coin(c).size.x / 2.0)
z1 = coin(c).pos.z - (coin(c).size.z / 2.0)
z2 = coin(c).pos.z + (coin(c).size.z / 2.0)
if (x <= x2) and (x >= x1) and (z <= z2) and (z >= z1)
` The coin c is occupying the space containing the given positions
exitfunction true
endif
next c
` If we get here no match was found; return false
endfunction false
function handleCoins()
` Rotate the icon coin
yrotate object coin(0).obj, wrapvalue(object angle y(coin(0).obj) + (2.5 * masterTime.force))
for c = 1 to level.coins
if not coin(c).isTaken
yrotate object coin(c).obj, wrapvalue(object angle y(coin(c).obj) + (2.5 * masterTime.force))
if (abs(player.pos.x - coin(c).pos.x) < player.size.x) and (abs(player.pos.z - coin(c).pos.z) < player.size.x)
coin(c).isTaken = true
delete object coin(c).obj
inc player.score
endif
endif
next c
if player.score = level.coins
goto wonGame
endif
endfunction
` Returns true if the player object is hitting a wall segment
function checkPlayerCollision()
local x as double float
local z as double float
local tx as dword
local ty as dword
` Check the tile of the front right "edge" of the player object (simplifying it to a rectangle)
x = newXValue(player.pos.x, object angle y(player.obj), (player.size.x / 2.0))
y = newZValue(player.pos.z, object angle y(player.obj), (player.size.z / 2.0))
tx = int(x / level.segSize)
ty = int((y / level.segSize) + 0.5)
if level(tx, ty).seg = SEGMENT_WALL
text 0, 20, "Wall; " + str$(tx) + "x" + str$(ty)
exitfunction true
endif
` Check the left front edge
x = newXValue(player.pos.x, object angle y(player.obj), -(player.size.x / 2.0))
y = newZValue(player.pos.z, object angle y(player.obj), (player.size.z / 2.0))
tx = int(x / level.segSize)
ty = int((y / level.segSize) + 0.5)
if level(tx, ty).seg = SEGMENT_WALL
text 0, 20, "Wall; " + str$(tx) + "x" + str$(ty)
exitfunction true
endif
` Check the rear left edge
x = newXValue(player.pos.x, object angle y(player.obj), -(player.size.x / 2.0))
y = newZValue(player.pos.z, object angle y(player.obj), -(player.size.z / 2.0))
tx = int((x / level.segSize) + 1.0)
ty = int((y / level.segSize) + 0.5)
if level(tx, ty).seg = SEGMENT_WALL
text 0, 20, "Wall; " + str$(tx) + "x" + str$(ty)
exitfunction true
endif
` Check the rear right edge
x = newXValue(player.pos.x, object angle y(player.obj), (player.size.x / 2.0))
z = newZValue(player.pos.z, object angle y(player.obj), -(player.size.z / 2.0))
tx = int((x / level.segSize) + 1.0)
ty = int((y / level.segSize) + 0.5)
if level(tx, ty).seg = SEGMENT_WALL
text 0, 20, "Wall; " + str$(tx) + "x" + str$(ty)
exitfunction true
endif
` If we get here, no collision was detected
endfunction false
` Handles the player movement, etc. Should be called once per cycle of the main loop.
function handlePlayer()
player.oldpos.x = player.pos.x
player.oldpos.y = player.pos.y
player.oldpos.z = player.pos.z
player.oldangle.y = player.angle.y
yrotate object player.obj, wrapvalue(object angle y(player.obj) + (masterTime.force * 2.0 * (rightkey() - leftkey())))
move object player.obj, masterTime.force * 3.5 * (upkey() - downkey())
player.pos.x = object position x(player.obj)
player.pos.y = object position y(player.obj)
player.pos.z = object position z(player.obj)
player.angle.y = object angle y(player.obj)
player.tile.x = int((player.pos.x / level.segSize) + 0.5)
player.tile.y = int((player.pos.z / level.segSize) - 0.5)
` Is the player colliding with a wall?
if (player.tile.x < level.width) and (player.tile.y < level.height) `and (not spacekey())
if checkPlayerCollision()
player.pos.x = player.oldpos.x
player.pos.y = player.oldpos.y
player.pos.z = player.oldpos.z
player.angle.y = player.oldangle.y
position object player.obj, player.pos.x, player.pos.y, player.pos.z
endif
endif
endfunction
function updateTimer()
if (timer() - time.last) >= 1000
time.last = timer()
dec time.remaining
endif
m = int(time.remaining / 60.0)
s = time.remaining - (m * 60)
timeStr$ = twoDigits(m) + ":" + twoDigits(s)
text screen width() - (text width(timeStr$) + 10), screen height() - 24, timeStr$
if time.remaining = 0
goto gameOver
endif
endfunction
function twoDigits(value as dword)
if value > 9
result$ = str$(value)
else
result$ = "0" + str$(value)
endif
endfunction result$
function updateMasterTimer()
masterTime.last = timer()
endfunction
function getTimeForce()
local force as double float
sinceLast = timer() - masterTime.last
force = (sinceLast * 1.0) / (masterTime.delta * 1.0)
endfunction force
function createFloorTexture(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, 32, 32 ` It doesn't need to be any larger due to the low detail we use
set current bitmap bmp
ink 0xaa00cc, 0x000000
box 0, 0, 31, 31
ink 0x510072, 0x000000
box 0, 0, 15, 15
box 16, 16, 31, 31
ink 0xffffff, 0x000001 ` Reset the ink colour
get image img, 0, 0, 31, 31
set current bitmap 0
delete bitmap bmp
endfunction
function createWallTexture(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, 32, 32 ` It doesn't need to be any larger due to the low detail we use
set current bitmap bmp
ink 0x310051, 0x000000
box 0, 0, 31, 31
ink 0x510099, 0x000000
box 0, 8, 31, 16
ink 0xffffff, 0x000001 ` Reset the ink colour
get image img, 0, 0, 31, 31
set current bitmap 0
delete bitmap bmp
endfunction
function createCoinTexture(img as dword)
local mem as dword : mem = findFreeMemblock()
make memblock mem, 16
write memblock dword mem, 0, 1
write memblock dword mem, 4, 1
write memblock dword mem, 8, 32
write memblock dword mem, 12, 0xfeef00
make image from memblock img, mem
delete memblock mem
endfunction
function createSkyTexture(img as dword)
local mem as dword : mem = findFreeMemblock()
local col as dword
make memblock mem, 12 + ((512 * 512) * 4)
write memblock dword mem, 0, 512
write memblock dword mem, 4, 512
write memblock dword mem, 8, 32
for y = 0 to 511
for x = 0 to 511
if rnd(99) = 99 ` Approx. 1 out of 100
col = 0xffffff
else
col = 0x000000
endif
write memblock dword mem, 12 + (((512 * y) + x) * 4), col
next x
next y
make image from memblock img, mem
delete memblock mem
endfunction
` Background sprite
function createGameOverScreen(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, bitmap width(0), bitmap height(0)
set current bitmap bmp
ink 0x000002, 0x000001
box 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
ink 0xff0000, 0x000001
txtSize = text size()
set text size 48
circle -50, -50, 100
circle bitmap width(bmp) + 50, bitmap height(bmp) + 50, 100
center text bitmap width(bmp) / 2, (bitmap height(bmp) / 2) - 32, "Aw, you ran out of time..."
get image img, 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
set text size txtSize
ink 0xffffff, 0x000001
set current bitmap 0
delete bitmap bmp
endfunction
` Foreground (text) sprite
function createGameOverScreen2(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, bitmap width(0) - 200, 120
set current bitmap bmp
ink 0xff0000, 0x000001
txtSize = text size()
set text size 24
text 0, 0, "Well, due to the lousy collision checks, it is" + _n + "almost impossible to finish this game, no matter" + _n + "how much time you've got."
txt$ = "(Press any key to quit)"
text bitmap width(bmp) - (text width(txt$) + 10), 80, txt$
get image img, 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
set text size txtSize
ink 0xffffff, 0x000001
set current bitmap 0
delete bitmap bmp
endfunction
` Background sprite
function createWinScreen(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, bitmap width(0), bitmap height(0)
set current bitmap bmp
ink 0x000002, 0x000001
box 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
ink 0x006700, 0x000001
txtSize = text size()
set text size 48
circle -100, -100, 200
circle bitmap width(bmp) + 100, bitmap height(bmp) + 100, 200
center text bitmap width(bmp) / 2, (bitmap height(bmp) / 2) - 32, "You won?!"
get image img, 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
set text size txtSize
ink 0xffffff, 0x000001
set current bitmap 0
delete bitmap bmp
endfunction
` Foreground (text) sprite
function createWinScreen2(img as dword)
local bmp as dword : bmp = findFreeBitmap()
create bitmap bmp, bitmap width(0) - 200, 120
set current bitmap bmp
ink 0x006700, 0x000001
txtSize = text size()
set text size 24
text 0, 0, "Wow, the creator never made it this far himself!" + _n + _n + chr$(9) + "... or are you cheating..?"
txt$ = "(Press any key to quit)"
text bitmap width(bmp) - (text width(txt$) + 10), 80, txt$
get image img, 0, 0, bitmap width(bmp) - 1, bitmap height(bmp) - 1
set text size txtSize
ink 0xffffff, 0x000001
set current bitmap 0
delete bitmap bmp
endfunction
function assembleSkybox(obj as dword, img as dword)
make object plain obj, 0, 0 `Base object
position object obj, 0, 0, 0
make object plain obj + 1, 5000, 5000
make mesh from object obj + 1, obj + 1
add limb obj, 1, obj + 1
offset limb obj, 1, 0, 2500, 0
rotate limb obj, 1, 90, 0, 0
add limb obj, 2, obj + 1
offset limb obj, 2, 0, 0, 2500
add limb obj, 3, obj + 1
offset limb obj, 3, 2500, 0, 0
rotate limb obj, 3, 0, 270, 0
add limb obj, 4, obj + 1
offset limb obj, 4, 0, 0, -2500
rotate limb obj, 2, 0, 180, 0
add limb obj, 5, obj + 1
offset limb obj, 5, -2500, 0, 0
rotate limb obj, 5, 0, 90, 0
add limb obj, 6, obj + 1
offset limb obj, 6, 0, -2500, 0
rotate limb obj, 6, 270, 0, 0
texture limb obj, 1, img
texture limb obj, 2, img
texture limb obj, 3, img
texture limb obj, 4, img
texture limb obj, 5, img
texture limb obj, 6, img
delete mesh obj + 1
delete object obj + 1
set object texture obj, 2, 0
set object light obj, false
endfunction
function findFreeBitmap()
for i = 1 to 32
if not bitmap exist(i)
exitfunction i
endif
next i
endfunction 0
function findFreeMemblock()
for m = 1 to 255
if not memblock exist(m)
exitfunction m
endif
next m
endfunction 0
` And here comes the mandatory sprites....
gameOver:
sprite IMG_LOOSE_BG, 0, 0, IMG_LOOSE_BG
t0 = timer()
for t = 0 to 255 step 2
while (timer() - t0) < 10
` Wait...
endwhile
set sprite alpha IMG_LOOSE_BG, t
sync
t0 = timer()
next t
sleep 500
sprite IMG_LOOSE_FRONT, 100, (sprite height(IMG_LOOSE_BG) / 2) + 20, IMG_LOOSE_FRONT
t0 = timer()
for t = 0 to 255 step 2
while (timer() - t0) < 10
` Wait...
endwhile
sync
t0 = timer()
next t
wait key
end
return
wonGame:
sprite IMG_WIN_BG, 0, 0, IMG_WIN_BG
t0 = timer()
for t = 0 to 255 step 2
while (timer() - t0) < 10
` Wait...
sleep 1
endwhile
set sprite alpha IMG_WIN_BG, t
sync
t0 = timer()
next t
sleep 500
sprite IMG_WIN_FRONT, 100, (sprite height(IMG_WIN_BG) / 2) + 20, IMG_WIN_FRONT
t0 = timer()
for t = 0 to 255 step 2
while (timer() - t0) < 10
` Wait...
endwhile
set sprite alpha IMG_WIN_FRONT, t
sync
t0 = timer()
next t
wait key
end
return