def crypter(filepath): crypt = Crypt() with open(filepath, "r") as reader: plaintext = reader.read() return crypt.encrypt(plaintext)
class LevelTableCreator(object): mLevelButtons = None mButtonSize = None def __init__(self, modelsize, lvlPerColumn, nrOfLevels, action): self.__mCrypt = Crypt() self.mLevelButtons = [] self.mButtonSize = b2Vec2(1,1) lock = self.__readLevelLockState() self.mRows = int(max(1, nrOfLevels / lvlPerColumn)) self.mCols = int(min(nrOfLevels, lvlPerColumn)) width = self.mButtonSize.x * self.mCols height = self.mButtonSize.y * self.mRows count = 1 for y in range(self.mRows): for x in range(self.mCols): mx = x * self.mButtonSize.x + modelsize.x / 2.0 - width / 2.0 my = y * self.mButtonSize.y + modelsize.y / 2.0 - height / 2.0 self.mLevelButtons.append(LevelButton(count, mx, my, self.mButtonSize, action, False if count <= int(lock) else True)) count += 1 def __readLevelLockState(self): lvldata = None try: with open(Resources.getInstance().resource_path("assets/state/state.json"), "rb") as state: decryptedData = self.__mCrypt.decrypt(state.read()) lvldata = json.loads(decryptedData) try: return lvldata["LVL"] except: raise IOError except (IOError): with open(Resources.getInstance().resource_path("assets/state/state.json"), "wb+") as state: data = self.__mCrypt.encrypt('{"LVL":"1"}') state.write(data) return 1
class LevelTimeScreen(BaseMenuScreen): def __init__(self, game, levelInt, currentTime = None): Id.getInstance().resetId() self.__mCrypt = Crypt() self.mCurrentTime = currentTime self.mLevelInt = levelInt self.mButtons = [] self.mTime = Time(self.__readPlayerTime()) if currentTime != None: super(LevelTimeScreen, self).__init__(game, False) self.__initializeFromGame() else: super(LevelTimeScreen, self).__init__(game) self.__initializeFromMenu() self.medallions = Animation(Resources.getInstance().mMedallions, 3, 3, 0, self.mCamera.getScaledSize(3, 3), False, False) self.mLevelTimes = [Time(x) for x in self.__readLevelTimes()] self.mButtons.append(Button("back", 0.5, 8.5, b2Vec2(2,1), lambda: self.mGame.setScreen(screen.LevelScreen.LevelScreen(self.mGame)))) self.achivedMedallion = self.__calculateMedallion() def __initializeFromMenu(self): self.mButtons.append(Button("play", 13.5, 8.5, b2Vec2(2,1), lambda: self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt)))) def __initializeFromGame(self): if self.mLevelInt < Level.Level.countLevels(): self.mButtons.append(Button("next", 13.5, 8.5, b2Vec2(2,1), lambda: self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt+1)))) else: self.mButtons.append(Button("end", 13.5, 8.5, b2Vec2(2,1), lambda: self.mGame.setScreen(screen.EndScreen.EndScreen(self.mGame)))) self.mButtons.append(Button("retry", 11, 8.5, b2Vec2(2,1), lambda: self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt)))) if self.mCurrentTime.isFaster(self.mTime): self.mTime = self.mCurrentTime found = False data = None try: with open(Resources.getInstance().resource_path("assets/state/time.json"), "rb") as readstate: decryptedData = self.__mCrypt.decrypt(readstate.read()) data = json.loads(decryptedData) for time in data: if time["ID"] == str(self.mLevelInt): found = True time["TIME"] = self.mCurrentTime.toString() if not found: data.append({"ID":"%s" % str(self.mLevelInt), "TIME":"%s" % self.mCurrentTime.toString()}) except Exception: pass if data == None: data = '[{"ID":"%s", "TIME":"%s"}]' % (str(self.mLevelInt), self.mCurrentTime.toString()) with open(Resources.getInstance().resource_path("assets/state/time.json"), "wb+") as writestate: writestate.write(self.__mCrypt.encrypt(json.dumps(data))) def __calculateMedallion(self): if self.mTime.isFaster(self.mLevelTimes[0]): return b2Vec2(0,0) elif self.mTime.isFaster(self.mLevelTimes[1]): return b2Vec2(1,0) elif self.mTime.isFaster(self.mLevelTimes[2]): return b2Vec2(2,0) else: return b2Vec2(0,2) def __readPlayerTime(self): pTime = None found = False try: with open(Resources.getInstance().resource_path("assets/state/time.json"), "rb") as state: decryptedData = self.__mCrypt.decrypt(state.read()) pTime = json.loads(decryptedData) for time in pTime: if time["ID"] == str(self.mLevelInt): pTime = time["TIME"] found = True break except Exception: with open(Resources.getInstance().resource_path("assets/state/time.json"), "wb+") as writer: writer.write(self.__mCrypt.encrypt("[]")) if not found: pTime = "00:00:00" return pTime def __readLevelTimes(self): times = [] parser = self.__mCrypt.dectryptParser(self.mLevelInt) times.append(parser.get("time", "gold")) times.append(parser.get("time", "silver")) times.append(parser.get("time", "bronze")) return times def update(self, delta): BaseMenuScreen.update(self, delta) def render(self, delta): Pgl.app.surface.fill((67,80,129)) #header title = self.titleFont.render("level %s" % str(self.mLevelInt), 0, (255,255,255)) size = self.titleFont.size("level %s" % str(self.mLevelInt)) titlepos = self.mCamera.getViewCoords(b2Vec2(self.modelsize.x / 2.0, self.modelsize.y / 6)) Pgl.app.surface.blit(title, (titlepos.x - size[0] / 2.0, titlepos.y - size[1] / 2.0)) #current runningtime (if comming from gamescreen) if self.mCurrentTime != None: current = Resources.getInstance().getScaledFont(self.mCamera.mScale.x / 1.5).render("Current time:", 0, (255, 255, 255)) currentsize = Resources.getInstance().getScaledFont(self.mCamera.scale.x / 1.5).size("Current time:") ctime = Resources.getInstance().getScaledFont(self.mCamera.scale.x / 1.5).render(self.mCurrentTime.toString(), 0, (255,74,20)) currentpos = self.mCamera.getViewCoords(b2Vec2(5, 3.3)) ctimepos = self.mCamera.getViewCoords(b2Vec2(5.5, 3.3)) Pgl.app.surface.blit(current, currentpos) Pgl.app.surface.blit(ctime, (ctimepos.x + currentsize[0], ctimepos.y)) #besttime best = Resources.getInstance().getScaledFont(self.mCamera.scale.x / 1.5).render("Best time:", 0, (255, 255, 255)) bestsize = Resources.getInstance().getScaledFont(self.mCamera.scale.x / 1.5).size("Best time:") time = Resources.getInstance().getScaledFont(self.mCamera.scale.x / 1.5).render(self.mTime.toString(), 0, (255,74,20)) bestpos = self.mCamera.getViewCoords(b2Vec2(5, 3.8)) timepos = self.mCamera.getViewCoords(b2Vec2(5.5, 3.8)) Pgl.app.surface.blit(best, bestpos) Pgl.app.surface.blit(time, (timepos.x + bestsize[0], timepos.y)) #buttons btnToDraw = self.menubutton for btn in self.mButtons: viewpos = self.mCamera.getViewCoords(b2Vec2(btn.x, btn.y)) btnToDraw.setSize(self.mCamera.getScaledSize(btn.size.x, btn.size.y)) color = None if btn.mActive: btnToDraw.freeze(1, 0) color = (255,255,255) else: btnToDraw.freeze(0, 0) color = (141,60,1) btnToDraw.draw(delta, viewpos) btntxt = self.screenFont.render(str(btn.mText), 0, color) size = self.screenFont.size(str(btn.mText)) txtpos = self.mCamera.getViewCoords(b2Vec2(btn.x + btn.size.x / 2 - (size[0] / self.mCamera.scale.x) / 2.0, btn.y + btn.size.y / 2 - (size[1] / self.mCamera.scale.y) / 2.0)) Pgl.app.surface.blit(btntxt, (txtpos.x, txtpos.y)) #small medallions for x in range(len(self.mLevelTimes)): self.medallions.freeze(x, 1) timetxt = self.infoFont.render(self.mLevelTimes[x].toString(), 0 , (255,255,255)) pos = self.mCamera.getViewCoords(b2Vec2(9, 5+x)) Pgl.app.surface.blit(timetxt, (pos.x, pos.y)) self.medallions.setSize(self.mCamera.getScaledSize(1,1)) self.medallions.draw(delta, self.mCamera.getViewCoords(b2Vec2(8,4.6+x))) self.medallions.freeze(self.achivedMedallion.x, self.achivedMedallion.y) self.medallions.setSize(self.mCamera.getScaledSize(3,3)) self.medallions.draw(delta, self.mCamera.getViewCoords(b2Vec2(4.9,4.6))) self.arrow.draw() def mouseClick(self, pos): xy = self.mCamera.getModelCoords(b2Vec2(pos[0], pos[1])) for btn in self.mButtons: if btn.rect.collidepoint(xy): btn.mAction() def mouseOver(self, pos): xy = self.mCamera.getModelCoords(b2Vec2(pos[0], pos[1])) for btn in self.mButtons: btn.mActive = False if btn.rect.collidepoint(xy): btn.mActive = True def keyInput(self, key): if key == pygame.K_r: self.__quickRetry() elif key == pygame.K_SPACE: self.__quickGame() def __quickRetry(self): if self.mCurrentTime != None: self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt)) def __quickGame(self): if self.mCurrentTime == None: self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt)) else: if self.mLevelInt < Level.Level.countLevels(): self.mGame.setScreen(screen.GameScreen.GameScreen(self.mGame, self.mLevelInt+1)) else: self.mGame.setScreen(screen.EndScreen.EndScreen(self.mGame))
class Level(object): CHUNK_SIZE = 8 mMaxLevels = None mCurrentLevel = None mTiles = None mMap = None mWidth = None mHeight = None mStartPos = None mEndPos = None mEnemies = None mObjects = None mLevelDone = None mChunkHandler = None mMapType = None mCurrentTileset = None mSwirlActive = None mAllTiles = None #dataholders mPickupData = None mEnemyData = None mBoxData = None #crypt/decrypt __mCrypt = None def __init__(self, world, gravity, lvl): self.__mCrypt = Crypt() self.mMaxLevels = self.countLevels() self.mSwirlActive = False self.mLevelDone = False self.mTiles = [] self.mObjects = [] self.mEnemies = [] self.mWorld = world self.mGravity = gravity self.mCurrentLevel = lvl self.mAllTiles = [] self.__loadLevel() def __loadLevel(self): self.mChunkHandler = ChunkHandler(self.mWorld, self.CHUNK_SIZE) self.__readLevel() if self.mMapType == MapType.PICTURE: self.__createPictureWorldCollision() print "startpos: ", self.mStartPos self.mChunkHandler.activateChunk(self.mChunkHandler.getChunk(self.mChunkHandler.getChunkPosition(self.mStartPos))) self.mTiles = self.mChunkHandler.mActiveTiles else: self.__createTextWorldCollision() self.__createPickups() self.__createEnemies() self.__createBoxes() """ Reads in enemies, pickups and if there's not a picture specified, worldcollision http://qq.readthedocs.org/en/latest/tiles.html#map-definition """ def __readLevel(self): parser = self.__mCrypt.dectryptParser(self.mCurrentLevel) self.mCurrentTileset = parser.get("level", "tileset") self.mBackground = parser.get("level", "bg") bgcolor = pygame.image.load("assets/gfx/%s" % self.mBackground) self.mBackgroundcolor = bgcolor.get_at((0, 0)) self.mPickupData = parser.get("objects", "pickups") self.mEnemyData = parser.get("objects", "enemies") self.mBoxData = parser.get("objects", "boxes") #Mapcollision #check for pictures first if os.path.exists("assets/Levels/level%d.png" % self.mCurrentLevel): self.mMap = pygame.image.load("assets/levels/level%d.png" % self.mCurrentLevel) self.mWidth, self.mHeight = self.mMap.get_size() self.mMapType = MapType.PICTURE else: #check for lvl-file self.mMap = parser.get("level", "map").replace(" ", "").split("\n") self.mWidth = len(self.mMap[0]) self.mHeight = len(self.mMap) self.mMapType = MapType.TEXT def __unloadCurrentLevel(self): self.mEndPos = None self.mStartPos = None self.mSwirlActive = False self.__unloadEntities() for tile in self.mTiles: tile.destroy() self.mTiles = [] def __unloadEntities(self): for obj in self.mObjects: if obj.alive: self.mWorld.DestroyBody(obj.getBody()) for e in self.mEnemies: self.mWorld.DestroyBody(e.getBody()) self.mObjects = [] self.mEnemies = [] def update(self, delta, playerpos): if self.mMapType == MapType.PICTURE: self.mChunkHandler.manageChunks(playerpos) if not self.mLevelDone: self.checkLevelCompletion(playerpos) else: self.mLevelDone = False return True def checkLevelCompletion(self, pos): done = True for o in self.mObjects: if isinstance(o, Crystal): if o.alive: done = False break if done: self.mSwirlActive = True if (pos.x > self.mEndPos.x and pos.x < self.mEndPos.x + Tile.TILE_SIZE and pos.y > self.mEndPos.y and pos.y < self.mEndPos.y + Tile.TILE_SIZE): self.__updateLevelLockState() self.mLevelDone = True #updates the statefile if a level is cleared def __updateLevelLockState(self): with open("assets/state/state.json", "rb") as state: decryptedData = self.__mCrypt.decrypt(state.read()) lvldata = json.loads(decryptedData) if int(lvldata["LVL"]) <= self.mCurrentLevel: with open("assets/state/state.json", "wb") as data: lvl = min(self.mCurrentLevel+1, self.mMaxLevels) data.write(self.__mCrypt.encrypt('{"LVL":"%s"}' % (str(lvl)))) #create collisiontiles from txt-file def __createTextWorldCollision(self): for y in range(self.mHeight): for x in range(self.mWidth): if self.mMap[y][x] == "#": self.mTiles.append(Tile(self.mWorld, b2Vec2(x, y), self.__calculateTileType(x, y))) elif self.mMap[y][x] == "S": self.mStartPos = b2Vec2(x, y) elif self.mMap[y][x] == "E": self.mEndPos = b2Vec2(x, y) elif self.mMap[y][x] == "*": self.mTiles.append(Tile(self.mWorld, b2Vec2(x, y), TileType.GRAVITYZONE)) elif self.mMap[y][x] == "B": self.mObjects.append(Box(b2Vec2(x, y), self.mWorld, self.mGravity)) for tile in self.mTiles: tile.create() #create collisiontiles from picture and divid em into chunks def __createPictureWorldCollision(self): self.mMap.lock() chunkx = self.mWidth / self.CHUNK_SIZE chunky = self.mHeight / self.CHUNK_SIZE for cy in range(chunky): self.mChunkHandler.chunkslist.append([]) for cx in range(chunkx): self.mChunkHandler.chunkslist[cy].append([]) chunkmap = self.mMap.subsurface(Rect(cx * self.CHUNK_SIZE, cy * self.CHUNK_SIZE, self.CHUNK_SIZE, self.CHUNK_SIZE)) chunktiles = [] for y in range(chunkmap.get_height()): for x in range(chunkmap.get_width()): r,g,b,a = chunkmap.get_at((x, y)) #mapx / mapy mx = x + cx * self.CHUNK_SIZE my = y + cy * self.CHUNK_SIZE if (r,g,b) != Color.WHITE: pos = b2Vec2(mx, my) if (r,g,b) == Color.WALL: self.mAllTiles.append(Tile(self.mWorld, pos, self.__calculateTileType(mx, my))) chunktiles.append(Tile(self.mWorld, pos, self.__calculateTileType(mx, my))) elif (r,g,b) == Color.STARTPOS: self.mStartPos = pos elif (r,g,b) == Color.ENDPOS: self.mEndPos = pos self.mChunkHandler.chunkslist[cy][cx] = Chunk(b2Vec2(cx, cy), chunktiles) self.mMap.unlock() def __isWallType(self, tile): if self.mMapType == MapType.PICTURE: return True if tile == Color.WALL else False else: return True if tile == "#" else False def __accessMap(self, x, y): if self.mMapType == MapType.PICTURE: return self.mMap.get_at((x, y)) else: return self.mMap[y][x] def __calculateTileType(self, mx, my): tiletype = TileType.M #left edge if mx == 0: if my == 0: tiletype = TileType.ETL elif my == self.mHeight-1: tiletype = TileType.EBL elif self.__isWallType(self.__accessMap(mx+1, my)) or self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.EL else: tiletype = TileType.R #right edge elif mx == self.mWidth-1: if my == 0: tiletype = TileType.ETR elif my == self.mHeight-1: tiletype = TileType.EBR elif self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.ER else: tiletype = TileType.L #top elif my == 0: if not self.__isWallType(self.__accessMap(mx, my+1)): tiletype = TileType.B else: tiletype = TileType.ET #bottom elif my == self.mHeight-1: if not self.__isWallType(self.__accessMap(mx, my-1)): tiletype = TileType.GM else: tiletype = TileType.EB if my > 0 and my < self.mHeight-1 and mx > 0 and mx < self.mWidth-1: #only under if not self.__isWallType(self.__accessMap(mx, my-1)) and self.__isWallType(self.__accessMap(mx, my+1)): #only right side if not self.__isWallType(self.__accessMap(mx-1, my)) and self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.GL #only left side elif not self.__isWallType(self.__accessMap(mx+1, my)) and self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.GR #neither sides elif not self.__isWallType(self.__accessMap(mx+1, my)) and not self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.SVT else: tiletype = TileType.GM #only over elif self.__isWallType(self.__accessMap(mx, my-1)) and not self.__isWallType(self.__accessMap(mx, my+1)): #only right side if not self.__isWallType(self.__accessMap(mx-1, my)) and self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.BL #only left side elif not self.__isWallType(self.__accessMap(mx+1, my)) and self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.BR #neither sides elif not self.__isWallType(self.__accessMap(mx+1, my)) and not self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.SVB else: tiletype = TileType.B #not over nor under elif not self.__isWallType(self.__accessMap(mx, my-1)) and not self.__isWallType(self.__accessMap(mx, my+1)): #neither sides if not self.__isWallType(self.__accessMap(mx-1, my)) and not self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.SG #only right side elif not self.__isWallType(self.__accessMap(mx-1, my)) and self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.SGL #only left side elif not self.__isWallType(self.__accessMap(mx+1, my)) and self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.SGR else: tiletype = TileType.SGM else: #only left side if not self.__isWallType(self.__accessMap(mx+1, my)) and self.__isWallType(self.__accessMap(mx-1, my)): tiletype = TileType.R #only right side elif not self.__isWallType(self.__accessMap(mx-1, my)) and self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.L #neither sides elif not self.__isWallType(self.__accessMap(mx-1, my)) and not self.__isWallType(self.__accessMap(mx+1, my)): tiletype = TileType.SVM else: tiletype = TileType.M return tiletype def __createPickups(self): objects = json.loads(self.mPickupData) if len(objects) > 0: for obj in range(len(objects)): x, y = [float(i) for i in objects[obj]["POS"].split(",")] objtype = objects[obj]["TYPE"] if objtype == ObjectType.NUGGET: self.mObjects.append(Crystal((x,y), self.mWorld)) def __createEnemies(self): enemies = json.loads(self.mEnemyData) if len(enemies) > 0: for e in range(len(enemies)): x, y = [float(i) for i in enemies[e]["POS"].split(",")] etype = enemies[e]["TYPE"] if etype == EnemyType.SPIKEBOX: speed = float(enemies[e]["SPEED"]) delay = float(enemies[e]["DELAY"]) ex, ey = [float(i) for i in enemies[e]["ENDPOS"].split(",")] self.mEnemies.append(SpikeBox(self.mWorld, (x,y), (ex, ey), delay, speed)) elif etype == EnemyType.SPIKE: facing = int(enemies[e]["FACING"]) self.mEnemies.append(Spike(self.mWorld, (x,y), facing)) elif etype == EnemyType.SAW: pattern = [(k, v) for k,v in (str(enemies[e]["PATTERN"][x]).split(",") for x in range(len(enemies[e]["PATTERN"])))] speed = float(enemies[e]["SPEED"]) radius = float(enemies[e]["RADIUS"]) self.mEnemies.append(Saw(self.mWorld, (x,y), pattern, radius, speed)) elif etype == EnemyType.LASER: ex, ey = [float(i) for i in enemies[e]["ENDPOS"].split(",")] delay = float(enemies[e]["DELAY"]) triggertime = float(enemies[e]["T_TIMER"]) firingtime = float(enemies[e]["F_TIMER"]) self.mEnemies.append(Laser(self.mWorld, b2Vec2(x,y), b2Vec2(ex,ey), delay, triggertime, firingtime)) def __createBoxes(self): boxes = json.loads(self.mBoxData) if len(boxes) > 0: for box in range(len(boxes)): x, y = [float(i) for i in boxes[box]["POS"].split(",")] self.mObjects.append(Box(b2Vec2(x, y), self.mWorld, self.mGravity)) def nextLevel(self): if self.mCurrentLevel < self.mMaxLevels: self.__unloadCurrentLevel() self.mCurrentLevel += 1 self.__loadLevel() def retryLevel(self): self.__unloadEntities() self.__createPickups() self.__createEnemies() #self.__createBoxes() self.mSwirlActive = False def isInActiveChunks(self, position): return True if self.mMapType == MapType.TEXT else self.mChunkHandler.isPositionInActiveChunks(position) @staticmethod def countLevels(): lvls = 0 for filename in os.listdir("assets/levels"): if filename.endswith(".lvl"): lvls += 1 return lvls