Esempio n. 1
0
class AreaCamera(object):
    """
    Base class for displaying maps.  Not really featured, here, you should
    subclass it.
    """

    def __init__(self, area, extent=None, tmxdata=None):
        self.area = area
        self.set_extent(extent)
        self.zoom = 1.0
        self.avatars = []

        # create a renderer for the map
        self.maprender = BufferedTilemapRenderer(tmxdata, self.extent.size)

        self.map_width = tmxdata.tilewidth * tmxdata.width
        self.map_height = tmxdata.tileheight*tmxdata.height
        self.center(self.extent.center)
        self.blank = True

        # load the children
        for child in self.area.getChildren():
            child.load()

        # add the avatars
        for child in self.area.getChildren():
            if isinstance(child, AvatarObject):
                child.avatar.update(0)              # hack to re-init avatar
                self.avatars.append(child.avatar)


    def set_extent(self, extent):
        """
        the camera caches some values related to the extent, so it becomes
        nessessary to call this instead of setting the extent directly.
        """
        self.extent = Rect(extent)
        self.half_width = self.extent.width / 2
        self.half_height = self.extent.height / 2
        self.width  = self.extent.width
        self.height = self.extent.height


    def update(self, time):
        self.maprender.update(None)
        [ a.update(time) for a in self.avatars ]


    def center(self, pos):
        """
        center the camera on a pixel location.
        """

        x, y = self.toSurface(pos)

        if self.map_width > self.width:
            if x < self.half_width:
                x = self.half_width

            elif x > self.map_width - self.half_width - 1:
                x = self.map_width - self.half_width - 1

        else:
            x = self.map_width / 2


        if self.map_height > self.height:
            if y < self.half_height:
                y = self.half_height

            elif y > self.map_height - self.half_height:
                y = self.map_height - self.half_height
        else:
            y = self.map_height / 2

        self.extent.center = (x, y)
        self.maprender.center((x, y))


    def clear(self, surface):
        raise NotImplementedError


    def draw(self, surface, origin=(0,0)):
        avatars = []
        for a in self.avatars:
            aWidth, aHeight = a.get_size()
            d, w, h = a.getSize()
            x, y = self.toSurface(a.getPosition())

            rect = Rect((x-(aWidth-w)/2, y-aHeight+d, aWidth, aHeight))
            if self.extent.colliderect(rect):
                x, y = self.toScreen(a.getPosition())
                x += origin[0]
                y += origin[1]
                rect = Rect((x-(aWidth-w)/2, y-aHeight+d, aWidth, aHeight))
                avatars.append((a, rect))

        onScreen = [ (a.image, r, 2) for a, r in avatars ]
        onScreen.sort(key=screenSorter)

        self.maprender.draw(surface, onScreen, origin)


    def toScreen(self, pos):
        """
        Transform the world to coordinates on the screen
        """

        x = pos[1] * self.zoom - self.extent.left
        y = pos[0] * self.zoom - self.extent.top

        # if there is a z value, just subtract it from y
        try:
            y -= pos[2]
        except:
            pass

        return x, y


    def toSurface(self, pos):
        """ Translate world coordinates to coordinates on the surface """
        return pos[1], pos[0]
