right now it’s just silly, the whole masking thing.
a list of
[True,False,True…etc]
would be easier no?
?
that way you could do,
active=[]
x=0
for items in states:
if items=1:
active=active+[x]
x=x+1
z=0
for items in active:
OutString="State "+(str(active[z]))+" is active"
print(OutString)
z=z+1
What is your question? What are you trying to do with this code? What do you need these states for? Why a boolean? It’s just not clear enough for me in order to help you.
class StateList(list):
def __init__(self, obj):
self.obj = obj
super().__init__([obj.state >> i & 1 for i in range(30)])
def __getitem__(self, i):
self.__init__(self.obj)
return super().__getitem__(i)
def __setitem__(self, i, val):
self.__init__(self.obj)
super().__setitem__(i, val)
self.obj.state = sum([2 ** i * v for i, v in enumerate(self)])
Bitwise operations are fast, simple means of setting multiple flags at the same time. You can avoid writing multiple assignment statements. The BGE expects a certain caliber / capability of programmer who uses it, and it is not too much to learn a fundamental aspect of computer programming.
@Goran
Are there 30 states? (IIRC there are only 20 :S)
The BGE build-in state machine supports up-to 30 States.
When using single-state activation the bit-mask seams a bit overhead, but does not disturb at all.
Finally the numbering of states does not matter that much as you need to translate them to the semantic meaning to avoid feeling like an accountant. So it does not matter if the “inital” state’s index is 1 or 2048 as long as it is unique.
@ BPR: Sorry. I totally missed that you were talking about the built-in states.
@ Goran: Thanks, this is very helpful. I got it working like this:
from bge import logic
class StateList(list):
def __init__(self, obj):
self.obj = obj
super().__init__([obj.state >> i & 1 for i in range(30)])
def __getitem__(self, i):
self.__init__(self.obj)
return super().__getitem__(i)
def __setitem__(self, i, val):
self.__init__(self.obj)
super().__setitem__(i, val)
self.obj.state = sum([2 ** i * v for i, v in enumerate(self)])
statelist = StateList(logic.getCurrentController().owner)
def main():
statelist[3] = True #enables state 4
Edit: To use it with a mutated object:
from bge import logic
from bge.types import KX_GameObject
class StateList(list):
def __init__(self, obj):
self.obj = obj
super().__init__([obj.state >> i & 1 for i in range(30)])
def __getitem__(self, i):
self.__init__(self.obj)
return super().__getitem__(i)
def __setitem__(self, i, val):
self.__init__(self.obj)
super().__setitem__(i, val)
self.obj.state = sum([2 ** i * v for i, v in enumerate(self)])
class CustomObject(KX_GameObject):
def __init__(self, obj):
self.states = StateList(self)
def main(self):
pass
CustomObject(logic.getCurrentController().owner)
def main(cont):
own = cont.owner
own.states[3] = True
Be aware that the previous code only works for one object. With multiple objects using the same code, the object has to be mutated locally:
from bge import logic
from bge.types import KX_GameObject
class StateList(list):
def __init__(self, obj):
self.obj = obj
super().__init__([obj.state >> i & 1 for i in range(30)])
def __getitem__(self, i):
self.__init__(self.obj)
return super().__getitem__(i)
def __setitem__(self, i, val):
self.__init__(self.obj)
super().__setitem__(i, val)
self.obj.state = sum([2 ** i * v for i, v in enumerate(self)])
class CustomObject(KX_GameObject):
def __init__(self, obj):
self.states = StateList(self)
def main(self):
pass
def main(cont):
own = cont.owner
if not hasattr(own, 'states'):
own = CustomObject(own)
own.states[3] = True
I purposely named it ‘main’ because it describes a main function on some object. It’s not specific, it could be anything. The same goes for naming the class which mutates the object. If the object would be the player, I wouldn’t be calling it ‘CustomObject’, but ‘Player’ instead. The same goes for the name of the object. I call it ‘own’ because it could be a player, but it could also be an enemy…
My point is that I don’t think it’s wrong to name a module ‘main’. As long as you don’t use it in your actual code. These were just examples.