Tuesday 17 April 2012

Game States - Check

As I left you to create the last couple of functions without a guide, here's a complete code listing of the program as it stands now for you to check against.

// April 17 2012 - Tabs converted to 3 spaces.
#constant PANEL_ROWS   3
#constant PANEL_COLS   4

#constant DEPTH_SCORE   20
#constant DEPTH_PANEL   30
#constant DEPTH_WORK   40

#constant MAX_WORKOBJECTS   100

#constant FRAME_HIGHLIGHT   251
#constant FRAME_TRASHCAN      252

#constant STATE_SETUP   0
#constant STATE_INTRO   1
#constant STATE_DEMO   2
#constant STATE_MENU   3
#constant STATE_RUNNING   4
#constant STATE_EXIT   99

type displayType
   physWidth#
   physHeight#
   virtWidth#
   virtHeight#
   iconSize#
   textHeight#
   lastFPS#
   iconImage
   highSprite
endtype

type touchType
   pointDX#
   pointDY#
   pointWX#
   pointWY#
   spritePicked
   objectPicked
   pickOffsetX#
   pickOffsetY#
endtype

type panelType
   height#
   speed#
   isOpen
   image
   sprite
   text
   sound
   iconMax
endtype

type WorkObjectType
   isFree
   objectID
   sprite
endtype

type GameType
   state
   level
endtype

global numWorkObjects = 0

Initialise()

// Temporary Objects

imageRef = SafeloadImage( "finger.png" )
spriteRef = createSprite( imageRef )

// Main Loop
do
   LoopStart()
   select GameState()
      case STATE_SETUP
         // Setup Code
         setGameState( STATE_RUNNING )
      endcase
      case STATE_INTRO
         // Intro Code
      endcase
      case STATE_DEMO
         // Demo Code
      endcase
      case STATE_MENU
         // Menu Code
      endcase
      case STATE_RUNNING
         // Running Code
         checkGamePointer()
      endcase
   endselect

   setSpritePosition( spriteRef , PointDX() , PointDY() )

   PrintDiagnostics()
   sync()
loop

// Loop Functions

function LoopStart()
   display.lastFPS# = screenFPS()
   panel.speed# = panelHeight() / (lastFPS() * 1.25)
   touch.pointDX# = getPointerX()
   touch.pointDY# = getPointerY()
   touch.pointWX# = ScreentoWorldX(PointDX())
   touch.pointWY# = ScreentoWorldY(PointDY())
endfunction

// Game Functions

