source: trunk/game/scripts/hud.py @ 253

Revision 182, 14.6 KB checked in by bretzel_parpg, 10 years ago (diff)

Put some help text in and also made it look better. I'm not very happy with pychan at the moment
because there is no word wrap on Labels, but I won't complain anymore within an SVN commit

  • Property svn:eol-style set to native
Line 
1#!/usr/bin/python
2
3#   This file is part of PARPG.
4
5#   PARPG is free software: you can redistribute it and/or modify
6#   it under the terms of the GNU General Public License as published by
7#   the Free Software Foundation, either version 3 of the License, or
8#   (at your option) any later version.
9
10#   PARPG is distributed in the hope that it will be useful,
11#   but WITHOUT ANY WARRANTY; without even the implied warranty of
12#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#   GNU General Public License for more details.
14
15#   You should have received a copy of the GNU General Public License
16#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
17
18import shutil, fife, pychan
19from pychan.tools import callbackWithArguments as cbwa
20
21
22class Hud():
23    """Main Hud class"""
24    def __init__(self, engine, settings):
25        """Initialise the instance.
26           @type engine: fife.Engine
27           @param engine: An instance of the fife engine
28           @type settings: settings.Setting
29           @param settings: The settings data
30           @return: None"""
31        pychan.init(engine, debug = True)
32        # TODO: perhaps this should not be hard-coded here
33        self.hud = pychan.loadXML("gui/hud.xml")
34        self.settings = settings
35        self.actionsBox = self.hud.findChild(name="actionsBox")
36        self.actionsText = []
37        self.menu_displayed = False
38        self.initializeHud()
39        self.initializeMainMenu()
40        self.initializeOptionsMenu()
41        self.initializeHelpMenu()
42
43    def initializeHud(self):
44        """Initialize and show the main HUD
45           @return: None"""
46        self.events_to_map = {"menuButton":self.displayMenu,}
47        self.hud.mapEvents(self.events_to_map) 
48        # set HUD size accoriding to screen size
49        screen_width = int(self.settings.readSetting('ScreenWidth'))
50        self.hud.findChild(name="mainHudWindow").size = (screen_width, 65)
51        self.hud.findChild(name="inventoryButton").position = (screen_width-59, 7)
52        # add ready slots
53        ready1 = self.hud.findChild(name='hudReady1')
54        ready2 = self.hud.findChild(name='hudReady2')
55        ready3 = self.hud.findChild(name='hudReady3')
56        ready4 = self.hud.findChild(name='hudReady4')
57        actions_scroll_area = self.hud.findChild(name='actionsScrollArea')
58        # annoying code that is both essential and boring to enter
59        if (screen_width == 1440):
60            ready1.position = (screen_width-1235, 7)
61            ready2.position = (screen_width-1175, 7)
62            ready3.position = (screen_width-215, 7)
63            ready4.position = (screen_width-155, 7)
64            actions_scroll_area.position = (325, 5)
65            actions_width = screen_width - 550
66        elif (screen_width == 1280):
67            ready1.position = (screen_width-1075, 7)
68            ready2.position = (screen_width-1015, 7)
69            ready3.position = (screen_width-215, 7)
70            ready4.position = (screen_width-155, 7)
71            actions_scroll_area.position = (325, 5)
72            actions_width = screen_width - 550
73        elif (screen_width == 1024):
74            ready1.position = (screen_width-820, 7)
75            ready2.position = (screen_width-760, 7)
76            ready3.position = (screen_width-215, 7)
77            ready4.position = (screen_width-155, 7)
78            actions_scroll_area.position = (325, 5)
79            actions_width = screen_width - 550
80        elif (screen_width == 800):
81            ready1.position = (screen_width-640, 7)
82            ready2.position = (screen_width-580, 7)
83            ready3.position = (screen_width-185, 7)
84            ready4.position = (screen_width-125, 7)
85            actions_scroll_area.position = (280, 5)
86            actions_width = screen_width - 475
87        else:
88            ready1.position = (screen_width-475, 7)
89            ready2.position = (screen_width-420, 7)
90            ready3.position = (screen_width-175, 7)
91            ready4.position = (screen_width-120, 7)
92            actions_scroll_area.position = (280, 5)
93            actions_width = screen_width - 465
94        # and finally add an actions box
95        self.hud.findChild(name="actionsBox").min_size = (actions_width, 0)
96        actions_scroll_area.min_size = (actions_width, 55)
97        actions_scroll_area.max_size = (actions_width, 55)
98        # now it should be OK to display it all
99        self.hud.show()
100
101    def refreshActionsBox(self):
102        """Refresh the actions box so that it displays the contents of
103           self.actionsText
104           @return: None"""
105        self.actionsBox.items = self.actionsText
106
107    def addAction(self, action):
108        """Add an action to the actions box.
109           @type action: string
110           @param action: The text that you want to display in the actions box
111           @return: None"""
112        self.actionsText.insert(0, action)
113        self.refreshActionsBox()
114
115    def showHUD(self):
116        """Show the HUD.
117           @return: None"""
118        self.hud.show()
119
120    def hideHUD(self):
121        """Hide the HUD.
122           @return: None"""
123        self.hud.hide()
124       
125    def initializeMainMenu(self):
126        """Initalize the main menu.
127           @return: None"""
128        self.main_menu = pychan.loadXML("gui/hud_main_menu.xml")
129        self.menu_events = {"resumeButton":self.hideMenu, 
130                            "optionsButton":self.displayOptions,
131                            "helpButton":self.displayHelp}
132        self.main_menu.mapEvents(self.menu_events)
133
134    def displayMenu(self):
135        """Displays the main in-game menu.
136           @return: None"""
137        if (self.menu_displayed == False):
138            self.main_menu.show()
139            self.menu_displayed = True
140        elif (self.menu_displayed == True):
141            self.hideMenu()
142
143    def hideMenu(self):
144        """Hides the main in-game menu.
145           @return: None"""
146        self.main_menu.hide()
147        self.menu_displayed = False
148
149    def initializeHelpMenu(self):
150        """Initialize the help menu
151           @return: None"""
152        self.help_dialog = pychan.loadXML("gui/help.xml")
153        help_events = {"closeButton":self.help_dialog.hide}
154        self.help_dialog.mapEvents(help_events)
155        main_help_text = "Welcome to Post-Apocalyptic RPG or PARPG![br][br]"\
156        "This game is still in development, so please expect for there to be bugs"\
157        " and[br]feel free to tell us about them at http://www.forums.parpg.net.[br]"\
158        "This game uses a \"Point 'N' Click\" interface, which means that to move around,[br]"\
159        "just click where you would like to go and your character will move there.[br]"\
160        "PARPG also utilizes a context menu. To access this, just right click "\
161        "anywhere[br]on the screen and a menu will come up. This menu will change"\
162        " depending on[br]what you have clicked on, hence it's name \"context menu\".[br][br]"
163       
164        k_text =" Keybindings" 
165        k_text+="[br] A : Add a test action to the actions display"
166        k_text+="[br] I : Toggle the inventory screen"
167        k_text+="[br] F5 : Take a screenshot"
168        k_text+="[br]      (saves to <parpg>/screenshots/)"
169        k_text+="[br] Q : Quit the game"
170        self.help_dialog.distributeInitialData({
171                "MainHelpText":main_help_text,
172                "KeybindText":k_text
173                })
174
175    def displayHelp(self):
176        """Display the help screen.
177           @return: None"""
178        self.help_dialog.show()
179
180    def initializeOptionsMenu(self):
181        """Initalize the options menu.
182           @return: None"""
183        self.options_menu = pychan.loadXML("gui/hud_options.xml")
184        self.options_events = {"applyButton":self.applyOptions,
185                               "closeButton":self.options_menu.hide,
186                               "defaultsButton":self.setToDefaults,
187                               "InitialVolumeSlider":self.updateVolumeText}
188
189        self.Resolutions = ['640x480', '800x600',
190                            '1024x768', '1280x1024', '1440x900']
191        self.RenderBackends = ['OpenGL', 'SDL']
192        self.renderNumber = 0
193        if (str(self.settings.readSetting('RenderBackend')) == "SDL"):
194            self.renderNumber = 1
195        initialVolume = float(self.settings.readSetting('InitialVolume'))
196        initialVolumeText = str('Initial Volume: %.0f%s' %
197                                (int(initialVolume*10), "%"))
198        self.options_menu.distributeInitialData({
199                'ResolutionBox': self.Resolutions,
200                'RenderBox': self.RenderBackends,
201                'InitialVolumeLabel' : initialVolumeText
202                })
203
204        sFullscreen = self.settings.readSetting(name="FullScreen")
205        sSounds = self.settings.readSetting(name="PlaySounds")
206        sRender = self.renderNumber
207        sVolume = initialVolume
208
209        screen_width = self.settings.readSetting(name="ScreenWidth")
210        screen_height = self.settings.readSetting(name="ScreenHeight")
211        indexRes = str(screen_width + 'x' + screen_height)
212        try:
213            sResolution = self.Resolutions.index(indexRes)
214            resolutionInList = True
215        except:
216            resolutionInList = False
217
218        dataToDistribute = {
219                'FullscreenBox':int(sFullscreen), 
220                'SoundsBox':int(sSounds),
221                'RenderBox': sRender,
222                'InitialVolumeSlider':sVolume
223                }
224
225        if (resolutionInList == True):
226            dataToDistribute['ResolutionBox'] = sResolution
227
228        self.options_menu.distributeData(dataToDistribute)
229
230        self.options_menu.mapEvents(self.options_events)
231
232    def updateVolumeText(self):
233        """
234        Update the initial volume label to reflect the value of the slider
235        """
236        volume = float(self.options_menu.collectData("InitialVolumeSlider"))
237        volume_label = self.options_menu.findChild(name="InitialVolumeLabel")
238        volume_label.text = unicode("Initial Volume: %.0f%s" %
239                                    (int(volume*10), "%"))
240
241    def requireRestartDialog(self):
242        """Show a dialog asking the user to restart PARPG in order for their
243           changes to take effect.
244           @return: None"""
245        require_restart_dialog = pychan.loadXML('gui/hud_require_restart.xml')
246        require_restart_dialog.mapEvents({'okButton':require_restart_dialog.hide})
247        require_restart_dialog.show()
248
249    def applyOptions(self):
250        """Apply the current options.
251           @return: None"""
252        # At first no restart is required
253        self.requireRestart = False
254
255        # get the current values of each setting from the options menu
256        enable_fullscreen = self.options_menu.collectData('FullscreenBox')
257        enable_sound = self.options_menu.collectData('SoundsBox')
258        screen_resolution = self.options_menu.collectData('ResolutionBox')
259        partition = self.Resolutions[screen_resolution].partition('x')
260        screen_width = partition[0]
261        screen_height = partition[2]
262        render_backend = self.options_menu.collectData('RenderBox')
263        initial_volume = self.options_menu.collectData('InitialVolumeSlider')
264        initial_volume = "%.1f" % initial_volume
265
266        # get the options that are being used right now from settings.xml
267        sFullscreen = self.settings.readSetting('FullScreen')
268        sSound = self.settings.readSetting('PlaySounds')
269        sRender = self.settings.readSetting('RenderBackend')
270        sVolume = self.settings.readSetting('InitialVolume')
271
272        sScreenHeight = self.settings.readSetting('ScreenHeight')
273        sScreenWidth = self.settings.readSetting('ScreenWidth')
274        sResolution = sScreenWidth + 'x' + sScreenHeight
275
276        # On each:
277        # - Check to see whether the option within the xml matches the
278        #   option within the options menu
279        # - If they do not match, set the option within the xml to
280        #   to be what is within the options menu
281        # - Require a restart
282
283        if (int(enable_fullscreen) != int(sFullscreen)):
284            self.setOption('FullScreen', int(enable_fullscreen))
285            self.requireRestart = True
286           
287        if (int(enable_sound) != int(sSound)):
288            self.setOption('PlaySounds', int(enable_sound))
289            self.requireRestart = True
290
291        if (screen_resolution != sResolution):
292            self.setOption('ScreenWidth', int(screen_width))
293            self.setOption('ScreenHeight', int(screen_height))
294            self.requireRestart = True
295
296        # Convert the number from the list of render backends to
297        # the string that FIFE wants for its settings.xml
298        if (render_backend == 0):
299            render_backend = 'OpenGL'
300        else:
301            render_backend = 'SDL'
302
303        if (render_backend != str(sRender)):
304            self.setOption('RenderBackend', render_backend)
305            self.requireRestart = True
306
307        if (initial_volume != float(sVolume)):
308            self.setOption('InitialVolume', initial_volume)
309            self.requireRestart = True
310       
311        # Write all the settings to settings.xml
312        self.settings.tree.write('settings.xml')
313       
314        # If the changes require a restart, popup the dialog telling
315        # the user to do so
316        if (self.requireRestart):
317            self.requireRestartDialog()
318        # Once we are done, we close the options menu
319        self.options_menu.hide()
320
321    def setOption(self, name, value):
322        """Set an option within the xml.
323           @type name: string
324           @param name: The name of the option within the xml
325           @type value: any
326           @param value: The value that the option 'name' should be set to
327           @return: None"""
328        element = self.settings.root_element.find(name)
329        if(element != None):
330            if(value != element.text):
331                element.text = str(value)
332        else:
333            print 'Setting,', name, 'does not exist!'
334
335    def setToDefaults(self):
336        """Reset all the options to the options in settings-dist.xml.
337           @return: None"""
338        shutil.copyfile('settings-dist.xml', 'settings.xml')
339        self.requireRestartDialog()
340        self.options_menu.hide()
341
342    def displayOptions(self):
343        """Display the options menu.
344           @return: None"""
345        self.options_menu.show()
346   
347    def toggleInventory(self):
348        """Manually toggles the inventory button.
349           @return: None"""
350        button = self.hud.findChild(name="inventoryButton")
351        if(button.toggled == 0):
352            button.toggled = 1
353        else:
354            button.toggled = 0
355
356    def readyAction(self, ready_button):
357        """ Called when the user selects a ready button from the HUD """
358        text = "Used the item from %s" % ready_button
359        self.addAction(text)
360       
Note: See TracBrowser for help on using the repository browser.