Exemplo n.º 1
0
Arquivo: lesson1.py Projeto: msarch/py
    def __init__(self, game):
        # While the game needs to work independently of the client the client
        # can't work independently of the game. The client will be sending
        # input to the game as well as looking up different elements (such as
        # all the blocks so we can draw them and tell the game when we click on
        # one).
        self.game = game

        # Setup our pyglet window.
        self.window = Window(width=self.game.size_xy[0]*20,
                height=self.game.size_xy[1]*20+50)
        self.window.set_caption("Mines")
        self.window.on_close = sys.exit
        # The default pyglet OpenGL display is setup a bit different than how
        # rabbyt would like, thus rabbyt.set_default_attribs
        rabbyt.set_default_attribs()

        # Using pyglet for input is really easy. When you get further down
        # you'll see GameContorl inherits from EventDispatcher. That's how
        # window.push_handlers does the magic as we'll see further down.
        self.ctrl = GameContorl(self)
        self.window.push_handlers(self.ctrl)


        # Here we have some sprites we are going to use for the client. For
        # bigger games I think it's better to separate stuff like this out;
        # but this is quite small and not an issue.
        self.smile_face = rabbyt.Sprite("data/smile.png")
        self.smile_face.x = self.window.width/2
        self.smile_face.y = self.window.height-25

        self.dead_face = rabbyt.Sprite("data/smile_dead.png")
        self.dead_face.xy = self.smile_face.xy

        self.won_face = rabbyt.Sprite("data/smile_won.png")
        self.won_face.xy = self.smile_face.xy
        # That sprite stuff was pretty self explanatory. It is also very basic.
        # I'm not going to be going into much depth with rabbyt in these
        # tutorials so you may want to check out the rabbyt documentation from
        # http://matthewmarshall.org/projects/rabbyt/
        # Very cool and elegant stuff there. Check it out!

        self.clock = Clock()
        self.clock.set_fps_limit(20)
        self.window.push_handlers(self.clock)
        self.time = 0
        self.clock.schedule(self._add_time)

        self.setup()
Exemplo n.º 2
0
    def __event_loop__(self, **win_args):
        """
        The event loop thread function. Do not override or call
        directly (it is called by __init__).
        """
        gl_lock.acquire()
        try:
            try:
                super().__init__(**self.win_args)
                self.switch_to()
                self.setup()
            except Exception as e:
                print("Window initialization failed: %s" % (str(e)))
                self.has_exit = True
        finally:
            gl_lock.release()

        clock = Clock()
        clock.fps_limit = self.fps_limit
        while not self.has_exit:
            dt = clock.tick()
            gl_lock.acquire()
            try:
                try:
                    self.switch_to()
                    self.dispatch_events()
                    self.clear()
                    self.update(dt)
                    self.draw()
                    self.flip()
                except Exception as e:
                    print("Uncaught exception in event loop: %s" % str(e))
                    self.has_exit = True
            finally:
                gl_lock.release()
        super().close()
Exemplo n.º 3
0
    def __event_loop__(self, **win_args):
        """
        The event loop thread function. Do not override or call
        directly (it is called by __init__).
        """
        gl_lock.acquire()
        try:
            try:
                super(ManagedWindow, self).__init__(**self.win_args)
                self.switch_to()
                self.setup()
            except Exception, e:
                print "Window initialization failed: %s" % (str(e))
                self.has_exit = True
        finally:
            gl_lock.release()

        clock = Clock()
        clock.set_fps_limit(self.fps_limit)
        while not self.has_exit:
            dt = clock.tick()
            gl_lock.acquire()
            try:
                try:
                    self.switch_to()
                    self.dispatch_events()
                    self.clear()
                    self.update(dt)
                    self.draw()
                    self.flip()
                except Exception, e:
                    print "Uncaught exception in event loop: %s" % str(e)
                    self.has_exit = True
            finally:
                gl_lock.release()
        super(ManagedWindow, self).close()
