Exemple #1
0
def load_map(map_image=None):
    """ Function that loads a PIL image and reads it, pixel by pixel, to decode it into a tile map. 
        
        Gets the map from the c.IMAGES["map"] object.
        Sets a map (two-dimensional list of Tiles), the width and height of the image loaded 
        and the player starting point, x and y, from the file as variables in the g module.
        (5 items) If no starting point is found, return 0, 0 as the starting point. 
    """
    if map_image is None:
        # Load the image
        map_image = pygame.image.load(os.path.join(os.getcwd(), c.RES_FOLDER, c.IMAGES["map"].png))

    g.map = []
    # Variable for holding multi_tiles until after the primary generation.
    multi_tiles = []
    width, height = map_image.get_size()
    player_start_x = 0
    player_start_y = 0
    
    for x in range(width):
        # Create a new vertical column for every pixel the image is wide.
        g.map.append([])
        for y in range(height):
            # The pixel variable is the pixel we're currently checking.
            pixel = map_image.get_at((x, y))[:3]
            px_type = pixel_type(pixel, x, y)
            # If the pixel is the player start tile, save the location of that pixel.
            if px_type == "start_tile":
                player_start_x = x * c.TILE_SIZE
                player_start_y = y * c.TILE_SIZE
                px_type = c.DEFAULT_TILE
            # Check to see if it's a multi-tile and, if so, store that in a variable to be done last
            g.map[x].append(None)
            if c.IMAGES[px_type].multi_tile:
                multi_tiles.append([px_type, x, y])
                tiles.make_tile(c.DEFAULT_TILE, x, y)
            else:
                # Make a new tile and add it to the map
                tiles.make_tile(px_type, x, y)
            
    # Sets the values to the global values
    g.width = width
    g.height = height
    g.player_start_x = player_start_x
    g.player_start_y = player_start_y
    
    # Create the multi-tiles
    for multi_tile in multi_tiles:
        px_type, x, y = multi_tile
        width, height = c.IMAGES[px_type].multi_tile
        if (g.map[x][y] and g.map[x][y].type == c.DEFAULT_TILE and 
                tiles.area_is_free(x, y, width, height)):
            tiles.make_tile(px_type, x, y)
Exemple #2
0
def main():
    """ Main function, initializes various variables and contains the main program loop.
        Should not be called any other way than running the file or running launch.
        Takes no arguments and returns nothing.
    """
    # initialize pygame
    pygame.init()

    # Make map
    maps.load_map(maps.generate_map())
    # maps.load_map()

    # Initiate player
    g.special_entity_list["player"] = players.Player(g.player_start_x, g.player_start_y)
    # Creates a window just the size to fit all the tiles in the map file.
    pygame.display.set_icon(g.images["icon"].get())
    pygame.display.set_caption("TileGame by ZeeQyu", "TileGame")
    g.screen = pygame.display.set_mode((g.width * c.TILE_SIZE, g.height * c.TILE_SIZE))

    # A variable for skipping a single cycle after f.ex. accessing a menu, so that
    # the entities won't fly across the screen
    skip_cycle = False

    # Get time once initially and make time variables
    time_last_tick = time_prev = time.clock()
    time_start = time_cycles = time_updates = time_last_sleep = 0

    # Main loop
    while True:
        # Make the screen update every frame
        if c.FORCE_UPDATE:
            g.force_update = True
        # Event checker. Allows closing of the program and passes keypresses to the player instance
        key_input.event_check()
        # Tick: Make sure certain things happen on a more regular basis than every frame
        # time_big_diff is the time the cycle took.
        # time_diff (defined below) is the simulated time difference that
        # the entities move after before ticking again in case of a lag spike.
        time_now = time.clock()
        time_big_diff = (time_now - time_prev) * c.GAME_SPEED
        time_prev = time_now

        # Skip the rest of this cycle if a menu was accessed until now
        if skip_cycle:
            skip_cycle = False
            continue
        # FPS meter (shown in console).
        # checks the amount of times this code is run every second and prints that every second.
        time_cycles += 1
        if time_start + 1 < time_now:
            if time_updates == 1 and time_cycles == 1:
                time_updates = 1.0 / time_big_diff
            if c.NORMAL_DEBUG:
                print(time_start, "seconds from start,", time_cycles, "cycles,", time_updates, "fps")
            time_cycles = 0
            time_updates = 0
            time_start = time_now

        # What happens every tick?
        while time_big_diff > 0:
            if time_big_diff >= c.TICK_FREQ:
                time_diff = c.TICK_FREQ
                time_big_diff -= time_diff
            else:
                time_diff = time_big_diff
                time_big_diff = 0

            if time_last_tick + c.TICK_FREQ <= time_now:
                time_last_tick = time_last_tick + c.TICK_FREQ
                # Tick all the entities (let them do whatever they do every tick
                for i in range(len(g.entity_list) - 1, -1, -1):
                    entity = g.entity_list[i]
                    if entity.tick() == "delete":
                        del g.entity_list[i]
                        g.force_update = True
                for entity in list(g.special_entity_list.values()):
                    entity.tick()
                for tile in g.tick_tiles:
                    g.map[tile[0]][tile[1]].tick()
            # Make sure the loop doesn't go too quickly and bog the processor down
            if time_last_sleep < c.SLEEP_TIME:
                time.sleep(c.SLEEP_TIME - time_last_sleep)

            # update all entities
            entity_has_moved = False
            if g.entity_list:
                for i in range(len(g.entity_list) - 1, -1, -1):
                    entity = g.entity_list[i]
                    entity.update(time_diff)
                    # Check if any of them have moved
                    if entity.has_moved():
                        entity_has_moved = True
            if g.special_entity_list:
                for entity in list(g.special_entity_list.values()):
                    # Update all entities and check for if any of them is a package that just finished moving.
                    # If so, skip the has_moved check for that entity.
                    if entity.update(time_diff) == "deleted":
                        continue
                    if entity.has_moved():
                        entity_has_moved = True
            if "tile_target" in g.special_entity_list:
                while g.tile_target_selection[0] >= g.width:
                    g.tile_target_selection[0] -= g.width
                while g.tile_target_selection[0] < 0:
                    g.tile_target_selection[0] += g.width

                while g.tile_target_selection[1] >= g.height:
                    g.tile_target_selection[1] -= g.height
                while g.tile_target_selection[1] < 0:
                    g.tile_target_selection[1] += g.height

                g.special_entity_list["tile_target"].x = g.tile_target_selection[0] * c.TILE_SIZE
                g.special_entity_list["tile_target"].y = g.tile_target_selection[1] * c.TILE_SIZE
            if g.non_entity_list:
                for item in list(g.non_entity_list.values()):
                    try:
                        if item.update(time_diff):
                            entity_has_moved = True
                    except AttributeError:
                        pass

            # Check if any tiles need to be updated.
            if g.tile_maker_queue:
                while g.tile_maker_queue:
                    tiles.make_tile(*g.tile_maker_queue.pop())

            # Update map buffer if needed
            if g.update_map:
                g.update_map = False
                g.force_update = True
                g.map_screen_buffer = maps.update_map()
                g.update_microtiles = False

        # If any entity moved, redraw the screen
        if entity_has_moved or g.force_update:
            g.force_update = False
            time_updates += 1
            g.screen.fill(c.BACKGROUND_COLOR)
            # Draw the map buffer on the screen
            g.screen.blit(g.map_screen_buffer, (0, 0))
            # Draw the objects
            for i in range(len(g.entity_list) - 1, -1, -1):
                entity = g.entity_list[i]
                entity.paint()
            for i in range(len(list(g.special_entity_list.values())) - 1, -1, -1):
                entity = list(g.special_entity_list.values())[i]
                entity.paint()
            for i in range(len(list(g.non_entity_list.values())) - 1, -1, -1):
                list(g.non_entity_list.values())[i].paint()
            del entity

            # Update the display
            pygame.display.flip()
