class Game(): def __init__(self, _main): self.main = _main # Physics self.physics = Physics(self) # Level self.levelloader = LevelLoader(self) # Input # Player self.player = Player(self) # GUI # STATE self.isFloating = False def start_game(self): self.physics.start() def stop_game(self): self.physics.stop()
class BlockStore(Thread): """ A class which deals with storing the block worlds, flushing them, etc. """ def __init__(self, blocks_path, sx, sy, sz): Thread.__init__(self) self.x, self.y, self.z = sx, sy, sz self.blocks_path = blocks_path self.in_queue = Queue() self.out_queue = Queue() self.saving = False def run(self): # Initialise variables self.physics = False self.physics_engine = Physics(self) self.raw_blocks = None self.running = True self.unflooding = False self.finite_water = False self.queued_blocks = {} # Blocks which need to be flushed into the file. self.create_raw_blocks() # Start physics engine self.physics_engine.start() # Main eval loop while self.running: try: # Pop something off the queue task = self.in_queue.get() # If we've been asked to flush, do so, and say we did. if task[0] is TASK_FLUSH: self.flush() self.out_queue.put([TASK_FLUSH]) # New block? elif task[0] is TASK_BLOCKSET: try: self[task[1]] = task[2] except AssertionError: logging.log("Tried to set a block at %s in %s!" % (task[1], self.blocks_path), logging.WARN) # Asking for a block? elif task[0] is TASK_BLOCKGET: self.out_queue.put([TASK_BLOCKGET, task[1], self[task[1]]]) # Perhaps physics was enabled? elif task[0] is TASK_PHYSICSOFF: logging.log(logging.DEBUG, "Disabling physics on '%s'..." % self.blocks_path) self.disable_physics() # Or disabled? elif task[0] is TASK_PHYSICSON: logging.log(logging.DEBUG, "Enabling physics on '%s'..." % self.blocks_path) self.enable_physics() # I can haz finite water tiem? elif task[0] is TASK_FWATERON: logging.log(logging.DEBUG, "Enabling finite water on '%s'..." % self.blocks_path) self.finite_water = True # Noes, no more finite water. elif task[0] is TASK_FWATEROFF: logging.log(logging.DEBUG, "Disabling finite water on '%s'..." % self.blocks_path) self.finite_water = False # Do they need to do a Moses? elif task[0] is TASK_UNFLOOD: logging.log(logging.DEBUG, "Unflood started on '%s'..." % self.blocks_path) self.unflooding = True # Perhaps that's it, and we need to stop? elif task[0] is TASK_STOP: logging.log(logging.DEBUG, "Stopping block store '%s'..." % self.blocks_path) self.physics_engine.stop() self.flush() logging.log(logging.DEBUG, "Stopped block store '%s'." % self.blocks_path) return # ??? else: raise ValueError("Unknown BlockStore task: %s" % task) except (KeyboardInterrupt, IOError): pass def enable_physics(self): "Turns on physics" self.flush() self.physics = True def disable_physics(self): "Disables physics, and clears the in-memory store." self.physics = False def create_raw_blocks(self): "Reads in the gzipped data into a raw array" # Open the blocks file fh = gzip.GzipFile(self.blocks_path) self.raw_blocks = array('c') # Read off the size header fh.read(4) # Copy into the array in chunks chunk = fh.read(2048) while chunk: self.raw_blocks.extend(chunk) chunk = fh.read(2048) fh.close() def get_offset(self, x, y, z): "Turns block coordinates into a data offset" assert 0 <= x < self.x assert 0 <= y < self.y assert 0 <= z < self.z return y*(self.x*self.z) + z*(self.x) + x def get_coords(self, offset): "Turns a data offset into coordinates" x = offset % self.x z = (offset // self.x) % self.z y = offset // (self.x * self.z) return x, y, z def world_message(self, message): "Sends a message out to users about this World." self.out_queue.put([TASK_WORLDMESSAGE, message]) def admin_message(self, message): "Sends a message out to admins about this World." self.out_queue.put([TASK_ADMINMESSAGE, message]) def send_block(self, x, y, z): "Tells the server to update the given block for clients." self.out_queue.put([TASK_BLOCKSET, (x, y, z, self[x, y, z])]) def __setitem__(self, (x, y, z), block): "Set a block in this level to the given value." assert isinstance(block, str) and len(block) == 1 # Save to queued blocks offset = self.get_offset(x, y, z) self.queued_blocks[offset] = block # And directly to raw blocks, if we must if self.raw_blocks: self.raw_blocks[offset] = block # Ask the physics engine if they'd like a look at that self.physics_engine.handle_change(offset, block)
class Game(DirectObject): def __init__(self, _main): self.main = _main ## PHYSICS HANDLER ## self.physics = Physics(self) ## LEVEL LOADER ## self.currentLevelName = None self.levelloader = LevelLoader(self) self.currentLevelName = "startLevel2-extra" ## INPUT HANDLER self.input = Input(self) self.movementOption = '1' ## HANDLE PLAYER ## self.isPlayerActive = False self.player = {} self.activePlayerName = "player2" ## Start GuI ## self.gui = Gui(self) self.accept("doStart", self.startGame) ## GAME STATE VARIABLES ## self.isMoving = False self.isFloating = False def startGame(self): self.gui.hideMenu() self.levelloader.newLevel(self.currentLevelName) self.createPlayer(self.activePlayerName) self.gui.showGameGui() self.levelloader.startCounter() ## HANDLE CAMERA ## self.camera = Camera(self) ## START PHYSICS ## self.physics.start() def stopGame(self): self.gui.hideGameGui() for object in self.levelloader.levelObjects: object.remove() for stateCoin in self.levelloader.levelStateCoins.keys(): self.levelloader.levelStateCoins["exit"].exitModel.remove() self.levelloader.levelStateCoins["exit"] = None for coin in self.levelloader.levelCoins.keys(): self.levelloader.levelCoins[coin].coinModel.remove() self.levelloader.levelCoins[coin] = None for node in self.physics.World.getRigidBodies(): self.physics.World.removeRigidBody(node) for node in self.physics.World.getGhosts(): self.physics.World.removeGhost(node) #self.levelloader.level = None self.levelloader.stopCounter() self.player[self.activePlayerName].removePlayer() self.player = None self.camera.stopCamTask() # Reset Cursor winProps = WindowProperties() winProps.setCursorHidden(False) base.win.requestProperties(winProps) self.camera = None self.physics.stop() self.gui.showMenu() def createPlayer(self, name): self.player = {} self.player[name] = Player(self, name)
class BlockStore(Thread): """ A class which deals with storing the block worlds, flushing them, etc. """ def __init__(self, blocks_path, sx, sy, sz): Thread.__init__(self) self.x, self.y, self.z = sx, sy, sz self.blocks_path = blocks_path self.in_queue = Queue() self.out_queue = Queue() self.saving = False self.logger = logging.getLogger("BlockStore") def run(self): # Initialise variables self.physics = False self.physics_engine = Physics(self) self.raw_blocks = None self.running = True self.unflooding = False self.finite_water = False self.queued_blocks = { } # Blocks which need to be flushed into the file. self.create_raw_blocks() # Start physics engine self.physics_engine.start() # Main eval loop while self.running: try: # Pop something off the queue task = self.in_queue.get() # If we've been asked to flush, do so, and say we did. if task[0] is TASK_FLUSH: self.flush() self.out_queue.put([TASK_FLUSH]) # New block? elif task[0] is TASK_BLOCKSET: try: self[task[1]] = task[2] except AssertionError: self.logger.warning( "Tried to set a block at %s in %s!" % (task[1], self.blocks_path)) # Asking for a block? elif task[0] is TASK_BLOCKGET: self.out_queue.put([TASK_BLOCKGET, task[1], self[task[1]]]) # Perhaps physics was enabled? elif task[0] is TASK_PHYSICSOFF: self.logger.debug("Disabling physics on '%s'..." % self.blocks_path) self.disable_physics() # Or disabled? elif task[0] is TASK_PHYSICSON: self.logger.debug("Enabling physics on '%s'..." % self.blocks_path) self.enable_physics() # I can haz finite water tiem? elif task[0] is TASK_FWATERON: self.logger.debug("Enabling finite water on '%s'..." % self.blocks_path) self.finite_water = True # Noes, no more finite water. elif task[0] is TASK_FWATEROFF: self.logger.debug("Disabling finite water on '%s'..." % self.blocks_path) self.finite_water = False # Do they need to do a Moses? elif task[0] is TASK_UNFLOOD: self.logger.debug("Unflood started on '%s'..." % self.blocks_path) self.unflooding = True # Perhaps that's it, and we need to stop? elif task[0] is TASK_STOP: self.logger.debug("Stopping block store '%s'..." % self.blocks_path) self.physics_engine.stop() self.flush() self.logger.debug("Stopped block store '%s'." % self.blocks_path) return # ??? else: raise ValueError("Unknown BlockStore task: %s" % task) except (KeyboardInterrupt, IOError): pass def enable_physics(self): "Turns on physics" self.flush() self.physics = True def disable_physics(self): "Disables physics, and clears the in-memory store." self.physics = False def create_raw_blocks(self): "Reads in the gzipped data into a raw array" # Open the blocks file fh = gzip.GzipFile(self.blocks_path) self.raw_blocks = array('c') # Read off the size header fh.read(4) # Copy into the array in chunks chunk = fh.read(2048) while chunk: self.raw_blocks.extend(chunk) chunk = fh.read(2048) fh.close() def get_offset(self, x, y, z): "Turns block coordinates into a data offset" assert 0 <= x < self.x assert 0 <= y < self.y assert 0 <= z < self.z return y * (self.x * self.z) + z * (self.x) + x def get_coords(self, offset): "Turns a data offset into coordinates" x = offset % self.x z = (offset // self.x) % self.z y = offset // (self.x * self.z) return x, y, z def world_message(self, message): "Sends a message out to users about this World." self.out_queue.put([TASK_WORLDMESSAGE, message]) def admin_message(self, message): "Sends a message out to admins about this World." self.out_queue.put([TASK_ADMINMESSAGE, message]) def send_block(self, x, y, z): "Tells the server to update the given block for clients." self.out_queue.put([TASK_BLOCKSET, (x, y, z, self[x, y, z])]) def __setitem__(self, (x, y, z), block): "Set a block in this level to the given value." assert isinstance(block, str) and len(block) == 1 # Save to queued blocks offset = self.get_offset(x, y, z) self.queued_blocks[offset] = block # And directly to raw blocks, if we must if self.raw_blocks: self.raw_blocks[offset] = block # Ask the physics engine if they'd like a look at that self.physics_engine.handle_change(offset, block)