Exemplo n.º 4
0
    def __init__(self, app):
		self.app = app
		self.window = Window(	width=self.app.size[0],
		        				height=self.app.size[1], 
		        				style='dialog',
		        				resizable=False )

		self.window.set_caption("ASTAR MAZE")
		self.window.on_close = sys.exit
		self.ctrl = InputHandler(self)
		self.window.push_handlers(self.ctrl)

		self.clock = Clock()
		self.clock.set_fps_limit(30)
		self.window.push_handlers(self.clock)

		self.grid = ClientGrid( self.app.grid )

		# S q u a r e s
		self.entities = {}
		self.setup()
Exemplo n.º 5
0
Arquivo: lesson1.py Projeto: msarch/py
class Client:
    """
    While we aren't networking this game it's better to learn this structure now
    rather than later. Even if you never plan on learning how to network your
    games this is still a very good architecture to use.

    This Client class should be considered completely separate from the Game. It
    is just a way of interacting with the game. The game should not depend on
    anything in this class. Working like this will help you keep your code much
    cleaner and, as stated before, networkable. You could also make multiple
    clients using different technologies. In our case we are using pyglet and
    rabbyt libraries, but it wouldn't be difficult to make a client using pygame
    or even just the consol (for a text mode).
    """
    def __init__(self, game):
        # While the game needs to work independently of the client the client
        # can't work independently of the game. The client will be sending
        # input to the game as well as looking up different elements (such as
        # all the blocks so we can draw them and tell the game when we click on
        # one).
        self.game = game

        # Setup our pyglet window.
        self.window = Window(width=self.game.size_xy[0]*20,
                height=self.game.size_xy[1]*20+50)
        self.window.set_caption("Mines")
        self.window.on_close = sys.exit
        # The default pyglet OpenGL display is setup a bit different than how
        # rabbyt would like, thus rabbyt.set_default_attribs
        rabbyt.set_default_attribs()

        # Using pyglet for input is really easy. When you get further down
        # you'll see GameContorl inherits from EventDispatcher. That's how
        # window.push_handlers does the magic as we'll see further down.
        self.ctrl = GameContorl(self)
        self.window.push_handlers(self.ctrl)


        # Here we have some sprites we are going to use for the client. For
        # bigger games I think it's better to separate stuff like this out;
        # but this is quite small and not an issue.
        self.smile_face = rabbyt.Sprite("data/smile.png")
        self.smile_face.x = self.window.width/2
        self.smile_face.y = self.window.height-25

        self.dead_face = rabbyt.Sprite("data/smile_dead.png")
        self.dead_face.xy = self.smile_face.xy

        self.won_face = rabbyt.Sprite("data/smile_won.png")
        self.won_face.xy = self.smile_face.xy
        # That sprite stuff was pretty self explanatory. It is also very basic.
        # I'm not going to be going into much depth with rabbyt in these
        # tutorials so you may want to check out the rabbyt documentation from
        # http://matthewmarshall.org/projects/rabbyt/
        # Very cool and elegant stuff there. Check it out!

        self.clock = Clock()
        self.clock.set_fps_limit(20)
        self.window.push_handlers(self.clock)
        self.time = 0
        self.clock.schedule(self._add_time)

        self.setup()


    def setup(self):
        """
        Just like the setup in the Game class this one fills out the block data.
        But wait, why do we have to do this again? Remeber how in the GameBlock
        we only had stuff related to the game engine; no display stuff? Well,
        we need display stuff for the client - that's why we have ClientBlock!
        As you'll see soon the ClientBlock sorta wraps the GameBlock to provide
        the graphical stuff we need.
        """
        self.blocks = {}
        for key,b in self.game.blocks.items():
            self.blocks[key] = ClientBlock(self, b)


    def _add_time(self, dt):
        """
        This is kept track of so we can pass it onto rabbyt (so animation works)
        """
        self.time += dt


    def loop(self):
        """
        And here is our main game loop! In case you are new to game programming
        this is what is called every frame. This is where we will handle the
        display and stuff.
        """
        # clock.tick is used for keeping track of time and limiting the frame
        # rate.
        self.clock.tick()
        self.window.dispatch_events()
        # And this is where that mysterious "time" comes in. This way rabbyt
        # knows how much time has passed and can do the awesome animations.
        rabbyt.set_time(self.time)

        # If you are new to this sort of thing rabbyt.clear clears the screen
        # (erases what was drawn last loop). We pass white as the color that we
        # want to clear it with.
        rabbyt.clear((1,1,1,1))

        # And now we draw our blocks and smile face.
        for b in self.blocks.values():
            b.draw()

        if self.game.gameover == True:
            if self.game.won == False:
                self.dead_face.render()
            else:
                self.won_face.render()
        else:
            self.smile_face.render()

        # This draws the buffer onto the screen. Without this we would be
        # staring at a blank screen.
        self.window.flip()


    def press_block(self, block):
        """
        This is called by the Control as we will see later. Pretty simple and
        even unneeded. But this is where you could add cool effects for when
        you click on a block if you wannted to. (That's the reasion I have it)
        """
        self.game.press_block(block.gameblock)


    def retry(self):
        """
        Re-sets up the game.
        """
        self.game.setup()
        self.setup()
