Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Wampus

#976
I should add, although the test screen I wrote is extremely basic, there is a lot behind this routine.

For example, some moves can ignore the state of firebutton, so you can charge your gun or whatever while performing special movements. Tolerance to mistakes or delays made by the player in trying to perform the special moves can be increased or diminished. This can help to change difficulty but is also good for adjusting to different fps. 60fps is fine but if the game was running on a device that could only manage 30fps it might be an idea to diminish the mistake & delay tolerance so special moves remain around the same difficult to do.

The same joypad can be set up for different sets of special moves. For example, in Street Fighter games many of the special moves depend on which direction you're facing. This could be easily achieved by setting two control schemes (or more) for the same controller:-

player1left = sfPadInitialise(j,n,m)
player1right = sfPadInitialise(j,n,m)
player1swimming = sfPadInitialise(j,n,m)
player1invehicle = sfPadInitialise(j,n,m)

Where j is the number of the joypad being used, n is the number of special moves for that control configuration and m the maximum number of steps in any special move

Ok, I'm done waffling about stuff no one will probably care about.  ;/
#977
Second part, the functions

Code (glbasic) Select
// Beginning of functions

FUNCTION sfPadInitialise: padnumber%, specials% = 0, maxmoves% = 0

LOCAL p AS allpad

p.sfjoypad = padnumber-1 // joypads 1 to 10 are set as 0 to 9
p.sfdirection = 9 // 9 is always "no direction". 0 should never be seen.
p.sffire = 0
p.sfjump = 0
p.sfspecial = specials
p.sfmaxmove = maxmoves

IF specials = 0
// do nothing as no special moves need to be defined. sfPad[] will still show how long fire and/or jump have been pressed however

ELSE

REDIM p.sfmoves[specials][maxmoves][2]
REDIM p.sftypemove[specials]
REDIM p.sfmovestate[specials]
REDIM p.sfmovecounter[specials]
REDIM p.sfmovetolerance[specials]
REDIM p.sfendmove[specials]
REDIM p.sftolerance[specials]
REDIM p.sfmovewait[specials]
REDIM p.sfcanignorefire[specials]

ENDIF

DIMPUSH sfPad[], p // add the new joypad configuration

LOCAL padconfig_id
padconfig_id = LEN(sfPad[]) - 1

RETURN padconfig_id // return the Pad ID number. Necessary for keeping track of which pad is set which control scheme

ENDFUNCTION

FUNCTION sfPadAddMove: move$, padnumber, move

IF move$="right dash"

sfPad[padnumber].sftypemove[move]=1 // its a step by step kind of special move.

sfPad[padnumber].sfmovestate[move]=0 // clear registers
sfPad[padnumber].sfmovecounter[move]=0 // clear registers
sfPad[padnumber].sfmovetolerance[move]=0 // clear registers

sfPad[padnumber].sfmoves[move][0][0]=9 // first direction is no direction. player must be still
sfPad[padnumber].sfmoves[move][0][1]=0 // no fire or jump needed. fire = 1. jump = 2. fire & jump = 3
sfPad[padnumber].sfmoves[move][1][0]=2 // move right
sfPad[padnumber].sfmoves[move][1][1]=0 // no fire or jump
sfPad[padnumber].sfmoves[move][2][0]=9 // don't move
sfPad[padnumber].sfmoves[move][2][1]=0 // no fire or jump
sfPad[padnumber].sfmoves[move][3][0]=2 // move right again
sfPad[padnumber].sfmoves[move][3][1]=0 // no fire or jump

sfPad[padnumber].sfendmove[move]=4 // if player reaches step 4 they have successfully executed the dash to the right
sfPad[padnumber].sfcanignorefire[move]=1 // fire status can be ignored. You can still charge your laser
sfPad[padnumber].sftolerance[move]=0 // tolerate NO accidental joypad slips. If you can't double press right in quick succession, there is something wrong with you.
sfPad[padnumber].sfmovewait[move]=8 // tolerate 8 fps between changes of step

ENDIF

IF move$="left dash"

