class Client(DirectObject): """ Client class handels gui/input audio and rendering """ def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp = self.loadWindoProperites() #open the window base.openMainWindow(props=wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused = base.win.getProperties().getForeground() self.window_x = base.win.getXSize() self.window_y = base.win.getYSize() self.window_minimized = base.win.getProperties().getMinimized() #filter manager, post process self.filters = Filters() #audio sound effects (sfx) + music self.audio = Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights = LightManager() #setup the user interface (gui+key/mouse bind) self.ui = UserInterface() #skybox self.sun_and_sky = Skybox(self.lights) #player (character) droid self.droid = PCDroid(self.ui) #some vars used later self.map_name = None self.loading_status = set() self.level_root = render.attachNewNode('level_root') self.level_root.hide() self.is_in_game = False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event', self.onClientExit) self.accept('window-event', self.onWindowEvent) self.accept('window-reset', self.onWindowReset) self.accept('client-mouselock', self.setMouseLock) self.accept('load-level', self.onLevelLoad) self.accept('loading-done', self.onLoadingDone) self.accept('reload-shaders', self.onShaderReload) self.accept('client-set-team', self.onTeamCahnge) self.accept('client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started') def doSomeStuffTsk(self, task): x = deque(range(5000)) for i in xrange(999): random.shuffle(x) #print i, x[0] #print 'done' return task.done def setMouseLock(self, lock): wp = WindowProperties.getDefault() if lock: wp.setMouseMode(WindowProperties.M_confined) else: wp.setMouseMode(WindowProperties.M_relative) if not cfg['use-os-cursor']: wp.setCursorHidden(True) base.win.requestProperties(wp) def loadWindoProperites(self): #check if we can open a fullscreen window at the requested size if cfg['fullscreen']: mods = [] for mode in base.pipe.getDisplayInformation().getDisplayModes(): mods.append([mode.width, mode.height]) if list(cfg['win-size']) not in mods: cfg['fullscreen'] = False log.warning('Can not open fullscreen window at ' + str(cfg['win-size'])) #the window props should be set by this time, but make sure wp = WindowProperties.getDefault() try: wp.setUndecorated(cfg['undecorated']) wp.setFullscreen(cfg['fullscreen']) wp.setSize(cfg['win-size'][0], cfg['win-size'][1]) wp.setFixedSize(cfg['win-fixed-size']) except: log.warning('Failed to set window properties, Traceback:') for error in traceback.format_exc().splitlines()[1:]: log.warning(error.strip()) #these probably won't be in the config (?) wp.setOrigin(-2, -2) wp.setTitle('A4P') if not cfg['use-os-cursor']: wp.setCursorHidden(True) return wp def loadLevel(self, task): log.debug('Client loading level...') with open(path + 'maps/' + self.map_name + '.json') as f: values = json.load(f) #set the time self.sun_and_sky.setTime(values['level']['time']) #self.sun_and_sky.show() #load visible objects for id, obj in enumerate(values['objects']): mesh = loader.loadModel(path + obj['model']) mesh.reparentTo(self.level_root) mesh.setPosHpr(tuple(obj['pos']), tuple(obj['hpr'])) mesh.setTag( 'id_' + str(id), str(id) ) #we may need to find this mesh later to link it to a Bullet object for name, value in obj['shader_inputs'].items(): if isinstance(value, basestring): mesh.setShaderInput(str(name), loader.loadTexture(path + value)) if isinstance(value, float): mesh.setShaderInput(str(name), value) if isinstance(value, list): if len(value) == 2: mesh.setShaderInput(str(name), Vec2(value[0], value[1])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec3(value[0], value[1], value[2])) elif len(value) == 3: mesh.setShaderInput( str(name), Vec4(value[0], value[1], value[2], value[3])) mesh.setShader( Shader.load(Shader.SLGLSL, obj['vertex_shader'], obj['fragment_shader'])) #set the music self.audio.setMusic(values['level']['music']) #self.level_root.prepareScene(base.win.getGsg()) messenger.send('loading-done', ['client']) return task.done #events def onQuit(self): self.level_root.removeNode() self.level_root = render.attachNewNode('level_root') self.level_root.hide() if self.ui.is_zoomed: self.ui.zoom() self.sun_and_sky.hide() self.droid.disable() self.ui.unbindKeys() self.ui.in_game_menu.hide() self.ui.main_menu.show() self.audio.setMusic('background') self.loading_status = set() self.is_in_game = False messenger.send('world-clear-level') def onTeamCahnge(self, team): self.droid.setTeam(team) def onShaderReload(self): log.debug('Client: Reloading shaders') for mesh in self.level_root.getChildren(): shader = mesh.getShader() v_shader = shader.getFilename(Shader.ST_vertex) f_shader = shader.getFilename(Shader.ST_fragment) mesh.setShader(Shader.load(Shader.SLGLSL, v_shader, f_shader)) self.ui.main_menu.setShader(path + 'shaders/gui_v.glsl', path + 'shaders/gui_f.glsl') self.filters.reset() def onLoadingDone(self, target): log.debug(str(target) + ' loading done') self.loading_status.add(target) if self.loading_status == set(['client', 'server', 'world']): self.ui.main_menu.hide() self.level_root.show() self.sun_and_sky.show() self.ui.bindKeys() self.droid.node.setPos(render, 20, 0, 2) self.droid.lockCamera() self.droid.model.show() self.droid.rig.show() self.droid.gun.show() self.ui.in_game_menu.showElements('hud_') self.ui.hideSoftCursor() self.ui.is_main_menu = False self.is_in_game = True messenger.send('world-link-objects', [self.droid.node, 'pc_droid_node']) def onLevelLoad(self, map_name): self.map_name = map_name #we wait 1.0 sec for the loading animation to finish just in case if loading takes < 1.0 sec. taskMgr.doMethodLater(1.0, self.loadLevel, 'client_loadLevel_task', taskChain='background_chain') #taskMgr.add(self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #the client needs to load/setup: # -visible geometry # -enviroment (skybox/dome + sunlight diection + fog + ???) # -water plane # -unmovable (point)light sources # -unmovable vfx # -the player droid def onClientExit(self): log.debug('Client exit') self.audio.cleanup() app.exit() def onWindowReset(self): wp = self.loadWindoProperites() base.win.requestProperties(wp) def onWindowMinimize(self): self.window_minimized = base.win.getProperties().getMinimized() log.debug('window-event: Minimize is ' + str(self.window_minimized)) def onWindowFocus(self): self.window_focused = base.win.getProperties().getForeground() log.debug('window-event: Focus set to ' + str(self.window_focused)) if self.is_in_game: self.ui.in_game_menu.showMenu(self.window_focused) if not self.window_focused: self.ui.cursor_pos = (0, 0, 0) if cfg['pause-on-focus-lost']: if not self.window_focused: self.audio.pauseMusic() base.win.setActive(False) else: self.audio.resumeMusic() base.win.setActive(True) def onWindowResize(self): self.window_x = base.win.getXSize() self.window_y = base.win.getYSize() log.debug('window-event: Resize') self.filters.update() self.ui.updateGuiNodes() def onWindowEvent(self, window=None): if window is not None: # window is none if panda3d is not started if self.window_x != base.win.getXSize( ) or self.window_y != base.win.getYSize(): self.onWindowResize() elif window.getProperties().getMinimized( ) != self.window_minimized: self.onWindowMinimize() elif window.getProperties().getForeground() != self.window_focused: self.onWindowFocus() #tasks def update(self, task): dt = globalClock.getDt() render.setShaderInput('camera_pos', base.cam.getPos(render)) return task.cont
class Client(DirectObject): """ Client class handels gui/input audio and rendering """ def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp=self.loadWindoProperites() #open the window base.openMainWindow(props = wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused=base.win.getProperties().getForeground() self.window_x=base.win.getXSize() self.window_y=base.win.getYSize() self.window_minimized=base.win.getProperties().getMinimized() #filter manager, post process self.filters=Filters() #audio sound effects (sfx) + music self.audio=Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights=LightManager() #setup the user interface (gui+key/mouse bind) self.ui=UserInterface() #skybox self.sun_and_sky=Skybox(self.lights) #player (character) droid self.droid=PCDroid(self.ui) #some vars used later self.map_name=None self.loading_status=set() self.level_root=render.attachNewNode('level_root') self.level_root.hide() self.is_in_game=False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event',self.onClientExit) self.accept( 'window-event', self.onWindowEvent) self.accept( 'window-reset', self.onWindowReset) self.accept( 'client-mouselock', self.setMouseLock) self.accept( 'load-level', self.onLevelLoad) self.accept( 'loading-done', self.onLoadingDone) self.accept( 'reload-shaders', self.onShaderReload) self.accept( 'client-set-team', self.onTeamCahnge) self.accept( 'client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started') def doSomeStuffTsk(self, task): x=deque(range(5000)) for i in xrange(999): random.shuffle(x) #print i, x[0] #print 'done' return task.done def setMouseLock(self, lock): wp = WindowProperties.getDefault() if lock: wp.setMouseMode(WindowProperties.M_confined) else: wp.setMouseMode(WindowProperties.M_relative) if not cfg['use-os-cursor']: wp.setCursorHidden(True) base.win.requestProperties(wp) def loadWindoProperites(self): #check if we can open a fullscreen window at the requested size if cfg['fullscreen']: mods=[] for mode in base.pipe.getDisplayInformation().getDisplayModes(): mods.append([mode.width, mode.height]) if list(cfg['win-size']) not in mods: cfg['fullscreen']=False log.warning('Can not open fullscreen window at '+str(cfg['win-size'])) #the window props should be set by this time, but make sure wp = WindowProperties.getDefault() try: wp.setUndecorated(cfg['undecorated']) wp.setFullscreen(cfg['fullscreen']) wp.setSize(cfg['win-size'][0],cfg['win-size'][1]) wp.setFixedSize(cfg['win-fixed-size']) except: log.warning('Failed to set window properties, Traceback:') for error in traceback.format_exc().splitlines()[1:]: log.warning(error.strip()) #these probably won't be in the config (?) wp.setOrigin(-2,-2) wp.setTitle('A4P') if not cfg['use-os-cursor']: wp.setCursorHidden(True) return wp def loadLevel(self, task): log.debug('Client loading level...') with open(path+'maps/'+self.map_name+'.json') as f: values=json.load(f) #set the time self.sun_and_sky.setTime(values['level']['time']) #self.sun_and_sky.show() #load visible objects for id, obj in enumerate(values['objects']): mesh=loader.loadModel(path+obj['model']) mesh.reparentTo(self.level_root) mesh.setPosHpr(tuple(obj['pos']), tuple(obj['hpr'])) mesh.setTag('id_'+str(id), str(id)) #we may need to find this mesh later to link it to a Bullet object for name, value in obj['shader_inputs'].items(): if isinstance(value, basestring): mesh.setShaderInput(str(name), loader.loadTexture(path+value)) if isinstance(value, float): mesh.setShaderInput(str(name), value) if isinstance(value, list): if len(value) == 2: mesh.setShaderInput(str(name), Vec2(value[0], value[1])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec3(value[0], value[1], value[2])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec4(value[0], value[1], value[2], value[3])) mesh.setShader(Shader.load(Shader.SLGLSL, obj['vertex_shader'],obj['fragment_shader'])) #set the music self.audio.setMusic(values['level']['music']) #self.level_root.prepareScene(base.win.getGsg()) messenger.send('loading-done', ['client']) return task.done #events def onQuit(self): self.level_root.removeNode() self.level_root=render.attachNewNode('level_root') self.level_root.hide() if self.ui.is_zoomed: self.ui.zoom() self.sun_and_sky.hide() self.droid.disable() self.ui.unbindKeys() self.ui.in_game_menu.hide() self.ui.main_menu.show() self.audio.setMusic('background') self.loading_status=set() self.is_in_game=False messenger.send('world-clear-level') def onTeamCahnge(self, team): self.droid.setTeam(team) def onShaderReload(self): log.debug('Client: Reloading shaders') for mesh in self.level_root.getChildren(): shader=mesh.getShader() v_shader=shader.getFilename(Shader.ST_vertex) f_shader=shader.getFilename(Shader.ST_fragment) mesh.setShader(Shader.load(Shader.SLGLSL, v_shader,f_shader)) self.ui.main_menu.setShader(path+'shaders/gui_v.glsl', path+'shaders/gui_f.glsl') self.filters.reset() def onLoadingDone(self, target): log.debug(str(target)+' loading done') self.loading_status.add(target) if self.loading_status == set(['client', 'server', 'world']): self.ui.main_menu.hide() self.level_root.show() self.sun_and_sky.show() self.ui.bindKeys() self.droid.node.setPos(render, 20,0,2) self.droid.lockCamera() self.droid.model.show() self.droid.rig.show() self.droid.gun.show() self.ui.in_game_menu.showElements('hud_') self.ui.hideSoftCursor() self.ui.is_main_menu=False self.is_in_game=True messenger.send('world-link-objects', [self.droid.node, 'pc_droid_node']) def onLevelLoad(self, map_name): self.map_name=map_name #we wait 1.0 sec for the loading animation to finish just in case if loading takes < 1.0 sec. taskMgr.doMethodLater(1.0, self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #taskMgr.add(self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #the client needs to load/setup: # -visible geometry # -enviroment (skybox/dome + sunlight diection + fog + ???) # -water plane # -unmovable (point)light sources # -unmovable vfx # -the player droid def onClientExit(self): log.debug('Client exit') self.audio.cleanup() app.exit() def onWindowReset(self): wp=self.loadWindoProperites() base.win.requestProperties(wp) def onWindowMinimize(self): self.window_minimized=base.win.getProperties().getMinimized() log.debug('window-event: Minimize is '+str(self.window_minimized)) def onWindowFocus(self): self.window_focused=base.win.getProperties().getForeground() log.debug('window-event: Focus set to '+str(self.window_focused)) if self.is_in_game: self.ui.in_game_menu.showMenu(self.window_focused) if not self.window_focused: self.ui.cursor_pos=(0,0,0) if cfg['pause-on-focus-lost']: if not self.window_focused: self.audio.pauseMusic() base.win.setActive(False) else: self.audio.resumeMusic() base.win.setActive(True) def onWindowResize(self): self.window_x=base.win.getXSize() self.window_y=base.win.getYSize() log.debug('window-event: Resize') self.filters.update() self.ui.updateGuiNodes() def onWindowEvent(self,window=None): if window is not None: # window is none if panda3d is not started if self.window_x!=base.win.getXSize() or self.window_y!=base.win.getYSize(): self.onWindowResize() elif window.getProperties().getMinimized() != self.window_minimized: self.onWindowMinimize() elif window.getProperties().getForeground() != self.window_focused: self.onWindowFocus() #tasks def update(self, task): dt = globalClock.getDt() render.setShaderInput('camera_pos', base.cam.getPos(render)) return task.cont