class World(EventListenerBase): def __init__(self, engine): super(World, self).__init__(engine, regKeys=True) self.engine = engine self.eventmanager = engine.getEventManager() self.model = engine.getModel() # self.filename = '' # self.pump_ctr = 0 # for testing purposis # self.ctrldown = False # self.instancemenu = None self.instance_to_agent = {} # self.dynamic_widgets = {} def load(self, filename): self.filename = filename # self.reset() loader = fife.MapLoader(self.engine.getModel(), self.engine.getVFS(), self.engine.getImageManager(), self.engine.getRenderBackend()) if loader.isLoadable(filename): self.map = loader.load(filename) # self.initCameras() self.initAgents() # Set background color self.engine.getRenderBackend().setBackgroundColor(80, 80, 255) def initAgents(self): self.agentlayer = self.map.getLayer('MapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'hero', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start()
def initAgents(self): """ Setup agents. For this techdemo we have a very simple 'active things on the map' model, which is called agents. All rio maps will have a separate layer for them. Note that we keep a mapping from map instances (C++ model of stuff on the map) to the python agents for later reference. """ self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(TDS, self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() # Fog of War stuff #self.hero.agent.setVisitor(True) #self.hero.agent.setVisitorRadius(2) #self.girl.agent.setVisitor(True) #self.girl.agent.setVisitorRadius(1) self.beekeepers = create_anonymous_agents(TDS, self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() # Clouds are currently defunct. cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(TDS, self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05)
def initAgents(self): """ Setup agents. For this techdemo we have a very simple 'active things on the map' model, which is called agents. All rio maps will have a separate layer for them. Note that we keep a mapping from map instances (C++ model of stuff on the map) to the python agents for later reference. """ self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(TDS, self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() self.beekeepers = create_anonymous_agents(TDS, self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() # Clouds are currently defunct. cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(TDS, self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05)
def load(self, filename): self.filename = filename self.reset() self.map = loadMapFile(filename, self.engine) self.maplistener = MapListener(self.map) self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() self.beekeepers = create_anonymous_agents(self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05) for cam in self.view.getCameras(): self.cameras[cam.getId()] = cam self.cameras['main'].attach(self.hero.agent) self.view.resetRenderers() renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main']) textfont = self.engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(TDS.readSetting("FontGlyphs", strip=False))); renderer.changeDefaultFont(textfont) renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small']) renderer.changeDefaultFont(None) renderer = self.cameras['main'].getRenderer('CoordinateRenderer') renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("CoordinateLayerName")))) renderer = self.cameras['main'].getRenderer('QuadTreeRenderer') renderer.setEnabled(True) renderer.clearActiveLayers() if str(TDS.readSetting("QuadTreeLayerName")): renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("QuadTreeLayerName")))) self.cameras['small'].getLocationRef().setExactLayerCoordinates( fife.ExactModelCoordinate( 40.0, 40.0, 0.0 )) self.initial_cam2_x = self.cameras['small'].getLocation().getExactLayerCoordinates().x self.cur_cam2_x = self.initial_cam2_x self.cam2_scrolling_right = True self.cameras['small'].setEnabled(False) self.target_rotation = self.cameras['main'].getRotation()
def initAgents(self): """ Setup agents. For this techdemo we have a very simple 'active things on the map' model, which is called agents. All rio maps will have a separate layer for them. Note that we keep a mapping from map instances (C++ model of stuff on the map) to the python agents for later reference. """ self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(TDS, self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() self.bees = create_anonymous_agents(TDS, self.model, 'bee', self.agentlayer,Bee) for bee in self.bees: self.instance_to_agent[bee.agent.getFifeId()] = bee bee.start() self.beekeepers = create_anonymous_agents(TDS, self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() self.tourist_male2 = create_anonymous_agents(TDS, self.model, 'tourist_male2',self.agentlayer, Tourist_male2) for tourist_male2 in self.tourist_male2: self.instance_to_agent[tourist_male2.agent.getFifeId()] = tourist_male2 tourist_male2.start() self.hippie_priest = Hippie_priest(TDS, self.model, 'hippie_priest', self.agentlayer) self.instance_to_agent[self.hippie_priest.agent.getFifeId()] = self.hippie_priest self.hippie_priest.start()
def _pump(self): """ This function gets called every frame. This is where you want to call your main game logic code. """ if not self._mapLoaded: self.loadMap("maps/testmap.xml") self._camera = self._map.getCamera("camera1") self._actorlayer = self._map.getLayer("actor_layer") self.hero = Hero(self._settings, self.engine.getModel(), 'player', self._actorlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self._camera.attach(self.hero.agent) if len(self._keylistener._pressedKeys): moveVec = (0,0) for key in self._keylistener._pressedKeys: if (key == fife.Key.A): moveVec = (moveVec[0]-1,moveVec[1]-1) elif (key == fife.Key.D): moveVec = (moveVec[0]+1,moveVec[1]+1) elif (key == fife.Key.W): moveVec = (moveVec[0]+1,moveVec[1]-1) elif (key == fife.Key.S): moveVec = (moveVec[0]-1,moveVec[1]+1) if moveVec[0] != 0 or moveVec[1] != 0: x, y = moveVec if abs(x) > 1: x /= abs(x) if abs(y) > 1: y /= abs(y) self.walkPlayer(x, y)
class World(EventListenerBase): def __init__(self, engine): super(World, self).__init__(engine, regMouse=True, regKeys=True) self.engine = engine self.eventmanager = engine.getEventManager() self.model = engine.getModel() self.view = self.engine.getView() self.filename = '' self.pump_ctr = 0 # for testing purposis self.ctrldown = False self.instancemenu = None self.instance_to_agent = {} self.dynamic_widgets = {} def show_instancemenu(self, clickpoint, instance): if instance.getFifeId() == self.hero.agent.getFifeId(): return dynamicbuttons = ('moveButton', 'talkButton', 'kickButton', 'inspectButton') if not self.instancemenu: self.instancemenu = pychan.loadXML('gui/instancemenu.xml') self.instancemenu.mapEvents({ 'moveButton' : self.onMoveButtonPress, 'talkButton' : self.onTalkButtonPress, 'kickButton' : self.onKickButtonPress, 'inspectButton' : self.onInspectButtonPress, }) for btn in dynamicbuttons: self.dynamic_widgets[btn] = self.instancemenu.findChild(name=btn) for btn in dynamicbuttons: try: self.instancemenu.removeChild(self.dynamic_widgets[btn]) except pychan.exceptions.RuntimeError: pass self.instancemenu.clickpoint = clickpoint self.instancemenu.instance = instance self.instancemenu.addChild(self.dynamic_widgets['inspectButton']) target_distance = self.hero.agent.getLocationRef().getLayerDistanceTo(instance.getLocationRef()) if target_distance > 3.0: self.instancemenu.addChild(self.dynamic_widgets['moveButton']) else: if self.instance_to_agent.has_key(instance.getFifeId()): self.instancemenu.addChild(self.dynamic_widgets['talkButton']) self.instancemenu.addChild(self.dynamic_widgets['kickButton']) self.instancemenu.position = (clickpoint.x, clickpoint.y) self.instancemenu.show() def hide_instancemenu(self): if self.instancemenu: self.instancemenu.hide() def reset(self): self.map, self.agentlayer = None, None self.cameras = {} self.hero, self.girl, self.clouds, self.beekeepers = None, None, [], [] self.cur_cam2_x, self.initial_cam2_x, self.cam2_scrolling_right = 0, 0, True self.target_rotation = 0 self.instance_to_agent = {} def load(self, filename): self.filename = filename self.reset() self.map = loadMapFile(filename, self.engine) self.maplistener = MapListener(self.map) self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() self.beekeepers = create_anonymous_agents(self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05) for cam in self.view.getCameras(): self.cameras[cam.getId()] = cam self.cameras['main'].attach(self.hero.agent) self.view.resetRenderers() renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main']) textfont = self.engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(TDS.readSetting("FontGlyphs", strip=False))); renderer.changeDefaultFont(textfont) renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small']) renderer.changeDefaultFont(None) renderer = self.cameras['main'].getRenderer('CoordinateRenderer') renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("CoordinateLayerName")))) renderer = self.cameras['main'].getRenderer('QuadTreeRenderer') renderer.setEnabled(True) renderer.clearActiveLayers() if str(TDS.readSetting("QuadTreeLayerName")): renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("QuadTreeLayerName")))) self.cameras['small'].getLocationRef().setExactLayerCoordinates( fife.ExactModelCoordinate( 40.0, 40.0, 0.0 )) self.initial_cam2_x = self.cameras['small'].getLocation().getExactLayerCoordinates().x self.cur_cam2_x = self.initial_cam2_x self.cam2_scrolling_right = True self.cameras['small'].setEnabled(False) self.target_rotation = self.cameras['main'].getRotation() def save(self, filename): saveMapFile(filename, self.engine, self.map) def keyPressed(self, evt): keyval = evt.getKey().getValue() keystr = evt.getKey().getAsString().lower() if keystr == 't': r = self.cameras['main'].getRenderer('GridRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 'c': r = self.cameras['main'].getRenderer('CoordinateRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 's': c = self.cameras['small'] c.setEnabled(not c.isEnabled()) elif keystr == 'r': pass # self.model.deleteMaps() # self.metamodel.deleteDatasets() # self.view.clearCameras() # self.load(self.filename) elif keystr == 'o': self.target_rotation = (self.target_rotation + 90) % 360 elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = True def keyReleased(self, evt): keyval = evt.getKey().getValue() if keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = False def mouseWheelMovedUp(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() * 1.05) def mouseWheelMovedDown(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() / 1.05) def changeRotation(self): currot = self.cameras['main'].getRotation() if self.target_rotation != currot: self.cameras['main'].setRotation((currot + 5) % 360) def mousePressed(self, evt): if evt.isConsumedByWidgets(): return clickpoint = fife.ScreenPoint(evt.getX(), evt.getY()) if (evt.getButton() == fife.MouseEvent.LEFT): self.hide_instancemenu() target_mapcoord = self.cameras['main'].toMapCoordinates(clickpoint, False) target_mapcoord.z = 0 l = fife.Location(self.agentlayer) l.setMapCoordinates(target_mapcoord) self.hero.run(l) if (evt.getButton() == fife.MouseEvent.RIGHT): instances = self.cameras['main'].getMatchingInstances(clickpoint, self.agentlayer) print "selected instances on agent layer: ", [i.getObject().getId() for i in instances] if instances: self.show_instancemenu(clickpoint, instances[0]) def mouseMoved(self, evt): renderer = fife.InstanceRenderer.getInstance(self.cameras['main']) renderer.removeAllOutlines() pt = fife.ScreenPoint(evt.getX(), evt.getY()) instances = self.cameras['main'].getMatchingInstances(pt, self.agentlayer); for i in instances: if i.getObject().getId() in ('girl', 'beekeeper'): renderer.addOutlined(i, 173, 255, 47, 2) def onConsoleCommand(self, command): result = '' try: result = str(eval(command)) except: pass return result def onMoveButtonPress(self): self.hide_instancemenu() self.hero.run(self.instancemenu.instance.getLocationRef()) def onTalkButtonPress(self): self.hide_instancemenu() instance = self.instancemenu.instance self.hero.talk(instance.getLocationRef()) if instance.getObject().getId() == 'beekeeper': beekeeperTexts = TDS.readSetting("beekeeperTexts", type='list', text=True) txtindex = random.randint(0, len(beekeeperTexts) - 1) instance.say(beekeeperTexts[txtindex], 5000) if instance.getObject().getId() == 'girl': girlTexts = TDS.readSetting("girlTexts", type='list', text=True) txtindex = random.randint(0, len(girlTexts) - 1) instance.say(girlTexts[txtindex], 5000) def onKickButtonPress(self): self.hide_instancemenu() self.hero.kick(self.instancemenu.instance.getLocationRef()) self.instancemenu.instance.say('Hey!', 1000) def onInspectButtonPress(self): self.hide_instancemenu() inst = self.instancemenu.instance saytext = ['Engine told me that this instance has'] if inst.getId(): saytext.append(' name %s,' % inst.getId()) saytext.append(' ID %s and' % inst.getFifeId()) saytext.append(' object name %s' % inst.getObject().getId()) self.hero.agent.say('\n'.join(saytext), 3500) def pump(self): if self.cameras['small'].isEnabled(): loc = self.cameras['small'].getLocation() c = loc.getExactLayerCoordinatesRef() if self.cam2_scrolling_right: self.cur_cam2_x = c.x = c.x+0.1 if self.cur_cam2_x > self.initial_cam2_x+10: self.cam2_scrolling_right = False else: self.cur_cam2_x = c.x = c.x-0.1 if self.cur_cam2_x < self.initial_cam2_x-10: self.cam2_scrolling_right = True self.cameras['small'].setLocation(loc) self.changeRotation() self.pump_ctr += 1
def initAgents(self): self.agentlayer = self.map.getLayer('MapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'hero', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start()
class World(EventListenerBase): """ The world! This class handles: setup of map view (cameras ...) loading the map GUI for right clicks handles mouse/key events which aren't handled by the GUI. ( by inheriting from EventlistenerBase ) That's obviously too much, and should get factored out. """ def __init__(self, engine): super(World, self).__init__(engine, regMouse=True, regKeys=True) self.engine = engine self.eventmanager = engine.getEventManager() self.model = engine.getModel() self.filename = '' self.pump_ctr = 0 # for testing purposis self.ctrldown = False self.instancemenu = None self.instance_to_agent = {} self.dynamic_widgets = {} self.light_intensity = 1 self.light_sources = 0 self.lightmodel = int(TDS.get("FIFE", "Lighting")) self.soundmanager = SoundManager(self.engine) self.music = None def show_instancemenu(self, clickpoint, instance): """ Build and show a popupmenu for an instance that the player clicked on. The available actions are dynamically added to the menu (and mapped to the onXYZ functions). """ if instance.getFifeId() == self.hero.agent.getFifeId(): return # Create the popup. self.build_instancemenu() self.instancemenu.clickpoint = clickpoint self.instancemenu.instance = instance # Add the buttons according to circumstances. self.instancemenu.addChild(self.dynamic_widgets['inspectButton']) target_distance = self.hero.agent.getLocationRef().getLayerDistanceTo(instance.getLocationRef()) if target_distance > 3.0: self.instancemenu.addChild(self.dynamic_widgets['moveButton']) else: if self.instance_to_agent.has_key(instance.getFifeId()): self.instancemenu.addChild(self.dynamic_widgets['talkButton']) self.instancemenu.addChild(self.dynamic_widgets['kickButton']) # And show it :) self.instancemenu.position = (clickpoint.x, clickpoint.y) self.instancemenu.show() def build_instancemenu(self): """ Just loads the menu from an XML file and hooks the events up. The buttons are removed and later re-added if appropiate. """ self.hide_instancemenu() dynamicbuttons = ('moveButton', 'talkButton', 'kickButton', 'inspectButton') self.instancemenu = pychan.loadXML('gui/instancemenu.xml') self.instancemenu.mapEvents({ 'moveButton' : self.onMoveButtonPress, 'talkButton' : self.onTalkButtonPress, 'kickButton' : self.onKickButtonPress, 'inspectButton' : self.onInspectButtonPress, }) for btn in dynamicbuttons: self.dynamic_widgets[btn] = self.instancemenu.findChild(name=btn) self.instancemenu.removeAllChildren() def hide_instancemenu(self): if self.instancemenu: self.instancemenu.hide() def reset(self): """ Clear the agent information and reset the moving secondary camera state. """ if self.music: self.music.stop() self.map, self.agentlayer = None, None self.cameras = {} self.hero, self.girl, self.clouds, self.beekeepers = None, None, [], [] self.cur_cam2_x, self.initial_cam2_x, self.cam2_scrolling_right = 0, 0, True self.target_rotation = 0 self.instance_to_agent = {} def load(self, filename): """ Load a xml map and setup agents and cameras. """ self.filename = filename self.reset() loader = fife.MapLoader(self.engine.getModel(), self.engine.getVFS(), self.engine.getImageManager(), self.engine.getRenderBackend()) if loader.isLoadable(filename): self.map = loader.load(filename) self.initAgents() self.initCameras() #Set background color self.engine.getRenderBackend().setBackgroundColor(80,80,255) if int(TDS.get("FIFE", "PlaySounds")): # play track as background music self.music = self.soundmanager.createSoundEmitter('music/rio_de_hola.ogg') self.music.looping = True self.music.gain = 128.0 self.music.play() self.waves = self.soundmanager.createSoundEmitter('sounds/waves.ogg') self.waves.looping = True self.waves.gain = 16.0 self.waves.play() def initAgents(self): """ Setup agents. For this techdemo we have a very simple 'active things on the map' model, which is called agents. All rio maps will have a separate layer for them. Note that we keep a mapping from map instances (C++ model of stuff on the map) to the python agents for later reference. """ self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(TDS, self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() self.beekeepers = create_anonymous_agents(TDS, self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() # Clouds are currently defunct. cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(TDS, self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05) def initCameras(self): """ Before we can actually see something on screen we have to specify the render setup. This is done through Camera objects which offer a viewport on the map. For this techdemo two cameras are used. One follows the hero(!) via 'attach' the other one scrolls around a bit (see the pump function). """ camera_prefix = self.filename.rpartition('.')[0] # Remove file extension camera_prefix = camera_prefix.rpartition('/')[2] # Remove path camera_prefix += '_' for cam in self.map.getCameras(): camera_id = cam.getId().replace(camera_prefix, '') self.cameras[camera_id] = cam cam.resetRenderers() self.cameras['main'].attach(self.hero.agent) # Floating text renderers currntly only support one font. # ... so we set that up. # You'll se that for our demo we use a image font, so we have to specify the font glyphs # for that one. renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main']) textfont = pychan.manager.hook.guimanager.createFont('fonts/rpgfont.png', 0, str(TDS.get("FIFE", "FontGlyphs"))); renderer.setFont(textfont) renderer.activateAllLayers(self.map) renderer.setBackground(100, 255, 100, 165) renderer.setBorder(50, 255, 50) renderer.setEnabled(True) # Activate the grid renderer on all layers renderer = self.cameras['main'].getRenderer('GridRenderer') renderer.activateAllLayers(self.map) # The small camera shouldn't be cluttered by the 'humm di dums' of our hero. # So we disable the renderer simply by setting its font to None. renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small']) renderer.setFont(None) # The following renderers are used for debugging. # Note that by default ( that is after calling View.resetRenderers or Camera.resetRenderers ) # renderers will be handed all layers. That's handled here. renderer = fife.CoordinateRenderer.getInstance(self.cameras['main']) renderer.setFont(textfont) renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer(str(TDS.get("rio", "CoordinateLayerName")))) renderer = self.cameras['main'].getRenderer('QuadTreeRenderer') renderer.setEnabled(True) renderer.clearActiveLayers() if str(TDS.get("rio", "QuadTreeLayerName")): renderer.addActiveLayer(self.map.getLayer(str(TDS.get("rio", "QuadTreeLayerName")))) # If Light is enabled in settings then init the lightrenderer. if self.lightmodel != 0: renderer = fife.LightRenderer.getInstance(self.cameras['main']) renderer.setEnabled(True) renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer('TechdemoMapGroundObjectLayer')) # Set up the second camera # NOTE: We need to explicitly call setLocation, there's a bit of a messup in the Camera code. self.cameras['small'].setLocation(self.hero.agent.getLocation()) self.cameras['small'].attach(self.girl.agent) self.target_rotation = self.cameras['main'].getRotation() def save(self, filename): saveMapFile(filename, self.engine, self.map) def getInstancesAt(self, clickpoint): """ Query the main camera for instances on our active(agent) layer. """ return self.cameras['main'].getMatchingInstances(clickpoint, self.agentlayer) def getLocationAt(self, clickpoint): """ Query the main camera for the Map location (on the agent layer) that a screen point refers to. """ target_mapcoord = self.cameras['main'].toMapCoordinates(clickpoint, False) target_mapcoord.z = 0 location = fife.Location(self.agentlayer) location.setMapCoordinates(target_mapcoord) return location def keyPressed(self, evt): keyval = evt.getKey().getValue() keystr = evt.getKey().getAsString().lower() if keystr == 't': r = self.cameras['main'].getRenderer('GridRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 'c': r = self.cameras['main'].getRenderer('CoordinateRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 's': c = self.cameras['small'] c.setEnabled(not c.isEnabled()) elif keystr == 'r': self.model.deleteMaps() self.load(self.filename) elif keystr == 'o': self.target_rotation = (self.target_rotation + 90) % 360 elif keystr == '2': self.lightIntensity(0.1) elif keystr == '1': self.lightIntensity(-0.1) elif keystr == '5': self.lightSourceIntensity(25) elif keystr == '4': self.lightSourceIntensity(-25) elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = True def keyReleased(self, evt): keyval = evt.getKey().getValue() if keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = False def mouseWheelMovedUp(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() * 1.05) def mouseWheelMovedDown(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() / 1.05) def changeRotation(self): """ Smoothly change the main cameras rotation until the current target rotation is reached. """ currot = self.cameras['main'].getRotation() if self.target_rotation != currot: self.cameras['main'].setRotation((currot + 5) % 360) def mousePressed(self, evt): if evt.isConsumedByWidgets(): return clickpoint = fife.ScreenPoint(evt.getX(), evt.getY()) if (evt.getButton() == fife.MouseEvent.LEFT): self.hide_instancemenu() self.hero.run( self.getLocationAt(clickpoint) ) if (evt.getButton() == fife.MouseEvent.RIGHT): instances = self.getInstancesAt(clickpoint) print "selected instances on agent layer: ", [i.getObject().getId() for i in instances] if instances: self.show_instancemenu(clickpoint, instances[0]) def mouseMoved(self, evt): renderer = fife.InstanceRenderer.getInstance(self.cameras['main']) renderer.removeAllOutlines() pt = fife.ScreenPoint(evt.getX(), evt.getY()) instances = self.getInstancesAt(pt); for i in instances: if i.getObject().getId() in ('girl', 'beekeeper'): renderer.addOutlined(i, 173, 255, 47, 2) def lightIntensity(self, value): if self.light_intensity+value <= 1 and self.light_intensity+value >= 0: self.light_intensity = self.light_intensity + value if self.lightmodel == 1: self.cameras['main'].setLightingColor(self.light_intensity, self.light_intensity, self.light_intensity) def lightSourceIntensity(self, value): if self.light_sources+value <= 255 and self.light_sources+value >= 0: self.light_sources = self.light_sources+value renderer = fife.LightRenderer.getInstance(self.cameras['main']) renderer.removeAll("beekeeper_simple_light") renderer.removeAll("hero_simple_light") renderer.removeAll("girl_simple_light") if self.lightmodel == 1: node = fife.RendererNode(self.hero.agent) renderer.addSimpleLight("hero_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255) node = fife.RendererNode(self.girl.agent) renderer.addSimpleLight("girl_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255) for beekeeper in self.beekeepers: node = fife.RendererNode(beekeeper.agent) renderer.addSimpleLight("beekeeper_simple_light", node, self.light_sources, 120, 32, 1, 1, 255, 255, 255) def onConsoleCommand(self, command): result = '' try: result = str(eval(command)) except Exception, e: result = str(e) return result
class World(EventListenerBase): """ The world! This class handles: setup of map view (cameras ...) loading the map GUI for right clicks handles mouse/key events which aren't handled by the GUI. ( by inheriting from EventlistenerBase ) That's obviously too much, and should get factored out. """ def __init__(self, engine): super(World, self).__init__(engine, regMouse=True, regKeys=True) self.engine = engine self.eventmanager = engine.getEventManager() self.model = engine.getModel() self.filename = '' self.pump_ctr = 0 # for testing purposis self.ctrldown = False self.instancemenu = None self.instance_to_agent = {} self.dynamic_widgets = {} self.light_intensity = 1 self.light_sources = 0 self.lightmodel = int(TDS.get("FIFE", "Lighting")) self.soundmanager = SoundManager(self.engine) self.music = None def show_instancemenu(self, clickpoint, instance): """ Build and show a popupmenu for an instance that the player clicked on. The available actions are dynamically added to the menu (and mapped to the onXYZ functions). """ if instance.getFifeId() == self.hero.agent.getFifeId(): return # Create the popup. self.build_instancemenu() self.instancemenu.clickpoint = clickpoint self.instancemenu.instance = instance # Add the buttons according to circumstances. self.instancemenu.addChild(self.dynamic_widgets['inspectButton']) target_distance = self.hero.agent.getLocationRef().getLayerDistanceTo(instance.getLocationRef()) if target_distance > 3.0: self.instancemenu.addChild(self.dynamic_widgets['moveButton']) else: if self.instance_to_agent.has_key(instance.getFifeId()): self.instancemenu.addChild(self.dynamic_widgets['talkButton']) self.instancemenu.addChild(self.dynamic_widgets['kickButton']) # And show it :) self.instancemenu.position = (clickpoint.x, clickpoint.y) self.instancemenu.show() def build_instancemenu(self): """ Just loads the menu from an XML file and hooks the events up. The buttons are removed and later re-added if appropiate. """ self.hide_instancemenu() dynamicbuttons = ('moveButton', 'talkButton', 'kickButton', 'inspectButton') self.instancemenu = pychan.loadXML('gui/instancemenu.xml') self.instancemenu.mapEvents({ 'moveButton' : self.onMoveButtonPress, 'talkButton' : self.onTalkButtonPress, 'kickButton' : self.onKickButtonPress, 'inspectButton' : self.onInspectButtonPress, }) for btn in dynamicbuttons: self.dynamic_widgets[btn] = self.instancemenu.findChild(name=btn) self.instancemenu.removeAllChildren() def hide_instancemenu(self): if self.instancemenu: self.instancemenu.hide() def reset(self): """ Clear the agent information and reset the moving secondary camera state. """ if self.music: self.music.stop() self.map, self.agentlayer = None, None self.cameras = {} self.hero, self.girl, self.clouds, self.beekeepers = None, None, [], [] self.cur_cam2_x, self.initial_cam2_x, self.cam2_scrolling_right = 0, 0, True self.target_rotation = 0 self.instance_to_agent = {} def load(self, filename): """ Load a xml map and setup agents and cameras. """ self.filename = filename self.reset() loader = fife.MapLoader(self.engine.getModel(), self.engine.getVFS(), self.engine.getImageManager(), self.engine.getRenderBackend()) if loader.isLoadable(filename): self.map = loader.load(filename) self.initAgents() self.initCameras() #Set background color self.engine.getRenderBackend().setBackgroundColor(80,80,255) if int(TDS.get("FIFE", "PlaySounds")): # play track as background music self.music = self.soundmanager.createSoundEmitter('music/rio_de_hola.ogg') self.music.looping = True self.music.gain = 128.0 self.music.play() self.waves = self.soundmanager.createSoundEmitter('sounds/waves.ogg') self.waves.looping = True self.waves.gain = 16.0 self.waves.play() def initAgents(self): """ Setup agents. For this techdemo we have a very simple 'active things on the map' model, which is called agents. All rio maps will have a separate layer for them. Note that we keep a mapping from map instances (C++ model of stuff on the map) to the python agents for later reference. """ self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer') self.hero = Hero(TDS, self.model, 'PC', self.agentlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self.girl = Girl(TDS, self.model, 'NPC:girl', self.agentlayer) self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl self.girl.start() # Fog of War stuff #self.hero.agent.setVisitor(True) #self.hero.agent.setVisitorRadius(2) #self.girl.agent.setVisitor(True) #self.girl.agent.setVisitorRadius(1) self.beekeepers = create_anonymous_agents(TDS, self.model, 'beekeeper', self.agentlayer, Beekeeper) for beekeeper in self.beekeepers: self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper beekeeper.start() # Clouds are currently defunct. cloudlayer = self.map.getLayer('TechdemoMapTileLayer') self.clouds = create_anonymous_agents(TDS, self.model, 'Cloud', cloudlayer, Cloud) for cloud in self.clouds: cloud.start(0.1, 0.05) def initCameras(self): """ Before we can actually see something on screen we have to specify the render setup. This is done through Camera objects which offer a viewport on the map. For this techdemo two cameras are used. One follows the hero(!) via 'attach' the other one scrolls around a bit (see the pump function). """ camera_prefix = self.filename.rpartition('.')[0] # Remove file extension camera_prefix = camera_prefix.rpartition('/')[2] # Remove path camera_prefix += '_' for cam in self.map.getCameras(): camera_id = cam.getId().replace(camera_prefix, '') self.cameras[camera_id] = cam cam.resetRenderers() self.cameras['main'].attach(self.hero.agent) # Floating text renderers currntly only support one font. # ... so we set that up. # You'll se that for our demo we use a image font, so we have to specify the font glyphs # for that one. renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main']) textfont = get_manager().createFont('fonts/rpgfont.png', 0, str(TDS.get("FIFE", "FontGlyphs"))); renderer.setFont(textfont) renderer.activateAllLayers(self.map) renderer.setBackground(100, 255, 100, 165) renderer.setBorder(50, 255, 50) renderer.setEnabled(True) # Activate the grid renderer on all layers renderer = self.cameras['main'].getRenderer('GridRenderer') renderer.activateAllLayers(self.map) # The small camera shouldn't be cluttered by the 'humm di dums' of our hero. # So we disable the renderer simply by setting its font to None. renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small']) renderer.setFont(None) # The following renderers are used for debugging. # Note that by default ( that is after calling View.resetRenderers or Camera.resetRenderers ) # renderers will be handed all layers. That's handled here. renderer = fife.CoordinateRenderer.getInstance(self.cameras['main']) renderer.setFont(textfont) renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer(str(TDS.get("rio", "CoordinateLayerName")))) renderer = self.cameras['main'].getRenderer('QuadTreeRenderer') renderer.setEnabled(True) renderer.clearActiveLayers() if str(TDS.get("rio", "QuadTreeLayerName")): renderer.addActiveLayer(self.map.getLayer(str(TDS.get("rio", "QuadTreeLayerName")))) # If Light is enabled in settings then init the lightrenderer. if self.lightmodel != 0: renderer = fife.LightRenderer.getInstance(self.cameras['main']) renderer.setEnabled(True) renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer('TechdemoMapGroundObjectLayer')) # Fog of War stuff renderer = fife.CellRenderer.getInstance(self.cameras['main']) renderer.setEnabled(True) renderer.clearActiveLayers() renderer.addActiveLayer(self.map.getLayer('TechdemoMapGroundObjectLayer')) concimg = self.engine.getImageManager().load("misc/black_cell.png") maskimg = self.engine.getImageManager().load("misc/mask_cell.png") renderer.setConcealImage(concimg) renderer.setMaskImage(maskimg) renderer.setFogOfWarLayer(self.map.getLayer('TechdemoMapGroundObjectLayer')) #disable FoW by default. Users can turn it on with the 'f' key. renderer.setEnabledFogOfWar(False) #renderer.setEnabledBlocking(True) # Set up the second camera # NOTE: We need to explicitly call setLocation, there's a bit of a messup in the Camera code. self.cameras['small'].setLocation(self.hero.agent.getLocation()) self.cameras['small'].attach(self.girl.agent) self.target_rotation = self.cameras['main'].getRotation() def save(self, filename): saveMapFile(filename, self.engine, self.map) def getInstancesAt(self, clickpoint): """ Query the main camera for instances on our active(agent) layer. """ return self.cameras['main'].getMatchingInstances(clickpoint, self.agentlayer) def getLocationAt(self, clickpoint): """ Query the main camera for the Map location (on the agent layer) that a screen point refers to. """ target_mapcoord = self.cameras['main'].toMapCoordinates(clickpoint, False) target_mapcoord.z = 0 location = fife.Location(self.agentlayer) location.setMapCoordinates(target_mapcoord) return location def keyPressed(self, evt): keyval = evt.getKey().getValue() keystr = evt.getKey().getAsString().lower() if keystr == 't': r = self.cameras['main'].getRenderer('GridRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 'c': r = self.cameras['main'].getRenderer('CoordinateRenderer') r.setEnabled(not r.isEnabled()) elif keystr == 's': c = self.cameras['small'] c.setEnabled(not c.isEnabled()) elif keystr == 'r': self.model.deleteMaps() self.load(self.filename) elif keystr == 'f': renderer = fife.CellRenderer.getInstance(self.cameras['main']) renderer.setEnabledFogOfWar(not renderer.isEnabledFogOfWar()) self.cameras['main'].refresh() elif keystr == 'o': self.target_rotation = (self.target_rotation + 90) % 360 elif keystr == '2': self.lightIntensity(0.1) elif keystr == '1': self.lightIntensity(-0.1) elif keystr == '5': self.lightSourceIntensity(25) elif keystr == '4': self.lightSourceIntensity(-25) elif keystr == '0' or keystr == fife.Key.NUM_0: if self.ctrldown: self.cameras['main'].setZoom(1.0) elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = True def keyReleased(self, evt): keyval = evt.getKey().getValue() if keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL): self.ctrldown = False def mouseWheelMovedUp(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() * 1.05) def mouseWheelMovedDown(self, evt): if self.ctrldown: self.cameras['main'].setZoom(self.cameras['main'].getZoom() / 1.05) def changeRotation(self): """ Smoothly change the main cameras rotation until the current target rotation is reached. """ currot = self.cameras['main'].getRotation() if self.target_rotation != currot: self.cameras['main'].setRotation((currot + 5) % 360) def mousePressed(self, evt): if evt.isConsumedByWidgets(): return clickpoint = fife.ScreenPoint(evt.getX(), evt.getY()) if (evt.getButton() == fife.MouseEvent.LEFT): self.hide_instancemenu() self.hero.run( self.getLocationAt(clickpoint) ) if (evt.getButton() == fife.MouseEvent.RIGHT): instances = self.getInstancesAt(clickpoint) print "selected instances on agent layer: ", [i.getObject().getId() for i in instances] if instances: self.show_instancemenu(clickpoint, instances[0]) def mouseMoved(self, evt): renderer = fife.InstanceRenderer.getInstance(self.cameras['main']) renderer.removeAllOutlines() pt = fife.ScreenPoint(evt.getX(), evt.getY()) instances = self.getInstancesAt(pt); for i in instances: if i.getObject().getId() in ('girl', 'beekeeper'): renderer.addOutlined(i, 173, 255, 47, 2) def lightIntensity(self, value): if self.light_intensity+value <= 1 and self.light_intensity+value >= 0: self.light_intensity = self.light_intensity + value if self.lightmodel == 1: self.cameras['main'].setLightingColor(self.light_intensity, self.light_intensity, self.light_intensity) def lightSourceIntensity(self, value): if self.light_sources+value <= 255 and self.light_sources+value >= 0: self.light_sources = self.light_sources+value renderer = fife.LightRenderer.getInstance(self.cameras['main']) renderer.removeAll("beekeeper_simple_light") renderer.removeAll("hero_simple_light") renderer.removeAll("girl_simple_light") if self.lightmodel == 1: node = fife.RendererNode(self.hero.agent) renderer.addSimpleLight("hero_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255) node = fife.RendererNode(self.girl.agent) renderer.addSimpleLight("girl_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255) for beekeeper in self.beekeepers: node = fife.RendererNode(beekeeper.agent) renderer.addSimpleLight("beekeeper_simple_light", node, self.light_sources, 120, 32, 1, 1, 255, 255, 255) def onConsoleCommand(self, command): result = '' try: result = str(eval(command)) except Exception, e: result = str(e) return result
class WinteroutApplication(ApplicationBase): def __init__(self, settings): super(WinteroutApplication,self).__init__(settings) self._settings = settings self._loader = fife.MapLoader(self.engine.getModel(), self.engine.getVFS(), self.engine.getImageManager(), self.engine.getRenderBackend()) # True if we have a map loaded. False otherwise. self._mapLoaded = False self.instance_to_agent = {} self._eventmanager = self.engine.getEventManager() self._mouselistener = WinteroutMouseListener(self) self._eventmanager.addMouseListenerFront(self._mouselistener) self._keylistener = WinteroutKeyListener(self) self._eventmanager.addKeyListenerFront(self._keylistener) def loadMap(self, filename): self._mapfilename = filename if self._loader.isLoadable(self._mapfilename): self._map = self._loader.load(self._mapfilename) self._mapLoaded = True def getLocationAt(self, screenpoint): """ Query the main camera for the Map location (on the actor layer) that a screen point refers to. @param screenpoint A fife.ScreenPoint """ # We must transform the point from screen coords to map coords then # create a Location object based on a the actor layer target_mapcoord = self._camera.toMapCoordinates(screenpoint, False) target_mapcoord.z = 0 location = fife.Location(self._actorlayer) location.setMapCoordinates(target_mapcoord) return location def walkPlayerToScrenPoint(self, screenpoint): """ Simple function that moves the player instance to the given screenpoint. @param screenpoint A fife.ScreenPoint """ # You must tell the move function which action should be used for moving. # In this case we have the "walk" action defined for the player so we # use that. The 4.0 is how fast we want the player instance to move. self.hero.walk(self.getLocationAt(screenpoint)) def walkPlayer(self, dX, dY): theta = math.radians(self._camera.getRotation()-45) # Just applying the 2D rotation matrix dc, ds = math.cos(theta), math.sin(theta) dX, dY = dc*dX - ds*dY, ds*dX + dc*dY location = self.hero.agent.getLocation() coords = location.getMapCoordinates() + fife.DoublePoint3D(dX,dY,0) location.setMapCoordinates(coords) self.hero.walk(location) def rotateCamera(self, dX): newRotation = round(self._camera.getRotation()+dX/2.0) if newRotation < 0: newRotation += 360 self._camera.setRotation(newRotation) def _pump(self): """ This function gets called every frame. This is where you want to call your main game logic code. """ if not self._mapLoaded: self.loadMap("maps/testmap.xml") self._camera = self._map.getCamera("camera1") self._actorlayer = self._map.getLayer("actor_layer") self.hero = Hero(self._settings, self.engine.getModel(), 'player', self._actorlayer) self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero self.hero.start() self._camera.attach(self.hero.agent) if len(self._keylistener._pressedKeys): moveVec = (0,0) for key in self._keylistener._pressedKeys: if (key == fife.Key.A): moveVec = (moveVec[0]-1,moveVec[1]-1) elif (key == fife.Key.D): moveVec = (moveVec[0]+1,moveVec[1]+1) elif (key == fife.Key.W): moveVec = (moveVec[0]+1,moveVec[1]-1) elif (key == fife.Key.S): moveVec = (moveVec[0]-1,moveVec[1]+1) if moveVec[0] != 0 or moveVec[1] != 0: x, y = moveVec if abs(x) > 1: x /= abs(x) if abs(y) > 1: y /= abs(y) self.walkPlayer(x, y)