functions? good or bad

BlitzMax Forums/BlitzMax Beginners Area/functions? good or bad

B(Posted 2009) [#1]
Hi,

I am currently making a game that using ascii graphics.
It works ok on my mac computer, however when I put the same code into blitzmax
on my IBM it hangs after an instant.

my mac has a 2.2Ghz Processor and 4G RAM

my IBM has a 1.5Ghz Processor and 1G RAM

I was wondering if this could be a result of the way I coded the game.

EXAMPLE CODE
while not keydown(key_escape)
cls

function1()
function2()
function3()
function4()

flip
wend
end


function function1()
code code code code
code code code code
code code code code
endfunction

function function2()
code code code code
code code code code
code code code code
endfunction

function function3()
code code code code
code code code code
code code code code
endfunction

function function4()
code code code code
code code code code
code code code code
endfunction


do all the functions slowdown the process?
sometimes I call functions within other functions.

if you need me to post code I will, however i thought that you may be able to fix the problem without looking at all of it.

Sidenote: other less important problem
I have searched the forums to the best of my abilities and I could not find a solution to my other problem.
I use a function that will pause the program for an instant every loop so that you dont fly off the screen when you use the arrow keys.
In my game you move 10px to the right or left every time and 15px up and down.
So it gives it a sorta feeling of a grid/old school rpg game.

is there a better way to get this effect? without using the method that I have?

Thank you in advanced!

B

you can download the exe HERE


markcw(Posted 2009) [#2]
I use a function that will pause the program for an instant every loop so that you dont fly off the screen when you use the arrow keys.

If you're using a delay for the pause that's probably why it's hanging.


B(Posted 2009) [#3]
ya that is what i thought.

do you know of a way to do that differently


Jesse(Posted 2009) [#4]
one simple way is to check for a key press every x number of milliseconds.

before your main loop get the millisecs count plus delay amount.
n = 100
wait! = millisecs()+ n

then inside your main loop

if (millisecs() > wait) or (millisecs() < (wait-2*n))
    if keydown(key) 
       process keypress
       kepressedflag = true
    endif
endif 

if keypressedflag = true
    wait = millisecs() + n
    keypressedflag = false
endif

[****************edited****************]
you can change the number 100 to adjust the speed.

another one is to use a counter when the counter reach the goal, process a key press and reset your counter else increment your counter.


xlsior(Posted 2009) [#5]
While Jesse's example should work *most* of the time, you do have to remember that millisecs() will *wrap* periodically if your computer is on long enough, and can turn into a negative number.

that means that 'if millisecs()> wait' will then never become true, and your program will stop processing keypresses at that point.

so instead of this:

if millisecs()> wait


use something like:

if (millisecs() > wait) or (millisecs() < wait-200)


That way it will continue to work should millisecs() all of a sudden turn negative on you.


Jesse(Posted 2009) [#6]
thanks for clarifying that for him xlsior I thought about that but decided to ignore it. I usually remove the last bit from millisecs() that way I never get a negative (ex. number&$7fffffff) but that creates another issue which I deal in my own way. I like your way better. :)


TaskMaster(Posted 2009) [#7]
xlsior

The only way that would be an issue is if the millisecs wrapped while his program was running.


xlsior(Posted 2009) [#8]
Which will happen sooner or later, if your PC is on long enough.
Since it's a real easy fix, why keep a known bug in your program?


Grey Alien(Posted 2009) [#9]
@xlsior: Are you sure it goes negative? I thought it just wrapped?


Gabriel(Posted 2009) [#10]
BlitzMax doesn't have any signed datatypes, so I would assume that wrapping would be the same as going negative.


Jesse(Posted 2009) [#11]
it does for integers anything greater than $7fffffff is a negative number.
the last bit in an integer is used for the sign. It doesn't work for shorts or bytes.
try this:
print $80000000

or this:
Print ($8000000 > $7fffffff)

if Grey is correct it should print 1


nawi(Posted 2009) [#12]
And make sure to do the "millisecs test" separately for each key to get proper input.


Gabriel(Posted 2009) [#13]
it does for integers anything greater than $7fffffff is a negative number.
the last bit in an integer is used for the sign. It doesn't work for shorts or bytes.

Oh, you're right. Shorts and Bytes are signed. Can't say that I've ever found myself using shorts or bytes but while I can see the logic of them being signed, it's messy having two signed numerical types and one unsigned.


Jesse(Posted 2009) [#14]
I've always had an issue with that but as I mentioned above I have learned to work around it. I know that for most casual games the integer size is more than enough but sooner or later someone's game will be haunted by it. Most likely to happen to someone using pixmap and integer color index comparison as it has to me.


xlsior(Posted 2009) [#15]
@xlsior: Are you sure it goes negative? I thought it just wrapped?


Not sure, but either way the value will stop incrementing and take a huge dive, so the if millisecs()> wait will never be true once it happens.


TaskMaster(Posted 2009) [#16]
It doesn't stop incrementing.

Millisecs() climbs to the highest possible positive number, then it jumps to the lowest possible number (largest negative) and starts counting up again.


B(Posted 2009) [#17]
ok so i implemented Jesse's edited code into my game, however I think I am putting the first part in the wrong place. because no matter how high or low I set the value of 'n' it does the exact same thing.

i dont know why.

my code
[code]
'I have tried putting it here
Global n = 2000000
wait! = MilliSecs() + n
while not keydown(key_escape)
cls
'and putting it herehere
Global n = 2000000
wait! = MilliSecs() + n
function1()
function2()
function3()
function4()

flip
wend
end


function function1()
'here is all my key process code, within this function
if (millisecs() > wait) or (millisecs() < (wait-2*n))
if keydown(key)
process keypress
kepressedflag = true
endif
endif

if keypressedflag = true
wait = millisecs() + n
keypressedflag = false
endif

code code code code
code code code code
code code code code
endfunction

function function2()
code code code code
code code code code
code code code code
endfunction

function function3()
code code code code
code code code code
code code code code
endfunction

function function4()
code code code code
code code code code
code code code code
endfunction


maybe a more detailed explanation of how the code works would help?

I'm pretty sure I understand how it works, but im am at a loss...

thanks for everyones help!


xlsior(Posted 2009) [#18]
It doesn't stop incrementing.


OK, bad choice of words from me -- bottom line, it has a maximum value and won't get any larger than that.


TaskMaster(Posted 2009) [#19]
The simplest solution to this problem is to make your own millisecs() function that gets the millsecs() at the start of your program. Then uses that value as an offset and begins returning numbers starting at 0. Check for the flip and fix it before returning your millisecs() value.


Jesse(Posted 2009) [#20]
And make sure to do the "millisecs test" separately for each key to get proper input.

I don't think so.

see if you can understand this B:
Graphics 800,600
Global n:Int = 200
Global wait:Long = MilliSecs() + n
Global oldkey:Int = -1
While Not KeyDown(key_escape)
	Cls
	Local key:Int = function1()
	If key > -1 Then
		If key = KEY_DOWN  DrawText "Down",50,50
		If key = KEY_UP    DrawText "Up",50,50
		If key = KEY_LEFT  DrawText "Left",50,50
		If key = KEY_RIGHT DrawText "Right",50,50
	End If

	function2()
	function3()
	function4()
	
	Flip
Wend
End


Function function1:Int()'returns the key pressed every n millisecs() and -1 to ignore it.
	Local key:Int
	Select True
		'add any keys you want here
		Case KeyDown(KEY_UP)    key = KEY_UP 
		Case KeyDown(KEY_DOWN)  key = KEY_DOWN
		Case KeyDown(KEY_LEFT)  key = KEY_LEFT
		Case KeyDown(KEY_RIGHT) key = KEY_RIGHT
		' don't mess with the default
		Default                 key = -1
	End Select
	If key > -1
		If (MilliSecs() > wait) Or (MilliSecs() < (wait-2*n)) Or key <> oldKey
			wait = MilliSecs() + n
			oldkey = key
			Return key
		EndIf
		
	EndIf		
	oldkey = key
	Return -1
EndFunction

Function function2()
EndFunction

Function function3()
EndFunction

Function function4()
EndFunction

this next code is the same but works with all of the keys but is a bit slower at times:

------- edit ---------
and although this is duable. I recomend moving your character in fractions instead of integers that way you won't have to go through all of this problems.
x:float = x:float + .1
y:float = y:float + .1


TwoCorin517(Posted 2009) [#21]
Have you thought about triggering a timer?

You'd probably have to either create of Global... You might want to look into a static variable, I'm not certain if that'd work or if BMax has those though.


B(Posted 2009) [#22]
ok so i read over, digested, and incorporated Jesse's new code into my program and it works great!

thanks for all the help Jesse and everyone else!

you can go to my website:
here
and download version 0.01
if you want to see the game.
mac version isnt up yet, but the windows version is.

Thanks again!

B