sfPad[padnumber].sftypemove[move]=1

sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

sfPad[padnumber].sfmoves[move][0][0]=9
sfPad[padnumber].sfmoves[move][0][1]=0
sfPad[padnumber].sfmoves[move][1][0]=6
sfPad[padnumber].sfmoves[move][1][1]=0
sfPad[padnumber].sfmoves[move][2][0]=9
sfPad[padnumber].sfmoves[move][2][1]=0
sfPad[padnumber].sfmoves[move][3][0]=6
sfPad[padnumber].sfmoves[move][3][1]=0

sfPad[padnumber].sfendmove[move]=4
sfPad[padnumber].sfcanignorefire[move]=1
sfPad[padnumber].sftolerance[move]=0
sfPad[padnumber].sfmovewait[move]=8

ENDIF

IF move$="right dragonpunch"

sfPad[padnumber].sftypemove[move]=1

sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

sfPad[padnumber].sfmoves[move][0][0]=2
sfPad[padnumber].sfmoves[move][0][1]=0
sfPad[padnumber].sfmoves[move][1][0]=4
sfPad[padnumber].sfmoves[move][1][1]=0
sfPad[padnumber].sfmoves[move][2][0]=3
sfPad[padnumber].sfmoves[move][2][1]=0
sfPad[padnumber].sfmoves[move][3][0]=2
sfPad[padnumber].sfmoves[move][3][1]=1

sfPad[padnumber].sfendmove[move]=4
sfPad[padnumber].sfcanignorefire[move]=0 // you cannot press fire until the right time (the end of the move) or the step by step sequence is void
sfPad[padnumber].sftolerance[move]=8
sfPad[padnumber].sfmovewait[move]=12 // tolerate 12 fps between changes of step. Very tolerant. Typical real world gameplay would be 8

ENDIF

IF move$="right dragonpunch slip" // Just added so dragonpunch is easier to perform. My gf kept messing up and complaining so I added this to make it easier to trigger

sfPad[padnumber].sftypemove[move]=1

sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

sfPad[padnumber].sfmoves[move][0][0]=2
sfPad[padnumber].sfmoves[move][0][1]=0
sfPad[padnumber].sfmoves[move][1][0]=9
sfPad[padnumber].sfmoves[move][1][1]=0
sfPad[padnumber].sfmoves[move][2][0]=3
sfPad[padnumber].sfmoves[move][2][1]=0
sfPad[padnumber].sfmoves[move][3][0]=2
sfPad[padnumber].sfmoves[move][3][1]=1

sfPad[padnumber].sfendmove[move]=4
sfPad[padnumber].sfcanignorefire[move]=0
sfPad[padnumber].sftolerance[move]=8
sfPad[padnumber].sfmovewait[move]=12

ENDIF

IF move$="left dragonpunch"

sfPad[padnumber].sftypemove[move]=1

sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

sfPad[padnumber].sfmoves[move][0][0]=6
sfPad[padnumber].sfmoves[move][0][1]=0
sfPad[padnumber].sfmoves[move][1][0]=4
sfPad[padnumber].sfmoves[move][1][1]=0
sfPad[padnumber].sfmoves[move][2][0]=5
sfPad[padnumber].sfmoves[move][2][1]=0
sfPad[padnumber].sfmoves[move][3][0]=6
sfPad[padnumber].sfmoves[move][3][1]=1

sfPad[padnumber].sfendmove[move]=4
sfPad[padnumber].sfcanignorefire[move]=0
sfPad[padnumber].sftolerance[move]=8
sfPad[padnumber].sfmovewait[move]=12

ENDIF

IF move$="left dragonpunch slip"

sfPad[padnumber].sftypemove[move]=1

sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

sfPad[padnumber].sfmoves[move][0][0]=6
sfPad[padnumber].sfmoves[move][0][1]=0
sfPad[padnumber].sfmoves[move][1][0]=9
sfPad[padnumber].sfmoves[move][1][1]=0
sfPad[padnumber].sfmoves[move][2][0]=5
sfPad[padnumber].sfmoves[move][2][1]=0
sfPad[padnumber].sfmoves[move][3][0]=6
sfPad[padnumber].sfmoves[move][3][1]=1

