class Game(object): """ The Game is the main entry point for the game. You'll want to inherit from this to create a game. Args: ip (string, Optional): the ip of the rgb display to target. Defaults to "127.0.0.1" resources (string, Optional): a list of resources to preload (e.g. Sound). This enables the use of playSound, stopSound and fadeoutSound. Defaults to None songs (string, Optional): a list of music to load into the MusicManager. Can be accessed with "self.music". Defaults to None states (string, Optional): a list of states to be used with the integrated StateMachine. Defaults to None """ def __init__(self, ip="127.0.0.1", resources=None, songs=None, states=None, port=6803): self.rgb = RGB(ip, port) self.rgb.invertedX = True self.rgb.invertedY = True self.framerate = 20 self.previousControllerState = [] self.controllers = [] self.controllerOrientations = [] if not resources: resources = [] if not songs: songs = [] if not states: states = [] self.stateMachine = StateMachine(self, states, self.on_state_changed) self.music = MusicManager(songs) pygame.init() pygame.joystick.init() pygame.mixer.init() self.resources = {} for r in resources: r.load() if self.resources.has_key(r.name): print "double resource key: '", r.name, "'" self.resources[r.name] = r pygame.display.set_mode([200, 100]) self.playerCount = pygame.joystick.get_count() print str(self.playerCount) + " Joysticks connected." for i in range(self.playerCount): joystick = pygame.joystick.Joystick(i) self.controllers.append(joystick) joystick.init() self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllerOrientations.append(Orientation.South) self.keyboardJoystick = False if self.playerCount == 0: self.playerCount = 2 self.keyboardJoystick = True self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllers.append(KeyboardController(controller_id=0)) self.controllerOrientations.append(Orientation.South) self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllers.append(KeyboardController(controller_id=1)) self.controllerOrientations.append(Orientation.South) self.lastFrame = time.time() def poll(self, dt): pygame.event.pump() if self.keyboardJoystick: events = pygame.event.get() for player in range(len(self.controllers)): controller = self.controllers[player] if self.keyboardJoystick: controller.set_events(events) previousControllerState = self.previousControllerState[player] xAxis = -controller.get_axis(0) yAxis = -controller.get_axis(1) previousXAxis = previousControllerState['xAxis'] previousYAxis = previousControllerState['yAxis'] xChanged = previousXAxis != xAxis yChanged = previousYAxis != yAxis if xChanged or yChanged: xAxis, yAxis = self._mapAxisToOrientation(player, xAxis, yAxis) self.onAxisChanged(player, xAxis, yAxis, previousXAxis, previousYAxis) previousControllerState['xAxis'] = xAxis previousControllerState['yAxis'] = yAxis aButton = controller.get_button(0) bButton = controller.get_button(1) cButton = controller.get_button(2) dButton = controller.get_button(3) previousAButton = previousControllerState['aButton'] previousBButton = previousControllerState['bButton'] previousCButton = previousControllerState['cButton'] previousDButton = previousControllerState['dButton'] aChanged = previousAButton != aButton bChanged = previousBButton != bButton cChanged = previousCButton != cButton dChanged = previousDButton != dButton if aChanged or bChanged: self.onButtonChanged(player, aButton, bButton, previousAButton, previousBButton) previousControllerState['aButton'] = aButton previousControllerState['bButton'] = bButton if cChanged: if not cButton: self._onChangeOrientation(player) previousControllerState['cButton'] = cButton if dChanged: if not dButton: self.onStartMenuTriggered(player) previousControllerState['dButton'] = dButton def run(self): clock = pygame.time.Clock() while True: dt = clock.tick(self.framerate) / 1000.0 #dt = time.time() - self.lastFrame self.update(dt) self.draw(self.rgb) self.rgb.send() self.lastFrame = time.time() def update(self, dt): self.poll(dt) self.stateMachine.update(dt) def draw(self, rgb): rgb.clear(BLACK) self.stateMachine.draw(rgb) def onAxisChanged(self, player, xAxis, yAxis, previousXAxis, previousYAxis): if (self._isZero(xAxis) and self._notIsZero(previousXAxis)) or \ (self._isZero(yAxis) and self._notIsZero(previousYAxis)): self.onClampedAxisChanged(player, 0, 0) elif (self._notIsZero(xAxis) and self._isZero(previousXAxis)) or \ (self._notIsZero(yAxis) and self._isZero(previousYAxis)): x = 1 if xAxis > 0.1 else 0 x = -1 if xAxis < -0.1 else x y = 1 if yAxis > 0.1 else 0 y = -1 if yAxis < -0.1 else y if x != 0 or y != 0: self.onClampedAxisChanged(player, x, y) self.stateMachine.onAxisChanged(player, xAxis, yAxis, previousXAxis, previousYAxis) def onButtonChanged(self, player, a_button, b_button, previous_a_button, previous_b_button): self.stateMachine.onButtonChanged(player, a_button, b_button, previous_a_button, previous_b_button) def onClampedAxisChanged(self, player, x, y): self.stateMachine.onClampedAxisChanged(player, x, y) def on_state_changed(self, state, change_type): pass def playSound(self, name): res = self.resources[name] if isinstance(res, Sound): self.resources[name].play() else: print "tried to play non-sound resource" def stopSound(self, name): res = self.resources[name] if isinstance(res, Sound): self.resources[name].stop() else: print "tried to stop non-sound resource" def fadeoutSound(self, name, time): res = self.resources[name] if isinstance(res, Sound): self.resources[name].fadeout(time) else: print "tried to fadeout non-sound resource" def setState(self, name): self.stateMachine.setState(name) def onStartMenuTriggered(self, player): sys.exit(0) def _isZero(self, d): return abs(d) < 0.1 def _notIsZero(self, d): return abs(d) > 0.1 def _mapAxisToOrientation(self, player, xAxis, yAxis): orientation = self.controllerOrientations[player] if orientation == Orientation.North: xAxis = -xAxis yAxis = -yAxis elif orientation == Orientation.West: xTmp = xAxis xAxis = -yAxis yAxis = xTmp elif orientation == Orientation.East: xTmp = xAxis xAxis = yAxis yAxis = -xTmp return xAxis, yAxis def _onChangeOrientation(self, player): self.controllerOrientations[player] = ( self.controllerOrientations[player] + 1) % Orientation.Count
class Game: def __init__(self, ip="127.0.0.1", resources=None, songs=None, states=None): self.rgb = RGB(ip) self.rgb.invertedX = False self.rgb.invertedY = True self.framerate = 20 self.previousControllerState = [] self.controllers = [] self.controllerOrientations = [] if not resources: resources = [] if not songs: songs = [] if not states: states = [] self.stateMachine = StateMachine(states) self.music = MusicManager(songs) pygame.init() pygame.joystick.init() pygame.mixer.init() self.resources = {} for r in resources: r.load() if self.resources.has_key(r.name): print "double resource key: '", r.name,"'" self.resources[r.name] = r pygame.display.set_mode([200,100]) self.playerCount = pygame.joystick.get_count() print str(self.playerCount) + " Joysticks connected." for i in range(self.playerCount): joystick = pygame.joystick.Joystick(i) self.controllers.append(joystick) joystick.init() self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllerOrientations.append(Orientation.South) self.keyboardJoystick = False if self.playerCount == 0: self.playerCount = 2 self.keyboardJoystick = True self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllers.append(KeyboardController(id=0)) self.controllerOrientations.append(Orientation.South) self.previousControllerState.append({ 'xAxis': 0, 'yAxis': 0, 'aButton': False, 'bButton': False, 'cButton': False, 'dButton': False }) self.controllers.append(KeyboardController(id=1)) self.controllerOrientations.append(Orientation.South) self.lastFrame = time.time() def poll(self, dt): pygame.event.pump() if self.keyboardJoystick: events = pygame.event.get() for player in range(len(self.controllers)): controller = self.controllers[player] if self.keyboardJoystick: controller.set_events(events) previousControllerState = self.previousControllerState[player] xAxis = -controller.get_axis(0) yAxis = -controller.get_axis(1) previousXAxis = previousControllerState['xAxis'] previousYAxis = previousControllerState['yAxis'] xChanged = previousXAxis != xAxis yChanged = previousYAxis != yAxis if xChanged or yChanged: xAxis, yAxis = self._mapAxisToOrientation(player, xAxis, yAxis) self.onAxisChanged(player, xAxis, yAxis, previousXAxis, previousYAxis) previousControllerState['xAxis'] = xAxis previousControllerState['yAxis'] = yAxis aButton = controller.get_button(0) bButton = controller.get_button(1) cButton = controller.get_button(2) dButton = controller.get_button(3) previousAButton = previousControllerState['aButton'] previousBButton = previousControllerState['bButton'] previousCButton = previousControllerState['cButton'] previousDButton = previousControllerState['dButton'] aChanged = previousAButton != aButton bChanged = previousBButton != bButton cChanged = previousCButton != cButton dChanged = previousDButton != dButton if aChanged or bChanged: self.onButtonChanged(player, aButton, bButton, previousAButton, previousBButton) previousControllerState['aButton'] = aButton previousControllerState['bButton'] = bButton if cChanged: if not cButton: self._onChangeOrientation(player) previousControllerState['cButton'] = cButton if dChanged: if not dButton: self.onStartMenuTriggered(player) previousControllerState['dButton'] = dButton def run(self): clock = pygame.time.Clock() while True: dt = clock.tick(self.framerate) / 1000.0 #dt = time.time() - self.lastFrame self.update(dt) self.draw(self.rgb) self.rgb.send() self.lastFrame = time.time() def update(self, dt): self.poll(dt) self.stateMachine.update(dt) def draw(self, rgb): rgb.clear(BLACK) self.stateMachine.draw(rgb) def onAxisChanged(self, player, xAxis, yAxis, previousXAxis, previousYAxis): #todo rotation if (self._notIsZero(xAxis) and self._isZero(previousXAxis)) or \ (self._notIsZero(yAxis) and self._isZero(previousYAxis)): x = 1 if xAxis > 0.1 else 0 x = -1 if xAxis < -0.1 else x y = 1 if yAxis > 0.1 else 0 y = -1 if yAxis < -0.1 else y if x != 0 or y != 0: self.onClampedAxisChanged(player, x, y) self.stateMachine.onAxisChanged(player, xAxis, yAxis, previousXAxis, previousYAxis) def onButtonChanged(self, player, aButton, bButton, previousAButton, previousBButton): self.stateMachine.onButtonChanged(player, aButton, bButton, previousAButton, previousBButton) def onClampedAxisChanged(self, player, x, y): self.stateMachine.onClampedAxisChanged(player, x, y) def playSound(self, name): res = self.resources[name] if isinstance(res, Sound): self.resources[name].play() else: print "tried to play non-sound resource" def stopSound(self, name): res = self.resources[name] if isinstance(res, Sound): self.resources[name].stop() else: print "tried to stop non-sound resource" def fadeoutSound(self, name, time): res = self.resources[name] if isinstance(res, Sound): self.resources[name].fadeout(time) else: print "tried to fadeout non-sound resource" def setState(self, name): self.stateMachine.setState(name) def onStartMenuTriggered(self, player): sys.exit(0) def _isZero(self, d): return abs(d) < 0.1 def _notIsZero(self, d): return abs(d) > 0.1 def _mapAxisToOrientation(self, player, xAxis, yAxis): orientation = self.controllerOrientations[player] if orientation == Orientation.North: xAxis = -xAxis yAxis = -yAxis elif orientation == Orientation.West: xTmp = xAxis xAxis = -yAxis yAxis = xTmp elif orientation == Orientation.East: xTmp = xAxis xAxis = yAxis yAxis = -xTmp return xAxis, yAxis def _onChangeOrientation(self, player): self.controllerOrientations[player] = (self.controllerOrientations[player] + 1) % Orientation.Count
class NekoNekoChan(object): def __init__(self): Config.update() self.sound = Sound() # sensor values self.sensLeft = ColorSensor(INPUT_1) self.sensRight = ColorSensor(INPUT_4) # TODO: Sensoren anschließen self.sensIR = InfraredSensor(INPUT_2) self.sensTouch = TouchSensor(INPUT_3) self.btn = Button() self.sensValues = {} # Classes for features self.drive = Drive() self.cross = Cross() # statemachine self.fsm = StateMachine() # adding States self.fsm.states["followLine"] = State("followLine") self.fsm.states["followLine"].addFunc(self.drive.followLine, self.sensValues) self.fsm.states["brake"] = State("brake") self.fsm.states["crossFirstTurn"] = State("crossFirstTurn") self.fsm.states["crossFirstTurn"].addFunc(self.cross.firstTurn, self.sensValues) self.fsm.states["checkNextExit"] = State("checkNextExit") self.fsm.states["checkNextExit"].addFunc(self.drive.followLine, self.sensValues) # adding Transitions self.fsm.transitions["toFollowLine"] = Transition("followLine") self.fsm.transitions["toBrake"] = Transition("brake") self.fsm.transitions["toBrake"].addFunc(self.drive.brake) self.fsm.transitions["toCrossFirstTurn"] = Transition("crossFirstTurn") def checkBlue(self): hue = self.sensValues["ColorLeft"][0] return hue > 0.4 and hue < 0.68 # TODO: measure best threshold for blue values def run(self): self.fsm.setState("followLine") while True: # update sensor values self.sensValues["ColorLeft"] = self.sensLeft.hls self.sensValues["ColorRight"] = self.sensRight.hls self.sensValues["IR"] = self.sensIR.proximity self.sensValues["Touch"] = self.sensTouch.is_pressed # copy current State curState = self.fsm.currentState #Debug.print(self.sensValues["ColorLeft"], self.sensValues["ColorRight"]) # TODO: find Lightness thresholds if self.btn.down: sleep(1) if self.btn.down: Config.update() self.drive.updateConfig() self.sound.beep() if curState == None: self.fsm.transition("toFollowLine") elif self.sensValues["ColorLeft"][1] < 10.0 or self.sensValues[ "ColorRight"][1] < 10.0: self.fsm.transition("toBrake") elif self.btn.any(): break elif curState.name != "followLine": self.fsm.transition("toFollowLine") """ # EmergencyStop TODO: Wert für Abgrund definieren # if self.sensValues["ColorLeft"] == ABGRUND or self.sensValues["ColorRight"] == ABGRUND: # self.fsm.transition("toBrake") # if clauses for changing state # calibrate sensors # wait for button press before starting # line following # intersection first turn # elif self.checkBlue(): # self.fsm.transition("toCrossFirstTurn") # detect ball # collect ball, turn around # intersection turn = entry turn """ self.fsm.execute() sleep(0.01)