function checkGamePointer()
   if getPointerPressed() > 0
      if PointDY() >= getTextY( panelText() ) and PointDY() < getSpriteY( panelSprite() )
         ToggleTrayOpen()
      elseif PointDY() < getTextY( panelText() )
         touch.spritePicked = getSpriteHit( PointWX() , pointWY() )
         if SpritePicked() > 0
            touch.objectPicked = FindWorkObjectBySprite( SpritePicked() )
            if ObjectPicked() > 0
             touch.pickOffsetX# = PointWX() - getSpriteXByOffset( SpritePicked() )
             touch.pickOffsetY# = PointWY() - getSpriteYByOffset( SpritePicked() )
            endif
         endif
      endif
   elseif getPointerReleased() > 0
      if thisObjectPicked > 0
         thisX# = PointWX() - PickOffsetX()
         thisY# = PointWY() - PickOffsetY()
         HideHighLight()
         if WorldToScreenY( thisY#) >= getTextY( panelText() )
            DelWorkObject( ObjectPicked() )
         else
            setSpritePositionByOffset( SpritePicked() , thisX# , thisY# )
            setSpriteDepth( SpritePicked() , DEPTH_WORK - 1 )
            thisObjectUnder = WorkObjectIsOver( ObjectPicked() )
            if thisObjectUnder > 0
               // This is where the merge objects code goes
            endif
         endif
      endif
      touch.spritePicked = 0
      touch.objectPicked = 0
      touch.pickOffsetX# = 0.0
      touch.pickOffsetY# = 0.0
   elseif getPointerState() > 0
      if ObjectPicked() > 0
         thisX# = PointWX() - PickOffsetX()
         thisY# = PointWY() - PickOffsetY()
         setSpritePositionByOffset( SpritePicked() , thisX# , thisY# )
         setSpriteDepth( SpritePicked() , DEPTH_PANEL - 5 )
         if WorldToScreenY( thisY#) >= getTextY( panelText() )
            HighlightSprite( SpritePicked() , FRAME_TRASHCAN )
         else
            thisObjectUnder = WorkObjectIsOver( ObjectPicked() )
            if thisObjectUnder > 0
               HighlightSprite( WorkObjectSprite( thisObjectUnder ) , FRAME_HIGHLIGHT )
            else
               HideHighLight()
            endif
         endif
      endif
   endif

   if panelIsOpen() = 1
      if getSpriteY( panelSprite() ) > ( PhysHeight() - panelHeight() )
         MovePanel( -panelSpeed() )
      endif
   else
      if getSpriteY( panelSprite() ) < PhysHeight()
         MovePanel( panelSpeed() )
      endif
   endif
endfunction

// Diagnostic Functions

function PrintDiagnostics()
   printc( "Phy: " + str( PhysWidth() , 0) + " x " + str( PhysHeight() , 0 ))
   printc( ", Vir: " + str( VirtWidth() , 1) + " x " + str( VirtHeight() , 1 ))
   print( ", @ " + str ( lastFPS() , 2 ) + " fps" + chr(10) )

   printc( "Pointer (Display): " )
   print( str( PointDX() ) + " x " + str( PointDY() ) )
   printc( "Pointer (World): " )
   print( str( PointWX() ) + " x " + str( PointWY() ) )
   printc( "Sprite: ")
   print( str( getSpriteHit( PointDX() , PointDY() )))
   printc( "Sprite Picked: ")
   printc( str( SpritePicked() ))
   printc( ", Object Picked: ")
   printc( str( ObjectPicked() ))
   printc( ", Over : " )
   print( str( WorkObjectIsOver( ObjectPicked() ) ))
endfunction

// Panel Functions

function ToggleTrayOpen()
   panel.isOpen = 1 - panelIsOpen()
   if panelSound() > 0 then playSound( panelSound() )
endfunction

function MovePanel( distance# )
   setSpriteY( panelSprite() , getSpriteY( panelSprite() ) + distance# )
   setTextY( panelText() , getTextY( panelText() ) + distance# )
   PositionPanelIcons()
endfunction

function PositionPanelIcons()
   iconDepth = getSpriteDepth( PanelSprite() ) - 1
   for icon = 1 to panelIconMax()
      offset = icon - 1
      col = offset mod PANEL_COLS
      row = offset / PANEL_COLS
      x = col * IconSize() + 2
      y = row * IconSize() + getSpriteY( PanelSprite() ) + 2
      setSpritePosition( panelIconSprite[ icon ] , x , y )
      setSpriteDepth( panelIconSprite[ icon ] , iconDepth )
   next icon
endfunction

// Load Functions

function SafeLoadImage( thisFileName$ )
   if getFileExists( thisFileName$ )
      thisImageRef = loadImage( thisFileName$ )
   else
      thisImageRef = 0
   endif
endfunction thisImageRef

function SafeLoadSound( thisFileName$ )
   if getFileExists( thisFileName$ )
      thisSoundRef = loadSound( thisFileName$ )
   else
      thisSoundRef = 0
   endif
endfunction thisSoundRef

// Base 96 Functions

function Base96Encode( thisValue )
   lowValue = thisValue mod 96
   highValue = ( thisValue / 96 ) mod 96
   thisString$ = chr( highValue + 32 ) + chr( lowValue + 32 )
endfunction thisString$

function Base96Decode( thisString$ )
   thisLen = len(thisString$)
   if thisLen = 0
      thisValue = 0
   else
      if thisLen = 1 then thisString$ = " " + thisString$
      highValue = asc( left( thisString$ , 1 ) ) - 32
      lowValue = asc( mid( thisString$ , 2, 1 ) ) - 32
      thisValue = highValue * 96 + lowValue
   endif
endfunction thisValue

function Base96Sort( thisString$ )
   thisLen = len(thisString$)
   if thisLen > 2 and (thisLen && 1) = 0
      thisArraySize = thisLen / 2
      dim tempArray[ thisArraySize ] as string
      for i=1 to thisArraySize
         tempArray[ i ] = mid( thisString$ , i*2 - 1 , 2)
      next i
      SortTempArray( thisArraySize )
      thisString$ = ""
      for i=1 to thisArraySize
         thisString$ = thisString$ + tempArray[ i ]
      next i
   endif
endfunction thisString$

function SortTempArray( thisSize )
   for i=1 to thisSize - 1
      thisLow = i
      for j = i + 1 to thisSize
         if tempArray[j] < tempArray[thisLow] then thisLow = j
      next j
      if thisLowest <> i
         temp$ = tempArray[i]
         tempArray[i] = tempArray[thisLow]
         tempArray[thisLow] = temp$
      endif
   next i
endfunction

// Work Object Functions

function TopWorkObject()
endfunction numWorkObjects

function WorkObjectValid( thisObject )
   thisBool = ( thisObject > 0 and thisObject <= TopWorkObject() )
endfunction thisBool

function FirstFreeWorkObject()
   for thisObject = 1 to TopWorkObject()
      if WorkObjectIsFree( thisObject ) > 0 then exit
   next thisObject
   if thisObject > MAX_WORKOBJECTS then thisObject = 0
endfunction thisObject

function AddWorkObject( thisObjectID, thisSprite )
   thisObject = FirstFreeWorkObject()
   if thisObject > TopWorkObject() then numWorkObjects = thisObject
   if WorkObjectValid( thisObject )
      workObject[ thisObject ].isFree = 0
      workObject[ thisObject ].objectID = thisObjectID
      workObject[ thisObject ].sprite = thisSprite
   endif
endfunction thisObject

function DelWorkObject( thisObject )
   if WorkObjectValid( thisObject )
      workObject[ thisObject ].isFree = 1
      if WorkObjectSprite( thisObject ) > 0
         thisSprite = WorkObjectSprite( thisObject )
         workObject[ thisObject ].sprite = 0
         if getSpriteExists( thisSprite ) then deleteSprite( thisSprite )
      endif
      while WorkObjectIsFree( TopWorkObject() ) = 1 and TopWorkObject() >= 0
         dec numWorkObjects , 1
      endwhile
   endif
endfunction

function CreateWorkObjectSprite( thisObject , thisX , thisY )
   if WorkObjectIsFree( thisObject ) = 0
      if WorkObjectSprite( thisObject ) = 0 then workObject[ thisObject ].sprite = createSprite( IconImage() )
      thisSprite = WorkObjectSprite( thisObject )
      fixSpriteToScreen( thisSprite , 0 )
      setSpriteSize( thisSprite , IconSize() , - 1)
      setSpriteOffset( thisSprite , iconSize() / 2.0 , iconSize() / 2.0 )
      setSpritePositionByOffset( thisSprite , thisX , thisY )
      setSpriteDepth( thisSprite , DEPTH_WORK - 1 )
      setSpriteAnimation( thisSprite , 64 , 64 , 252 )
      setSpriteFrame( thisSprite , WorkObjectID( thisObject ) )
   endif
endfunction

function WorkObjectIsOver( thisWorkObject )
   thisSprite = WorkObjectSprite( thisWorkObject )
   if thisSprite > 0
      thisX# = getSpriteXByOffset( thisSprite )
      thisY# = getSpriteYByOffset( thisSprite )
      for thisObject = 1 to TopWorkObject()
         if thisObject <> thisWorkObject
            thisSprite = WorkObjectSprite( thisObject )
            if thisSprite > 0
               diffX# = abs( getSpriteXByOffset( thisSprite ) - thisX# )
               diffY# = abs( getSpriteYByOffset( thisSprite ) - thisY# )
               if diffX# < iconSize() and diffY# < iconSize() then exit
            endif
         endif
      next thisObject
      if thisObject > TopWorkObject() then thisObject = 0
   else
      thisObject = -1
   endif
endfunction thisObject

function FindWorkObjectBySprite( thisSprite )
   for thisObject = 1 to TopWorkObject()
      if WorkObjectSprite( thisObject ) = thisSprite then exit
   next thisObject
   if thisObject > TopWorkObject() then thisObject = 0
endfunction thisObject

function HideHighLight()
   if HighSprite() > 0
      if getSpriteExists( HighSprite() ) then deleteSprite( HighSprite() )
      display.highSprite = 0
   endif
endfunction

function HighlightSprite( thisSprite , thisFrame )
   if thisSprite > 0 and thisFrame > 0 and thisFrame < 253
      if getSpriteExists( thisSprite )
         HideHighLight()
         display.highSprite = cloneSprite( thisSprite )
         setSpriteFrame( HighSprite() , thisFrame )
         setSpriteDepth( HighSprite() , getSpriteDepth( HighSprite() ) - 1)
      endif
   endif
endfunction

// Game State Functions

function SetGameState( thisState )
   game.state = thisState
endfunction

// Initialisation Functions

function Initialise()
   // Prepare Globals
   global game as gameType
      game.level = 0
      game.state = STATE_SETUP

   global touch as touchType
      touch.pointDX# = 0.0
      touch.pointDY# = 0.0
      touch.pointWX# = 0.0
      touch.pointWY# = 0.0
      touch.spritePicked = 0
      touch.objectPicked = 0
      touch.pickOffsetX# = 0.0
      touch.pickOffsetY# = 0.0

   global display as displayType
      display.physWidth# = getDeviceWidth()
      display.physHeight# = getDeviceHeight()
      display.virtWidth# = PhysWidth()
      display.virtHeight# = PhysHeight()
      display.iconSize# = PhysWidth() / PANEL_COLS
      display.textHeight# = PhysHeight() / 20.0
      display.highSprite = 0
      display.iconImage = SafeloadImage( "objects.png" )

   global panel as panelType
      panel.iconMax = PANEL_ROWS * PANEL_COLS
      panel.height# = IconSize() * PANEL_ROWS
      panel.speed# = 0.0
      panel.isOpen = 0
      panel.Image = SafeloadImage( "panel.jpg" )
      panel.sprite = createSprite( PanelImage() )
      panel.text = createText( "Objects" )
      panel.sound = SafeLoadSound("panel.wav")

   setImageWrapU( PanelImage() , 1 )
   setImageWrapV( PanelImage() , 1 )

   uScale# = getImageWidth( PanelImage() ) / PhysWidth()
   vScale# = getImageHeight( PanelImage() ) / PanelHeight()
   setSpriteUVScale( PanelSprite() , uScale# , vScale# )
   setSpriteSize( PanelSprite() , PhysWidth() , PanelHeight() )
   setSpritePosition( PanelSprite() , 0 , PhysHeight() )
   setSpriteDepth( PanelSprite() , DEPTH_PANEL)

   setTextSize( panelText() , textHeight() )
   setTextAlignMent( panelText() , 1)
   setTextPosition( panelText() , PhysWidth() / 2.0 , PhysHeight() - TextHeight() )
   setTextDepth( panelText() , DEPTH_PANEL - 1 )

   // Prepare Arrays

   dim panelIconSprite[ panelIconMax() ]
      for icon = 1 to panelIconMax()
         panelIconSprite[ icon ] = createSprite( 0 )
         setSpriteSize( panelIconSprite[ icon ] , IconSize() - 4, IconSize() - 4)
         setSpriteColor( panelIconSprite[ icon ] , 255 , 255 , 255 , 127 )
      next icon

   dim workObject[ MAX_WORKOBJECTS ] as WorkObjectType
      for thisObject = 1 to MAX_WORKOBJECTS
         workObject[ thisObject ].isFree = 1
         workObject[ thisObject ].objectID = 0
         workObject[ thisObject ].sprite = 0
      next thisObject
   setVirtualResolution( VirtWidth(), VirtHeight() )
   PositionPanelIcons()
endfunction

// Return Functions - Game

function GameLevel()
endfunction game.level
function GameState()
endfunction game.state

// Return Functions - Display

function PhysWidth()
endfunction display.physWidth#
function PhysHeight()
endfunction display.physHeight#
function VirtWidth()
endfunction display.virtWidth#
function VirtHeight()
endfunction display.virtHeight#
function IconSize()
endfunction display.iconSize#
function TextHeight()
endfunction display.textHeight#
function LastFPS()
endfunction display.lastFPS#
function IconImage()
endfunction display.iconImage
function HighSprite()
endfunction display.highSprite

// Return Functions - Touch

function PointDX()
endfunction touch.pointDX#
function PointDY()
endfunction touch.pointDY#
function PointWX()
endfunction touch.pointWX#
function PointWY()
endfunction touch.pointWY#
function SpritePicked()
endfunction touch.spritePicked
function ObjectPicked()
endfunction touch.objectPicked
function PickOffsetX()
endfunction touch.pickOffsetX#
function PickOffsetY()
endfunction touch.pickOffsetY#

// Return Functions - Panel

function PanelHeight()
endfunction panel.height#
function PanelSpeed()
endfunction panel.speed#
function PanelIsOpen()
endfunction panel.isOpen
function PanelImage()
endfunction panel.image
function PanelSprite()
endfunction panel.sprite
function PanelText()
endfunction panel.text
function PanelSound()
endfunction panel.sound
function PanelIconMax()
endfunction panel.iconMax

// Return Functions - WorkObject Array

function WorkObjectIsFree( thisObject )
   if WorkObjectValid( thisObject )
      thisIsFree = workObject[ thisObject ].isFree
   else
      thisIsFree = -1
   endif
endfunction thisIsFree

function WorkObjectID( thisObject )
   if WorkObjectValid( thisObject )
      thisObjectID = workObject[ thisObject ].objectID
   else
      thisObjectID = -1
   endif
endfunction thisObjectID

function WorkObjectSprite( thisObject )
   if WorkObjectValid( thisObject )
      thisSprite = workObject[ thisObject ].sprite
   else
      thisSprite = -1
   endif
endfunction thisSprite
//

No comments:

Post a Comment