sfPad[padnumber].sfendmove[move]=4
sfPad[padnumber].sfcanignorefire[move]=0
sfPad[padnumber].sftolerance[move]=8
sfPad[padnumber].sfmovewait[move]=12

ENDIF

IF move$="fast fire"

sfPad[padnumber].sftypemove[move]=2 // This move is rapid dire, triggered when player hits fire quickly

sfPad[padnumber].sfmovestate[move]=0 // In this case, how many times has player hit fire quickly?
sfPad[padnumber].sfmovecounter[move]=0 // How long has fire button not been pressed?
sfPad[padnumber].sfmovetolerance[move]=0 // last count was fire? then 32. last count was not fire? then 64.

sfPad[padnumber].sfendmove[move]=0 // This is set to 255 when fast fire special move is activated
sfPad[padnumber].sfcanignorefire[move]=6 // How many times must player hit fire before special move is activated?
sfPad[padnumber].sftolerance[move]=6 // How long can fire be pressed for before you are too slow to activate move
sfPad[padnumber].sfmovewait[move]=6 // How long can a break between fire last before you are too slow to activate move

ENDIF

ENDFUNCTION

FUNCTION sfPadDefaultControls: padnumber

sfPad[padnumber].firebutton = 0 // fire button is first joypad button - only used if GLBasic is in full version
sfPad[padnumber].jumpbutton = 1 // jump button is second joypad button - only used is GLBasic is in full version
sfPad[padnumber].keyright = 205 // right arrow
sfPad[padnumber].keydown = 208 // down arrow
sfPad[padnumber].keyleft = 203 // left arrow
sfPad[padnumber].keyup = 200 // up arrow
sfPad[padnumber].keyfire = 29 // left CTRL
sfPad[padnumber].keyjump = 56 // Left ALT

ENDFUNCTION

// The main routine for checking joypad state and status of special moves

FUNCTION sfPadState: padnumber%, cancelspecials% = FALSE, cancelcharge% = FALSE

LOCAL isfire% = FALSE; LOCAL isjump% = FALSE; LOCAL isblock% = FALSE; LOCAL ismagic% = FALSE; LOCAL isup% = FALSE; LOCAL isdown% = FALSE; LOCAL isleft% = FALSE; LOCAL isright% = FALSE; LOCAL jumpfire% = 0
LOCAL jx = 0; LOCAL jy = 0; LOCAL ba = 0; LOCAL bb = 0; LOCAL bc = 0; LOCAL bd = 0
LOCAL state% = 0; LOCAL checkmove% = 0; LOCAL checkbutton% = 0; LOCAL checknextmove% = 0; LOCAL checknextbutton% = 0
// Read joypad & keyboard

JOYSTATE jx, jy, ba, bb // Works with trial version. Can't use more than one joypad! Tested with keyboard as second input and that works.

// If you have the full version of GLBasic then you can enable the following two lines of code and remove the line above
// Theoretically this routine could support up to 10 joypads, all with their own set of special moves.
// jx = GETJOYX(sfPad[padnumber].sfjoypad); jy = GETJOYY(sfPad[padnumber].sfjoypad)
// ba = GETJOYBUTTON(sfPad[padnumber].sfjoypad,sfPad[padnumber].firebutton); bb = GETJOYBUTTON(sfPad[padnumber].sfjoypad,sfPad[padnumber].jumpbutton)

IF KEY(sfPad[padnumber].keyfire) = 1 OR ba > 0
isfire = TRUE
jumpfire = jumpfire +1
ENDIF
IF KEY(sfPad[padnumber].keyjump) = 1 OR bb > 0
isjump = TRUE
jumpfire = jumpfire +2
ENDIF
IF KEY(sfPad[padnumber].keyup) = 1 OR jy < -0.8
isup = TRUE
ELSEIF KEY(sfPad[padnumber].keydown) = 1 OR jy > 0.8
isdown = TRUE
ENDIF
IF KEY(sfPad[padnumber].keyleft) = 1 OR jx < -0.8
isleft = TRUE
ELSEIF KEY(sfPad[padnumber].keyright) = 1 OR jx > 0.8
isright = TRUE
ENDIF

