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

Revision 54, 4.9 KB checked in by maximinus_parpg, 11 years ago (diff)

Set Model / View data model for PARPG.
Code no longer looks like Rio demo.
Started to split map from objects.
Added crate and NPC character.

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