예제 #1
0
    def __init__(self, save_dir):
        '''
        Initializes the main screen that gameplay takes place on

        @param save_dir - The directory to be saved to
        '''
        self.sound = pygame.mixer.Sound(LASER)
        self.tileMap = TileMap(save_dir)
        
        self.crate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.crates)
        data = json.loads(open('{0}player.json'.format(save_dir)).read())
        self.player = PlayerSprite(json=data)
        self.button_group = pygame.sprite.RenderPlain(*self.tileMap.tile.buttons)
        self.gate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.gates)

        self.keyboard_input = {
            K_a: (KEYUP, KEYUP),
            K_d: (KEYUP, KEYUP),
            K_l: (KEYUP, KEYUP),
            K_s: (KEYUP, KEYUP),
            K_w: (KEYUP, KEYUP),
            K_h: (KEYUP, KEYUP)
        }

        self.player_group = pygame.sprite.RenderClear(self.player)
        self.enemies = self.tileMap.tile.enemies
        self.boss = self.tileMap.tile.bosses
        self.shooters = self.tileMap.tile.shooters + self.boss
        enemies = self.enemies + self.shooters
        self.enemy_group = pygame.sprite.RenderPlain(*enemies)
        self.bullet_group = pygame.sprite.Group()
        self.enemy_bullet_group = pygame.sprite.Group()
        self.player_group.update()
        self.enemy_group.update()
예제 #2
0
    def __init__(self, manager):
        self.background = Sprite("Resources/Backgrounds/level1.png").get_image(0, 0, public.display_dimensions[0], public.display_dimensions[1])

        self.manager = manager;

        self.player = Player()
        self.player.set_position(250, 254)

        minion1 = CommonMinion()
        minion1.set_movement(300, 278, 300, 500)

        self.enemies = [
            minion1
        ]

        self.tile_map = TileMap("Resources/Maps/level1.map")