IF isfire
INC sfPad[padnumber].sffire
ELSE
sfPad[padnumber].sffire= 0 // sffire = 1 then fire. sffire > 1 then IMMA CHARGIN' MAH LAZER!
ENDIF

IF isjump
INC sfPad[padnumber].sfjump
ELSE
sfPad[padnumber].sfjump = 0 // sfjump = 1 then just pressed jump. sfjump > 1 then still holding it.
ENDIF

IF isup AND isright
sfPad[padnumber].sfdirection = 1
ELSEIF isup AND isleft
sfPad[padnumber].sfdirection = 7
ELSEIF isdown AND isright
sfPad[padnumber].sfdirection = 3
ELSEIF isdown AND isleft
sfPad[padnumber].sfdirection = 5
ELSEIF isup
sfPad[padnumber].sfdirection = 8
ELSEIF isdown
sfPad[padnumber].sfdirection = 4
ELSEIF isright
sfPad[padnumber].sfdirection = 2
ELSEIF isleft
sfPad[padnumber].sfdirection = 6
ELSE
sfPad[padnumber].sfdirection = 9
ENDIF

IF cancelcharge = TRUE THEN sfPad[padnumber].sffire = 0

// Check Special Moves

IF sfPad[padnumber].sfspecial = 0 OR cancelspecials = TRUE // Are there any special moves defined for this joypad? Are we even checking for special moves this cycle?
// do nothing
ELSE

FOR move = 0 TO sfPad[padnumber].sfspecial - 1

SELECT sfPad[padnumber].sftypemove[move]

CASE 1 // the type of move is a step by step move

IF sfPad[padnumber].sfmovestate[move] = 255 THEN sfPad[padnumber].sfmovestate[move] = 0 // if special move was triggered last cycle, remove the flag

state = sfPad[padnumber].sfmovestate[move]

IF state = 0 // here we have the start of lots of IF statements. My favourite! >:(

checkmove = sfPad[padnumber].sfmoves[move][0][0]
checkbutton = sfPad[padnumber].sfmoves[move][0][1]

IF sfPad[padnumber].sfcanignorefire[move] = 1
checkbutton = jumpfire
ENDIF

IF checkmove = sfPad[padnumber].sfdirection AND checkbutton = jumpfire
sfPad[padnumber].sfmovestate[move]=1
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0
ENDIF

ELSE

checkmove = sfPad[padnumber].sfmoves[move][state-1][0]
checkbutton = sfPad[padnumber].sfmoves[move][state-1][1]
checknextmove = sfPad[padnumber].sfmoves[move][state][0]
checknextbutton = sfPad[padnumber].sfmoves[move][state][1]
IF sfPad[padnumber].sfcanignorefire[move] = 1
checkbutton = jumpfire
checknextbutton = jumpfire
ENDIF

IF checkmove = sfPad[padnumber].sfdirection AND checkbutton = jumpfire

INC sfPad[padnumber].sfmovecounter[move]
IF sfPad[padnumber].sfmovecounter[move] > sfPad[padnumber].sfmovewait[move]
sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0
ENDIF

ELSE

IF checknextmove = sfPad[padnumber].sfdirection AND checknextbutton = jumpfire

INC sfPad[padnumber].sfmovestate[move]
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0

ELSE

INC sfPad[padnumber].sfmovetolerance[move]
IF sfPad[padnumber].sfmovetolerance[move] > sfPad[padnumber].sftolerance[move]
sfPad[padnumber].sfmovestate[move]=0
sfPad[padnumber].sfmovecounter[move]=0
sfPad[padnumber].sfmovetolerance[move]=0
ENDIF

ENDIF

ENDIF

ENDIF

IF sfPad[padnumber].sfmovestate[move] = sfPad[padnumber].sfendmove[move] THEN sfPad[padnumber].sfmovestate[move] = 255

