Ejemplo n.º 1
0
class Game(object):

    def __init__(self):
        # Set up our middleware which will handle messages from the client.
        middleware = ControllerMiddleware(game_server=self)

        # Our "middleware" will populate this dictionary with legal directional
        # events from the client when they are received.
        self.network_events = {"left": False,
                               "right": False,
                               "up": False,
                               "down": False}

        # Create a Neteria server instance and start listening.
        self.server = NeteriaServer(middleware)
        self.server.listen()


        # Set up and configure PyGame.
        pygame.init()
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption("Neteria Server")
        self.clock = pygame.time.Clock()

        # Create a player sprite that we can move around.
        self.sprite = pygame.image.load("assets/player.png").convert_alpha()
        self.sprite_position = [(self.screen.get_width() / 2) - self.sprite.get_width() / 2,
                                (self.screen.get_height() / 2) - self.sprite.get_height() / 2]


    def start(self):
        # Set up our main game loop.
        while True:
            self.clock.tick(60)

            # Loop through all of our PyGame events.
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                    return

            if self.network_events["left"]:
                self.sprite_position[0] -= 1
            if self.network_events["right"]:
                self.sprite_position[0] += 1
            if self.network_events["up"]:
                self.sprite_position[1] -= 1
            if self.network_events["down"]:
                self.sprite_position[1] += 1

            self.screen.fill((0,0,0))
            self.screen.blit(self.sprite, self.sprite_position)

            if len(self.server.registry) > 0:
                pygame.display.set_caption("Neteria Server (Client Registered!)")

            pygame.display.flip()