Exemplo n.º 6
0
class Client( object ):
    def __init__(self, app):
		self.app = app
		self.window = Window(	width=self.app.size[0],
		        				height=self.app.size[1], 
		        				style='dialog',
		        				resizable=False )

		self.window.set_caption("ASTAR MAZE")
		self.window.on_close = sys.exit
		self.ctrl = InputHandler(self)
		self.window.push_handlers(self.ctrl)

		self.clock = Clock()
		self.clock.set_fps_limit(30)
		self.window.push_handlers(self.clock)

		self.grid = ClientGrid( self.app.grid )

		# S q u a r e s
		self.entities = {}
		self.setup()


    def setup(self):
		glClearColor( .113, .121, .1289, 1 )
		glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
		glDisable( GL_LIGHTING )
		glCullFace( GL_BACK )
		glDisable( GL_DEPTH_TEST )

		self.runner = None
		self.goal = None
		self.isSearching = False
		self.found = False
		self.solution = []
		self.prev = None

		self.entitiesBatch = pyglet.graphics.Batch()
		group = ClientGroup()
		for k,v in self.app.squares.iteritems():
			verts = self.entitiesBatch.add( 4, GL_QUADS, group, 'v2i/static', 'c4B/dynamic' )
			verts.vertices 		= v.vertices['positions']
			verts.colors 		= v.vertices['colors']
			self.entities[k] 	= ClientSquare( v, verts )


    def draw(self):
		self.grid.draw()
		self.entitiesBatch.draw()
		if self.found: 
			curr = None
			if self.prev:
				self.setVisited( self.entities[self.prev] )
			if len(self.solution):
				curr = self.solution.pop()
				self.entities[curr].update( SquareType.RUNNER )
				self.prev = curr


    def update(self):
        self.clock.tick()
        self.window.dispatch_events()
        self.window.clear()
        self.draw()
        self.window.flip()


    def reset(self):
    	self.app.setup()
    	self.setup()


    def astar(self):
		startState = ASState( self.runner.pos, self.goal.pos, self )
		nodesGenerated = 1
		frontier = Heap()
		expanded = set()
		frontier.push( 0, ASNode( startState ) )

		while len(frontier):
			n = frontier.pop()

			if n.state.isGoal():
				self.solution = n.execute()
				print "%d node(s) generated.\n" % nodesGenerated
				return True

			successors = n.state.expand()
			for succ in successors:
				if succ['successor'] not in expanded:
					nodesGenerated = nodesGenerated + 1
					nprime = ASNode( succ['successor'], succ['action'], n )
					frontier.push( nprime.hCost, nprime )
					expanded.add( succ['successor'] )
		return False


    def search(self):
    	if not self.runner or not self.goal:
    		print "You must select a start and end position on the grid"
    		print "Press 1 and then click a square for start position (in purple)."
    		print "Press 2 and then click a square for end position (in red)."
    	else:
    		self.isSearching = True
    		print "\nRUNNING A*\n"
    		print "Goal position:   \t",		self.goal.pos
    		print "Start position:  \t",		self.runner.pos
    		print "Using heuristic: \t%s\n" 	% SETTINGS['HEURISTIC']

    		if self.astar():
    			self.found = True
    		else:
    			print "Failed to solve maze."
    		self.isSearching = False


    def pressSquare( self, sqr ):
		sqr.update( SquareType.BLOCKED )


    def resetSquare( self, sqr ):
		sqr.update( SquareType.EMPTY )

    
    def setStart( self, sqr ):
    	if not self.runner:
    		sqr.update( SquareType.START )
    		self.runner = sqr


    def setEnd( self, sqr ):
    	if not self.goal:
    		sqr.update( SquareType.GOAL )
    		self.goal = sqr

    def setVisited( self, sqr ):
    	sqr.update( SquareType.TRAIL )