CASE 2 // the move is a rapid fire sequence.

state = sfPad[padnumber].sfmovestate[move]
sfPad[padnumber].sfendmove[move]=0

IF state = 0 AND isfire
sfPad[padnumber].sfmovestate[move]=1
sfPad[padnumber].sfmovetolerance[move]=32
sfPad[padnumber].sfmovecounter[move]=0
ENDIF

IF state > 0
IF sfPad[padnumber].sffire > sfPad[padnumber].sftolerance[move]
sfPad[padnumber].sfmovestate[move]=0 // if time fire is held is beyond tolerance, you are too slow!
ELSEIF sfPad[padnumber].sfmovecounter[move] > sfPad[padnumber].sfmovewait[move]
sfPad[padnumber].sfmovestate[move]=0
ENDIF
ENDIF

IF state > 0
IF sfPad[padnumber].sffire = 0 AND sfPad[padnumber].sfmovetolerance[move] = 32
INC sfPad[padnumber].sfmovestate[move]
sfPad[padnumber].sfmovetolerance[move] = 64
ELSEIF sfPad[padnumber].sffire > 0 AND sfPad[padnumber].sfmovetolerance[move] = 64
INC sfPad[padnumber].sfmovestate[move]
sfPad[padnumber].sfmovetolerance[move] = 32
sfPad[padnumber].sfmovecounter[move]=0
ELSEIF sfPad[padnumber].sfmovetolerance[move] = 64
INC sfPad[padnumber].sfmovecounter[move]
ENDIF
ENDIF

IF state > sfPad[padnumber].sfcanignorefire[move]
sfPad[padnumber].sfendmove[move] = 255
ENDIF

// Add hold and release special move routine here
// e.g. Guile's "Sonic Boom" move, where the joystick is held back for two seconds then moved forward and fire pressed.

ENDSELECT

NEXT

ENDIF

ENDFUNCTION

#978
Fighting games often have complicated series of steps to perform special moves, e.g. down, down & forward, forward & fire to perform Ken's Shoryuken fireball attack.

I wrote some code to see what it would require to add such moves into a control scheme. After that I realised I'd never use it anyway (I like writing strategy games, not action games).

The code below was written to accomodate:-

  • charging up fire (or jump)
  • step by step special moves
  • rapid fire moves

I was going to add hold & release moves, e.g. hold down for 2 seconds then press up & fire, but that was when I got tired of writing code I wasn't going to use.  ::)