예제 #3
0
class GameScreen(Screen):
    def __init__(self, save_dir):
        '''
        Initializes the main screen that gameplay takes place on

        @param save_dir - The directory to be saved to
        '''
        self.sound = pygame.mixer.Sound(LASER)
        self.tileMap = TileMap(save_dir)
        
        self.crate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.crates)
        data = json.loads(open('{0}player.json'.format(save_dir)).read())
        self.player = PlayerSprite(json=data)
        self.button_group = pygame.sprite.RenderPlain(*self.tileMap.tile.buttons)
        self.gate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.gates)

        self.keyboard_input = {
            K_a: (KEYUP, KEYUP),
            K_d: (KEYUP, KEYUP),
            K_l: (KEYUP, KEYUP),
            K_s: (KEYUP, KEYUP),
            K_w: (KEYUP, KEYUP),
            K_h: (KEYUP, KEYUP)
        }

        self.player_group = pygame.sprite.RenderClear(self.player)
        self.enemies = self.tileMap.tile.enemies
        self.boss = self.tileMap.tile.bosses
        self.shooters = self.tileMap.tile.shooters + self.boss
        enemies = self.enemies + self.shooters
        self.enemy_group = pygame.sprite.RenderPlain(*enemies)
        self.bullet_group = pygame.sprite.Group()
        self.enemy_bullet_group = pygame.sprite.Group()
        self.player_group.update()
        self.enemy_group.update()

    def render(self):
        '''
        Renders each of the groups to the main game screen

        That includes tile, crates, button, bullets, enemies and the player
        '''

        self.tileMap.draw(State.screen)
        self.crate_group.draw(State.screen)
        self.button_group.draw(State.screen)
        self.gate_group.draw(State.screen)
        self.bullet_group.draw(State.screen)
        self.enemy_bullet_group.draw(State.screen)
        self.player_group.draw(State.screen)
        self.enemy_group.draw(State.screen)

    def reset_sprite_groups(self):
        '''
        Resets each of the sprite groups back to their original parameters
        '''
        self.crate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.crates)
        self.button_group = pygame.sprite.RenderPlain(*self.tileMap.tile.buttons)
        self.gate_group = pygame.sprite.RenderPlain(*self.tileMap.tile.gates)
        self.enemies = self.tileMap.tile.enemies
        self.boss = self.tileMap.tile.bosses
        self.shooters = self.tileMap.tile.shooters + self.boss
        enemies = self.enemies + self.shooters
        self.enemy_group = pygame.sprite.RenderPlain(*enemies)

    def update(self, events):
        '''
        Updates everything in the game

        This includes: 
            - checking to see if the final condition has been met
            - handling keybour events
            - Checking kill count
            - Having each enemy call their act functions
            - Checking collisions
            - Updating each tile
            - Checking the health of the player

        '''
        if State.boss_ready:
            self.gate_group.empty()
            self.tileMap.tile.gates = []

        self.handle_keyboard(events)
        self.player.handle_input(self.keyboard_input, self.tileMap.tile, self.bullet_group)
        self.player.check_count()
        
        for enemy in self.enemy_group:
            enemy.act(self.tileMap.tile)

        for shooter in self.shooters:
            (px, py) = self.player.coords
            if shooter.shouldShoot(px, py): 
                shooter.shoot(shooter, self.enemy_bullet_group)

        self.check_collisions()

        if(self.tileMap.update(self.player, self.enemy_group)):
            self.bullet_group.update()
            self.enemy_bullet_group.update()
            self.player_group.update()
            self.enemy_group.update()
        else:
            self.reset_sprite_groups()

        if self.player.health <= 0:
            self.player.lives -= 1
            if self.player.lives <= 0:
                State.push_screen(
                    GameOverScreen(
                        TileMap.width*TileMap.BLOCK_SIZE[0], 
                        TileMap.height*TileMap.BLOCK_SIZE[1]
                    )
                )
            else:
                self.tileMap.set_tile(self.player, 0, 0)
                self.player.health = self.player.std_health
                self.player.coords = (5, 5)
                self.reset_sprite_groups()

    def handle_keyboard(self, events):
        '''
        Function to handle the keyboard events and act accordingly

        @param events - The list of events from the game
        '''

        self.keyboard_input = { 
            key: (new_val, new_val) 
            for key, (old_val, new_val) 
            in self.keyboard_input.items() 
        }
	

        for event in events:
            if not hasattr(event, 'key'): 
                continue
            if event.type == KEYDOWN:
                if event.key == K_p:
                    State.push_screen(PauseScreen(self.player, self.tileMap))
                if event.key == K_i:
                    State.push_screen(InventoryScreen(self.player))

            if event.key in self.keyboard_input:
                (old_val, new_val) = self.keyboard_input[event.key]
                self.keyboard_input[event.key] = (new_val, event.type)


    def check_collisions(self):
        '''
        Checks the collisions between each of the sprite groups and removes them if health is 0 
        '''

        player_crate_collisions = pygame.sprite.spritecollide(self.player, self.crate_group, False, self.did_player_crate_collide)
        player_button_collisions = pygame.sprite.spritecollide(self.player, self.button_group, False, self.did_player_button_collide)
        player_gate_collisions = pygame.sprite.spritecollide(self.player, self.gate_group, False, self.did_player_gate_collide)
        player_enemy_collisions = pygame.sprite.spritecollide(self.player, self.enemy_group, False, self.player_enemy_collide)

        for bullet in self.bullet_group:
            collisions = pygame.sprite.spritecollide(bullet, self.crate_group, False, self.did_bullet_collide)
            for crate in collisions:
                self.bullet_group.remove(bullet)
            collisions = pygame.sprite.spritecollide(bullet, self.enemy_group, False, self.did_bullet_collide)
            for enemy in collisions:
                self.bullet_group.remove(bullet)
                if enemy.health <= 0:
                    self.player.increment_count()
                    self.enemy_group.remove(enemy)
                    try:
                        self.tileMap.tile.enemies.remove(enemy)
                    except ValueError:
                        try:
                            self.tileMap.tile.shooters.remove(enemy)
                            self.shooters.remove(enemy)
                        except ValueError:
                            self.tileMap.tile.bosses.remove(enemy)
                            self.victory()
            (x, y) = bullet.coords
            if y < 0 or y > TileMap.height - 1: 
                self.bullet_group.remove(bullet)
            if x < 0 or x > TileMap.width - 1: 
                self.bullet_group.remove(bullet)

        for bullet in self.enemy_bullet_group:
            collisions = pygame.sprite.spritecollide(bullet, self.crate_group, False)
            for crate in collisions:
                self.enemy_bullet_group.remove(bullet)
            collisions = pygame.sprite.spritecollide(bullet, self.player_group, False)
            if collisions:
                self.enemy_bullet_group.remove(bullet)
                self.player.takeHit(1)
            (x, y) = bullet.coords
            if y < 0 or y > TileMap.height - 1: 
                self.enemy_bullet_group.remove(bullet)
            if x < 0 or x > TileMap.width - 1: 
                self.enemy_bullet_group.remove(bullet)

    def player_enemy_collide(self, player, enemy):
        '''
        Function to test if a player and enemy have collided

        @param player - The player sprite
        @param enemy - The enemy that might have collided with the player
        '''
        if player.coords == enemy.coords:
            self.player.takeHit(1)
            self.throwBack(player, enemy.direction)
            return True
        else:
            return False

    def throwBack(self, entity, direction):
        '''
        Throws the player/enemy back if they collide with each other

        @param entity - The entity to be thrown back
        @param direction - The direction the entity will be thrown

        '''
        (ox, oy) = entity.coords
        entity.move(direction, self.tileMap.tile)
        (x, y) = entity.coords
        entity.isOutOfBounds(
            TileMap.width, 
            TileMap.height, 
            TileMap.TILE_LEFT, 
            TileMap.TILE_RIGHT, 
            TileMap.TILE_UP, 
            TileMap.TILE_DOWN
        )
        (px, py) = entity.coords
        if (px, py) != (x, y):
            entity.coords = (ox, oy)
            oppDir = self.oppositeDirection(direction)
            entity.move(oppDir, self.tileMap.tile)
            entity.move(oppDir, self.tileMap.tile)
        else:
            entity.move(direction, self.tileMap.tile)
            entity.isOutOfBounds(
                TileMap.width, 
                TileMap.height, 
                TileMap.TILE_LEFT, 
                TileMap.TILE_RIGHT, 
                TileMap.TILE_UP, 
                TileMap.TILE_DOWN
            )

    def oppositeDirection(self, direction):
        '''
        Changes the direction to the opposite one

        @param direction - The direction currently being faced
        '''
        if direction == Direction.up: 
            return Direction.down
        elif direction == Direction.down: 
            return Direction.up
        elif direction == Direction.left: 
            return Direction.right
        else: 
            return Direction.left

    def did_player_crate_collide(self, player_sprite, crate_sprite):
        '''
        Checks to see if a player and crate have collided and if it has an item in it
        it will be collected

        @param player_sprite - The player's sprite
        @param crate_sprite - The crate's sprite
        '''
        if player_sprite.coords == crate_sprite.coords:
            crate_sprite.takeHit(1)
            self.player.takeItem(crate_sprite)
            return True
        else:
            return False

    def did_bullet_collide(self, sprite_one, crate_sprite):
        '''
        Checks to see if a bullet collided with a crate

        @param sprite_one - The bullet's sprite 
        @param crate_sprite - The crate's sprite
        '''
        if sprite_one.coords == crate_sprite.coords:
            crate_sprite.takeHit(self.player.laser)
            return True
        else: 
            return False

    def did_player_button_collide(self, player_sprite, button_sprite):
        '''
        Checks to see if the button and player have collided

        @param player_sprite - The player's sprite
        @param button_sprite - THe button's sprite
        '''
        if player_sprite.coords == button_sprite.coords:
            if self.boss:
                self.enemy_group.remove(self.boss[0])
            self.shooters = []
            self.victory()
            return True
        else:
            return False

    def did_player_gate_collide(self, player_sprite, gate_sprite):
        '''
        Checks to see if player and gate have collided

        @param player_sprite - The player's sprite
        @param gate_sprite - The gate's sprite
        '''
        if player_sprite.coords == gate_sprite.coords:
            self.throwBack(player_sprite, self.oppositeDirection(player_sprite.direction))
            return True
        else:
            return False

    def victory(self):
        '''
        Once the victory condition has been met, it will push the victory screen to state
        '''
        State.push_screen(
            VictoryScreen(
                TileMap.width*TileMap.BLOCK_SIZE[0], 
                TileMap.height*TileMap.BLOCK_SIZE[1]
            )
        )
