//----------------------------------------------------------------------------
// Lesson11: MAKING A GAME
//
// STATES
//
// Okay, the big thing to get through your head for making games is you get
// input, process data, change the states of anything based on that data, and
// then do it all again.
//
// In the previous lesson, we showed that a button was pressed by entering
// setting a state to be "pressed".  In this example, we will combine the
// concepts of animation, user input, and states to walk a guy left and right.
// This will put together a number of the things we've learned.  After this,
// you can study any of the pre-made games to learn collision with a maze,
// real-physics jumping, and so on!
//
// To check out Lesson11...
//
//       MAP TEST
//       LOADAPE Lesson11
//       GOAPE 2:1
//
// More advanced commands in Lesson 12!
//
//#############################################################################
// DEFINES
//#############################################################################

#define @StateTest			"2:1"
#define @Before            		"2:2"
#define @During            		"2:3"
#define @After             		"2:4"
#define @LeftWasPressed     		"2:8"
#define @RightWasPressed   		"2:9"
#define @ProcessEvent			"2:10"
#define @UpdateCounters			"2:11"

#define @DoLeftThings			"2:110"
#define @DoRightThings			"2:120"
#define @MoveGuy			"2:130"
#define @GuyWalkLeft			"2:140"
#define @GuyWalkRight			"2:150"
//-------------------------------------------------------
// CONSTANTS
//-------------------------------------------------------
#define %MSPERFRAME      "50"	// 50 milliseconds * 20 = 1 sec
#define %FRAMESPERSECOND "20"

#define %LEFTSIDE	    	"-100"	// can move 100 left and 100 right
#define %RIGHTSIDE		"100"

#define %PRESSED		"1"	// a button or key was pressed!

//-------------------------------------------------------
#define STATE_STANDINGLEFT		"1"
#define STATE_STANDINGRIGHT		"2"
#define STATE_WALKINGRIGHT	"3"
#define STATE_WALKINGLEFT	"4"
//-------------------------------------------------------
#define KEY_LEFT		"1"
#define KEY_RIGHT		"2"

//#############################################################################
// CODE
//#############################################################################
#window @StateTest
startswitch @Before
thinkswitch @During
finishswitch @After
//-------------------------------------------------------
width 232
height 256
title "Using States"

if (guyState == STATE_WALKINGRIGHT) image apeshape\sideactr\GUYWR$guyFrame$.PCX guyX,guyY
if (guyState == STATE_WALKINGLEFT) image apeshape\sideactr\GUYWL$guyFrame$.PCX guyX,guyY
if (guyState == STATE_STANDINGLEFT) image apeshape\sideactr\GUYSL$guyFrame$.PCX guyX,guyY
if (guyState == STATE_STANDINGRIGHT) image apeshape\sideactr\GUYSR$guyFrame$.PCX guyX,guyY


//=======================================================
// Before
// Initialize stuff!
//=======================================================
#switch @Before
lastMS = func_GameTime
currentMS = lastMS

set guyX = 7 * 16
set guyY = 2 * 16
set guyFrame = 0
set guyState = STATE_STANDINGRIGHT			// Start standing

console "pushbind"
console "bind LEFTARROW invoke @LeftWasPressed"
console "bind RIGHTARROW invoke @RightWasPressed"



return				// at the program

//=======================================================
// During
// Actively update appropriate variables
//=======================================================
#switch @During
set currentMS = func_GameTime		// get starting time, start to count
set delta = currentMS - lastMS
if (delta < %MSPERFRAME) return		// do nothing unless frame starts

set lastMS = currentMS		


if (keyMeaning > 0) gosub @ProcessEvent
gosub @UpdateCounters
gosub @MoveGuy
return
//=======================================================
// ProcessEvent
// If someone pressed a key, let's do stuff!
//=======================================================
#switch @ProcessEvent
if (keyMeaning == KEY_RIGHT) gosub @DoRightThings
else if (keyMeaning == KEY_LEFT) gosub @DoLeftThings
set keyMeaning = 0
return

////==============================================================================
#switch @DoRightThings
if (guyX > 200) guyState = STATE_STANDINGRIGHT
else guyState = STATE_WALKINGRIGHT
return
////==============================================================================
#switch @DoLeftThings
if (guyX < 8) guyState = STATE_STANDINGLEFT
else guyState = STATE_WALKINGLEFT
return

//=======================================================
// Update Counters
// Animate dude if he's walking.
//=======================================================
#switch @UpdateCounters
if (guyState == STATE_WALKINGRIGHT || guyState == STATE_WALKINGLEFT)
{
	guyFrame = guyFrame + 1
	if (guyFrame > 3) guyFrame = 0
}

return					// we're done!

////==============================================================================
#switch @MoveGuy
if (guyState == STATE_WALKINGRIGHT) gosub @GuyWalkRight
else if (guyState == STATE_WALKINGLEFT) gosub @GuyWalkLeft
return
////==============================================================================
#switch @GuyWalkRight
if (guyX < 200) guyX = guyX + 2
else
{
	guyState = STATE_STANDINGRIGHT
	guyFrame = 0
}
return
////==============================================================================
#switch @GuyWalkLeft
if (guyX > 8) guyX = guyX - 2
else
{
	guyState = STATE_STANDINGLEFT
	guyFrame = 0
}
return

//=======================================================
// After
// Leave the place like we found it
//=======================================================
#switch @After
unset delta
unset lastMS
unset currentMS
unset guyX 	
unset guyY
console "popbind"


return

//=======================================================
// LeftWasPressed
// Service Keypad Left being pressed.
//=======================================================
#switch @LeftWasPressed
keyMeaning = KEY_LEFT
return
//=======================================================
// RightWasPressed
// Service KeyPad Right being pressed.
//=======================================================
#switch @RightWasPressed
keyMeaning = KEY_RIGHT
return