Built into the routine are dash special moves (tap left or right quickly), a Dragonpunch in either direction (like Street Fighter 2) and rapid fire (like Chun Lee's Hundred Rending Kicks)

The code supports up to 10 joypads. This is in theory because I have the trial of GLBasic so can't test this more than making sure the syntax is correct. The code is a bit of an obscure mess and would best be tailored for particular needs. However, if anyone did want this done I would re-write the code for their needs.

First part below

Code (glbasic) Select

SETSCREEN 640,480,0
LIMITFPS 60
LOADFONT "smallfont.png", 1 // A workaround because the default font won't load by, er, default

TYPE allpad
sfjoypad% // The joypad number that will be used. Can be 1 to 10. (Who has 10 joypads?!)
sfdirection% // The direction the joypad is in. 9 = no direction : 1 = up right : 2 = right : 3 = down right : 4 = down : 5 = down left : 6 = left : 7 = up left : 8 = up
sffire% // How long the FIRE button has been pressed. 1 = new bullet/punch/whatever. Numbers bigger than 1 used for build up to a super shot in R-Type or MegaMan where the fire button is held down to charge and released to fire.
sfjump% // How long the JUMP button has been pressed. Might be useful for super-jumps or whatnot.
sfspecial% // Number of special moves joypad n should be configured for
sfmaxmove% // Maximum steps in any one special move. Used for limiting dimensional array usage
sfmoves%[] // Array for holding the steps of special moves in.
sftypemove%[] // The type of special move. 1 = step by step. 2 = rapid fire. 3 = build up. The build up type hasn't been completed in this example
sftolerance%[] // Higher = easier to execute special moves. How long should slips of joypad be ignored before next step HAS to be completed?
sfmovewait%[] // higher = easier to execute special moves. How long can you be holding a direction before the step in a special move is considered void
sfmovestate%[] // which step is the special move currently in? 0 = not in any state
sfmovecounter%[] // Variable to check how long the move state has been in one state
sfmovetolerance%[] // Variable to check gow long the move been out of sequence
sfendmove%[] // Which is the final move in the combination? When reached, set sfmovestate to 255
sfcanignorefire%[] // Can you charge your gun while performing this move? If yes, then ignore fire & jump status while checking.
firebutton% // Set button used to shoot on Joypad - used for non-trial GLBasic only
jumpbutton% // Set button used to jump on Joypad - used for non-trial GLBasic only
keyright% // Set key for right
keydown% // Set key for down
keyleft% // Set key for left
keyup% // Set key for up
keyfire% // Set key for fire
keyjump% // Set key for jump
ENDTYPE

GLOBAL sfPad[] AS allpad // Possibility of up to 10 joysticks but only one used in this code

// Initialise the JoyPad settings. Any number of settings can be set for one joypad, though here I am just setting up one configuration
// Muliple settings is useful for games where the controls can change often. e.g. Street Fighter games, where the direction you are facing
// changes the kind of special moves that are available to you. It could also be useful for Megaman types games where weapons layouts change

LOCAL pla1

pla1 = sfPadInitialise(1,7,4) // pla1 will be configured for joypad 1, will have 6 special moves and 4 steps is the maximum number for any special move

// Define Controls for pla1, i.e. player 1

sfPadDefaultControls(pla1)

// Add pre-defined special moves into the 6 slots set out by sfPadInitialise(*,6,*)
// Obviously, don't try to add any moves or check for them if you haven't specified that the joypad configuration will need some

sfPadAddMove("right dash", pla1, 0) // tap right twice quickly
sfPadAddMove("left dash", pla1, 1) // tap left twice quickly
sfPadAddMove("right dragonpunch", pla1, 2) // right, down, down + right, right + fire
sfPadAddMove("right dragonpunch slip", pla1, 3) // included to make dragonpunch easier for noobs (e.g. my complaining gf)
sfPadAddMove("left dragonpunch", pla1, 4) // left, down, down + left, left + fire
sfPadAddMove("left dragonpunch slip", pla1, 5) // included to make dragonpunch easier for noobs
sfPadAddMove("fast fire", pla1, 6) // press fire repeatedly as quick as possible to active fast fire move

// Main test loop

spectimer% = 0
s$=""

WHILE TRUE

sfPadState(pla1) // Check what the state of the joypad and special moves are in

dire=sfPad[pla1].sfdirection

SELECT dire

CASE 9
PRINT "direction: no movement", 0, 0
CASE 1
PRINT "direction: up & right", 0, 0
CASE 2
PRINT "direction: right", 0, 0
CASE 3
PRINT "direction: down & right", 0, 0
CASE 4
PRINT "direction: down", 0, 0
CASE 5
PRINT "direction: down & left", 0, 0
CASE 6
PRINT "direction: left", 0, 0
CASE 7
PRINT "direction: up & left", 0, 0
CASE 8
PRINT "direction: up", 0, 0
DEFAULT
PRINT "direction: Whoops! An error.", 0, 0
ENDSELECT

PRINT "Imma chargin' mah lazer: " + sfPad[0].sffire, 0, 16
PRINT "Jump pressed for: " + sfPad[0].sfjump, 0, 32

IF spectimer > 0
DEC spectimer
PRINT "Special Move:" + s$, 0, 80
ENDIF

IF sfPad[pla1].sfmovestate[0]=255
spectimer = 120
s$="A dash to the right!"
ENDIF

IF sfPad[pla1].sfmovestate[1]=255
spectimer = 120
s$="A dash to the left!"
ENDIF

IF sfPad[pla1].sfmovestate[2]=255 OR sfPad[pla1].sfmovestate[3]=255
spectimer = 120
s$="Dragonpunch to the right!"
ENDIF

IF sfPad[pla1].sfmovestate[4]=255 OR sfPad[pla1].sfmovestate[5]=255
spectimer = 120
s$="Dragonpunch to the left!"
ENDIF

IF sfPad[pla1].sfendmove[6]=255
spectimer = 4
s$="Very fast hitting!"
ENDIF

SHOWSCREEN

WEND
END
#979
I should but I don't. If you do I wonder if there is something wrong with my installation.
#980
Hi

In version 7.301 there doesn't appear to be a default font loaded into index 0 anymore.

For now the workarounds I've found for old routines:-


  • Include a smalfont.bmp file in the .app directory as this will still be automatically loaded into font index 0
  • Explicitly load a font first of all into index 1
#981
Curious

If someone else can replicate this issue on another iPhone then that would be helpful.

If its only happening with the directory Media/Music on the iPhone (as far as anyone can tell) then at least it can be marked as a known issue with the workaround of changing the directory name.

If the MP3s are in different folders, can they be found? If a WAV file or other non-sound related files are in the Music folder, can they be found? Sorry, just suggestions. I would check this myself if I had an iPhone.
#982
You're right. Talking about a 640 x 480 display was hasty. There is no reason I can't create a 320 x 240 display for GP2X after the PC platform version has been completed. Since yesterday I've actually increased the PC resolution to 800 x 600 because then I can fit in a neat mini-map and other useful things.

After playing with GLBasic all day yesterday I'm convinced GLBasic is right for what I'm trying to do. I also had a lot of fun with it!  :-*

As part of trialling GLBasic I'm going to implement an A * Pathfinding routine that can make use of diagonals with a little math cheating to speed it up. I'll be away for a week so I'll write it & post results on the forum when I get back. I'm guessing it will be a lot slower than the FINDPATH() so it will be interesting to find out just how much slower by comparing results! Alternatively to writing my own routine, if I can figure out how to make use of C++ code embedded in GLBasic I would use something like this: http://www.grinninglizard.com/MicroPather/index.htm
#983
Incidentally, the FINDPATH() command would be perfect for the A * pathfinding algorithm I need if it only dealt with diagonals as well as the 4 main directions.  :)
#985
Hi