예제 #4
0
    def __init__(self, pnl):
        wx.Frame.__init__(self,
                          None,
                          wx.ID_ANY,
                          pnl["title"],
                          size=(100, 100),
                          style=0)
        self.Bind(wx.EVT_CLOSE, self.onClose)

        self.bmps = BitMaps(os.path.join("..", "bitmaps"))
        self.tileMap = TileMap(self.bmps)

        self.fontTurnouts = wx.Font(10, wx.FONTFAMILY_TELETYPE,
                                    wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorTurnouts = wx.Colour(255, 128, 20)

        self.fontSignals = wx.Font(8, wx.FONTFAMILY_TELETYPE,
                                   wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorSignals = wx.Colour(255, 255, 0)

        self.fontBlocks = wx.Font(14, wx.FONTFAMILY_TELETYPE,
                                  wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorBlocks = wx.Colour(255, 20, 20)

        self.fontLabels = wx.Font(18, wx.FONTFAMILY_TELETYPE,
                                  wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorLabels = wx.Colour(255, 255, 255)

        self.loadData(pnl["filename"])

        rows = len(self.mapArray)
        cols = len(self.mapArray[0])

        sz = wx.BoxSizer(wx.VERTICAL)

        self.panelMap = []
        self.turnouts = []
        self.signals = []
        self.turnoutMap = {}  # label to turnout map
        self.signalMap = {}  # label to signal map

        for r in range(rows):
            rowsz = wx.BoxSizer(wx.HORIZONTAL)
            rowMap = []

            for c in range(cols):
                tid = self.mapArray[r][c]
                tileType = self.tileMap.getTileType(tid)
                if tileType.isSignal():
                    b = wx.StaticBitmap(self,
                                        wx.ID_ANY,
                                        tileType.getBmp(STYPE_RED),
                                        size=BMPDIM,
                                        style=0)
                    sid = len(self.signals)
                    sg = RRSignal(sid, tileType, r, c, b, self.clickSignal)
                    lbl = self.getSignalLabel(r, c)
                    if lbl is not None:
                        self.signalMap[lbl] = sg

                    self.signals.append([sg])
                    rowMap.append([b, None])
                else:
                    te = TrackElement(tileType, r, c)
                    b = wx.StaticBitmap(self,
                                        wx.ID_ANY,
                                        te.getBmp(),
                                        size=BMPDIM,
                                        style=0)
                    if tileType.isTurnout():
                        toid = len(self.turnouts)
                        to = Turnout(toid, te, b, self.clickTurnout)
                        te.setTurnout(to)
                        lbl = self.getTurnoutLabel(r, c)
                        if lbl is not None:
                            self.turnoutMap[lbl] = to

                        self.turnouts.append(to)
                        b.SetBitmap(te.getBmp())
                    rowMap.append([b, te])

                rowsz.Add(b)

            sz.Add(rowsz)
            self.panelMap.append(rowMap)

        self.SetSizer(sz)
        self.Fit()

        self.stLabels = []
        for to in self.annotations["turnouts"].values():
            self.placeLabel(to["row"] + to["offsetr"],
                            to["col"] + to["offsetc"],
                            to["adjx"],
                            to["adjy"],
                            to["label"],
                            font=self.fontTurnouts,
                            fg=self.colorTurnouts)

        for sg in self.annotations["signals"].values():
            self.placeLabel(sg["row"] + sg["offsetr"],
                            sg["col"] + sg["offsetc"],
                            sg["adjx"],
                            sg["adjy"],
                            sg["label"],
                            font=self.fontSignals,
                            fg=self.colorSignals)

        for bl in self.annotations["blocks"]["blocks"].values():
            self.placeLabel(bl["row"],
                            bl["col"],
                            bl["adjx"],
                            bl["adjy"],
                            bl["label"],
                            font=self.fontBlocks,
                            fg=self.colorBlocks)

        for lbl in self.annotations["labels"]:
            self.placeLabel(lbl["row"],
                            lbl["col"],
                            lbl["adjx"],
                            lbl["adjy"],
                            lbl["label"],
                            font=self.fontLabels,
                            fg=self.colorLabels)
예제 #5
0
class Panel(wx.Frame):
    def __init__(self, pnl):
        wx.Frame.__init__(self,
                          None,
                          wx.ID_ANY,
                          pnl["title"],
                          size=(100, 100),
                          style=0)
        self.Bind(wx.EVT_CLOSE, self.onClose)

        self.bmps = BitMaps(os.path.join("..", "bitmaps"))
        self.tileMap = TileMap(self.bmps)

        self.fontTurnouts = wx.Font(10, wx.FONTFAMILY_TELETYPE,
                                    wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorTurnouts = wx.Colour(255, 128, 20)

        self.fontSignals = wx.Font(8, wx.FONTFAMILY_TELETYPE,
                                   wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorSignals = wx.Colour(255, 255, 0)

        self.fontBlocks = wx.Font(14, wx.FONTFAMILY_TELETYPE,
                                  wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorBlocks = wx.Colour(255, 20, 20)

        self.fontLabels = wx.Font(18, wx.FONTFAMILY_TELETYPE,
                                  wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.colorLabels = wx.Colour(255, 255, 255)

        self.loadData(pnl["filename"])

        rows = len(self.mapArray)
        cols = len(self.mapArray[0])

        sz = wx.BoxSizer(wx.VERTICAL)

        self.panelMap = []
        self.turnouts = []
        self.signals = []
        self.turnoutMap = {}  # label to turnout map
        self.signalMap = {}  # label to signal map

        for r in range(rows):
            rowsz = wx.BoxSizer(wx.HORIZONTAL)
            rowMap = []

            for c in range(cols):
                tid = self.mapArray[r][c]
                tileType = self.tileMap.getTileType(tid)
                if tileType.isSignal():
                    b = wx.StaticBitmap(self,
                                        wx.ID_ANY,
                                        tileType.getBmp(STYPE_RED),
                                        size=BMPDIM,
                                        style=0)
                    sid = len(self.signals)
                    sg = RRSignal(sid, tileType, r, c, b, self.clickSignal)
                    lbl = self.getSignalLabel(r, c)
                    if lbl is not None:
                        self.signalMap[lbl] = sg

                    self.signals.append([sg])
                    rowMap.append([b, None])
                else:
                    te = TrackElement(tileType, r, c)
                    b = wx.StaticBitmap(self,
                                        wx.ID_ANY,
                                        te.getBmp(),
                                        size=BMPDIM,
                                        style=0)
                    if tileType.isTurnout():
                        toid = len(self.turnouts)
                        to = Turnout(toid, te, b, self.clickTurnout)
                        te.setTurnout(to)
                        lbl = self.getTurnoutLabel(r, c)
                        if lbl is not None:
                            self.turnoutMap[lbl] = to

                        self.turnouts.append(to)
                        b.SetBitmap(te.getBmp())
                    rowMap.append([b, te])

                rowsz.Add(b)

            sz.Add(rowsz)
            self.panelMap.append(rowMap)

        self.SetSizer(sz)
        self.Fit()

        self.stLabels = []
        for to in self.annotations["turnouts"].values():
            self.placeLabel(to["row"] + to["offsetr"],
                            to["col"] + to["offsetc"],
                            to["adjx"],
                            to["adjy"],
                            to["label"],
                            font=self.fontTurnouts,
                            fg=self.colorTurnouts)

        for sg in self.annotations["signals"].values():
            self.placeLabel(sg["row"] + sg["offsetr"],
                            sg["col"] + sg["offsetc"],
                            sg["adjx"],
                            sg["adjy"],
                            sg["label"],
                            font=self.fontSignals,
                            fg=self.colorSignals)

        for bl in self.annotations["blocks"]["blocks"].values():
            self.placeLabel(bl["row"],
                            bl["col"],
                            bl["adjx"],
                            bl["adjy"],
                            bl["label"],
                            font=self.fontBlocks,
                            fg=self.colorBlocks)

        for lbl in self.annotations["labels"]:
            self.placeLabel(lbl["row"],
                            lbl["col"],
                            lbl["adjx"],
                            lbl["adjy"],
                            lbl["label"],
                            font=self.fontLabels,
                            fg=self.colorLabels)

    def emulateSignalClick(self, lbl, right=False):
        if lbl in self.signalMap.keys():
            sg = self.signalMap[lbl]
            if right:
                sg.emulateRightClick()
            else:
                sg.emulateClick()

            return True

        return False

    def emulateTurnoutClick(self, lbl, right=False):
        if lbl in self.turnoutMap.keys():
            to = self.turnoutMap[lbl]
            if right:
                to.emulateRightClick()
            else:
                to.emulateClick()

            return True

        return False

    def getSignalLabel(self, r, c):
        sgl = self.annotations["signals"]

        for sg in sgl.values():
            if sg["row"] == r and sg["col"] == c:
                return sg["label"]

        return None

    def getTurnoutLabel(self, r, c):
        tol = self.annotations["turnouts"]

        for to in tol.values():
            if to["row"] == r and to["col"] == c:
                return to["label"]

        return None

    def placeLabel(self,
                   row,
                   col,
                   adjx,
                   adjy,
                   text,
                   font=None,
                   fg=None,
                   bg=None):
        st = wx.StaticText(self, wx.ID_ANY, text)
        self.stLabels.append(st)

        b = self.panelMap[row][col][0]
        p = b.GetPosition()
        p[0] += adjx
        p[1] += adjy

        st.SetPosition(p)

        if font is None:
            st.SetFont(
                wx.Font(70, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL,
                        wx.FONTWEIGHT_NORMAL))
        else:
            st.SetFont(font)

        if fg is None:
            st.SetForegroundColour(wx.Colour(255, 128, 20))
        else:
            st.SetForegroundColour(fg)

        if bg is None:
            st.SetBackgroundColour(wx.Colour(0, 0, 0))
        else:
            st.SetBackgroundColour(bg)

    def loadData(self, basename):
        with open(os.path.join("..", basename + '.arr')) as f:
            inlns = f.readlines()

        arr = [x.strip() for x in inlns]

        if len(arr) < 1:
            print("no data in arr file")
            exit()

        maxl = len(arr[0])
        for ln in arr:
            maxl = max(maxl, len(ln))

        self.mapArray = [a + '.' * (maxl - len(a)) for a in arr]

        with open(os.path.join("..", basename + '.json'), "r") as fp:
            try:
                self.annotations = json.load(fp)
            except IOError:
                self.annotations = {
                    "turnouts": {},
                    "signals": {},
                    "blocks": {
                        "blockends": {},
                        "blocks": {}
                    },
                    "labels": {}
                }

    def tracksMesh(self, te, lastAdj):
        # return values:
        #		boolean true if tracks mesh, false otherwise
        #		direction from which the tile is entered
        #		boolean true if tile is a turnout and is entered through the reverse leg
        #		<0, 0, >0 indicating vertical movement up, none, down
        nadj = te.getAdjacent(ADJ_EAST)
        if lastAdj == nadj:
            # coming in on the east leg
            if te.isTurnout() and te.isReversed():
                revAdj = te.getAdjacent(ADJ_REVERSED)
                if nadj[0] == revAdj[0]:
                    # incoming leg and reversed leg coming from the same direction
                    # this is impossible
                    return False, None, False, 0

                else:
                    return True, ADJ_EAST, False, 0
            else:
                return True, ADJ_EAST, False, 0

        if lastAdj[0] == 0 and nadj[0] == 0 and nadj[1] is None:
            # allowance for vertical movement
            return True, ADJ_EAST, False, -lastAdj[1]

        nadj = te.getAdjacent(ADJ_WEST)
        if lastAdj == nadj:
            # coming in on the east leg
            if te.isTurnout() and te.isReversed():
                revAdj = te.getAdjacent(ADJ_REVERSED)
                if nadj[0] == revAdj[0]:
                    # incoming leg and reversed leg coming from the same direction
                    # this is impossible
                    return False, None, False, 0

                else:
                    return True, ADJ_WEST, False, 0

            else:
                return True, ADJ_WEST, False, 0

        if lastAdj[0] == 0 and nadj[0] == 0 and nadj[1] is None:
            # allowance for vertical movement
            return True, ADJ_WEST, False, -lastAdj[1]

        if te.isTurnout() and te.isReversed():
            nadj = te.getAdjacent(ADJ_REVERSED)
            if lastAdj == nadj:
                if nadj[0] < 0:
                    return True, ADJ_WEST, True, 0
                else:
                    return True, ADJ_EAST, True, 0

        return False, None, False, 0

    def findBlockByName(self, name, rtype):
        eobs = []
        for b in self.annotations["blocks"]["blockends"].values():
            if b["blockname"] == name:
                eobs.append([b["row"], b["col"]])

        maxCols = len(self.panelMap[0]) - 1
        maxRows = len(self.panelMap) - 1

        for r, c in eobs:
            te = self.panelMap[r][c][1]
            eadj = te.getAdjacent(ADJ_EAST)
            wadj = te.getAdjacent(ADJ_WEST)
            if eadj == [0, 0]:
                eastbound = False
            else:
                eastbound = True
            if eadj == [0, None]:
                lastAdjRow = 1
            elif wadj == [0, None]:
                lastAdjRow = -1
            else:
                lastAdjRow = None

            startRow = r
            startCol = c
            startEast = eastbound
            startVert = lastAdjRow

            lastAdj = None

            foundRoute = False
            while True:
                entryReverse = False

                if c < 0 or c > maxCols:
                    foundRoute = True
                    break
                if r < 0 or r > maxRows:
                    foundRoute = True
                    break

                try:
                    te = self.panelMap[r][c][1]
                except IndexError:
                    break

                if lastAdj:
                    mesh, tileEntry, entryReverse, _ = self.tracksMesh(
                        te, lastAdj)
                    if not mesh:
                        break
                    if tileEntry == ADJ_WEST:
                        eastbound = True
                    elif tileEntry == ADJ_EAST:
                        eastbound = False

                if (not entryReverse) and te.isTurnout() and te.isReversed():
                    adj = te.getAdjacent(ADJ_REVERSED)
                elif eastbound:
                    adj = te.getAdjacent(ADJ_EAST)
                else:
                    adj = te.getAdjacent(ADJ_WEST)

                if adj is None:
                    break
                if adj == [0, 0]:
                    foundRoute = True
                    break

                if adj[1] is None:
                    adj[1] = lastAdjRow

                c += adj[0]
                r += adj[1]

                # set up the last adjacency matrix to match against the COMPLEMENT of this movement
                lastAdj = [-x for x in adj]
                lastAdjRow = adj[1]

            if foundRoute:
                self.markRoute(startRow, startCol, rtype, startEast, startVert)
                break

    def markRoute(self, rStart, cStart, rtype, eb=True, vert=None):
        r = rStart
        c = cStart
        eastbound = eb

        lastAdj = None
        lastAdjRow = vert

        while True:
            entryReverse = False
            vertDir = 0

            try:
                bmp, te = self.panelMap[r][c]
            except IndexError:
                break

            if lastAdj:
                mesh, tileEntry, entryReverse, vertDir = self.tracksMesh(
                    te, lastAdj)
                if not mesh:
                    break
                if tileEntry == ADJ_WEST:
                    eastbound = True
                elif tileEntry == ADJ_EAST:
                    eastbound = False

            if rtype == TTYPE_OCCUPIED:
                te.setOccupied(True)
            elif rtype == TTYPE_ROUTED:
                if te.isReversible():
                    if vertDir != 0:
                        if vertDir > 0:  #moving down
                            te.setDownRouted()
                        else:
                            te.setUpRouted()
                    else:
                        if eastbound:
                            te.setEastRouted()
                        else:
                            te.setWestRouted()
                else:
                    te.setRouted(True)
            else:
                te.setOccupied(False)
                te.setRouted(False)

            bmp.SetBitmap(te.getBmp())

            if (not entryReverse) and te.isTurnout() and te.isReversed():
                adj = te.getAdjacent(ADJ_REVERSED)
            elif eastbound:
                adj = te.getAdjacent(ADJ_EAST)
            else:
                adj = te.getAdjacent(ADJ_WEST)

            if adj is None:
                break
            if adj == [0, 0]:
                break
            if adj[1] is None:
                adj[1] = lastAdjRow

            c += adj[0]
            r += adj[1]

            # set up the last adjacency matrix to match against the COMPLEMENT of this movement
            lastAdj = [-x for x in adj]
            lastAdjRow = adj[1]

    def clickTurnout(self, to, lr):
        bmp = to.getBmp()
        te = to.getTe()
        if lr == LEFT:
            if te.isRouted():
                print("not while routed")
                return

            if te.isOccupied():
                print("not while occupied")
                return

            if to.isReversed():
                to.setReversed(False)
                bmp.SetBitmap(te.getBmp())
            else:
                to.setReversed(True)
                bmp.SetBitmap(te.getBmp())

    def clickSignal(self, sg, lr):
        red = sg.isRed()

        r, c = sg.getBlockStart()
        te = self.panelMap[r][c][1]

        if red:
            # attempt to turn signal green
            # only allowed if block is not otherwise busy
            if te.isOccupied() or te.isRouted():
                print("route is busy")
                return

        red = not red
        sg.setRed(red)
        self.markRoute(r, c, TTYPE_NORMAL if red else TTYPE_ROUTED,
                       sg.isEast())

    def onClose(self, _):
        #pass
        self.Hide()
예제 #6
0
class Level1:

    def __init__(self, manager):
        self.background = Sprite("Resources/Backgrounds/level1.png").get_image(0, 0, public.display_dimensions[0], public.display_dimensions[1])

        self.manager = manager;

        self.player = Player()
        self.player.set_position(250, 254)

        minion1 = CommonMinion()
        minion1.set_movement(300, 278, 300, 500)

        self.enemies = [
            minion1
        ]

        self.tile_map = TileMap("Resources/Maps/level1.map")

    def update(self):
        if self.player.rect.bottom >= public.display_dimensions[1]:
            self.manager.state_index = 0

        self.tile_map.set_exceed(self.player.bound_exceed)
        self.tile_map.update()

        self.player.set_blocks(self.tile_map.blocks)
        self.player.update()

        for enemy in self.enemies:
            enemy.set_exceed(self.player.bound_exceed)
            enemy.update()

        self.player.rect.y += 1
        test_collisions = pygame.sprite.spritecollide(self.player, self.tile_map.blocks, False)

        if test_collisions:
            self.player.rect.bottom = test_collisions[0].rect.top
            self.player.d_y = 0
        else:
            self.player.d_y += self.player.gravity
            self.player.rect.y -= 1

        collisions = pygame.sprite.spritecollide(self.player, self.tile_map.blocks, False)
        for block in collisions:
            if self.player.moving_right:
                self.player.rect.right = block.rect.left
            elif self.player.moving_left:
                self.player.rect.left = block.rect.right

    def draw(self, display):
        display.blit(self.background, (0, 0))
        self.tile_map.draw(display)

        for enemy in self.enemies:
            enemy.draw(display)

        self.player.draw(display)

    def key_pressed(self, key):
        self.player.key_pressed(key)

    def key_released(self, key):
        self.player.key_released(key)