Exemplo n.º 7
0
 def _init_clock(self, command):
     # print 'Got clock'
     self._clock = Clock()
     self._clock.set_fps_limit(command[1])
Exemplo n.º 8
0
class Pen(object):
    """'Worker' process. Does all the processing for moving objects, collision, etc.
    """
    _frame = 0

    def __init__(self):
        self._ents = {}
        self._nokey_ents = {}
        self._contexts = {}
        self._contexts['start'] = {}
        self._current_context = 'start'
        self._clock = None
        self._running = True
        self._sleep_time = None
        self._event_handlers = {
            'KILL': self._kill,
            'KEYEVENT': self._handle_key,
            'CLOCK': self._init_clock
        }
        self._well_handlers = {
            'CREATE': self._well_create,
            'DESTROY': self._well_destroy,
            'TEXT': self._well_text
        }

    def __call__(self, pen, paper):
        self.dip(pen, paper)

    def _listen_to_paper(self):
        while self._paper_ear.poll():
            yield self._paper_ear.recv()

    def _tell_paper(self, ink_blob):
        self._pen_mouth.send(ink_blob)

    def _init_clock(self, command):
        # print 'Got clock'
        self._clock = Clock()
        self._clock.set_fps_limit(command[1])

    def _run_initial(self):
        for func in _init_funcs:
            for msg in func():
                if hasattr(msg, 'type'):
                    remove_later = []
                    create_later = []
                    self._handle_returned_msgs([msg], None, remove_later, create_later)
                    self._handle_delayed_ents(create_later, remove_later)
                else:
                    self._tell_paper(msg)

    def _kill(self, command=None):
        print 'Killing Pen process'
        # if None in self._contexts:
        #     print 'Something is/was in "None" context.'
        #     if len(self._contexts[None]) > 1:
        #         print 'Stuff in "None" context: %s' % str(self._contexts[None])
        self._pen_mouth.close()
        self._paper_ear.close()
        exit(0)

    def _add_ent(self, ent):
        self._ents[ent.uid] = ent
        if ent.context not in self._contexts:
            self._contexts[ent.context] = {}
        self._contexts[ent.context][ent.uid] = ent

    def _delete_ent(self, ent):
        if ent.uid in self._ents:
            del self._ents[ent.uid]
        else:
            del self._nokey_ents[ent.uid]
            del self._contexts[ent.context][ent.uid]

    def _handle_delayed_ents(self, created, removed):
        for ent in created:
            self._add_ent(ent)
        for ent in removed:
            self._delete_ent(ent)

    def _well_create(self, msg, ent, remove_later, create_later):
        if msg.constructor is None:
            self._tell_paper(Nibs.Create(msg.x, msg.y, msg.assets,
                msg.width, msg.height, msg.level, ent.uid))
        elif msg.x == None and msg.y == None and msg.assets == None:
            uid = Nibs.next_uid()
            new_ent = msg.constructor(uid, msg.context)
            new_ent.init(**msg.extra)
            create_later.append(new_ent)
        else:
            uid = Nibs.next_uid()
            child = msg.constructor(uid, msg.x, msg.y, msg.context)
            try:
                self._handle_returned_msgs(child.init(msg.assets, **msg.extra),
                    child, remove_later, create_later)
            except TypeError:
                # print 'Needed width/height'
                self._handle_returned_msgs(child.init(msg.assets, msg.width, msg.height, **msg.extra),
                    child, remove_later, create_later)
            create_later.append(child)
            if msg.child:
                ent.give_child(child)

    def _well_destroy(self, msg, ent, remove_later, create_later):
        if msg.uid in self._ents:
            to_destroy = self._ents[msg.uid]
        else:
            to_destroy = self._nokey_ents[msg.uid]
        children = to_destroy.get_children()
        remove_later.append(to_destroy)
        remove_later += children
        self._tell_paper(Nibs.Destroy(msg.uid))
        for child in children:
            self._tell_paper(Nibs.Destroy(child.uid))

    def _well_text(self, msg, ent, remove_later, create_later):
        command = Nibs.Text(msg.x, msg.y, msg.chars, msg.font, msg.font_size, msg.level)
        child = msg.constructor(command[1], msg.x, msg.y, msg.context)
        self._tell_paper(command)
        self._handle_returned_msgs(child.init(msg.chars, **msg.extra), child, remove_later, create_later)
        create_later.append(child)
        if msg.child:
            ent.give_child(child)

    def _handle_well_msg(self, msg, ent, remove_later, create_later):
        try:
            self._well_handlers[msg.type](msg, ent, remove_later, create_later)
        except KeyError:
            print "Don't know how to handle: %s" % str(msg)

    def _move_children(self, msg):
        ent = self._ents[msg[1]]
        for child in ent._children:
            child._x += msg[2]
            child._y += msg[3]

    def _handle_returned_msgs(self, msgs, ent, remove_later, create_later):
        if msgs is None:
            return
        if type(msgs) == list:
            for msg in msgs:
                if hasattr(msg, 'type'):
                    self._handle_well_msg(msg, ent, remove_later, create_later)
                elif type(msg) == tuple:
                    if msgs[0] == Nibs.MOVE_KEY:
                        self._move_children(msg)
                    self._tell_paper(msg)
                else:
                    print "Don't know how to handle: %s" % str(msg)
        else:
            if msgs[0] == Nibs.MOVE_KEY:
                self._move_children(msgs)
            self._tell_paper(msgs)

    def _get_key_events(self, command):
        remove_later = []
        for uid, ent in self._ents.iteritems():
            ret = (None, False)
            try:
                if command[2]:
                    ret = (ent, ent.on_key_press(command))
                else:
                    ret = (ent, ent.on_key_release(command))
            except AttributeError:
                self._nokey_ents[ent.uid] = ent
                remove_later.append(ent)
            if type(ret[1]) == bool:
                if ret[1]:
                    print 1, ret
                    break
                else:
                    continue
            else:
                print 2, ret
                break
        self._handle_delayed_ents([], remove_later)
        del remove_later
        return ret

    def _handle_key_events(self, ent, events):
        if type(events) != bool:
            remove_later = []
            create_later = []
            self._handle_returned_msgs(events, ent, remove_later, create_later)
            self._handle_delayed_ents(create_later, remove_later)
            del remove_later
            del create_later

    def _handle_key(self, command):
        command = command[1:]
        # print 'Key event - code=%s, string=%s, pressed=%s, modifers=%s' % command
        self._handle_key_events(*self._get_key_events(command))

    def _tick_current_ents(self, dt):
        handle_msgs = self._handle_returned_msgs
        remove_later = []
        create_later = []
        # Handle the normal entities.
        for uid, ent in self._ents.iteritems():
            event = ent.tick(dt)
            handle_msgs(event, ent, remove_later, create_later)
        # Handle the entities that have been discovered to not be able to handle key events.
        for uid, ent in self._nokey_ents.iteritems():
            event = ent.tick(dt)
            handle_msgs(event, ent, remove_later, create_later)
        self._handle_delayed_ents(create_later, remove_later)

    def _run_loop(self):
        # Make everything local so that no global lookups occur.
        clock_func = self._clock.update_time
        listen_func = self._listen_to_paper
        handlers = self._event_handlers
        sleep_func = self._clock._limit
        while True:
            dt = clock_func()
            for event in listen_func():
                handlers[event[0]](event)
            self._tick_current_ents(dt)
            Pen._frame += 1
            sleep_func()

    def dip(self, pen, paper):
        """Tells the Pen to start processing movement, collision, etc.
        """
        to_close, self._pen_mouth = pen
        to_close.close()
        self._paper_ear, to_close = paper
        to_close.close()

        random.seed()
        while self._clock is None:
            for event in self._listen_to_paper():
                if event[0] == 'CLOCK':
                    self._init_clock(event)
                    break
            time.sleep(0.01)
        self._run_initial()
        self._tell_paper(Nibs.EndInit())
        try:
            self._run_loop()
        except EOFError:
            self._kill()
        except IOError:
            self._kill()
        except OSError:
            self._kill()