Key Combinations for fighting game?

yeah,

adjusting that value is how long to wait before clearing the list if a button is not pressed,

I ended up getting the best results with changing 59 to



if own['MoveList'] == [['Right','space'],['Down','Right'],['Down']] or own['MoveList'] == [['space'],['Right'],['Down','Right'],['Down']] :
        print("FireBall")
        own['MoveList']=["FireBall"]+own['MoveList']    
        added = bge.logic.getCurrentScene().addObject('FireBall',own,120)

also, change space sensor to ‘tap’



import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    if own['MoveList']=="Empty":
        own['MoveList']=["blarg"]
        own['PopTimer']=0
    space = cont.sensors['space']
    Down = cont.sensors['Down']
    Right = cont.sensors['Right']
    ListS = [Down,Right,space]
    move=["Empty"]
    print(str(own['PopTimer']))
    if own['PopTimer']>=1:
        own['PopTimer']-=1
        if own['PopTimer']==0:
            own['PopTimer']=35
            own['MoveList']=[]
                        
    if own['timer']==0:
        for sensors in ListS:
            
            if sensors.positive:
                if move[0] == "Empty":
                    
                    move=[sensors.name]
                    
                else:
                    move+=[sensors.name]
                        
       
        if move[0]!="Empty":
            own['timer']=10
            print(move)
            own['MoveList']=[move]+own['MoveList']
            own['PopTimer']=35
            
                   
    else:
        if own['timer']>=1:
            own['timer']-=1
            print(str(own['timer']))
        
            
        
                    
                    
                    
                    
            
                 
    
    if own['MoveList'] == [['Right','space'],['Down','Right'],['Down']] or own['MoveList'] == [['space'],['Right'],['Down','Right'],['Down']] :
        print("FireBall")
        own['MoveList']=["FireBall"]+own['MoveList']    
        added = bge.logic.getCurrentScene().addObject('FireBall',own,120)
        
    print(str(own['MoveList']))
    x=0
    for items in own['MoveList']:
        x+=1
            
    if x>6:
        own['MoveList'].pop(5)
    own['Status']=str(own['MoveList'])
                                              
main()



seems to work well for me, (timing is tricky on the keyboard as you can’t “Roll”)

have you tried applying this to a joystick yet?

and do joysticks have a down right button?

@@BluePrintRandom: I added some joystick sensors and tested your file, it’s still a hit and miss with joystick or keyboard input. I’m gonna mess around with it for a while but I think Monster’s way is more robust. I edited your file for joystick input => FightingSystem_workingWell (withFireBall_and_Joystick_Input).blend (488 KB)

I don’t have a joystick, however did you try those on tap?

are you going to fast (missing inputs) or too slow (to many inputs)?

monsters method still requires timing,

the value own[‘timer’] can also be adjusted,

also, I believe I am using a always sensor on tap 1- this will make the clock run faster @ zero
so you can have a finer resolution on the timer setting

Tap indeed gives better results but is not perfect, you have to perform the move very slow, faster speeds and it won’t work more then half the time. I’ll test some more!

the line 44 - is the ‘timer’ that is counted down to zero before accepting another input, is where you want to adjust input speed

I think in your file its 10,

if you check the always sensor , change the rate to 0 (the script will count down 2x faster), and then try line 44 @ 19, then 18 etc

i like your system , is pretty simple.

this is my implementation:(support multiple combos ;))


import bge
from time import clock as CLOCK


class Timer:
    def __init__(self, val=0.0):
        self.set(val)
    def set(self, val):
        self._time = CLOCK() - val
    def __call__(self):
        return CLOCK() - self._time
    


class Combo:
    def __init__(self, cont, names, timemax=0.5):
        self.cont = cont
        self.names = names
        self.sensors = [i for i in self.cont.sensors if i.name in names]
        self.current_names = []
        self.timemax = timemax
        self.timer = Timer()
    
    def reset(self):
        self.current_names = []
        self.timer.set(0)
        
    def update(self):
        for sensor in [i for i in self.sensors if i.status == 1]:
            if not self.current_names:
                self.reset()
            elif self.timer() > self.timemax:
                self.reset()
            
            self.current_names += [sensor.name]
            if self.current_names == self.names:
                self.action()
                self.reset()
                    
    def action(self):
        pass
    
class ComboJump(Combo):
    def action(self):
        own = self.cont.owner
        own.applyForce((0,0,500),1)
        
class ComboFire(Combo):
    def action(self):
        own = self.cont.owner
        own.scene.addObject("FireBall", own, 500)




COMBO_FIRE = ["Up", "Up", "Right"]
COMBO_JUMP = ["Down", "Down", "Up"]


def main(cont):
    own = cont.owner
    if not "combos" in own:
        combo_fire = ComboFire(cont, COMBO_FIRE , 0.8)
        combo_jump = ComboJump(cont, COMBO_JUMP, 0.5)
        own["combos"] = [combo_fire, combo_jump]
    
    for i in own["combos"]:
        i.update()
        
        
        

Holding two keys is no big deal.
A) You can do that directly at the keyboard sensor (up to three keys) or
B) you use two sensors connected by an AND controller (which is fine with joystick input too)

to trigger the state change

you can do that by adding a “cancelling” transition (-> to state “Waiting”) when the according key is released (NAND/NOR controller).

Hint:

Another thing I forgot. You might want to send a “reset combo” message to all TICDs that makes them cancelling their current state (-> switch to “Waiting”). It is optional.

Otherwise the current combo might count as start of the next combo. You might do not want that. e.g. A->B->C->Punsh
B->C->D->Plopp