Exemple #3
0
 def update(self, time_diff):
     """ Calls the superclass update and updates the state of the aim marker.
         Manages if the player is placing or destroying a block.
     """
     super(Player, self).update(time_diff)
     # Update screen whenever aim marker changes states
     if self.removing_tile != self.last_removing_tile:
         self.last_removing_tile = self.removing_tile
         g.force_update = True
     
     # Get which tile the player is looking at
     aim_tile = self.get_aim_tile()
     x, y = aim_tile
     # If the aim tile has changed
     if aim_tile != self.last_aim_tile or self.update_aim_tile:
         self.update_aim_tile = False
         # Checks if the aim tile has a remove time (can be destroyed).
         # If so, assign that value to self.remove_timer.
         try:
             if c.IMAGES[g.map[x][y].type].destroy is not None:
                 self.remove_timer = c.IMAGES[g.map[x][y].type].destroy[0]
             elif type(g.map[x][y]) == tiles.MultiTilePointer:
                 # Finding out which tile the pointer is pointing to, and if that has a destroy value
                 head_x, head_y = g.map[x][y].target
                 multi_tile_head = g.map[head_x][head_y]
                 if c.IMAGES[multi_tile_head.type].destroy is not None:
                     self.remove_timer = c.IMAGES[multi_tile_head.type].destroy[0]
                 else:
                     self.remove_timer = None
             else:
                 self.remove_timer = None
         except IndexError:
             self.remove_timer = None
         except:
             raise
     self.last_aim_tile = aim_tile
     
     # Placing tile
     if self.placing_tile and not self.removing_tile:
         try:
             if c.IMAGES[g.map[x][y].type].placeable:
                 # If there is a special case for placing tiles, use that. Otherwise, use the default
                 tiles.make_tile(c.DEFAULT_PLACE_TILE, x, y)
         # Ignore IndexErrors because the indices might be outside of the map
         except IndexError:
             pass
         except:
             raise
         
     # Removing tile
     if self.removing_tile and not self.placing_tile:
         # If the timer isn't None (is removable)
         if self.remove_timer is not None:
             # If remove_timer has reached 0 which means the countdown is done
             if self.remove_timer < 1:
                 tiles.destroy_tile(x, y)
                 self.update_aim_tile = True
                 self.remove_timer = None
                 return
             
     # Grabbing tile
     if self.toggle_grab:
         # If the grab button is pressed
         self.toggle_grab = False
         if self.following_entity is not None:
             x, y = self.get_aim_tile()
             if c.IMAGES[g.map[x][y].type].placeable:
                 g.special_entity_list[self.following_entity].target_coords = [x*c.TILE_SIZE,
                                                                               y*c.TILE_SIZE]
         else:
             if g.map[x][y].type in c.PACKAGE_TILE_NAMES.keys():
                 tiles.make_tile(c.PACKAGE_TILE_NAMES[g.map[x][y].type], x, y)
                 g.update_map = True
                 units.Package(x*c.TILE_SIZE, y*c.TILE_SIZE, "player")
Exemple #4
0
def _put_tile(tile_id):
    tiles.make_tile(tile_id, *g.special_entity_list["player"].get_aim_tile())
    return True