Select Expression for Controls

Blitz3D Forums/Blitz3D Beginners Area/Select Expression for Controls

The3Leaf(Posted 2012) [#1]
First off I would like to apologize for how often I have been coming to the forums for help. I look threw the help pages every now and then to see If I can return the favor to someone, but I rarely find a question I can actually help with unless its a simple one already answered lol.

Anyway to my question. I'm trying to use a Select Expression to handle my attack controls.



Select True
Case 	MouseHit(1) And player\alt = False
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,30,60)
		AnimateMD2(player\body,3,2.5,30,60)
		AnimateMD2(player\legs,3,2.5,30,60)
	
Case    MouseHit(1) And player\alt = True 
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,90,120)
		AnimateMD2(player\body,3,2.5,90,120)
		AnimateMD2(player\legs,3,2.5,90,120)

Case    MouseHit(2)
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,60,90)
		AnimateMD2(player\body,3,2.5,60,90)
		AnimateMD2(player\legs,3,2.5,60,90)
			
End Select		


Case 2 (Case MouseHit(1) And player\alt = True) is the only one that doesnt work. Although what is really confusing me is that if I remove Case 1 (Case MouseHit(1) And player\alt = False) and then run the code, Case 2 will work. So basically with Case 1 present Case 2 will not work. If I move Case 2 to the top then it will work, but Case 1 (witch would become Case 2) will not work. Sorry if I'm not making any since. Thanks.


Zethrax(Posted 2012) [#2]
Something to bear in mind is that And, Or, etc are actually boolean operators rather than logical operators. This means that they're not simply working exclusively with True/False logical values but are actually operating on a bit by bit boolean level. To use them as logical operators you need to convert the expressions being evaluated to 0 or 1 values.

eg. (untested)
Select True
Case 	MouseHit(1) And ( player\alt <> False ) = False
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,30,60)
		AnimateMD2(player\body,3,2.5,30,60)
		AnimateMD2(player\legs,3,2.5,30,60)
	
Case    MouseHit(1) And ( player\alt <> False ) = True 
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,90,120)
		AnimateMD2(player\body,3,2.5,90,120)
		AnimateMD2(player\legs,3,2.5,90,120)

Case    MouseHit(2)
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,60,90)
		AnimateMD2(player\body,3,2.5,60,90)
		AnimateMD2(player\legs,3,2.5,60,90)
			
End Select


Also bear in mind that successful Case statements don't fall through to the next Case down. If a Case's test expression returns True then it will run the code for the Case and jump straight to the End of the Select statement.


The3Leaf(Posted 2012) [#3]
Thanks alot for the help Zthrax, but I dont really understand what your saying about boolean operators. Also I tryed your code and played a bit with it and havnt gotten any better results. If you could elaborate a little more about what your saying about boolean operators and converting them I would greatly appreciate it. Do you mean like using player\alt as in integer where 1 is true and 0 is false? I do however understand what your saying about the Case statements. I understand this and I think its my best bet right now. Thanks again for your time and help.


Zethrax(Posted 2012) [#4]
Actually MouseHit returns the number of times the specified mouse button has been pressed since the last MouseHit command was processed for that button. I was thinking that it returns 0 or 1 results. The code I posted didn't factor that in. New code is below.

And, Or, Xor have higher operator precedence than = so I'm assuming that ( player\alt = False ) and ( player\alt = True ) are what you intended to do with those parts of the expressions. It's best to use parentheses to make execution order clear and easily understandable where possible.

A boolean/bitwise operator will compare ALL of the bits in the two 32 bit integer values to each side of the boolean/bitwise operator. Unless you are comparing 0 or 1 values to each other you can get different results than you might expect when comparing True (any non zero or non empty value) or False (a zero or empty value) values.

A logical operator will only compare values as True (non zero or non empty) and False (zero or empty) values. It basically treats any non zero or non empty value as a 1 and any zero or empty value as a zero.

EDIT: Modified code after reading Floyd's post. Been a while since I last played around with Blitz3D so there's some brain farting going on. Note that you could also convert the mousehit values to logical 0/1 values when assigning the results of the mousehit functions to the state variables, if that was desirable. It depends on whether you actually need to know how many times a mouse hit has happened since the last mousehit check.
mousehit_1_state = MouseHit(1)
mousehit_2_state = MouseHit(2)

Select True
Case ( mousehit_1_state <> False ) And ( player\alt = False )
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,30,60)
		AnimateMD2(player\body,3,2.5,30,60)
		AnimateMD2(player\legs,3,2.5,30,60)
	
Case   (  mousehit_1_state <> False ) And ( player\alt = True )
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,90,120)
		AnimateMD2(player\body,3,2.5,90,120)
		AnimateMD2(player\legs,3,2.5,90,120)

Case    mousehit_2_state
		player\busy = True
		player\attacking = True
		AnimateMD2(player\head,3,2.5,60,90)
		AnimateMD2(player\body,3,2.5,60,90)
		AnimateMD2(player\legs,3,2.5,60,90)
			
End Select


Last edited 2012


Floyd(Posted 2012) [#5]
I'll explain the logical operator thing later. The first problem is that MouseHit() does not return True/False. It returns the number of times a mouse button was clicked since the previous time MouseHit was called. This will usually be 0 or 1, but it might be more.

You are calling MouseHit(1) twice. Even if only one case is actually executed the condition must be checked for all of them. If the left button was hit once then that click will get "eaten" when the first Case is checked. You really should store the MouseHit values in variables before the Select/Case block.

[bbcode]mh1 = MouseHit(1)
mh2 = MouseHit(2) ; preventive medicine, you might some day use MouseHit(2) more than once.
Select
; process the mouse handling code here, using mh1 and mh2 instead of MouseHit()
End Select[/bbcode]
Logical operators deal only with the values True and False, which are 1 and 0 in Blitz. The Blitz operators And, Or are actually bitwise. They act on separately on each bit of their operands. You can it here:

[bbcode]Print Bin(13) + " = " + 13
Print Bin(11) + " = " + 11
Print Bin(13 And 11) + " = " + "(13 And 11)"
WaitKey[/bbcode]

Blitz comparison operators always return True/False. So ( mh1 <> 0 ) would evaluate to True if mouse button one has been hit, False if not. So your first Case would look like this:

Case ( mh1 <> False ) And ( player\alt = False )



Rob the Great(Posted 2012) [#6]
@Floyd,

How did you get your code box to display color like an IDE? That's really nice to look at in the forums.


Floyd(Posted 2012) [#7]
That's the new bbcode tag. Use it just like the old code tag.

The last line of code uses the old style. When I tried using the new one I found that bbcode turns <> into <;>.


The3Leaf(Posted 2012) [#8]
Wow Zethrax and Floyd. Thanks so much for your explanations and examples. My code now works and I under stand it. Thanks for the BlitzBasic lesson guys.