Esempio n. 2
0
class LevelCamera(object):
    """
    Base class for displaying maps.  Not really featured, here, you should
    subclass it.
    """

    def __init__(self, area, rect, tmxdata=None):
        rect = Rect(rect)
        self.rect = rect
        self.area = area
        self.set_extent(rect)

        # create a renderer for the map
        self.maprender = BufferedTilemapRenderer(tmxdata, rect)
        self.map_width = tmxdata.tilewidth * tmxdata.width
        self.map_height = tmxdata.tileheight*tmxdata.height
        self.blank = True

        # add the avatars
        #for child in self.area.getChildren():
        ##    if isinstance(child, AvatarObject):
        #        child.avatar.update(0)              # hack to re-init avatar

        self.ao = self.refreshAvatarObjects()
 

    def refreshAvatarObjects(self):
        return [ i for i in self.area.bodies.keys() if hasattr(i, "avatar")]
        

    # HACK
    def getAvatarObjects(self):
        if self.area.changedAvatars:
            self.area.changedAvatars = False
            self.ao = self.refreshAvatarObjects()
        return self.ao


    def set_extent(self, extent):
        """
        the camera caches some values related to the extent, so it becomes
        nessessary to call this instead of setting the extent directly.
        """

        self.extent = Rect(extent)
        self.half_width = self.extent.width / 2
        self.half_height = self.extent.height / 2
        self.width  = self.extent.width
        self.height = self.extent.height
        self.zoom = 1.0


    def update(self, time):
        self.maprender.update(None)
        for ao in self.refreshAvatarObjects():
            if ao: 
                # HACK
                try:
                   ao.avatar.update(time)
                except:
                    pass


    def center(self, pos):
        """
        center the camera on a pixel location.
        """

        x, y = self.toSurface(pos)

        if self.map_width > self.width:
            if x < self.half_width:
                x = self.half_width

            elif x > self.map_width - self.half_width - 1:
                x = self.map_width - self.half_width - 1

        else:
            x = self.map_width / 2


        if self.map_height > self.height:
            if y < self.half_height:
                y = self.half_height

            elif y > self.map_height - self.half_height:
                y = self.map_height - self.half_height
        else:
            y = self.map_height / 2

        self.extent.center = (x, y)
        self.maprender.center((x, y))


    def clear(self, surface):
        raise NotImplementedError


    def draw(self, surface):
        avatarobjects = self.refreshAvatarObjects()

        onScreen = []

        if self.blank:
            self.blank = False
            self.maprender.blank = True

        # quadtree collision testing would be good here
        for a in avatarobjects:
            bbox = self.area.getBBox(a)
            x, y, z, d, w, h = bbox
            x, y = self.toSurface((x, y, z))
            xx, yy = a.avatar.axis
            x += xx
            y += yy + h
            if self.extent.colliderect((x, y, w, h)):
                onScreen.append((a.avatar.image, Rect(self.toScreen((x, y)), (w, h)), 1, a, bbox))

        # should not be sorted every frame
        onScreen.sort(key=screenSorter)

        return self.maprender.draw(surface, onScreen)

        dirty = self.maprender.draw(surface, onScreen)

        clip = surface.get_clip()
        surface.set_clip(self.rect)

        for (x, y, w, h) in self.area.geoRect:
            draw.rect(surface, (128,128,255), \
            (self.toScreen(self.toSurface((0, x, y))), (w, h)), 1)

        for i, r, l, a in onScreen:
            x, y, z, d, w, h, = self.area.getBBox(a)
            x, y = self.toScreen(self.toSurface((x, y, z+h)))
            draw.rect(surface, (255,128,128), (x, y, w, h), 1)

        surface.set_clip(clip)
        return dirty


    def toScreen(self, (x, y)):
        """
        Transform the world to coordinates on the screen
        """

        return (x * self.zoom - self.extent.left + self.rect.left,
                y * self.zoom - self.extent.top + self.rect.top)
Esempio n. 3
0
class OverworldState(GameState):
    """
    State for looking at the world map.  Tools can be used to check
    various aspects of it.  Kinda like...simcity.
    """

    def __init__(self, map_name=None):
        GameState.__init__(self)
        self.map_name = map_name


    def activate(self):
        GameState.activate(self)

        w, h = sd.get_size()

        self.cr_open = scale(res.loadImage("open.png", 0, 1), (20,30))
        self.cr_grasp = scale(res.loadImage("grasp.png", 0, 1), (20, 25))
        self.cr_arrow = res.loadImage("next_arrow.png", 0, 1)

        self.cr = KeyCursor(self.cr_open)
        self.cr_state = HAND_OPEN

        self.cr_bounds = Rect(0,0,w,h).inflate(-w*.2, -h*.2)
        self.cr_bounds.height -= 30
        self.cr_bounds.width -= 20
        self.cr_pos = list(self.cr_bounds.center)
        self.cr_speed = 0
        self.cr.enable()

        self.map_pos = self.cr_pos[:]

        path = res.mapPath("overworld3.tmx")

        self.tilemap = BufferedTilemapRenderer(path,
                       (w,h), force_colorkey=(128,0,63))

        self.camera = OverworldCamera([], self.tilemap, ((0,0), (w,h)))
        self.camera.center(self.cr_pos)
        self.tilemap.redraw()


        self.cleared = 0


    def deactivate(self):
        GameState.deactivate(self)
    

    def draw(self, surface):
        if self.cleared == 0:
            surface.fill((0,64,128))
            self.cleared = 1

        if self.cr_pos[0] < self.cr_bounds.left:
            self.map_pos[0] -= self.cr_bounds.left - self.cr_pos[0]
            self.cr_pos[0] = self.cr_bounds.left
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(self.cr_arrow)
                self.cr_state = HAND_ARROW

        elif self.cr_pos[0] > self.cr_bounds.right:
            self.map_pos[0] -= self.cr_bounds.right - self.cr_pos[0]
            self.cr_pos[0] = self.cr_bounds.right
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(self.cr_arrow)
                self.cr_state = HAND_ARROW
 
        if self.cr_pos[1] < self.cr_bounds.top:
            self.map_pos[1] -= self.cr_bounds.top - self.cr_pos[1]
            self.cr_pos[1] = self.cr_bounds.top
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(rotate(self.cr_arrow, 90))
                self.cr_state = HAND_ARROW

        elif self.cr_pos[1] > self.cr_bounds.bottom:
            self.map_pos[1] -= self.cr_bounds.bottom - self.cr_pos[1]
            self.cr_pos[1] = self.cr_bounds.bottom
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(rotate(self.cr_arrow, -90))
                self.cr_state = HAND_ARROW

        self.cr.setPos(self.cr_pos)
        self.tilemap.center(self.map_pos)
        self.camera.draw(surface)
        self.cr.draw(surface)


    def grasp(self):
        self.cr_state = HAND_CLOSED
        self.cr.setImage(self.cr_grasp)

    
    def ungrasp(self):
        self.cr_state = HAND_OPEN
        self.cr.setImage(self.cr_open)


    def update(self, time):
        self.camera.update(time)


    def handle_commandlist(self, cmdlist):
        buttonup = 0
        x = 0
        y = 0

        for cls, cmd, arg in cmdlist:
            if arg == BUTTONUP:
                if cmd == P1_ACTION1:
                    self.ungrasp()
 
                elif (cmd == P1_UP) or (cmd == P1_DOWN) \
                or (cmd == P1_LEFT) or (cmd == P1_RIGHT):
                    buttonup = 1  

            elif arg:
                if cmd == P1_UP:        y = -1
                elif cmd == P1_DOWN:    y = 1
                elif cmd == P1_LEFT:    x = -1
                elif cmd == P1_RIGHT:   x = 1
                elif (cmd == P1_ACTION1) and (self.cr_state == HAND_OPEN):
                    self.grasp()

        if (not x == 0) and (not y == 0):
            x *= movt_fix
            y *= movt_fix

        if (not x == 0) or (not y == 0):
            self.cr_speed += .8
            if self.cr_speed > 16: self.cr_speed = 16
            self.cr_pos[0] += x*self.cr_speed
            self.cr_pos[1] += y*self.cr_speed

        elif buttonup:
            self.cr_speed = 0
            if (x==y==0) or (self.cr_state == HAND_ARROW):
                self.cr_state = HAND_OPEN
                self.cr.setImage(self.cr_open)
Esempio n. 4
0
class OverworldState(GameState):
    """
    State for looking at the world map.  Tools can be used to check
    various aspects of it.  Kinda like...simcity.
    """
    def __init__(self, map_name=None):
        GameState.__init__(self)
        self.map_name = map_name

    def activate(self):
        GameState.activate(self)

        w, h = sd.get_size()

        self.cr_open = scale(res.loadImage("open.png", 0, 1), (20, 30))
        self.cr_grasp = scale(res.loadImage("grasp.png", 0, 1), (20, 25))
        self.cr_arrow = res.loadImage("next_arrow.png", 0, 1)

        self.cr = KeyCursor(self.cr_open)
        self.cr_state = HAND_OPEN

        self.cr_bounds = Rect(0, 0, w, h).inflate(-w * .2, -h * .2)
        self.cr_bounds.height -= 30
        self.cr_bounds.width -= 20
        self.cr_pos = list(self.cr_bounds.center)
        self.cr_speed = 0
        self.cr.enable()

        self.map_pos = self.cr_pos[:]

        path = res.mapPath("overworld3.tmx")

        self.tilemap = BufferedTilemapRenderer(path, (w, h),
                                               force_colorkey=(128, 0, 63))

        self.camera = OverworldCamera([], self.tilemap, ((0, 0), (w, h)))
        self.camera.center(self.cr_pos)
        self.tilemap.redraw()

        self.cleared = 0

    def deactivate(self):
        GameState.deactivate(self)

    def draw(self, surface):
        if self.cleared == 0:
            surface.fill((0, 64, 128))
            self.cleared = 1

        if self.cr_pos[0] < self.cr_bounds.left:
            self.map_pos[0] -= self.cr_bounds.left - self.cr_pos[0]
            self.cr_pos[0] = self.cr_bounds.left
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(self.cr_arrow)
                self.cr_state = HAND_ARROW

        elif self.cr_pos[0] > self.cr_bounds.right:
            self.map_pos[0] -= self.cr_bounds.right - self.cr_pos[0]
            self.cr_pos[0] = self.cr_bounds.right
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(self.cr_arrow)
                self.cr_state = HAND_ARROW

        if self.cr_pos[1] < self.cr_bounds.top:
            self.map_pos[1] -= self.cr_bounds.top - self.cr_pos[1]
            self.cr_pos[1] = self.cr_bounds.top
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(rotate(self.cr_arrow, 90))
                self.cr_state = HAND_ARROW

        elif self.cr_pos[1] > self.cr_bounds.bottom:
            self.map_pos[1] -= self.cr_bounds.bottom - self.cr_pos[1]
            self.cr_pos[1] = self.cr_bounds.bottom
            if self.cr_state == HAND_OPEN:
                self.cr.setImage(rotate(self.cr_arrow, -90))
                self.cr_state = HAND_ARROW

        self.cr.setPos(self.cr_pos)
        self.tilemap.center(self.map_pos)
        self.camera.draw(surface)
        self.cr.draw(surface)

    def grasp(self):
        self.cr_state = HAND_CLOSED
        self.cr.setImage(self.cr_grasp)

    def ungrasp(self):
        self.cr_state = HAND_OPEN
        self.cr.setImage(self.cr_open)

    def update(self, time):
        self.camera.update(time)

    def handle_commandlist(self, cmdlist):
        buttonup = 0
        x = 0
        y = 0

        for cls, cmd, arg in cmdlist:
            if arg == BUTTONUP:
                if cmd == P1_ACTION1:
                    self.ungrasp()

                elif (cmd == P1_UP) or (cmd == P1_DOWN) \
                or (cmd == P1_LEFT) or (cmd == P1_RIGHT):
                    buttonup = 1

            elif arg:
                if cmd == P1_UP: y = -1
                elif cmd == P1_DOWN: y = 1
                elif cmd == P1_LEFT: x = -1
                elif cmd == P1_RIGHT: x = 1
                elif (cmd == P1_ACTION1) and (self.cr_state == HAND_OPEN):
                    self.grasp()

        if (not x == 0) and (not y == 0):
            x *= movt_fix
            y *= movt_fix

        if (not x == 0) or (not y == 0):
            self.cr_speed += .8
            if self.cr_speed > 16: self.cr_speed = 16
            self.cr_pos[0] += x * self.cr_speed
            self.cr_pos[1] += y * self.cr_speed

        elif buttonup:
            self.cr_speed = 0
            if (x == y == 0) or (self.cr_state == HAND_ARROW):
                self.cr_state = HAND_OPEN
                self.cr.setImage(self.cr_open)