Ejemplo n.º 2
0
class Control(object):
    """Control class for entire project. Contains the game loop, and contains
    the event_loop which passes events to States as needed. Logic for flipping
    states is also found here.

    :param caption: The window caption to use for the game itself.

    :type caption: String

    :rtype: None
    :returns: None

    """

    def __init__(self, caption):
        self.screen = pg.display.get_surface()
        self.caption = caption
        self.done = False
        self.clock = pg.time.Clock()
        self.fps = 60.0
        self.show_fps = True
        self.current_time = 0.0
        self.keys = pg.key.get_pressed()
        self.key_events = []
        self.state_dict = {}
        self.state_name = None
        self.state = None
        if NeteriaServer and Controller:
            self.network_events = []
            self.server = NeteriaServer(Controller(self))
            self.server.listen()
        else:
            self.server = None

        # Set up our game's configuration from the prepare module.
        from core import prepare
        self.imports = {
                "prepare": prepare,
                "ai": ai,
                "rumble": rumble,
                "db": db,
                "monster": monster,
                "player": player,
                "item": item,
                "map": maps,
                "pyganim": pyganim
                }
        self.config = prepare.CONFIG

        # Set up our game's event engine which executes actions based on
        # conditions defined in map files.
        self.event_engine = event.EventEngine()
        self.event_conditions = {}
        self.event_actions = {}
        self.event_persist = {}

        # Set up a variable that will keep track of currently playing music.
        self.current_music = {"status": "stopped", "song": None}

        # Keep track of animations that we will play.
        self.animations = {}

        # Create these Pygame event objects to simulate KEYDOWN and KEYUP
        # events for all the directional keys
        self.keyboard_events = {}
        self.keyboard_events["KEYDOWN"] = {}
        self.keyboard_events["KEYDOWN"]["up"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 111, 'key': 273, 'unicode': u'', 'mod': 4096})
        self.keyboard_events["KEYDOWN"]["down"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 116, 'key': 274, 'unicode': u'', 'mod': 4096})
        self.keyboard_events["KEYDOWN"]["left"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 113, 'key': 276, 'unicode': u'', 'mod': 4096})
        self.keyboard_events["KEYDOWN"]["right"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 114, 'key': 275, 'unicode': u'', 'mod': 4096})
        self.keyboard_events["KEYDOWN"]["enter"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 36, 'key': 13, 'unicode': u'\r', 'mod': 4096})
        self.keyboard_events["KEYDOWN"]["escape"] = pg.event.Event(
            pg.KEYDOWN,
            {'scancode': 9, 'key': 27, 'unicode': u'\x1b', 'mod': 4096})
        self.keyboard_events["KEYUP"] = {}
        self.keyboard_events["KEYUP"]["up"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 111, 'key': 273, 'mod': 4096})
        self.keyboard_events["KEYUP"]["down"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 116, 'key': 274, 'mod': 4096})
        self.keyboard_events["KEYUP"]["left"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 113, 'key': 276, 'mod': 4096})
        self.keyboard_events["KEYUP"]["right"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 114, 'key': 275, 'mod': 4096})
        self.keyboard_events["KEYUP"]["enter"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 36, 'key': 13, 'mod': 4096})
        self.keyboard_events["KEYUP"]["escape"] = pg.event.Event(
            pg.KEYUP,
            {'scancode': 9, 'key': 27, 'mod': 4096})


        # Set up the command line. This provides a full python shell for
        # troubleshooting. You can view and manipulate any variables in
        # the game.
        self.exit = False   # Allow exit from the CLI
        if self.config.cli:
            self.cli = cli.CommandLine(self)

        # Controller overlay
        if self.config.controller_overlay == "1":
            self.controller = controller.Controller(self)
            self.controller.load()

            # Keep track of what buttons have been pressed when the overlay
            # controller is enabled.
            self.overlay_pressed = {
                    "up": False,
                    "down": False,
                    "left": False,
                    "right": False,
                    "a": False,
                    "b": False
                    }


        # Set up rumble support for gamepads
        self.rumble_manager = rumble.RumbleManager()
        self.rumble = self.rumble_manager.rumbler


    def setup_states(self, state_dict, start_state):
        """Given a dictionary of States and a State to start in,
        builds the self.state_dict.

        :param state_dict: A dictionary of core.tools._State objects.
        :param start_state: A string of the starting state. E.g. "START"

        :type state_dict: Dictionary
        :type start_state: String

        :rtype: None
        :returns: None

        **Examples:**

        >>> state_dict
        {'COMBAT': <core.states.combat.Combat object at 0x7f681d736590>,
         'START': <core.states.start.StartScreen object at 0x7f68230f5150>,
         'WORLD': <core.states.world.World object at 0x7f68230f54d0>}
        >>> start_state
        "START"

        """

        self.state_dict = state_dict
        self.state_name = start_state
        self.state = self.state_dict[self.state_name]


    def update(self, dt):
        """Checks if a state is done or has called for a game quit.
        State is flipped if neccessary and State.update is called. This
        also calls the currently active state's "update" function each
        frame.

        :param dt: Time delta - Amount of time passed since last frame.

        :type dt: Float

        :rtype: None
        :returns: None

        **Example:**

        >>> dt
        0.031

        """

        self.current_time = pg.time.get_ticks()
        if self.state.quit:
            self.done = True
            self.exit = True
        elif self.state.done:
            self.flip_state()
        self.state.update(self.screen, self.keys, self.current_time, dt)
        if self.config.controller_overlay == "1":
            self.controller.draw(self)


    def flip_state(self):
        """When a State changes to "done" necessary startup and cleanup functions
        are called and the current State is changed. In addition, the state
        specified in self.state.next is loaded.

        :param None:

        :rtype: None
        :returns: None

        """

        previous, self.state_name = self.state_name, self.state.next
        persist = self.state.cleanup()
        self.state = self.state_dict[self.state_name]
        self.state.startup(self.current_time, persist)
        self.state.previous = previous


    def event_loop(self):
        """Process all events and pass them down to current State.  The F5 key
        globally turns on/off the display of FPS in the caption

        :param None:

        :rtype: None
        :returns: None

        """

        # Loop through our pygame events and pass them to the current state.
        self.key_events = []
        self.keys = list(pg.key.get_pressed())
        for event in pg.event.get():
            self.key_events.append(event)
            if event.type == pg.QUIT:
                self.done = True
                self.exit = True

            elif event.type == pg.KEYDOWN:
                self.toggle_show_fps(event.key)

            # Loop through our controller overlay events and pass them to the current state.
            if self.config.controller_overlay == "1":
                self.mouse_pos = pg.mouse.get_pos()
                contr_events = self.controller_event_loop(event)
                if contr_events:
                    for contr_event in contr_events:
                        self.key_events.append(contr_event)
                        self.state.get_event(contr_event)

            # Loop through our joystick events and pass them to the current state.
            joy_events = self.joystick_event_loop(event)
            if joy_events:
                for joy_event in joy_events:
                    self.key_events.append(joy_event)
                    self.state.get_event(joy_event)

            self.state.get_event(event)

        # Loop through our network events and pass them to the current state.
        if self.server:
            net_events = self.network_event_loop()
            if net_events:
                for net_event in net_events:
                    self.key_events.append(net_event)
                    self.state.get_event(net_event)


    def network_event_loop(self):
        """Process all network events from the mobile controller and pass them
        down to current State. All network events are converted to keyboard
        events for compatibility.

        :param None:

        :rtype: None
        :returns: None

        """
        events = []
        for event_data in self.network_events:
            if event_data == "KEYDOWN:up":
                self.keys[pg.K_UP] = 1
                event = self.keyboard_events["KEYDOWN"]["up"]

            elif event_data == "KEYUP:up":
                self.keys[pg.K_UP] = 0
                event = self.keyboard_events["KEYUP"]["up"]

            elif event_data == "KEYDOWN:down":
                self.keys[pg.K_DOWN] = 1
                event = self.keyboard_events["KEYDOWN"]["down"]

            elif event_data == "KEYUP:down":
                self.keys[pg.K_DOWN] = 0
                event = self.keyboard_events["KEYUP"]["down"]

            elif event_data == "KEYDOWN:left":
                self.keys[pg.K_LEFT] = 1
                event = self.keyboard_events["KEYDOWN"]["left"]

            elif event_data == "KEYUP:left":
                self.keys[pg.K_LEFT] = 0
                event = self.keyboard_events["KEYUP"]["left"]

            elif event_data == "KEYDOWN:right":
                self.keys[pg.K_RIGHT] = 1
                event = self.keyboard_events["KEYDOWN"]["right"]

            elif event_data == "KEYUP:right":
                self.keys[pg.K_RIGHT] = 0
                event = self.keyboard_events["KEYUP"]["right"]

            elif event_data == "KEYDOWN:enter":
                self.keys[pg.K_RETURN] = 1
                event = self.keyboard_events["KEYDOWN"]["enter"]

            elif event_data == "KEYUP:enter":
                self.keys[pg.K_RETURN] = 0
                event = self.keyboard_events["KEYUP"]["enter"]

            elif event_data == "KEYDOWN:esc":
                self.keys[pg.K_ESCAPE] = 1
                event = self.keyboard_events["KEYDOWN"]["escape"]

            elif event_data == "KEYUP:esc":
                self.keys[pg.K_ESCAPE] = 0
                event = self.keyboard_events["KEYUP"]["escape"]

            else:
                print "Unknown network event."
                event = None

            if event:
                events.append(event)

        self.network_events = []

        return events


    def controller_event_loop(self, event):
        """Process all events from the controller overlay and pass them down to
        current State. All controller overlay events are converted to keyboard
        events for compatibility. This is primarily used for the mobile version
        of Tuxemon.

        :param event: A Pygame event object from pg.event.get()
        :type event: pygame.event.Event

        :rtype: None
        :returns: None

        """
        events = []
        if (event.type == pg.MOUSEBUTTONDOWN
            and event.button == 1):

            if self.controller.dpad["rect"]["up"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["up"])
                self.keys[pg.K_UP] = 1
                self.overlay_pressed["up"] = True
            if self.controller.dpad["rect"]["down"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["down"])
                self.keys[pg.K_DOWN] = 1
                self.overlay_pressed["down"] = True
            if self.controller.dpad["rect"]["left"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["left"])
                self.keys[pg.K_LEFT] = 1
                self.overlay_pressed["left"] = True
            if self.controller.dpad["rect"]["right"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["right"])
                self.keys[pg.K_RIGHT] = 1
                self.overlay_pressed["right"] = True
            if self.controller.a_button["rect"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["enter"])
                self.keys[pg.K_RETURN] = 1
                self.overlay_pressed["a"] = True
            if self.controller.b_button["rect"].collidepoint(self.mouse_pos):
                events.append(
                    self.keyboard_events["KEYDOWN"]["escape"])
                self.keys[pg.K_ESCAPE] = 1
                self.overlay_pressed["b"] = True


        if (event.type == pg.MOUSEBUTTONUP) and (event.button == 1):
            if self.overlay_pressed["up"]:
                events.append(self.keyboard_events["KEYUP"]["up"])
                self.overlay_pressed["up"] = False
            if self.overlay_pressed["down"]:
                events.append(self.keyboard_events["KEYUP"]["down"])
                self.overlay_pressed["down"] = False
            if self.overlay_pressed["left"]:
                events.append(self.keyboard_events["KEYUP"]["left"])
                self.overlay_pressed["left"] = False
            if self.overlay_pressed["right"]:
                events.append(self.keyboard_events["KEYUP"]["right"])
                self.overlay_pressed["right"] = False
            if self.overlay_pressed["a"]:
                events.append(self.keyboard_events["KEYUP"]["enter"])
                self.overlay_pressed["a"] = False
                self.keys[pg.K_RETURN] = 0
            if self.overlay_pressed["b"]:
                events.append(self.keyboard_events["KEYUP"]["escape"])
                self.overlay_pressed["b"] = False

        return events


    def joystick_event_loop(self, event):
        """Process all events from a joystick and pass them down to
        current State. All joystick events are converted to keyboard
        events for compatibility.

        :param event: A Pygame event object from pg.event.get()
        :type event: pygame.event.Event

        :rtype: None
        :returns: None

        """
        from core import prepare

        # Handle joystick events if we detected one
        events = []
        if len(prepare.JOYSTICKS) > 0:

            # Xbox 360 Controller buttons:
            # A = 0    Start = 7    D-Up = 13
            # B = 1    Back = 6     D-Down = 14
            # X = 2                 D-Left = 11
            # Y = 3                 D-Right = 12
            #
            if event.type == pg.JOYBUTTONDOWN:
                if event.button == 0:
                    events.append(
                        self.keyboard_events["KEYDOWN"]["enter"])
                    self.keys[pg.K_RETURN] = 1
                if (event.button == 1
                    or event.button == 7 or event.button == 6):
                    events.append(
                        self.keyboard_events["KEYDOWN"]["escape"])
                    self.keys[pg.K_ESCAPE] = 1

                if event.button == 13:
                    events.append(
                        self.keyboard_events["KEYDOWN"]["up"])
                    self.keys[pg.K_UP] = 1
                if event.button == 14:
                    events.append(
                        self.keyboard_events["KEYDOWN"]["down"])
                    self.keys[pg.K_DOWN] = 1
                if event.button == 11:
                    events.append(
                        self.keyboard_events["KEYDOWN"]["left"])
                    self.keys[pg.K_LEFT] = 1
                if event.button == 12:
                    events.append(
                        self.keyboard_events["KEYDOWN"]["right"])
                    self.keys[pg.K_RIGHT] = 1

            elif event.type == pg.JOYBUTTONUP:
                if event.button == 0:
                    events.append(
                        self.keyboard_events["KEYUP"]["enter"])
                if (event.button == 1
                    or event.button == 7 or event.button == 6):
                    events.append(
                        self.keyboard_events["KEYUP"]["escape"])

                if event.button == 13:
                    events.append(self.keyboard_events["KEYUP"]["up"])
                if event.button == 14:
                    events.append(
                        self.keyboard_events["KEYUP"]["down"])
                if event.button == 11:
                    events.append(
                        self.keyboard_events["KEYUP"]["left"])
                if event.button == 12:
                    events.append(
                        self.keyboard_events["KEYUP"]["right"])

            # Handle left joystick movement as well.
            # Axis 1 - up = negative, down = positive
            # Axis 0 - left = negative, right = positive
            if event.type == pg.JOYAXISMOTION and False:    # Disabled until input manager is implemented

                # Handle the left/right axis
                if event.axis == 0:
                    if event.value >= 0.5:
                        events.append(
                            self.keyboard_events["KEYDOWN"]["right"])
                        self.keys[pg.K_RIGHT] = 1
                    elif event.value <= -0.5:
                        events.append(
                            self.keyboard_events["KEYDOWN"]["left"])
                        self.keys[pg.K_LEFT] = 1
                    else:
                        events.append(
                            self.keyboard_events["KEYUP"]["left"])
                        events.append(
                            self.keyboard_events["KEYUP"]["right"])

                # Handle the up/down axis
                if event.axis == 1:
                    if event.value >= 0.5:
                        events.append(
                            self.keyboard_events["KEYDOWN"]["down"])
                        self.keys[pg.K_DOWN] = 1
                    elif event.value <= -0.5:
                        events.append(
                            self.keyboard_events["KEYDOWN"]["up"])
                        self.keys[pg.K_LEFT] = 1
                    else:
                        events.append(
                            self.keyboard_events["KEYUP"]["up"])
                        events.append(
                            self.keyboard_events["KEYUP"]["down"])

        return events


    def toggle_show_fps(self, key):
        """Press f5 to turn on/off displaying the framerate in the caption.

        :param key: A pygame key event from pygame.event.get()

        :type key: PyGame Event

        :rtype: None
        :returns: None

        """

        if key == pg.K_F5:
            self.show_fps = not self.show_fps
            if not self.show_fps:
                pg.display.set_caption(self.caption)


    def main(self):
        """Initiates the main game loop. Since we are using Asteria networking
        to handle network events, we pass this core.tools.Control instance to
        networking which in turn executes the "main_loop" method every frame.
        This leaves the networking component responsible for the main loop.

        :param None:

        :rtype: None
        :returns: None

        """

        # This sets up Asteria networking to handle executing the game loop
        #listen(Controller(self), self, port=8000, game_loop=True)
        while not self.exit:
            self.main_loop()


    def main_loop(self):
        """Main loop for entire game. This method gets execute every frame
        by Asteria Networking's "listen()" function. Every frame we get the
        amount of time that has passed each frame, check game conditions,
        and draw the game to the screen.

        :param None:

        :rtype: None
        :returns: None

        """

        # Android-specific check for pause
        if android:
            if android.check_pause():
                android.wait_for_resume()

        # Get the amount of time that has passed since the last frame.
        time_delta = self.clock.tick(self.fps)/1000.0
        self.time_passed_seconds = time_delta
        self.event_loop()

        # Run our event engine which will check to see if game conditions
        # are met and run an action associated with that condition.
        self.event_data = {}
        self.event_engine.check_conditions(self, time_delta)
        logger.debug("Event Data:" + str(self.event_data))

        # Draw and update our display
        self.update(time_delta)
        pg.display.update()
        if self.show_fps:
            fps = self.clock.get_fps()
            with_fps = "{} - {:.2f} FPS".format(self.caption, fps)
            pg.display.set_caption(with_fps)
        if self.exit:
            self.done = True
