-- Author: Barry Swan
-- Email: gerbil@theburrow.co.uk
-- URL: www.theburrow.co.uk
-- Drop this behaviour onto a bitmap sprite
-- Works on the sprite size, not the member
-- Should restore the bitmap member when finished with, but Director is buggy
-- calling endSprite upon exiting, so don't put anything important in the bitmap
-- member or keep a duplicate for easy restoration
----------------------------------------------------------------------------------
------------------------------> Main game loop
on exitFrame me
-- React to game state
case pMode of
#intro:
-- Start game when fire is released
if me.mKeyPressed(pFire) then
repeat while me.mKeyPressed(pFire)
nothing
end repeat
-- Set up game and prepare to play
me.mSetUpLevel(1)
pMode = #playing
end if
#gameover:
-- Stay on game over screen for 3 seconds
pTimer = pTimer - 1
if pTimer <= 0 then
piM.copyPixels(piIntro, pGameRect, pGameRect)
pMode = #intro
end if
#playing:
-- Update player
me.mUpdatePlayer()
-- Update asteroids
tDied = me.mUpdateAsteroids()
-- Update bullets
me.mUpdateBullets()
-- Check game status
if tDied then
pLives = pLives - 1
if pLives < 0 then
-- Game over code
piM.copyPixels(piGameOver, pGameRect, pGameRect)
pMode = #gameover
pTimer = 100
exit
else
-- Lost a life code
pX = pW / 2
pY = pH / 2
pAngle = pi
pDX = 0.0
pDY = 0.0
pInvulnerability = 40
me.mDrawLives()
end if
else if plAsteroids = [] then me.mSetUpLevel(pLevel + 1)
------------------------------> Reacts to player input
on mUpdatePlayer me
-- Reduce invulnerability
if pInvulnerability then pInvulnerability = max(pInvulnerability - 1, 0)
-- Rotate
if me.mKeyPressed(pLeft) then pAngle = pAngle + 0.2
else if me.mKeyPressed(pRight) then pAngle = pAngle - 0.2
-- Accelerate / slow down
if me.mKeyPressed(pAccelerate) then
pDX = pDX + sin(pAngle) * 0.5
pDY = pDY + cos(pAngle) * 0.5
end if
-- Move player
pX = pX + pDX
pY = pY + pDY
-- Limit overall movement speed
tSpeed = pDX * pDX + pDY * pDY
if tSpeed > 100.0 then
pDX = pDX * 100.0 / tSpeed
pDY = pDY * 100.0 / tSpeed
end if
-- Clip player
if pX < 0.0 then pX = pX + pW
else if pX >= pW then pX = pX - pW
if pY < 0.0 then pY = pY + pH
else if pY >= pH then pY = pY - pH
-- Firing?
if me.mKeyPressed(pFire) AND plBullets.count < 8 then
tFX = sin(pAngle) * 7.0
tFY = cos(pAngle) * 7.0
tNewDX = pDX + tFX
tNewDY = pDY + tFY
plBullets.add([pX + tFX, pY + tFY, tNewDX, tNewDY, 20])
end if
end
on mKeyPressed me, tKey
-- Return key pressed state of tKey
case tKey of
"UP CURSOR": return keyPressed(126)
"DOWN CURSOR": return keyPressed(125)
"LEFT CURSOR": return keyPressed(123)
"RIGHT CURSOR": return keyPressed(124)
"SHIFT": return the shiftDown
otherwise: return keyPressed(tKey)
end case
end
------------------------------> Moves asteroids and checks whether they hit the player
on mUpdateAsteroids me
-- Move asteroids
if plAsteroids <> [] then
repeat with a in plAsteroids
-- Move asteroid
tSpeed = (4 - a[4])
tAngle = a[3]
tX = a[1]
tY = a[2]
tX = tX + sin(tAngle) * tSpeed
tY = tY + cos(tAngle) * tSpeed
-- Clip asteroid
if tX < 0.0 then tX = tX + pW
else if tX >= pW then tX = tX - pW
if tY < 0.0 then tY = tY + pH
else if tY >= pH then tY = tY - pH
-- Collision with player (if not invulnerable)
if pInvulnerability = 0 then
tRadius = plAsteroidGraphics[a[4]][2] + 5
tDX = pX - tX
tDY = pY - tY
if tDX * tDX + tDY * tDY <= tRadius * tRadius then return TRUE
end if
-- Store new position
a[1] = tX
a[2] = tY
end repeat
end if
-- Return normal message
return FALSE
end
------------------------------> Moves bullets and checks whether they hit asteroids
on mUpdateBullets me
-- Move bullets
if plBullets <> [] then
tCount = plBullets.count
repeat while tCount
-- Get bullet
tlBullet = plBullets[tCount]
-- Age bullet
if tlBullet[5] <= 0 then plBullets.deleteAt(tCount)
else
tlBullet[5] = tlBullet[5] - 1
-- Draw the character
if tChar <> " " then
tFW = tCW - 1
tFH = tH - 1
tpEnd = point(0, 0)
repeat with b in tlCharData
-- Is this a complete line or following on from the previous one?
if b.count = 2 then
tStart = b[1]
tpStart = point(\
integer(tStart[1] * tFW - 0.49),\
integer(tStart[2] * tFH - 0.49)\
)
tEnd = b[2]
else
tpStart = tpEnd
tEnd = b[1]
end if
-- Process end point
tpEnd = point(\
integer(tEnd[1] * tFW - 0.49),\
integer(tEnd[2] * tFH - 0.49)\
)
-- Draw line
tiChar.draw(tpStart, tpEnd, [#color: tFGColor])
end repeat
end if
-- Save character list
tlFont.font[tChar] = [tiChar, tCharRect, tCW]
end repeat
-- Return new font object
return tlFont
end
------------------------------> Writes text into a buffer
on mText me, tlFont, tiImage, tX, tY, tText, tGap, tInk
-- Set font reference for speed
tlFontChars = tlFont.font
-- Set parameters if missed
if NOT objectP(tiImage) then
tInk = tGap
tGap = tText
tText = tY
tY = tX
tX = tiImage
tNeedBuffer = TRUE
else tNeedBuffer = FALSE
if voidP(tInk) then
-- Set ink and gap if missing
if integerP(tGap) then tInk = #copy
else if symbolP(tGap) then
tInk = tGap
tGap = 2
else
tInk = #copy
tGap = 2
end if
end if
-- Convert string to uppercase
tChars = tText.length
repeat with a = 1 to tChars
-- Get ASCII code of char
tASCII = charToNum(tText.char[a])
-- Convert lower case letters to upper case
if tASCII >= 97 AND tASCII <= 122 then put numToChar(tASCII - 32) into tText.char[a]
end repeat
-- Create new buffer for text
if tNeedBuffer then
-- Loop through string
tW = 0
repeat with a = 1 to tChars
-- Get character
tChar = tText.char[a]
-- Get character width
tlChar = tlFontChars.getAProp(tChar)
if NOT voidP(tlChar) then tW = tW + tlChar[3] + tGap
end repeat
------------------------------> Prevents behaviour being attached to inappropriate sprite
on IsOkToAttach me, tSType, tSN
-- Only attach to valid sprites
if tSN >= 1 then
if tSType = #graphic AND sprite(tSN).member.type = #bitmap then return TRUE
end if
-- Return false
return FALSE
end
------------------------------> Set parameters when behaviour is set
on getPropertyDescriptionList me
-- Set up data
tlData = [:]
-- Set up valid keys
tKeys = "abcdefghijklmnopqrstuvwxyz"
tlKeys = []
tlKeys.add("UP CURSOR")
tlKeys.add("DOWN CURSOR")
tlKeys.add("LEFT CURSOR")
tlKeys.add("RIGHT CURSOR")
tlKeys.add("SHIFT")
repeat with a = 1 to tKeys.length
tlKeys.add(tKeys.char[a])
end repeat
tText = tText & "Drop this behaviour onto a bitmap sprite" & RETURN
tText = tText & "Works on the sprite size, not the member" & RETURN
tText = tText & "Should restore the bitmap member when finished with, but Director is buggy"
tText = tText & "calling endSprite upon exiting, so don't put anything important in the bitmap"
tText = tText & "member or keep a duplicate for easy restoration"
-- Return information
return tText
end
Contact
MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA