Exemple #1
0
    def _renderItemsIcons(self):

        self.iconsNode.node().removeAllChildren()
        for icon in self.itemIcons:
            icon.destroy()
        self.itemIcons = []

        startItem = 0
        endItem = self.inventory.getSlotsCount()
        if self.itemsRange is not None:
            startItem = self.itemsRange[0]
            endItem = self.itemsRange[1]

        for i in xrange(endItem - startItem):
            itemNum = startItem + i
            s = self.inventory.getSlotByNum(itemNum)
            if not s.isFree():
                # get slot position and size in aspect2d space
                p, sz = self.slotsLayout.getRelativeSlotPosSize(s.getNum())
                itemImage = s.getItem().getImage()
                imagePath = self.game.getResources().getResourceFullPath(
                    PanoConstants.RES_TYPE_TEXTURES, itemImage)
                iconNode = OnscreenImage(parent=self.iconsNode,
                                         image=imagePath,
                                         pos=(p[0] + sz[0] / 2.0, 0.0,
                                              p[1] + sz[1] / 2.0),
                                         scale=0.2)
                iconNode.setTransparency(TransparencyAttrib.MAlpha)
                iconNode.setBin("fixed",
                                PanoConstants.RENDER_ORDER_INVENTORY_ITEMS)
                self.itemIcons.append(iconNode)
class SplashCard(object):
    '''this class shows up a splash message'''
    #------------------------------------------------------------
    #
    def __init__(self, image, backgroundColor):
        self.loadingimage = OnscreenImage(image, color=(1, 1, 1, 1), scale=.5, parent=aspect2d)
        self.loadingimage.setTransparency(1)
        # this image will be on top of all therefore we use setBin 'fixed' and with the higher sort value
        self.loadingimage.setBin("fixed", 20)

        self.curtain = OnscreenImage('textures/curtain.png', parent=render2d, color=backgroundColor)
        self.curtain.setTransparency(1)
        # this is to set it below the loading panel
        self.curtain.setBin("fixed", 10)

        # the loading panel faders
        self.loadingOut = self.loadingimage.colorInterval(1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1))
        # the black curtain faders
        self.openCurtain = self.curtain.colorScaleInterval(1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1))
        for i in range(4):
            base.graphicsEngine.renderFrame()
    #------------------------------------------------------------
    #
    def destroy(self):
        Sequence(self.loadingOut, self.openCurtain).start()
        #Sequence(self.openCurtain).start()
        #self.loadingimage.destroy()
        #self.curtain.destroy()
Exemple #3
0
class ItemIcon():
    
    def __init__(self, itemName, parentNode):
        print 'itemicon', itemName, parentNode
        self.parentNode = parentNode    # The node of its parent (e.g. the inventory)
        self.itemName = itemName        # The filename of the icon
        self.image = None               # The actual icon
        #self.iconNode = aspect2d.attachNewNode('iconnode')
        
        self.LoadContent()
        
    def LoadContent(self):
        self.itemImage = OnscreenImage(image = "Assets/Images/Items/%s.png" % (self.itemName))
        self.itemImage.setScale((self.itemImage.getTexture().getOrigFileXSize() / 1024.0, 1, self.itemImage.getTexture().getOrigFileYSize() / 1024.0))
        self.itemImage.setTransparency(TransparencyAttrib.MAlpha)
        self.itemImage.reparentTo(self.parentNode)
        
    def setBin(self, binType, value):
        print 'set bin', binType, value
        self.itemImage.setBin(binType, value)
        
    def SetPos(self, pos):
        self.itemImage.setPos(pos)
        
    def Destroy(self):
        self.itemImage.destroy()
Exemple #4
0
class SplashCard(object):
    '''this class shows up a splash message'''

    #------------------------------------------------------------
    #
    def __init__(self, image, backgroundColor):
        self.loadingimage = OnscreenImage(image,
                                          color=(1, 1, 1, 1),
                                          scale=.5,
                                          parent=aspect2d)
        self.loadingimage.setTransparency(1)
        # this image will be on top of all therefore we use setBin 'fixed' and with the higher sort value
        self.loadingimage.setBin("fixed", 20)

        self.curtain = OnscreenImage('textures/curtain.png',
                                     parent=render2d,
                                     color=backgroundColor)
        self.curtain.setTransparency(1)
        # this is to set it below the loading panel
        self.curtain.setBin("fixed", 10)

        # the loading panel faders
        self.loadingOut = self.loadingimage.colorInterval(
            1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1))
        # the black curtain faders
        self.openCurtain = self.curtain.colorScaleInterval(
            1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1))
        for i in range(4):
            base.graphicsEngine.renderFrame()

    #------------------------------------------------------------
    #
    def destroy(self):
        Sequence(self.loadingOut, self.openCurtain).start()
Exemple #5
0
class RankingGui(Gui):
    def __init__(self, mdt, background, font, fg_col):
        Gui.__init__(self, mdt)
        self.ranking_texts = []
        self.background_path = background
        self.font = font
        self.fg_col = fg_col

    def show(self):
        self.background = OnscreenImage(self.background_path,
                                        scale=(1.77778, 1, 1.0))
        self.background.setBin('background', 10)
        items = self.mdt.logic.ranking.items()
        sorted_ranking = reversed(sorted(items, key=lambda el: el[1]))
        font = eng.load_font(self.font)
        self.ranking_texts = []
        for i, (name, score) in enumerate(sorted_ranking):
            txt = OnscreenText('%s %s' % (name, score),
                               pos=(0, .5 - .2 * i),
                               font=font,
                               fg=self.fg_col,
                               scale=.12)
            self.ranking_texts += [txt]

    def hide(self):
        map(lambda wdg: wdg.destroy(), self.ranking_texts + [self.background])

    def destroy(self):
        self.ranking_texts = None
        Gui.destroy(self)
Exemple #6
0
 def LoadContent(self):
     bg = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/background.png', scale = (2, 1, 1))
     bg.setTransparency(TransparencyAttrib.MAlpha)
     bg.reparentTo(self.node)
     bg.setBin('fixed', 1)
     
     title = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/title.png')
     title.setTransparency(TransparencyAttrib.MAlpha)
     title.reparentTo(self.node)
     
     self.spinner = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/loadingSpinner.png', pos = (-0.15, 1, 0.15), scale = 128.0/1024.0)
     self.spinner.setTransparency(TransparencyAttrib.MAlpha)
     self.spinner.reparentTo(base.a2dBottomRight)
     self.spinner.setBin('gui-popup', 0)
     self.spinner.hide()
     
     self.LoadButton('Button_Offline', 'offline', 'offline_over', 0, 0.2, self.OnButtonClicked, ['offline'])
     self.LoadButton('Button_Multiplayer', 'multiplayer', 'multiplayer_over', 0, 0, self.OnButtonClicked, ['multiplayer'])
     self.LoadButton('Button_Options', 'options', 'options_over', 0, -0.2, self.OnButtonClicked, ['options'])
     self.LoadButton('Button_Exit', 'exit', 'exit_over', 0, -0.4, self.OnButtonClicked, ['exit'])
Exemple #7
0
class TuningGui(Gui):
    def __init__(self, mdt, tuninggui_props):
        Gui.__init__(self, mdt)
        self.props = tuninggui_props

    def show(self):
        self.background = OnscreenImage(self.props.background,
                                        scale=(1.77778, 1, 1.0))
        self.background.setBin('background', 10)
        self.buttons = [
            ImageButton(scale=.4,
                        pos=(-1.2, 1, .1),
                        frameColor=(0, 0, 0, 0),
                        image=self.props.tuning_imgs[0],
                        command=self.on_btn,
                        extraArgs=['engine'])
        ]
        self.buttons += [
            ImageButton(scale=.4,
                        pos=(0, 1, .1),
                        frameColor=(0, 0, 0, 0),
                        image=self.props.tuning_imgs[1],
                        command=self.on_btn,
                        extraArgs=['tires'])
        ]
        self.buttons += [
            ImageButton(scale=.4,
                        pos=(1.2, 1, .1),
                        frameColor=(0, 0, 0, 0),
                        image=self.props.tuning_imgs[2],
                        command=self.on_btn,
                        extraArgs=['suspensions'])
        ]

    def on_btn(self, val):
        tun = self.mdt.logic.tunings[self.props.car]
        setattr(tun, val, getattr(tun, val) + 1)
        self.notify('on_tuning_done')

    def hide(self):
        map(lambda wdg: wdg.destroy(), self.buttons + [self.background])
Exemple #8
0
class Cursor:
    def __init__(self, path, scale, hotspot):
        if not path:
            return
        self.__set_standard_curson(False)
        self.cursor_img = OnscreenImage(path)
        self.cursor_img.setTransparency(True)
        self.cursor_img.setScale(scale)
        self.cursor_img.setBin('gui-popup', 50)
        self.hotspot_dx = scale[0] * (1 - 2 * hotspot[0])
        self.hotspot_dy = scale[2] * (1 - 2 * hotspot[1])
        eng.event.attach(self.on_frame)

    def __set_standard_curson(self, show):
        props = WindowProperties()
        props.setCursorHidden(not show)
        base.win.requestProperties(props)

    def show(self):
        self.cursor_img.show()

    def show_standard(self):
        self.__set_standard_curson(True)

    def hide(self):
        self.cursor_img.hide()

    def hide_standard(self):
        self.__set_standard_curson(False)

    def cursor_top(self):
        self.cursor_img.reparent_to(self.cursor_img.get_parent())

    def on_frame(self):
        if base.mouseWatcherNode.hasMouse():
            x = base.mouseWatcherNode.getMouseX()
            y = base.mouseWatcherNode.getMouseY()
            h_x = x * base.getAspectRatio() + self.hotspot_dx
            self.cursor_img.setPos(h_x, 0, y - self.hotspot_dy)
Exemple #9
0
class InventoryView:
    """
    Renders the inventory screen.
    """

    ButtonStateNormal = 1
    ButtonStatePressed = 2
    ButtonStateHover = 3

    POINTER_NAME = "inventory_pointer"
    INVENTORY_SCENE_NODE = "inventory_sceneNode"
    ICONS_NODE = "inventory_icons_node"
    BACKDROP_NODE = "backdrop"
    TEXT_NODE = "item_text"

    def __init__(self, game):
        self.log = logging.getLogger('pano.inventoryView')
        self.game = game
        self.msn = Messenger(
            self
        )  # the messenger is used to broadcast user events related to the interface
        self.inventory = None  # the inventory to render

        self.node = None  # the root scenegraph node for inventory rendering nodes
        self.iconsNode = None  # the parent node for all OnscreenImages that render items' icons
        self.pos = (0.0, 0.0)  # position in absolute screen coordinates
        self.size = (1.0, 1.0)  # size in absolute screen coordinates
        self.textPos = (0.0, 0.0)  # position of the item's description text
        self.textScale = 0.07  # the text scale
        self.opacity = 1.0  # controls the opacity of all rendering elements included in the inventory

        self.backdropImage = None  # the name of the image to use as a backdrop
        self.backdropImageObject = None  # the OnscreenImage object used to render the backdrop
        self.backdropNode = None  # the scenegraph node that parents the backdrop

        self.updateIcons = False  # if True then we need to update the rendering of the items' icons
        self.itemText = None  # the TextNode used to render the text
        self.itemTextNode = None  # nodepath that acts as a parent to the TextNode
        self.fontName = None  # the name of the font to use when rendering items' descriptions
        self.font = None  # the Panda3D font resource
        self.fontColor = (1.0, 1.0, 1.0, 1.0
                          )  # colour of the text for an item's description
        self.fontBgColor = (0.0, 0.0, 0.0, 1.0
                            )  # background colour of the text

        # scrolling and paging buttons are DirectButton instances
        self.nextPageButton = None
        self.prevPageButton = None
        self.scrollNextButton = None
        self.scrollPrevButton = None

        # specifies the range of items to be rendered in the next frame as a list [start_item_index, end_item_index]
        # used for scrolling and paging
        self.itemsRange = None

        # number of items displayed per page
        self.pageSize = 0

        # provides the layout of the slots
        self.slotsLayout = None

        # stores image objects for each item's icon
        self.itemIcons = []

        self.mousePointer = InventoryView.POINTER_NAME

        self.debugLayout = False

    def initialize(self, inventory):
        """
        Initialises the inventory, call this method only once otherwise resources could be leaked
        and rendering artifacts created.
        """
        if self.node is not None:
            self.node.removeNode()
#            self.node.detachNode()

        self.node = aspect2d.attachNewNode(InventoryView.INVENTORY_SCENE_NODE)
        self.iconsNode = self.node.attachNewNode(InventoryView.ICONS_NODE)

        # from here on we just initialize the member fields according to the cvars...
        cfg = self.game.getConfig()
        if not self._validateConfig(cfg):
            self.log.error('Missing or invalid inventory configuration')
            return

        view = self.game.getView()

        if self.backdropImageObject is not None:
            self.backdropImageObject.destroy()
            self.backdropImageObject = None

        self.pos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_POS)
        if self.pos is None:
            self.pos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_REL_POS)
            self.pos = view.relativeToAbsolute(self.pos)

        self.textPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_TEXT_POS)
        if self.textPos is None:
            self.textPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_REL_POS)
            self.textPos = view.relativeToAbsolute(self.textPos)

        self.pos, self.textPos = PandaUtil.convertScreenToAspectCoords(
            [self.pos, self.textPos])

        self.size = cfg.getVec2(PanoConstants.CVAR_INVENTORY_SIZE, (1.0, 1.0))

        self.textScale = cfg.getFloat(PanoConstants.CVAR_INVENTORY_TEXT_SCALE,
                                      0.07)
        self.opacity = cfg.getFloat(PanoConstants.CVAR_INVENTORY_OPACITY)
        self.fontName = cfg.get(PanoConstants.CVAR_INVENTORY_FONT)
        self.fontColor = cfg.getVec4(PanoConstants.CVAR_INVENTORY_FONT_COLOR)
        if self.fontColor is None:
            self.fontColor = (1.0, 1.0, 1.0, 1.0)

        self.fontBgColor = cfg.getVec4(
            PanoConstants.CVAR_INVENTORY_FONT_BG_COLOR)
        if self.fontBgColor is None:
            self.fontBgColor = (0.0, 0.0, 0.0, 0.0)

        self.mousePointer = cfg.get(PanoConstants.CVAR_INVENTORY_POINTER)

        layout = cfg.get(PanoConstants.CVAR_INVENTORY_SLOTS)
        self._parseLayout(layout)

        slotsCount = self.slotsLayout.getNumSlots()
        self.log.debug('Setting slots count to %i' % slotsCount)

        # by default render all items, the controller state can later overridde this
        self.itemsRange = [0, slotsCount]

        if cfg.hasVar(PanoConstants.CVAR_INVENTORY_PAGESIZE):
            self.pageSize = cfg.getInt(PanoConstants.CVAR_INVENTORY_PAGESIZE)
        else:
            self.pageSize = slotsCount

        self.inventory = inventory
        self.inventory.setSlotsCount(slotsCount)

        self.backdropImage = cfg.get(PanoConstants.CVAR_INVENTORY_BACKDROP)
        if self.backdropImage is not None:
            self._createBackdrop(show=False)

        # create the scrolling and paging gui buttons
        self._createButtons(cfg)

        # force an initial rendering of the icons
        self.updateIcons = True

        # start as  hidden
        self.node.hide()

    def update(self, millis):
        """
        Re-renders anything that has updated.        
        """
        if self.isVisible() and self.updateIcons:
            self._renderItemsIcons()
            self.updateIcons = False

    def redraw(self):
        """
        Called to indicate that the underlying inventory has updated its state and now we
        should redraw it.
        """
        self.updateIcons = True

    def show(self):
        """
        Shows the inventory.
        """
        self.node.show()
        if self.nextPageButton:
            self.nextPageButton.show()

        if self.prevPageButton:
            self.prevPageButton.show()

        if self.scrollNextButton:
            self.scrollNextButton.show()

        if self.scrollPrevButton:
            self.scrollPrevButton.show()

        if self.debugLayout:
            self.enableDebugRendering()

    def hide(self):
        """
        Hides the inventory.
        """
        self.node.hide()
        if self.nextPageButton:
            self.nextPageButton.hide()

        if self.prevPageButton:
            self.prevPageButton.hide()

        if self.scrollNextButton:
            self.scrollNextButton.hide()

        if self.scrollPrevButton:
            self.scrollPrevButton.hide()

        if self.debugLayout:
            self.disableDebugRendering()

    def isVisible(self):
        """
        Returns True if the inventory is visible and False if otherwise.
        """
        return (self.node is not None) and (not self.node.isHidden())

    def getMousePointerName(self):
        return self.mousePointer

    def getSlotAtScreenPos(self, x, y):
        return self.slotsLayout.getSlotAtScreenPos(x, y)

    def getBackdropImage(self):
        return self.backdropImage

    def setBackdropImage(self, imageName):
        self.backdropImage = imageName
        self._createBackdrop()

    def getText(self):
        return self.text

    def setText(self, text):
        self.text = text
        self._updateText()

    def clearText(self):
        self.text = ""
        if self.itemTextNode is not None:
            self.itemTextNode.hide()

    def getNode(self):
        return self.node

    def enableDebugRendering(self):
        self.slotsLayout.enableDebugRendering(self.game)
        self.debugLayout = True

    def disableDebugRendering(self):
        self.slotsLayout.disableDebugRendering(self.game)
        self.debugLayout = False

    def _validateConfig(self, config):
        return (config.hasVar(PanoConstants.CVAR_INVENTORY_BACKDROP)
                and (config.hasVar(PanoConstants.CVAR_INVENTORY_POS)
                     or config.hasVar(PanoConstants.CVAR_INVENTORY_REL_POS))
                and (config.hasVar(PanoConstants.CVAR_INVENTORY_TEXT_POS)
                     or config.hasVar(PanoConstants.CVAR_INVENTORY_REL_POS))
                and config.hasVar(PanoConstants.CVAR_INVENTORY_SIZE)
                and config.hasVar(PanoConstants.CVAR_INVENTORY_FONT)
                and config.hasVar(PanoConstants.CVAR_INVENTORY_POINTER)
                and config.hasVar(PanoConstants.CVAR_INVENTORY_SLOTS))

    def _createBackdrop(self, show=True):
        """
        Setups rendering for the inventory's backdrop image.
        The backdrop image is rendered through a OnscreenImage object and is attached under the scenegraph node
        named Inventory.BACKDROP_NODE.
        If the parameter show is True then the backdrop image becomes visible as well, otherwise it is hidden.
        """
        if self.backdropImageObject is not None:
            self.backdropImageObject.destroy()
            self.backdropImageObject = None

        if self.backdropNode is not None:
            self.backdropNode.removeNode()

        imagePath = self.game.getResources().getResourceFullPath(
            PanoConstants.RES_TYPE_TEXTURES, self.backdropImage)

        self.backdropNode = self.node.attachNewNode(
            InventoryView.BACKDROP_NODE)
        self.backdropImageObject = OnscreenImage(parent=self.node,
                                                 image=imagePath,
                                                 pos=(self.pos[0], 0.0,
                                                      self.pos[1]),
                                                 sort=0)

        self.backdropImageObject.setTransparency(TransparencyAttrib.MAlpha)
        self.backdropImageObject.setBin("fixed",
                                        PanoConstants.RENDER_ORDER_INVENTORY)

        if not show:
            self.backdropNode.hide()

    def _updateText(self):
        if self.itemText is not None:
            self.itemText.destroy()
            self.itemText = None

        if self.itemTextNode is None:
            self.itemTextNode = self.node.attachNewNode(self.TEXT_NODE)
            self.itemTextNode.setPos(self.textPos[0], 0.0, self.textPos[1])
        self.itemTextNode.show()

        i18n = self.game.getI18n()
        translated = i18n.translate(self.text)

        localizedFont = i18n.getLocalizedFont(self.fontName)
        fontPath = self.game.getResources().getResourceFullPath(
            PanoConstants.RES_TYPE_FONTS, localizedFont)
        self.font = loader.loadFont(fontPath)

        self.itemText = DirectButton(
            parent=self.itemTextNode,
            text=translated,
            text_font=self.font,
            text_bg=(self.fontBgColor[0], self.fontBgColor[1],
                     self.fontBgColor[2], self.fontBgColor[3]),
            text_fg=(self.fontColor[0], self.fontColor[1], self.fontColor[2],
                     self.fontColor[3]),
            text_scale=self.textScale,
            frameColor=(0, 0, 0, 0),
            text_wordwrap=None,
            text_align=TextNode.ALeft,
            sortOrder=10,
            pressEffect=0)
        self.itemText.setBin("fixed",
                             PanoConstants.RENDER_ORDER_INVENTORY_ITEMS)

    def _parseLayout(self, layoutName):
        layoutName = layoutName.strip()
        if layoutName.startswith('grid'):
            # pos, res, size, offset
            grid_re = re.compile(
                r'grid\(\s*(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+'
            )
            m = grid_re.match(layoutName)
            self.slotsLayout = GridSlotsLayout(
                self.game,
                (int(m.group(1)) + self.pos[0],
                 int(m.group(2)) + self.pos[1]),  # position within inventory
                (int(m.group(3)), int(m.group(4))),  # grid resolution
                (int(m.group(5)), int(m.group(6))),  # slot size
                (int(m.group(7)), int(m.group(8))))  # slots offset
        elif layoutName.starts_with('image'):
            self.slotsLayout = ImageBasedSlotsProvider(layoutName)
        # a default to avoid None
        else:
            self.slotsLayout = GridSlotsLayout(self.game, 100, 100, 5, 5, 50,
                                               50)

    def _renderItemsIcons(self):

        self.iconsNode.node().removeAllChildren()
        for icon in self.itemIcons:
            icon.destroy()
        self.itemIcons = []

        startItem = 0
        endItem = self.inventory.getSlotsCount()
        if self.itemsRange is not None:
            startItem = self.itemsRange[0]
            endItem = self.itemsRange[1]

        for i in xrange(endItem - startItem):
            itemNum = startItem + i
            s = self.inventory.getSlotByNum(itemNum)
            if not s.isFree():
                # get slot position and size in aspect2d space
                p, sz = self.slotsLayout.getRelativeSlotPosSize(s.getNum())
                itemImage = s.getItem().getImage()
                imagePath = self.game.getResources().getResourceFullPath(
                    PanoConstants.RES_TYPE_TEXTURES, itemImage)
                iconNode = OnscreenImage(parent=self.iconsNode,
                                         image=imagePath,
                                         pos=(p[0] + sz[0] / 2.0, 0.0,
                                              p[1] + sz[1] / 2.0),
                                         scale=0.2)
                iconNode.setTransparency(TransparencyAttrib.MAlpha)
                iconNode.setBin("fixed",
                                PanoConstants.RENDER_ORDER_INVENTORY_ITEMS)
                self.itemIcons.append(iconNode)

    def _createButtons(self, cfg):
        '''
        Creates DirectGui elements for displaying the paging and scrolling buttons.
        The sprite names are read from the configuration.
        The create DirectButtons use sprites as images.
        @param cfg: a ConfigVars instance
        '''
        # button to display next page of items
        nxPgBtnSprite = cfg.get(PanoConstants.CVAR_INVENTORY_NEXTPAGE_SPRITE)
        nxPgBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_NEXTPAGE_PRESSED_SPRITE)
        nxPgBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_NEXTPAGE_HOVER_SPRITE)
        nxPgBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_NEXTPAGE_POS)

        # button to display previous page of items
        pvPgBtnSprite = cfg.get(PanoConstants.CVAR_INVENTORY_PREVPAGE_SPRITE)
        pvPgBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_PREVPAGE_PRESSED_SPRITE)
        pvPgBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_PREVPAGE_HOVER_SPRITE)
        pvPgBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_PREVPAGE_POS)

        # button to scroll to next items
        scrNxBtnSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_SPRITE)
        scrNxBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_PRESSED_SPRITE)
        scrNxBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_HOVER_SPRITE)
        scrNxBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_SCROLLNEXT_POS)

        # button to scroll to previous items
        scrPvBtnSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_SPRITE)
        scrPvBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_PRESSED_SPRITE)
        scrPvBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_HOVER_SPRITE)
        scrPvBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_SCROLLPREV_POS)

        sprites = self.game.getView().getSpritesFactory()
        origin = aspect2d.getRelativePoint(screen2d, VBase3(0, 0, 0))

        # for every button define property name, position, callback, list of sprites for normal, pressed and hover state
        pagingButtons = [
            ('nextPageButton', nxPgBtnPos, self._nextPageCallback,
             [(nxPgBtnSprite, 'next_page_sprite'),
              (nxPgBtnPressedSprite, 'next_page_pressed_sprite'),
              (nxPgBtnHoverSprite, 'next_page_hover_sprite')]),
            ('prevPageButton', pvPgBtnPos, self._previousPageCallback,
             [(pvPgBtnSprite, 'previous_page_sprite'),
              (pvPgBtnPressedSprite, 'previous_page_pressed_sprite'),
              (pvPgBtnHoverSprite, 'previous_page_hover_sprite')]),
            ('scrollNextButton', scrNxBtnPos, self._scrollNextCallback,
             [(scrNxBtnSprite, 'scroll_next_sprite'),
              (scrNxBtnPressedSprite, 'scroll_next_pressed_sprite'),
              (scrNxBtnHoverSprite, 'scroll_next_hover_sprite')]),
            ('scrollPrevButton', scrPvBtnPos, self._scrollPreviousCallback,
             [(scrPvBtnSprite, 'scroll_previous_sprite'),
              (scrPvBtnPressedSprite, 'scroll_previous_pressed_sprite'),
              (scrPvBtnHoverSprite, 'scroll_previous_hover_sprite')]),
        ]

        for buttonName, buttonPos, buttonCallback, spritesList in pagingButtons:
            buttonGeoms = [None, None, None, None]
            btnScrBounds = [0, 0, 0]
            i = 0
            for spriteFile, spriteName in spritesList:
                print 'adding sprite %s' % spriteName
                if spriteFile is not None:
                    spr = None
                    if spriteFile.rindex('.') >= 0:
                        ext = spriteFile[spriteFile.rindex('.'):]
                        print ext
                        if ResourcesTypes.isExtensionOfType(
                                ext, PanoConstants.RES_TYPE_IMAGES):
                            spr = Sprite(spriteName)
                            spr.image = spriteFile
                    else:
                        spr = self.game.getResources().loadSprite(spriteFile)

                    if spr:
                        buttonGeoms[i] = sprites.createSprite(spr).nodepath
                        buttonGeoms[i].setScale(1.0)
                        btnScrBounds = aspect2d.getRelativePoint(
                            screen2d, VBase3(spr.width, 1.0,
                                             spr.height)) - origin
                        btnScrBounds[2] *= -1

                i += 1

            if buttonGeoms[0] is not None:
                b = DirectButton(
                    geom=(buttonGeoms[0],
                          buttonGeoms[1] if buttonGeoms[1] else buttonGeoms[0],
                          buttonGeoms[2] if buttonGeoms[2] else buttonGeoms[0],
                          buttonGeoms[3]
                          if buttonGeoms[3] else buttonGeoms[0]),
                    relief=None)
                b['geom_pos'] = (0, 0, 0)
                b.setTransparency(1)

                # if position is omitted from the configuration, put the button on the upper left corner
                if buttonPos is not None:
                    b.setPos(
                        aspect2d.getRelativePoint(
                            screen2d, VBase3(buttonPos[0], 1.0, buttonPos[1])))
                else:
                    b.setPos(origin[0], 1.0, origin[2])

                b.setScale(btnScrBounds[0], 1.0, btnScrBounds[2])
                b.setFrameSize((0, btnScrBounds[0], 1.0, btnScrBounds[2]))
                b['command'] = buttonCallback
                b['extraArgs'] = (self.msn, )
                b.hide()
            else:
                b = None

            setattr(self, buttonName, b)

    def _nextPageCallback(self, messenger):
        '''
        Callback for next page button which only sends the appropriate message.
        '''
        messenger.sendMessage(PanoConstants.EVENT_ITEMS_NEXT_PAGE)

    def _previousPageCallback(self, messenger):
        messenger.sendMessage(PanoConstants.EVENT_ITEMS_PREV_PAGE)

    def _scrollNextCallback(self, messenger):
        messenger.sendMessage(PanoConstants.EVENT_ITEMS_SCROLL_NEXT)

    def _scrollPreviousCallback(self, messenger):
        messenger.sendMessage(PanoConstants.EVENT_ITEMS_SCROLL_PREV)
Exemple #10
0
class MainMenu(DirectObject):
    def __init__(self, skipIntro=False):
        render.show()
        engine.Mouse.showCursor()
        # In case we just got back from the tutorial, which hides everything
        # sometimes.
        engine.renderLit.show()
        self.backgroundSound = audio.FlatSound("menu/background.ogg",
                                               volume=0.3)
        self.backgroundSound.setVolume(0)
        self.backgroundSound.setLoop(True)
        self.clickSound = audio.FlatSound("menu/click.ogg", volume=0.3)
        self.active = True
        self.accept("escape", self.escape)
        self.accept("mouse1", self.click)
        self.cameraDistance = 20

        self.globe = engine.loadModel("menu/Globe")
        self.globe.reparentTo(render)
        self.globe.setTransparency(TransparencyAttrib.MAlpha)
        self.globe.setColor(Vec4(1, 1, 1, 0.6))
        self.globe.setTwoSided(True)
        self.globe.setRenderModeWireframe()

        self.overlay = camera.attachNewNode("overlay")
        self.overlay.setTransparency(TransparencyAttrib.MAlpha)
        self.overlay.setColor(Vec4(1, 1, 1, 0))
        self.overlay.setPos(0, 0, 0)
        self.overlay.setPos(0, self.cameraDistance, 0)

        self.overlay1 = engine.loadModel("menu/overlay1")
        self.overlay1.setScale(4)
        self.overlay1.setTwoSided(True)
        self.overlay1.setRenderModeWireframe()
        self.overlay1.reparentTo(self.overlay)

        self.overlay2 = engine.loadModel("menu/overlay2")
        self.overlay2.setScale(4)
        self.overlay2.setTwoSided(True)
        self.overlay2.setRenderModeWireframe()
        self.overlay2.reparentTo(self.overlay)

        self.overlay3 = engine.loadModel("menu/overlay3")
        self.overlay3.setScale(4)
        self.overlay3.setTwoSided(True)
        self.overlay3.setRenderModeWireframe()
        self.overlay3.setR(uniform(0, 360))
        self.overlay3.setP(uniform(0, 360))
        self.overlay3.setH(uniform(0, 360))
        self.overlay3.reparentTo(self.overlay)

        self.overlay4 = engine.loadModel("menu/overlay3")
        self.overlay4.setScale(4)
        self.overlay4.setTwoSided(True)
        self.overlay4.setRenderModeWireframe()
        self.overlay4.setH(uniform(0, 360))
        self.overlay4.setR(uniform(0, 360))
        self.overlay4.setP(uniform(0, 360))
        self.overlay4.reparentTo(self.overlay)

        self.text = engine.loadModel("menu/text")
        self.text.setScale(4)
        self.text.setTwoSided(True)
        self.text.reparentTo(self.overlay)

        self.selector = engine.loadModel("menu/selector")
        self.selector.setScale(4)
        self.selector.setTwoSided(True)
        self.selector.reparentTo(self.overlay)

        self.selectedItem = 0

        self.skyBox = engine.loadModel("menu/skybox")
        self.skyBox.setScale(self.cameraDistance * 5)
        self.skyBox.setRenderModeWireframe()
        self.skyBox.setTwoSided(True)
        self.skyBox.reparentTo(render)
        self.skyBox.setTransparency(TransparencyAttrib.MAlpha)
        self.skyBox.setColor(Vec4(1, 1, 1, 0))

        cmbg = CardMaker("background")
        size = 10
        cmbg.setFrame(-size * engine.aspectRatio, size * engine.aspectRatio,
                      -size, size)
        self.background = camera.attachNewNode(cmbg.generate())
        self.background.setTexture(loader.loadTexture("menu/background.jpg"),
                                   1)
        self.background.setPos(0, size * 1.25, 0)
        self.background.setDepthWrite(False)

        self.belt = JunkBelt(5)

        self.angle = uniform(0, 360)
        self.period = 60
        self.uiAngle = 0

        self.logo = OnscreenImage(image="menu/logo.png",
                                  pos=(0, 0, 0),
                                  scale=((512.0 / 175.0) * 0.075, 0, 0.075))
        self.logo.setTransparency(TransparencyAttrib.MAlpha)
        self.logo.setColor(1, 1, 1, 0)
        self.logo.setBin("transparent", 0)

        self.loadingScreen = OnscreenImage(image="menu/loading.jpg",
                                           pos=(0, 0, 0))
        self.loadingScreen.setScale(render2d, VBase3(1))
        self.loadingScreen.setSx(2)
        self.loadingScreen.hide()

        self.skipToEndOfTutorial = skipIntro

        global firstBoot
        firstBoot = False

        self.introTime = 2
        if firstBoot and not skipIntro:
            self.introTime = 4

        self.showLogin = firstBoot

        self.hostList = ui.HostList(self.startClient)
        self.mapList = ui.MapList(self.startServer)
        self.loginDialog = ui.LoginDialog(self.setUsername)
        self.loginDialogShown = False

        self.introSound = audio.FlatSound("menu/intro.ogg", volume=0.15)
        self.introSound.play()

        self.clientConnectAddress = None
        self.serverMapName = None
        self.serverMode = 0  # 0 for normal, 1 for tutorial
        self.serverGameType = 0  # 0 for deathmatch, 1 for survival

        self.username = "******"

        self.startTime = -1
        self.goTime = -1
        if base.appRunner is not None:
            token = base.appRunner.getToken("username")
            if token != "" and token != "Unnamed":
                self.setUsername(token)
                self.loginDialogShown = True

    def escape(self):
        if self.hostList.visible:
            self.hostList.hide()
        elif self.mapList.visible:
            self.mapList.hide()

    def startClient(self, host):
        self.clickSound.play()
        self.hostList.hide()
        self.loadingScreen.show()
        self.clientConnectAddress = host
        self.goTime = engine.clock.time

    def startServer(self, map, gametype):
        # Tutorial works on Point Control maps.
        if not (self.serverMode == 1 and gametype == 1):
            self.clickSound.play()
            self.mapList.hide()
            self.loadingScreen.show()
            self.serverMapName = map
            self.serverGameType = gametype
            self.goTime = engine.clock.time

    def setUsername(self, username):
        self.clickSound.play()
        self.username = username
        engine.savedUsername = self.username
        engine.saveConfigFile()
        self.loginDialog.hide()

    def update(self):
        if not self.active:
            return
        net.context.readTick()
        if self.startTime == -1:
            self.startTime = engine.clock.time
        elapsedTime = engine.clock.time - self.startTime
        if elapsedTime < self.introTime:
            blend = elapsedTime / self.introTime
            self.angle += engine.clock.timeStep * (1 - blend)
            self.cameraDistance = 20 + (1 - blend)**2 * 200
        elif elapsedTime < self.introTime + 2:
            self.cameraDistance = 20
            blend = (elapsedTime - self.introTime) / 2
            self.overlay.setColor(Vec4(1, 1, 1, blend))
            self.logo.setColor(1, 1, 1, blend)
            self.skyBox.setColor(Vec4(1, 1, 1, blend))
            if not self.backgroundSound.isPlaying():
                self.backgroundSound.play()
            self.backgroundSound.setVolume(blend * 0.5)
        else:
            self.cameraDistance = 20
            self.overlay.setColor(Vec4(1, 1, 1, 1))
            self.logo.setColor(1, 1, 1, 1)
            self.skyBox.setColor(Vec4(1, 1, 1, 1))
            self.backgroundSound.setVolume(0.5)

        if elapsedTime > self.introTime:
            if not self.loginDialogShown and self.showLogin:
                self.loginDialog.show()
                self.loginDialogShown = True

        self.uiAngle -= engine.clock.timeStep * 2
        self.text.setR(self.uiAngle)

        self.hostList.update()
        self.mapList.update()
        self.loginDialog.update()
        mouse = base.win.getPointer(0)
        props = base.win.getProperties()
        vector = Vec3((mouse.getX() / float(props.getXSize())) - 0.5,
                      (mouse.getY() / float(props.getYSize())) - 0.5, 0)
        vector.normalize()
        angle = math.degrees(math.atan2(-vector.getX(), vector.getY())) + 180
        angle -= self.uiAngle
        if not self.hostList.visible and not self.mapList.visible and not self.loginDialog.visible:
            self.selectedItem = int(round(angle / 90.0))
        while self.selectedItem > 3:
            self.selectedItem -= 4
        while self.selectedItem < 0:
            self.selectedItem += 4
        self.selector.setR(self.uiAngle + self.selectedItem * 90)

        self.overlay1.setR(self.overlay1.getR() - engine.clock.timeStep * 2)
        self.overlay2.setR(self.overlay2.getR() + engine.clock.timeStep * 2)
        self.overlay3.setH(self.overlay3.getH() + engine.clock.timeStep * 10)
        self.overlay4.setP(self.overlay4.getP() - engine.clock.timeStep * 10)
        self.belt.update()
        self.angle += engine.clock.timeStep * 0.025
        camera.setPos(
            math.cos(self.angle) * self.cameraDistance,
            math.sin(self.angle) * self.cameraDistance,
            math.cos(elapsedTime / 45 + 2) * 2)
        camera.lookAt(Point3(0, 0, 0))

        backend = None
        game = None

        if self.goTime != -1 and engine.clock.time - self.goTime > 0.25:
            if self.clientConnectAddress is not None:
                self.delete()
                online.connectTo(self.clientConnectAddress)
                backend = ClientBackend(self.clientConnectAddress,
                                        self.username)
                game = Game(backend)
            elif self.serverMapName is not None:
                if self.serverMode == 0:
                    # Normal server mode
                    self.delete()
                    if self.serverGameType == 0:
                        backend = PointControlBackend(
                            True, self.username)  # Deathmatch
                    else:
                        backend = SurvivalBackend(True,
                                                  self.username)  # Survival
                    game = Game(backend)
                    game.localStart(self.serverMapName)
                elif self.serverMode == 1:
                    # Tutorial mode
                    self.delete()
                    backend = PointControlBackend(False, self.username)
                    game = Tutorial(backend,
                                    2 if self.skipToEndOfTutorial else 0)
                    game.localStart(self.serverMapName)

        net.context.writeTick()
        return backend, game

    def click(self):
        if self.mapList.visible or self.hostList.visible or self.loginDialog.visible or engine.clock.time - \
                self.startTime < self.introTime + 0.5:
            return
        self.clickSound.play()
        if self.selectedItem == 0:  # Join
            self.hostList.show()
        elif self.selectedItem == 1:  # Tutorial
            self.mapList.show()
            self.serverMode = 1
        elif self.selectedItem == 2:  # Exit
            engine.exit()
        elif self.selectedItem == 3:  # Host
            self.mapList.show()
            self.serverMode = 0

    def delete(self):
        self.loadingScreen.destroy()
        self.hostList.delete()
        self.mapList.delete()
        self.loginDialog.delete()
        self.active = False
        self.overlay.removeNode()
        self.belt.delete()
        self.background.removeNode()
        self.globe.removeNode()
        self.skyBox.removeNode()
        self.ignoreAll()
        self.logo.destroy()
        self.introSound.stop()
        self.backgroundSound.stop()
Exemple #11
0
class RankingGui(GuiColleague):
    def __init__(self, mediator, background_fpath, font, fg_col):
        GuiColleague.__init__(self, mediator)
        self.ranking_texts = []
        self.background_path = background_fpath
        self.font = font
        self.fg_col = fg_col
        self.rank_menu = self.background = None

    @staticmethod
    def set_drv_txt_img(page, i, car_name, pos_x, top, text, players):
        drivers = [player.driver for player in players]
        info('drivers: ' + str([drv for drv in drivers]))
        info('i: %s  - carname: %s - text: %s' % (i, car_name, text))
        drv = next(player.driver for player in players
                   if player.car == car_name)
        player_car_names = [
            player.car for player in players if player.kind == Player.human
        ]
        is_player_car = car_name in player_car_names
        info('%s %s %s %s' %
             (text % drv.name, car_name, drv.img_idx, is_player_car))
        name = text % drv.name
        if '@' in name:
            name = name.split('@')[0] + '\1smaller\1@' + name.split('@')[1] + \
                '\2'
        txt = Text(name,
                   align='left',
                   scale=.072,
                   pos=(pos_x, top - i * .16),
                   font=page.font,
                   fg=page.text_fg if is_player_car else page.text_bg)
        gprops = page.rprops.season_props.gameprops
        img = Img(gprops.cars_img % car_name,
                  pos=(pos_x - .16, top + .02 - i * .16),
                  scale=.074)
        filtervpath = RankingGui.eng.curr_path + \
            'yyagl/assets/shaders/filter.vert'
        with open(filtervpath) as fvs:
            vert = fvs.read()
        drvfpath = RankingGui.eng.curr_path + \
            'yyagl/assets/shaders/drv_car.frag'
        with open(drvfpath) as ffs:
            frag = ffs.read()
        shader = load_shader(vert, frag)
        if shader:
            img.set_shader(shader)
        img.set_transparent()
        t_s = TextureStage('ts')
        t_s.set_mode(TextureStage.MDecal)
        txt_path = gprops.drivers_img.path_sel % drv.img_idx
        img.set_texture(t_s, loader.loadTexture(txt_path))
        return txt, img

    def show(self, rprops, sprops, ranking, players):
        self.background = OnscreenImage(
            sprops.gameprops.menu_props.background_img_path,
            scale=(1.77778, 1, 1))
        self.background.setBin('background', 10)
        self.rank_menu = RankingMenu(rprops, sprops, ranking, players)

    def hide(self):
        self.background.destroy()
        self.rank_menu.destroy()

    def attach_obs(self, mth):
        self.rank_menu.attach_obs(mth)

    def detach_obs(self, mth):
        self.rank_menu.detach_obs(mth)

    def destroy(self):
        self.hide()
        self.rank_menu = self.ranking_texts = self.background = None
        GuiColleague.destroy(self)
Exemple #12
0
class MousePointerDisplay:
    def __init__(self, game):
        
        self.log = logging.getLogger('pano.mouseDisplay')
        
        self.game = game
        self.resources = game.getResources()
        
        self.defaultScale = 0.05
        
        self.pointer = None
        
        #the parent node of the mouse pointer
        self.pointerParentNP = None
        
        #the mouse pointer node, it can be a ModelNode if the cursor is animated and was read by an .egg file
        #or it can be a OnScreenImage if the cursor is static
        self.mousePointer = None
        
        #True if the pointer is a static image and therefore is rendered through a OnScreenImage object
        self.isImagePointer = False
        
        #True if the mouse pointer is hidden
        self.mouseHidden = True 
        
        # the name of the image used as a pointer through a call to setImageAsPointer
        self.pointerImage = None                               
        
    def initialize(self):        
        self.pointerParentNP = render2d.attachNewNode('mousePointer')
        
        # create a GUI Layer for the pointer
        CullBinManager.getGlobalPtr().addBin(PanoConstants.MOUSE_CULL_BIN_NAME, CullBinManager.BTUnsorted, PanoConstants.MOUSE_CULL_BIN_VAL)
        
        # add task that updates the location of the mouse pointer
        taskMgr.add(self.updatePointerLocationTask, PanoConstants.TASK_MOUSE_POINTER)
        
    def isShown(self):
        return not self.mouseHidden
    
    def show(self):
        self.mouseHidden = False
        self.pointerParentNP.show()
 
                
    def hide(self):
        """
        Hides the mouse pointer.
        For image based pointers, the associated OnScreenImage is destroyed with a call to the member function destroy().
        While for model based pointers the associated model node is simply removed from the scenegraph. 
        """        
        self.mouseHidden = True
        self.pointerParentNP.hide()
            
    def _destroyPointer(self):        
        if self.mousePointer is not None:
            if self.isImagePointer:
                self.mousePointer.destroy()
                self.mousePointer = None                
            else:
                self.mousePointer.removeNode()
#                self.mousePointer.detachNode() 
            
            if self.pointerParentNP is not None:
                self.pointerParentNP.node().removeAllChildren()
                
            self.isImagePointer = False
            self.pointerImage = None
            self.mousePointer = None
            self.pointer = None
            self.mouseHidden = True
    
    def getScale(self):
        return self.scale
    
    def setScale(self, scale):
        self.scale = scale
        
    def setByName(self, pointerName):
        """
        Sets and displays the specified mouse pointer. If None is passed in place
        of the pointerName parameter, then the mouse pointer is hidden.
        
        Convention: A texture file or egg file with a base name equal
        to pointerName must exist in one of the resource locations
        associated with the cursors resource type.
        
        Convention: If the pointer name corresponds to an egg file, then
        the pointer is assumed to be animated. Otherwise the pointer is
        assumed to be a static image.
        
        Returns True if the pointer was set successfully and False if otherwise.
        """        
        pointerChanged = (self.pointer is None) or (pointerName != self.pointer.getName())
        if (pointerName is None) or pointerChanged:
            self._destroyPointer()
            
        if pointerChanged:
            self.pointer = self.game.getResources().loadPointer(pointerName)
            if self.pointer is None:
                self.log.error("Could'nt find pointer: %s", pointerName)
                return False
             
            if self.pointer.getModelFile() is not None:                
                self.isImagePointer = False
                self.mousePointer = self.game.getResources().loadModel(self.pointer.getModelFile())
                self.mousePointer.setScale(self.pointer.getScale() if self.pointer.getScale() is not None else self.defaultScale)
                self.mousePointer.setTag('model', 'True')
                self.mousePointer.reparentTo(self.pointerParentNP)
                self.isImagePointer = False
                self.pointerImage = None
            else:                
                self.setImageAsPointer(self.pointer.getTexture(), self.pointer.getScale())
                
            self.mousePointer.setTransparency(TransparencyAttrib.MAlpha)            
            self.mousePointer.setBin("fixed", PanoConstants.RENDER_ORDER_MOUSE_POINTER)
            self.mousePointer.setDepthTest(False)
            self.mousePointer.setDepthWrite(False)            
            self.mouseHidden = False
            self.show()
            
        return True   
    
    def setImageAsPointer(self, image, scale = None):
        self._destroyPointer()
        self.isImagePointer = True        
        texPath = self.game.getResources().getResourceFullPath(PanoConstants.RES_TYPE_TEXTURES, image)
        if texPath is not None:
            x, y = 0, 0
            if base.mouseWatcherNode.hasMouse():
                x=base.mouseWatcherNode.getMouseX()
                y=base.mouseWatcherNode.getMouseY()
                                                         
            self.mousePointer = OnscreenImage(
                                              parent=self.pointerParentNP, 
                                              image = texPath, 
                                              pos = Point3(x, 0, y), 
                                              scale = scale if scale is not None else self.defaultScale 
                                              )
            
            self.pointerImage = image
            self.mousePointer.setTransparency(TransparencyAttrib.MAlpha)            
            self.mousePointer.setBin("fixed", PanoConstants.RENDER_ORDER_MOUSE_POINTER)
            self.mousePointer.setDepthTest(False)
            self.mousePointer.setDepthWrite(False)            
            self.mouseHidden = False
            self.show()
            return True
        else:
            return False

    def getPosition(self):
        '''
        Returns the current location of the mouse pointer.
        @return: A (x, y) tuple containing the coordinates of the pointers in the coordinate of the render node.
        '''
        if self.mousePointer is not None:
            pos = self.mousePointer.getPos(render)            
            return (pos[0], pos[2])
        else:
            return (-1, 1)
            
    def updatePointerLocationTask(self, task):   
        if base.mouseWatcherNode.hasMouse():     
            if self.mousePointer is not None and not self.mouseHidden  and base.mouseWatcherNode.hasMouse() and not self.game.isPaused():
                x=base.mouseWatcherNode.getMouseX()
                y=base.mouseWatcherNode.getMouseY()            
                self.mousePointer.setPos(Point3(x, 0, y))
            
        return Task.cont

    def persistState(self, persistence):
        ctx = persistence.createContext('mouse_pointer')
        ctx.addVar('is_image', self.isImagePointer)
        ctx.addVar('scale', self.scale)
        ctx.addVar('pointer_name', self.pointer.getName() if self.pointer is not None else '')
        ctx.addVar('image', self.pointerImage if self.pointer is None else '')
        return ctx
    
    def resumeState(self, persistence):
        pass
