Saturday, 7 April 2012

User Defined Types

The last post was a bit hefty - I had to get a lot in so apologies if it made anyone cross-eyed following everything.

I was going to post a code summary, but first I wanted to tidy things up a bit and introduce one of the most useful features of AGK.

User Defined Types

UDTs for short are custom data structures which allow a number of different pieces of information be combined into a single entity.

They are used in exactly the same way as normal variables, but are structured using fields which are separated from the main variable name with a full stop.

The best way to show their use is with an example so I'm going to use the existing variables to do that.

At the moment we have several variables that deal with the display, these are;

physWidth#
physHeight#
virtWidth#
virtHeight#
iconSize#
textSize#

These can be combined into a single entity under a group variable display, by defining a UDT called displayType.  This is done immediately after the constant definitions at the start of the program;

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

Between the type and the endtype keywords is a list of fields which will replace the existing variables.  The definition is followed by a global definition which sets the parent name and identifies the type definition which describes it's contents.

global display as displayType

Now each occurrence of the original variable is replaced by it's UDT equivalent and the definition for textheight# is brought up to be with the rest.

Now the block

physWidth# = getDeviceWidth()
physHeight# = getDeviceHeight()
setVirtualResolution( physWidth# , physHeight# )
virtWidth# = getVirtualWidth()
virtHeight# = getVirtualHeight()

iconSize# = physWidth# / PANEL_COLS
panelHeight# = iconSize# * PANEL_ROWS

Becomes 

display.physWidth# = getDeviceWidth()
display.physHeight# = getDeviceHeight()
setVirtualResolution( display.physWidth# , display.physHeight# )
display.virtWidth# = getVirtualWidth()
display.virtHeight# = getVirtualHeight()

display.textHeight# = display.physHeight# / 20.0

display.iconSize# = display.physWidth# / PANEL_COLS

panelHeight# = display.iconSize# * PANEL_ROWS

All other references to the original variables are changed accordingly.

Next a UDT is created for the panel and all panel based variables adjusted in the same way.

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


global panel as panelType
panel.height# = display.iconSize# * PANEL_ROWS
panel.speed# = 0.0
panel.isOpen = 0
panel.iconMax = PANEL_ROWS * PANEL_COLS


panel.Image = loadImage( "panel.jpg" )
setImageWrapU( panel.Image , 1 )
setImageWrapV( panel.Image , 1 )


panel.sprite = createSprite( panel.Image )
uScale# = getImageWidth( panel.Image ) / display.physWidth#
vScale# = getImageHeight( panel.Image ) / panel.Height#
setSpriteUVScale( panel.sprite , uScale# , vScale# )
setSpriteSize( panel.sprite , display.physWidth# , panel.height# )
setSpritePosition( panel.sprite , 0 , display.physHeight# )


panel.text = createText( "Objects" )
setTextSize( panel.text , display.textHeight# )
setTextAlignMent( panel.text , 1)
setTextPosition( panel.text , display.physWidth# / 2.0 , display.physHeight# - display.textHeight# )


panel.sound = loadSound("panel.wav")

And again, all other references changed

Once that is done, the complete program looks like this.

// 7th April 2012 - Tabs Converted to 3 Spaces
#constant PANEL_ROWS   3
#constant PANEL_COLS   4

type displayType
   physWidth#
   physHeight#
   virtWidth#
   virtHeight#
   iconSize#
   textHeight#
endtype

global display as displayType
display.physWidth# = getDeviceWidth()
display.physHeight# = getDeviceHeight()
display.iconSize# = display.physWidth# / PANEL_COLS
display.textHeight# = display.physHeight# / 20.0

setVirtualResolution( display.physWidth# , display.physHeight# )
display.virtWidth# = getVirtualWidth()
display.virtHeight# = getVirtualHeight()

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

global panel as panelType
panel.height# = display.iconSize# * PANEL_ROWS
panel.speed# = 0.0
panel.isOpen = 0
panel.iconMax = PANEL_ROWS * PANEL_COLS

panel.Image = loadImage( "panel.jpg" )
setImageWrapU( panel.Image , 1 )
setImageWrapV( panel.Image , 1 )

panel.sprite = createSprite( panel.Image )
uScale# = getImageWidth( panel.Image ) / display.physWidth#
vScale# = getImageHeight( panel.Image ) / panel.Height#
setSpriteUVScale( panel.sprite , uScale# , vScale# )
setSpriteSize( panel.sprite , display.physWidth# , panel.height# )
setSpritePosition( panel.sprite , 0 , display.physHeight# )

panel.text = createText( "Objects" )
setTextSize( panel.text , display.textHeight# )
setTextAlignMent( panel.text , 1)
setTextPosition( panel.text , display.physWidth# / 2.0 , display.physHeight# - display.textHeight# )

panel.sound = loadSound("panel.wav")

dim panelIconSprite[ panel.iconMax ]
for icon = 1 to panel.iconMax
   panelIconSprite[ icon ] = createSprite( 0 )
   setSpriteSize( panelIconSprite[ icon ] , display.iconSize# - 4, display.iconSize#  - 4)
   setSpriteColor( panelIconSprite[ icon ] , 255 , 255 , 255 , 127 )
next icon

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

PositionPanelIcons()

do
   display.lastFPS# = screenFPS()
   print( "FPS: " + str ( display.lastFPS# ) )
   panel.speed# = panel.height# / (display.lastFPS# * 1.25)

   if getPointerPressed() > 0
      if getPointerY() >= getTextY( panel.text ) and getPointerY() < getSpriteY( panel.sprite )
         panel.isOpen = 1 - panel.isOpen
         playSound( panel.sound )
      endif
   endif

   if panel.isOpen = 1
      if getSpriteY( panel.sprite ) > ( display.physHeight# - panel.height# )
         setSpriteY( panel.sprite , getSpriteY( panel.sprite ) - panel.speed# )
         setTextY( panel.text , getTextY( panel.text ) - panel.speed# )
         PositionPanelIcons()
      endif
   else
      if getSpriteY( panel.sprite ) < display.physHeight#
         setSpriteY( panel.sprite , getSpriteY( panel.sprite ) + panel.speed# )
         setTextY( panel.text , getTextY( panel.text ) + panel.speed# )
         PositionPanelIcons()
      endif
   endif

   setSpritePosition( spriteRef , getPointerX() , getPointerY() )
   printc( "Physical: " )
   print( str( display.physWidth# ) + " x " + str( display.physHeight# ) )
   printc( "Pointer: " )
   print( str( getPointerX() ) + " x " + str( getPointerY() ) )
   sync()
loop

function PositionPanelIcons()
   iconDepth = getSpriteDepth( panel.sprite ) - 1
   for icon = 1 to panel.iconMax
      offset = icon - 1
      col = offset mod PANEL_COLS
      row = offset / PANEL_COLS
      x = col * display.iconSize# + 2
      y = row * display.iconSize# + getSpriteY( panel.sprite ) + 2
      setSpritePosition( panelIconSprite[ icon ] , x , y )
      setSpriteDepth( panelIconSprite[ icon ] , iconDepth )
   next icon
endfunction
//

No comments:

Post a Comment