I'm working on a clone of Lords Of Chaos, a fantasy turn-based strategy game that was available on the old 8-bit & 16-bit home computers - arguably the best game of its kind from that era. I'm a couple of weeks away from finishing the basic tileset & sprites and then I can start coding the map editor.

I'm not new to programming (Basic, Assembly and web specific languages) or OOP (some Java experience) but I thought I should learn something new. After spending some time considering which language to use I was going to go with C++ but then it occurred to me that I might be making things much harder for myself than necessary. Maybe GLBasic would be more suitable. It does everything I need for the basic game engine and I take it I can call C++ routines from within it if need be. I've decided to try GLBasic first of all to see how that goes. Anyway, more on the game...

The game mechanics will be (relatively) easy to code. In a matter of a few months I'll probably be able to reach the point where the game is playable as a one player experience without any enemy AI. I don't need fancy graphics, real-time physics, fast frame rates, networking, particle engines, etc. Look at a screenshot from the original Atari ST version to see why:-



My game will look very similar, but in 640 x 480 instead. Here's the thing: The enemy AI is everything in this game. It's 95% of why it was fun to play and by far the most advanced thing I'll be doing. For example, I'll need my own special A* pathfinding algorithm, goal driven teamwork, complex state-driven agents and some rudimentary scripting for setting behavioural traits in the map & agent editor. If that sounds ambitious, it is. My question is, can anyone think of a reason why GLBasic wouldn't be a good choice if complex AI needs to be introduced?

No matter which language I use the AI component of the game will be by far the most difficult and timely part. I can't think of any reason why GLBasic would be worse or better than another language in this respect. I guess I'm just fishing for advice here. Can anyone with experience in GLBasic see potential problems arising?