Exemple #13
0
class TuningGui(GuiColleague, DirectObject):
    def __init__(self, mediator, sprops):
        GuiColleague.__init__(self, mediator)
        self.buttons = self.background = None
        self.sprops = sprops
        self.txt = self.upg1_txt = self.upg2_txt = self.upg3_txt = \
            self.hint1_txt = self.hint2_txt = self.hint3_txt = None

    def show(self, players):
        self.background = OnscreenImage(
            self.sprops.gameprops.menu_props.background_img_path,
            scale=(1.77778, 1, 1))
        self.background.setBin('background', 10)
        bprops = {'scale': (.4, .4), 'cmd': self.on_btn}
        self.txt = OnscreenText(
            text=_('What do you want to upgrade?'),
            scale=.1,
            pos=(0, .76),
            font=loader.loadFont(self.sprops.font),
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.buttons = [
            ImgBtn(pos=(-1.2, .1),
                   img=self.sprops.tuning_imgs[0],
                   extra_args=['engine'],
                   **bprops)
        ]
        self.buttons += [
            ImgBtn(pos=(0, .1),
                   img=self.sprops.tuning_imgs[1],
                   extra_args=['tires'],
                   **bprops)
        ]
        self.buttons += [
            ImgBtn(pos=(1.2, .1),
                   img=self.sprops.tuning_imgs[2],
                   extra_args=['suspensions'],
                   **bprops)
        ]
        self._set_events()
        # tuning = self.mediator.car2tuning[self.sprops.player_car_name]
        player_car_name = [
            player.car for player in players if player.kind == Player.human
        ][0]
        tuning = [
            player.tuning for player in players
            if player.car == player_car_name
        ][0]
        self.upg1_txt = OnscreenText(
            text=_('current upgrades: +') + str(tuning.engine),
            scale=.06,
            pos=(-1.53, -.36),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.upg2_txt = OnscreenText(
            text=_('current upgrades: +') + str(tuning.tires),
            scale=.06,
            pos=(-.35, -.36),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.upg3_txt = OnscreenText(
            text=_('current upgrades: +') + str(tuning.suspensions),
            scale=.06,
            pos=(.85, -.36),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.hint1_txt = OnscreenText(
            text=_("engine: it increases car's maximum speed"),
            scale=.06,
            pos=(-1.53, -.46),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.hint2_txt = OnscreenText(
            text=_("tires: they increase car's adherence"),
            scale=.06,
            pos=(-.35, -.46),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)
        self.hint3_txt = OnscreenText(
            text=_("suspensions: they increase car's stability"),
            scale=.06,
            pos=(.85, -.46),
            font=loader.loadFont(self.sprops.font),
            wordwrap=12,
            align=TextNode.ALeft,
            fg=self.sprops.gameprops.menu_props.text_normal_col)

    def _set_events(self):
        self._curr_btn = 0
        self.buttons[0]._on_enter(None)
        self.accept('joypad0-dpad_left-up', self.__on_evt, ['left'])
        self.accept('joypad0-dpad_right-up', self.__on_evt, ['right'])
        self.accept('joypad0-face_a-up', self.__on_evt, ['enter'])
        nav = self.sprops.gameprops.menu_props.nav.navinfo_lst[0]
        self.accept(self.eng.lib.remap_str(nav.left), self.__on_evt, ['left'])
        self.accept(self.eng.lib.remap_str(nav.right), self.__on_evt,
                    ['right'])
        self.accept(self.eng.lib.remap_str(nav.fire), self.__on_evt, ['enter'])

    def __on_evt(self, evt):
        self.buttons[self._curr_btn]._on_exit(None)
        d = 1 if evt == 'right' else (-1 if evt == 'left' else 0)
        self._curr_btn = min(2, max(0, self._curr_btn + d))
        self.buttons[self._curr_btn]._on_enter(None)
        if evt == 'enter':
            self.on_btn(self.buttons[self._curr_btn].wdg['extraArgs'][0])

    def on_btn(self, val):
        self.notify('on_tuning_sel', val)

    def hide(self):
        wdgs = [
            self.background, self.txt, self.hint1_txt, self.hint2_txt,
            self.hint3_txt, self.upg1_txt, self.upg2_txt, self.upg3_txt
        ]
        list(map(lambda wdg: wdg.destroy(), self.buttons + wdgs))
        self.ignore_all()
class QuestEmblemGui(DirectFrame):
    notify = directNotify.newCategory('QuestEmblemGui')

    def __init__(self, parent):
        DirectFrame.__init__(self, parent)

        self.emblem = OnscreenImage(image=loader.loadTexture(
            'phase_5/maps/quest_available_emblem.png'),
                                    parent=self)
        self.emblem.setTransparency(TransparencyAttrib.MAlpha)
        self.emblem.setBillboardAxis()
        self.emblem.setTwoSided(1)

        glowMdl = loader.loadModel('phase_4/models/minigames/particleGlow.bam')
        self.glow = OnscreenImage(parent=self.emblem,
                                  image=glowMdl,
                                  color=(1.0, 1.0, 0.4, 1.0),
                                  scale=(3.0, 3.0, 3.0),
                                  pos=(0, 0.05, 0))
        self.glow.setBin('gui-popup', 10)

        glowMdl.removeNode()

        self.track = None
        self.state = LOADED

    def setEmblem(self, questAvailable=QUEST_AVAILABLE):
        # Sets the texture of the emblem.
        texture = loader.loadTexture('phase_5/maps/quest_available_emblem.png')
        if questAvailable is 0:
            texture = loader.loadTexture(
                'phase_5/maps/quest_scroll_emblem.png')
        self.state = questAvailable
        self.emblem.setImage(texture)
        self.emblem.setTransparency(TransparencyAttrib.MAlpha)
        self.emblem.setBillboardAxis()
        self.emblem.setTwoSided(1)

    def start(self, bobMinHeight=0.5, bobMaxHeight=0.5):
        # Shows the emblem and starts the bobbing animation.

        # Stops so we don't have two animations running at once.
        self.stop()

        # Shows the emblem
        self.show()

        # Let's create the animation and run the animation.
        self.track = Sequence(
            LerpPosInterval(self.emblem,
                            1.35,
                            pos=(0, 0, self.getZ() - bobMinHeight),
                            startPos=(0, 0, bobMaxHeight),
                            blendType='easeInOut'),
            LerpPosInterval(self.emblem,
                            1.35,
                            pos=(0, 0, bobMaxHeight),
                            startPos=(0, 0, self.getZ() - bobMinHeight),
                            blendType='easeInOut')).loop()

    def stop(self):
        # Hides the emblem and stops the animation.
        self.hide()

        if self.track:
            self.track.pause()
            self.track = None

        self.state = DISABLED

    def destroy(self):
        self.stop()
        self.glow.destroy()
        self.emblem.destroy()
        self.state = None
        DirectFrame.destroy(self)
Exemple #15
0
class MenuGui(Gui):
    def __init__(self, mdt, menu_args):
        Gui.__init__(self, mdt)
        self.menu_args = menu_args
        self.background = None
        if self.menu_args.background:
            self.background = OnscreenImage(scale=(1.77778, 1, 1.0),
                                            image=self.menu_args.background)
            self.background.setBin('background', 10)

    @property
    def imgbtn_args(self):
        return {
            'rolloverSound': self.menu_args.rollover,
            'clickSound': self.menu_args.click
        }

    @property
    def btn_args(self):
        return {
            'scale': self.menu_args.text_scale,
            'text_font': self.menu_args.font,
            'text_fg': self.menu_args.text_fg,
            'frameColor': self.menu_args.btn_color,
            'frameSize': self.menu_args.btn_size,
            'rolloverSound': self.menu_args.rollover,
            'clickSound': self.menu_args.click
        }

    @property
    def label_args(self):
        return {
            'scale': self.menu_args.text_scale,
            'text_fg': self.menu_args.text_fg,
            'text_font': self.menu_args.font,
            'frameColor': (1, 1, 1, 0)
        }

    @property
    def option_args(self):
        tfg = self.menu_args.text_fg
        return {
            'scale': self.menu_args.text_scale,
            'text_font': self.menu_args.font,
            'text_fg': tfg,
            'frameColor': self.menu_args.btn_color,
            'frameSize': self.menu_args.btn_size,
            'rolloverSound': self.menu_args.rollover,
            'clickSound': self.menu_args.click,
            'text_scale': .85,
            'item_text_font': self.menu_args.font,
            'item_frameColor': tfg,
            'item_relief': FLAT,
            'popupMarker_frameColor': self.menu_args.btn_color,
            'textMayChange': 1,
            'highlightColor': (tfg[0] * 1.2, tfg[1] * 1.2, tfg[2] * 1.2, .2)
        }

    @property
    def checkbtn_args(self):
        return {
            'scale': self.menu_args.text_scale,
            'text_font': self.menu_args.font,
            'text_fg': self.menu_args.text_fg,
            'frameColor': self.menu_args.btn_color,
            'rolloverSound': self.menu_args.rollover,
            'clickSound': self.menu_args.click
        }

    @property
    def text_args(self):
        return {
            'scale': self.menu_args.text_scale,
            'fg': self.menu_args.text_fg,
            'font': self.menu_args.font
        }

    def destroy(self):
        Gui.destroy(self)
        if self.background:
            self.background.destroy()
Exemple #16
0
class MainMenu(DirectObject):
    
    def __init__(self):
        self.node = aspect2d.attachNewNode('MainMenu')
        self.buttons = []
        self.LoadContent()
        self.SetupEventHandlers()
        
    def SetupEventHandlers(self):
        self.accept(ServerJoinResponseEvent.EventName, self.OnServerJoinResponseEvent)
        
        
    def LoadContent(self):
        bg = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/background.png', scale = (2, 1, 1))
        bg.setTransparency(TransparencyAttrib.MAlpha)
        bg.reparentTo(self.node)
        bg.setBin('fixed', 1)
        
        title = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/title.png')
        title.setTransparency(TransparencyAttrib.MAlpha)
        title.reparentTo(self.node)
        
        self.spinner = OnscreenImage(image = 'Assets/Images/Menus/MainMenu/loadingSpinner.png', pos = (-0.15, 1, 0.15), scale = 128.0/1024.0)
        self.spinner.setTransparency(TransparencyAttrib.MAlpha)
        self.spinner.reparentTo(base.a2dBottomRight)
        self.spinner.setBin('gui-popup', 0)
        self.spinner.hide()
        
        self.LoadButton('Button_Offline', 'offline', 'offline_over', 0, 0.2, self.OnButtonClicked, ['offline'])
        self.LoadButton('Button_Multiplayer', 'multiplayer', 'multiplayer_over', 0, 0, self.OnButtonClicked, ['multiplayer'])
        self.LoadButton('Button_Options', 'options', 'options_over', 0, -0.2, self.OnButtonClicked, ['options'])
        self.LoadButton('Button_Exit', 'exit', 'exit_over', 0, -0.4, self.OnButtonClicked, ['exit'])
        
    def LoadButton(self, egg, up, over, x, y, cmd, args):
        maps = loader.loadModel("Assets/Images/Menus/MainMenu/%s" % (egg))
        b = DirectButton(geom = (maps.find('**/%s' % (up)),
                         maps.find('**/%s' % (over)),
                         maps.find('**/%s' % (over)),
                         maps.find('**/%s' % (up))),
                         command = cmd,
                         extraArgs = args,
                         pressEffect = 0,
                         relief = None,
                         rolloverSound = None, 
                         clickSound = None,
                         pos = (x, 1, y),
                         scale = (1, 1, 75.0/500.0))
        b.reparentTo(self.node)
        self.buttons.append(b)
        
    def OnButtonClicked(self, buttonText):
        if(buttonText == 'multiplayer'):
            Globals.ROCKET_CONTEXT.LoadDocument('Assets/libRocket/multiplayer.rml').Show()
            self.DisableButtons()
            self.acceptOnce('multiplayerPopupClose', self.OnMultiplayerClose)
        
        elif(buttonText == 'options'):
            Globals.ROCKET_CONTEXT.LoadDocument('Assets/libRocket/options.rml').Show()
            self.DisableButtons()
            self.acceptOnce('optionsPopupClose', self.OnOptionsClose)
            
        elif(buttonText == 'exit'):
            self.CreateAlertPopup('Exit Game', 'Do you really want to exit?', self.OnExitPopupOkay, self.OnExitPopupCancel)
            
        elif(buttonText == 'offline'):
            Globals.ROCKET_CONTEXT.LoadDocument('Assets/libRocket/offline.rml').Show()
            self.DisableButtons()
            self.acceptOnce('offlinePopupClose', self.OnOfflineClose)
            
    def CreatePopup(self, title, fields, values, onOkay, onCancel):
        p = Popup(title, fields, values, onOkay, onCancel)
        self.OnPopupCreated(p)
        
    def CreateAlertPopup(self, title, text, onOkay, onCancel):
        p = AlertPopup(title, text, onOkay, onCancel)
        self.OnPopupCreated(p)
        
    def CreateFullScreenPopup(self, title, fields, values, onOkay, onCancel):
        p = FullscreenPopup(title, fields, values, onOkay, onCancel)
        self.OnPopupCreated(p)                              
            
    def OnOfflineClose(self, accept):
        if(accept):
            SettingsController.SaveClientSettings()
            taskMgr.doMethodLater(0.1, messenger.send, 'as', ['startOffline'])
        self.EnableButtons()
        
    def OnOptionsClose(self, accept):
        if(accept):
            SettingsController.SaveClientSettings()
        self.EnableButtons()
            
    def OnMultiplayerClose(self, accept):
        if(accept):
            SettingsController.SaveClientSettings()
            self.StartLoadingSpinner()
            self.DisableButtons()
            taskMgr.doMethodLater(0.1, messenger.send, 'as1', ['mainMenuMulti'])
        else:
            self.EnableButtons()
        
    def DisableButtons(self):
        for b in self.buttons:
            b['state'] = DGG.DISABLED
            
    def EnableButtons(self):
        for b in self.buttons:
            b['state'] = DGG.NORMAL
        
    def OnAlertPopupClose(self, popup):
        self.DestroyPopup(popup)
        
    def OnExitPopupOkay(self, popup):
        self.DestroyPopup(popup)
        messenger.send('mainMenuExit')
        
    def OnExitPopupCancel(self, popup):
        self.DestroyPopup(popup)
            
    def OnPopupCreated(self, popup):
        self.DisableButtons()
            
    def DestroyPopup(self, popup):
        popup.Destroy()
        del popup
        
        self.EnableButtons()
            
    def Hide(self):
        self.node.hide()
        
    def Show(self):
        self.node.show()
        
    def StartLoadingSpinner(self):
        self.spinner.show()
        self.spinSequence = Sequence(LerpHprInterval(self.spinner, 2, VBase3(0, 0, 180), VBase3(0, 0, 0)),
                                     LerpHprInterval(self.spinner, 2, VBase3(0, 0, 360), VBase3(0, 0, 180)))
        self.spinSequence.loop()
        
    def StopLoadingSpinner(self):
        self.spinSequence.finish()
        self.spinner.hide()
        
    def OnServerJoinResponseEvent(self, event):
        self.StopLoadingSpinner()
        self.EnableButtons()
        if(not event.GetResponse()):
            p = AlertPopup('Join Game Failed', event.GetReason(), self.ClosePopup, self.ClosePopup)
            self.OnPopupCreated(p)
        
    def ClosePopup(self, popup):
        self.DestroyPopup(popup)