source: trunk/PARPG/scripts/engine.py @ 55

Revision 55, 5.1 KB checked in by maximinus_parpg, 11 years ago (diff)

Objects now loaded from seperate XML file.
Cleaned up some small areas in various .py files
Added crate details.
Added some simple documentation in world.py
Removed some remaining RIO code that was not needed.

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
18# there should be NO references to FIFE here!
19from xml.sax import make_parser
20from xml.sax.handler import ContentHandler
21from agents.hero import Hero
22from agents.npc import NPC
23
24# design note:
25# there is a map file that FIFE reads. We use that file for half the map
26# format because the map editor in FIFE uses it, and secondly because it
27# save us writing a bunch of new code.
28# However, the objects and characters on a map are liable to change
29# whilst the game is being run, so when we change the map, we need to
30# to grab the objects and npc data EITHER from the engine state, or grab
31# from another file if in their initial state
32# This other file has the name AAA_objects.xml where AAA.xml is the name
33# of the original mapfile.
34
35class LocalXMLParser(ContentHandler):
36    """Class inherits from ContantHandler, and is used to parse the
37       local objects data"""
38    def __init__(self):
39        self.search="objects"
40        self.pc=None
41        self.objects=[]
42        self.npcs=[]
43   
44    def startElement(self,name,attrs):
45        """Called every time we meet a new element in the XML file"""
46        # we are only looking for the 'layer' elements, the rest we ignore
47        if(name=="PC"):
48            # already have a PC?
49            if(self.pc!=None):
50                sys.stderr.write("Error: 2 PC characters defined")
51                sys.exit(False)
52            # grab the data and store that as well
53            try:
54                xpos=attrs.getValue("xpos")
55                ypos=attrs.getValue("ypos")
56            except(KeyError):
57                sys.stderr.write("Error: Data missing in PC definition")
58                sys.exit(False)
59            # store for later
60            self.pc=[xpos,ypos]
61        elif(name=="NPC"):
62            # let's parse and add the data
63            try:
64                xpos=attrs.getValue("xpos")
65                ypos=attrs.getValue("ypos")
66                gfx=attrs.getValue("gfx")
67            except(KeyError):
68                sys.stderr.write("Error: Data missing in NPC definition\n")
69                sys.exit(False)
70            # now we have the data, save it for later
71            self.npcs.append([xpos,ypos,gfx])
72        elif(name=="object"):
73            # same old same old
74            try:
75                xpos=attrs.getValue("xpos")
76                ypos=attrs.getValue("ypos")
77                gfx=attrs.getValue("gfx")
78            except(KeyError):
79                sys.stderr.write("Error: Data missing in object definition\n")
80                sys.exit(False)
81            # now we have the data, save it for later
82            self.objects.append([xpos,ypos,gfx])
83
84class Engine:
85    """Engine holds the logic for the game
86       Since some data (object position and so forth) is held in the
87       fife, and would be pointless to replicate, we hold a instance of
88       the fife view here. This also prevents us from just having a
89       function heavy controller"""
90    def __init__(self,view):
91        self.view=view
92        self.PC=None
93        self.npcs=[]
94        self.objects=[]
95
96    def loadObjects(self,filename):
97        """Load objects from the XML file
98           Returns True if it worked, False otherwise"""
99        try:
100            objects_file=open(filename,'rt')
101        except(IOError):
102            sys.stderr.write("Error: Can't find objects file\n")
103            return False
104        # now open and read the XML file
105        parser=make_parser()
106        cur_handler=LocalXMLParser()
107        parser.setContentHandler(cur_handler)
108        parser.parse(objects_file)
109        objects_file.close()
110        # must have at least 1 PC
111        if(cur_handler.pc==None):
112            sys.stderr.write("Error: No PC defined\n")
113            sys.exit(False)
114        # transfer the data
115        self.pc=cur_handler.pc
116        self.npcs=cur_handler.npcs
117        self.objects=cur_handler.objects
118        return True
119
120    def addObjects(self):
121        """Add all of the objects we found into the fife map"""
122        for i in self.objects:
123            self.view.addObject(float(i[0]),float(i[1]),i[2])
124
125    def loadMap(self,map_file):
126        """Load a new map
127           TODO: needs some error checking"""
128        # first we go and grab the character details
129        self.loadObjects(map_file[:-4]+"_objects.xml")
130        # then we let FIFE load the rest of the map
131        self.view.load(map_file)
132        # finally, we update FIFE with the PC, NPC and object details
133        self.view.addPC(self.pc[0],self.pc[1])
134        self.addObjects()
135
Note: See TracBrowser for help on using the repository browser.