Пример #1
0
def crypter(filepath):
    crypt = Crypt()
    
    with open(filepath, "r") as reader:
        plaintext = reader.read()
    
    return crypt.encrypt(plaintext)
Пример #2
0
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
Пример #3
0
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))
Пример #4
0
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