source: trunk/PARPG/scripts/world.py @ 62

Revision 62, 6.7 KB checked in by maximinus_parpg, 11 years ago (diff)

Large restructure of PC and NPC classes.
Data seperation is a lot cleaner.
Again some old Rio code removed.

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 fife
19from datetime import date
20from scripts.common.eventlistenerbase import EventListenerBase
21from loaders import loadMapFile
22from agents.hero import Hero
23from agents.npc import NPC
24from settings import Setting
25
26TDS = Setting()
27
28# this file should be the meta-file for all FIFE-related code
29# engine.py handles is our data model, whilst this is our view
30# in order to not replicate data, some of our data model will naturally
31# reside on this side of the fence (PC xpos and ypos, for example).
32# we should aim to never replicate any data as this leads to maintainance
33# issues (and just looks plain bad).
34# however, any logic needed to resolve this should sit in engine.py
35
36class MapListener(fife.MapChangeListener):
37    """This class listens to changes happening on the map.
38       Since in theory we initiate these ourselves, do we need this class?"""
39    def __init__(self, map):
40        fife.MapChangeListener.__init__(self)
41
42    def onMapChanged(self, map, changedLayers):
43        pass
44
45    def onLayerCreate(self, map, layer):
46        pass
47
48    def onLayerDelete(self, map, layer):
49        pass
50
51class Map:
52    def __init__(self,fife_map):
53        self.listener=MapListener
54        self.map=fife_map
55
56class World(EventListenerBase):
57    """World holds the data needed by fife to render the engine
58       The engine keeps a copy of this class"""
59    def __init__(self, engine):
60        super(World, self).__init__(engine, regMouse=True, regKeys=True)
61        self.engine=engine
62        self.eventmanager=engine.getEventManager()
63        self.model=engine.getModel()
64        self.view=self.engine.getView()
65        self.quitFunction=None
66        self.mouseCallback=None
67
68    def reset(self):
69        """Rest the map to default settings"""
70        self.transitions=[]
71        self.PC=None
72        self.npcs=[]
73        self.map,self.agent_layer=None,None
74        self.cameras={}
75        self.PC=None
76        self.npcs=[]
77        self.cur_cam2_x,self.initial_cam2_x,self.cam2_scrolling_right=0,0,True
78        self.target_rotation=0
79
80    def load(self,filename):
81        """Load a map given the filename
82           TODO: a map should only contain static items and floor tiles
83           Everything else should be loaded from the engine, because it
84           is subject to change"""
85        self.reset()
86        self.map=loadMapFile(filename,self.engine)
87        self.maplistener=MapListener(self.map)
88
89        # there must be a PC object on the objects layer!
90        self.agent_layer=self.map.getLayer('ObjectLayer')
91        # it's possible there's no transition layer
92        size=len('TransitionLayer')
93        for layer in self.map.getLayers():
94            # could be many layers, but hopefully no more than 3
95            if(layer.getId()[:size]=='TransitionLayer'):
96                self.transitions.append(self.map.getLayer(layer.getId()))
97
98        # init the camera
99        for cam in self.view.getCameras():
100            self.cameras[cam.getId()] = cam
101        self.view.resetRenderers()
102        self.target_rotation = self.cameras['main'].getRotation()
103        self.cord_render=self.cameras['main'].getRenderer('CoordinateRenderer')
104
105    def addPC(self,agent):
106        """Add the player character to the map"""
107        # actually this is real easy, we just have to
108        # attach the main camera to the PC
109        self.cameras['main'].attach(agent)
110   
111    def addObject(self,xpos,ypos,name):
112        """Add an object or an NPC to the map
113           It makes no difference to fife which is which"""
114        obj=self.agent_layer.createInstance(
115                self.model.getObject(str(name),"PARPG"),
116                fife.ExactModelCoordinate(xpos,ypos,0.0),str(name))
117        obj.setRotation(0)
118        fife.InstanceVisual.create(obj)
119
120    # all key / mouse event handling routines go here
121    def keyPressed(self, evt):
122        """When a key is depressed, fife calls this routine."""
123        key=evt.getKey()
124        keyval = key.getValue()
125
126        if(keyval==key.Q):
127            # we need to quit the game
128            self.quitGame()
129        if(keyval==key.T):
130            self.toggle_renderer('GridRenderer')
131        if(keyval==key.F1):
132            # display the help screen and pause the game
133            self.displayHelp()
134        if(keyval==key.F5):
135            # logic would say we use similar code to above and toggle
136            # logic here does not work, my friend :-(
137            self.cord_render.setEnabled(not self.cord_render.isEnabled())
138        if(keyval==key.F7):
139            # F7 saves a screenshot to fife/clients/parpg/screenshots
140            # TODO: add a time stamp as well as a date stamp
141            t="screenshots/screen-%s.png" % date.today().strftime('%Y-%m-%d')
142            self.engine.getRenderBackend().captureScreen(t)
143
144    def mousePressed(self, evt):
145        """If a mouse button is pressed down, fife cals this routine
146           Currently we only check for a left click, and we assume this is on
147           the map"""
148        clickpoint = fife.ScreenPoint(evt.getX(), evt.getY())
149        if (evt.getButton()==fife.MouseEvent.LEFT):
150            target_mapcoord=self.cameras['main'].toMapCoordinates(clickpoint,
151                                                                  False)
152            target_mapcoord.z = 0
153            l=fife.Location(self.agent_layer)
154            l.setMapCoordinates(target_mapcoord)
155            self.mouseCallback(l)
156           
157    def toggle_renderer (self,r_name):
158        """Enable or disable the renderer named `r_name`"""
159        renderer = self.cameras['main'].getRenderer('GridRenderer')
160        renderer.setEnabled(not renderer.isEnabled())
161
162    def displayHelp(self):
163        """Displays the pop-up info and help screen"""
164        print "Help not yet coded"
165
166    def quitGame(self):
167        """Called when user requests to quit game
168           Just calls the ApplicationListener to do the quit"""
169        if(self.quitFunction!=None):
170            self.quitFunction()
171
172    def pump(self):
173        """Routine called during each frame. Our main loop is in ./run.py
174           We ignore this main loop (but FIFE complains if it is missing)"""
175        pass
176
Note: See TracBrowser for help on using the repository browser.