Ejemplo n.º 3
0
#!/usr/bin/python

import logging
import sys
import time
from neteria.server import NeteriaServer
from neteria.tools import _Middleware

# Create a middleware object that will echo events. "event_execute" is
# executed for every legal event message.
class EchoMiddleware(_Middleware):
    def event_legal(self, cuuid, euuid, event_data):
        return True

    def event_execute(self, cuuid, euuid, event_data):
        print event_data

# Create a client instance.
server = NeteriaServer(EchoMiddleware())
server.listen()
print "Server started. Press CTRL+C to quit."

while True:
    time.sleep(1)
Ejemplo n.º 4
0
class Control(object):
    """Control class for entire project. Contains the game loop, and contains
    the event_loop which passes events to States as needed. Logic for flipping
    states is also found here.

    :param caption: The window caption to use for the game itself.

    :type caption: String

    :rtype: None
    :returns: None

    """
    def __init__(self, caption):
        self.screen = pg.display.get_surface()
        self.caption = caption
        self.done = False
        self.clock = pg.time.Clock()
        self.fps = 60.0
        self.show_fps = True
        self.current_time = 0.0
        self.keys = pg.key.get_pressed()
        self.key_events = []
        self.state_dict = {}
        self.state_name = None
        self.state = None
        if NeteriaServer and Controller:
            self.network_events = []
            self.server = NeteriaServer(Controller(self))
            self.server.listen()
        else:
            self.server = None

        # Set up our game's configuration from the prepare module.
        from core import prepare
        self.imports = {
            "prepare": prepare,
            "ai": ai,
            "rumble": rumble,
            "db": db,
            "monster": monster,
            "player": player,
            "item": item,
            "map": maps,
            "pyganim": pyganim
        }
        self.config = prepare.CONFIG

        # Set up our game's event engine which executes actions based on
        # conditions defined in map files.
        self.event_engine = event.EventEngine()
        self.event_conditions = {}
        self.event_actions = {}
        self.event_persist = {}

        # Set up a variable that will keep track of currently playing music.
        self.current_music = {"status": "stopped", "song": None}

        # Keep track of animations that we will play.
        self.animations = {}

        # Create these Pygame event objects to simulate KEYDOWN and KEYUP
        # events for all the directional keys
        self.keyboard_events = {}
        self.keyboard_events["KEYDOWN"] = {}
        self.keyboard_events["KEYDOWN"]["up"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 111,
                'key': 273,
                'unicode': u'',
                'mod': 4096
            })
        self.keyboard_events["KEYDOWN"]["down"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 116,
                'key': 274,
                'unicode': u'',
                'mod': 4096
            })
        self.keyboard_events["KEYDOWN"]["left"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 113,
                'key': 276,
                'unicode': u'',
                'mod': 4096
            })
        self.keyboard_events["KEYDOWN"]["right"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 114,
                'key': 275,
                'unicode': u'',
                'mod': 4096
            })
        self.keyboard_events["KEYDOWN"]["enter"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 36,
                'key': 13,
                'unicode': u'\r',
                'mod': 4096
            })
        self.keyboard_events["KEYDOWN"]["escape"] = pg.event.Event(
            pg.KEYDOWN, {
                'scancode': 9,
                'key': 27,
                'unicode': u'\x1b',
                'mod': 4096
            })
        self.keyboard_events["KEYUP"] = {}
        self.keyboard_events["KEYUP"]["up"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 111,
                'key': 273,
                'mod': 4096
            })
        self.keyboard_events["KEYUP"]["down"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 116,
                'key': 274,
                'mod': 4096
            })
        self.keyboard_events["KEYUP"]["left"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 113,
                'key': 276,
                'mod': 4096
            })
        self.keyboard_events["KEYUP"]["right"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 114,
                'key': 275,
                'mod': 4096
            })
        self.keyboard_events["KEYUP"]["enter"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 36,
                'key': 13,
                'mod': 4096
            })
        self.keyboard_events["KEYUP"]["escape"] = pg.event.Event(
            pg.KEYUP, {
                'scancode': 9,
                'key': 27,
                'mod': 4096
            })

        # Set up the command line. This provides a full python shell for
        # troubleshooting. You can view and manipulate any variables in
        # the game.
        self.exit = False  # Allow exit from the CLI
        if self.config.cli:
            self.cli = cli.CommandLine(self)

        # Controller overlay
        if self.config.controller_overlay == "1":
            self.controller = controller.Controller(self)
            self.controller.load()

            # Keep track of what buttons have been pressed when the overlay
            # controller is enabled.
            self.overlay_pressed = {
                "up": False,
                "down": False,
                "left": False,
                "right": False,
                "a": False,
                "b": False
            }

        # Set up rumble support for gamepads
        self.rumble_manager = rumble.RumbleManager()
        self.rumble = self.rumble_manager.rumbler

    def setup_states(self, state_dict, start_state):
        """Given a dictionary of States and a State to start in,
        builds the self.state_dict.

        :param state_dict: A dictionary of core.tools._State objects.
        :param start_state: A string of the starting state. E.g. "START"

        :type state_dict: Dictionary
        :type start_state: String

        :rtype: None
        :returns: None

        **Examples:**

        >>> state_dict
        {'COMBAT': <core.states.combat.Combat object at 0x7f681d736590>,
         'START': <core.states.start.StartScreen object at 0x7f68230f5150>,
         'WORLD': <core.states.world.World object at 0x7f68230f54d0>}
        >>> start_state
        "START"

        """

        self.state_dict = state_dict
        self.state_name = start_state
        self.state = self.state_dict[self.state_name]

    def update(self, dt):
        """Checks if a state is done or has called for a game quit.
        State is flipped if neccessary and State.update is called. This
        also calls the currently active state's "update" function each
        frame.

        :param dt: Time delta - Amount of time passed since last frame.

        :type dt: Float

        :rtype: None
        :returns: None

        **Example:**

        >>> dt
        0.031

        """

        self.current_time = pg.time.get_ticks()
        if self.state.quit:
            self.done = True
            self.exit = True
        elif self.state.done:
            self.flip_state()
        self.state.update(self.screen, self.keys, self.current_time, dt)
        if self.config.controller_overlay == "1":
            self.controller.draw(self)

    def flip_state(self):
        """When a State changes to "done" necessary startup and cleanup functions
        are called and the current State is changed. In addition, the state
        specified in self.state.next is loaded.

        :param None:

        :rtype: None
        :returns: None

        """

        previous, self.state_name = self.state_name, self.state.next
        persist = self.state.cleanup()
        self.state = self.state_dict[self.state_name]
        self.state.startup(self.current_time, persist)
        self.state.previous = previous

    def event_loop(self):
        """Process all events and pass them down to current State.  The F5 key
        globally turns on/off the display of FPS in the caption

        :param None:

        :rtype: None
        :returns: None

        """

        # Loop through our pygame events and pass them to the current state.
        self.key_events = []
        self.keys = list(pg.key.get_pressed())
        for event in pg.event.get():
            self.key_events.append(event)
            if event.type == pg.QUIT:
                self.done = True
                self.exit = True

            elif event.type == pg.KEYDOWN:
                self.toggle_show_fps(event.key)

            # Loop through our controller overlay events and pass them to the current state.
            if self.config.controller_overlay == "1":
                self.mouse_pos = pg.mouse.get_pos()
                contr_events = self.controller_event_loop(event)
                if contr_events:
                    for contr_event in contr_events:
                        self.key_events.append(contr_event)
                        self.state.get_event(contr_event)

            # Loop through our joystick events and pass them to the current state.
            joy_events = self.joystick_event_loop(event)
            if joy_events:
                for joy_event in joy_events:
                    self.key_events.append(joy_event)
                    self.state.get_event(joy_event)

            self.state.get_event(event)

        # Loop through our network events and pass them to the current state.
        if self.server:
            net_events = self.network_event_loop()
            if net_events:
                for net_event in net_events:
                    self.key_events.append(net_event)
                    self.state.get_event(net_event)

    def network_event_loop(self):
        """Process all network events from the mobile controller and pass them
        down to current State. All network events are converted to keyboard
        events for compatibility.

        :param None:

        :rtype: None
        :returns: None

        """
        events = []
        for event_data in self.network_events:
            if event_data == "KEYDOWN:up":
                self.keys[pg.K_UP] = 1
                event = self.keyboard_events["KEYDOWN"]["up"]

            elif event_data == "KEYUP:up":
                self.keys[pg.K_UP] = 0
                event = self.keyboard_events["KEYUP"]["up"]

            elif event_data == "KEYDOWN:down":
                self.keys[pg.K_DOWN] = 1
                event = self.keyboard_events["KEYDOWN"]["down"]

            elif event_data == "KEYUP:down":
                self.keys[pg.K_DOWN] = 0
                event = self.keyboard_events["KEYUP"]["down"]

            elif event_data == "KEYDOWN:left":
                self.keys[pg.K_LEFT] = 1
                event = self.keyboard_events["KEYDOWN"]["left"]

            elif event_data == "KEYUP:left":
                self.keys[pg.K_LEFT] = 0
                event = self.keyboard_events["KEYUP"]["left"]

            elif event_data == "KEYDOWN:right":
                self.keys[pg.K_RIGHT] = 1
                event = self.keyboard_events["KEYDOWN"]["right"]

            elif event_data == "KEYUP:right":
                self.keys[pg.K_RIGHT] = 0
                event = self.keyboard_events["KEYUP"]["right"]

            elif event_data == "KEYDOWN:enter":
                self.keys[pg.K_RETURN] = 1
                event = self.keyboard_events["KEYDOWN"]["enter"]

            elif event_data == "KEYUP:enter":
                self.keys[pg.K_RETURN] = 0
                event = self.keyboard_events["KEYUP"]["enter"]

            elif event_data == "KEYDOWN:esc":
                self.keys[pg.K_ESCAPE] = 1
                event = self.keyboard_events["KEYDOWN"]["escape"]

            elif event_data == "KEYUP:esc":
                self.keys[pg.K_ESCAPE] = 0
                event = self.keyboard_events["KEYUP"]["escape"]

            else:
                print "Unknown network event."
                event = None

            if event:
                events.append(event)

        self.network_events = []

        return events

    def controller_event_loop(self, event):
        """Process all events from the controller overlay and pass them down to
        current State. All controller overlay events are converted to keyboard
        events for compatibility. This is primarily used for the mobile version
        of Tuxemon.

        :param event: A Pygame event object from pg.event.get()
        :type event: pygame.event.Event

        :rtype: None
        :returns: None

        """
        events = []
        if (event.type == pg.MOUSEBUTTONDOWN and event.button == 1):

            if self.controller.dpad["rect"]["up"].collidepoint(self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["up"])
                self.keys[pg.K_UP] = 1
                self.overlay_pressed["up"] = True
            if self.controller.dpad["rect"]["down"].collidepoint(
                    self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["down"])
                self.keys[pg.K_DOWN] = 1
                self.overlay_pressed["down"] = True
            if self.controller.dpad["rect"]["left"].collidepoint(
                    self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["left"])
                self.keys[pg.K_LEFT] = 1
                self.overlay_pressed["left"] = True
            if self.controller.dpad["rect"]["right"].collidepoint(
                    self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["right"])
                self.keys[pg.K_RIGHT] = 1
                self.overlay_pressed["right"] = True
            if self.controller.a_button["rect"].collidepoint(self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["enter"])
                self.keys[pg.K_RETURN] = 1
                self.overlay_pressed["a"] = True
            if self.controller.b_button["rect"].collidepoint(self.mouse_pos):
                events.append(self.keyboard_events["KEYDOWN"]["escape"])
                self.keys[pg.K_ESCAPE] = 1
                self.overlay_pressed["b"] = True

        if (event.type == pg.MOUSEBUTTONUP) and (event.button == 1):
            if self.overlay_pressed["up"]:
                events.append(self.keyboard_events["KEYUP"]["up"])
                self.overlay_pressed["up"] = False
            if self.overlay_pressed["down"]:
                events.append(self.keyboard_events["KEYUP"]["down"])
                self.overlay_pressed["down"] = False
            if self.overlay_pressed["left"]:
                events.append(self.keyboard_events["KEYUP"]["left"])
                self.overlay_pressed["left"] = False
            if self.overlay_pressed["right"]:
                events.append(self.keyboard_events["KEYUP"]["right"])
                self.overlay_pressed["right"] = False
            if self.overlay_pressed["a"]:
                events.append(self.keyboard_events["KEYUP"]["enter"])
                self.overlay_pressed["a"] = False
                self.keys[pg.K_RETURN] = 0
            if self.overlay_pressed["b"]:
                events.append(self.keyboard_events["KEYUP"]["escape"])
                self.overlay_pressed["b"] = False

        return events

    def joystick_event_loop(self, event):
        """Process all events from a joystick and pass them down to
        current State. All joystick events are converted to keyboard
        events for compatibility.

        :param event: A Pygame event object from pg.event.get()
        :type event: pygame.event.Event

        :rtype: None
        :returns: None

        """
        from core import prepare

        # Handle joystick events if we detected one
        events = []
        if len(prepare.JOYSTICKS) > 0:

            # Xbox 360 Controller buttons:
            # A = 0    Start = 7    D-Up = 13
            # B = 1    Back = 6     D-Down = 14
            # X = 2                 D-Left = 11
            # Y = 3                 D-Right = 12
            #
            if event.type == pg.JOYBUTTONDOWN:
                if event.button == 0:
                    events.append(self.keyboard_events["KEYDOWN"]["enter"])
                    self.keys[pg.K_RETURN] = 1
                if (event.button == 1 or event.button == 7
                        or event.button == 6):
                    events.append(self.keyboard_events["KEYDOWN"]["escape"])
                    self.keys[pg.K_ESCAPE] = 1

                if event.button == 13:
                    events.append(self.keyboard_events["KEYDOWN"]["up"])
                    self.keys[pg.K_UP] = 1
                if event.button == 14:
                    events.append(self.keyboard_events["KEYDOWN"]["down"])
                    self.keys[pg.K_DOWN] = 1
                if event.button == 11:
                    events.append(self.keyboard_events["KEYDOWN"]["left"])
                    self.keys[pg.K_LEFT] = 1
                if event.button == 12:
                    events.append(self.keyboard_events["KEYDOWN"]["right"])
                    self.keys[pg.K_RIGHT] = 1

            elif event.type == pg.JOYBUTTONUP:
                if event.button == 0:
                    events.append(self.keyboard_events["KEYUP"]["enter"])
                if (event.button == 1 or event.button == 7
                        or event.button == 6):
                    events.append(self.keyboard_events["KEYUP"]["escape"])

                if event.button == 13:
                    events.append(self.keyboard_events["KEYUP"]["up"])
                if event.button == 14:
                    events.append(self.keyboard_events["KEYUP"]["down"])
                if event.button == 11:
                    events.append(self.keyboard_events["KEYUP"]["left"])
                if event.button == 12:
                    events.append(self.keyboard_events["KEYUP"]["right"])

            # Handle left joystick movement as well.
            # Axis 1 - up = negative, down = positive
            # Axis 0 - left = negative, right = positive
            if event.type == pg.JOYAXISMOTION and False:  # Disabled until input manager is implemented

                # Handle the left/right axis
                if event.axis == 0:
                    if event.value >= 0.5:
                        events.append(self.keyboard_events["KEYDOWN"]["right"])
                        self.keys[pg.K_RIGHT] = 1
                    elif event.value <= -0.5:
                        events.append(self.keyboard_events["KEYDOWN"]["left"])
                        self.keys[pg.K_LEFT] = 1
                    else:
                        events.append(self.keyboard_events["KEYUP"]["left"])
                        events.append(self.keyboard_events["KEYUP"]["right"])

                # Handle the up/down axis
                if event.axis == 1:
                    if event.value >= 0.5:
                        events.append(self.keyboard_events["KEYDOWN"]["down"])
                        self.keys[pg.K_DOWN] = 1
                    elif event.value <= -0.5:
                        events.append(self.keyboard_events["KEYDOWN"]["up"])
                        self.keys[pg.K_LEFT] = 1
                    else:
                        events.append(self.keyboard_events["KEYUP"]["up"])
                        events.append(self.keyboard_events["KEYUP"]["down"])

        return events

    def toggle_show_fps(self, key):
        """Press f5 to turn on/off displaying the framerate in the caption.

        :param key: A pygame key event from pygame.event.get()

        :type key: PyGame Event

        :rtype: None
        :returns: None

        """

        if key == pg.K_F5:
            self.show_fps = not self.show_fps
            if not self.show_fps:
                pg.display.set_caption(self.caption)

    def main(self):
        """Initiates the main game loop. Since we are using Asteria networking
        to handle network events, we pass this core.tools.Control instance to
        networking which in turn executes the "main_loop" method every frame.
        This leaves the networking component responsible for the main loop.

        :param None:

        :rtype: None
        :returns: None

        """

        # This sets up Asteria networking to handle executing the game loop
        #listen(Controller(self), self, port=8000, game_loop=True)
        while not self.exit:
            self.main_loop()

    def main_loop(self):
        """Main loop for entire game. This method gets execute every frame
        by Asteria Networking's "listen()" function. Every frame we get the
        amount of time that has passed each frame, check game conditions,
        and draw the game to the screen.

        :param None:

        :rtype: None
        :returns: None

        """

        # Android-specific check for pause
        if android:
            if android.check_pause():
                android.wait_for_resume()

        # Get the amount of time that has passed since the last frame.
        time_delta = self.clock.tick(self.fps) / 1000.0
        self.time_passed_seconds = time_delta
        self.event_loop()

        # Run our event engine which will check to see if game conditions
        # are met and run an action associated with that condition.
        self.event_data = {}
        self.event_engine.check_conditions(self, time_delta)
        logger.debug("Event Data:" + str(self.event_data))

        # Draw and update our display
        self.update(time_delta)
        pg.display.update()
        if self.show_fps:
            fps = self.clock.get_fps()
            with_fps = "{} - {:.2f} FPS".format(self.caption, fps)
            pg.display.set_caption(with_fps)
        if self.exit:
            self.done = True
Ejemplo n.º 5
0
 def run(self):
     server = NeteriaServer(EchoMiddleware())
     server.listen() 
     while(True):
        time.sleep(1)
Ejemplo n.º 6
0
#!/usr/bin/python

import logging
import sys
import time
from neteria.server import NeteriaServer
from neteria.tools import _Middleware


# Create a middleware object that will echo events. "event_execute" is
# executed for every legal event message.
class EchoMiddleware(_Middleware):
    def event_legal(self, cuuid, euuid, event_data):
        return True

    def event_execute(self, cuuid, euuid, event_data):
        print event_data


# Create a client instance.
server = NeteriaServer(EchoMiddleware())
server.listen()
print "Server started. Press CTRL+C to quit."

while True:
    time.sleep(1)