def render_light_map(self): self.light_map.fill((255, 255, 255)) tmp_light_map = pygame.Surface( (self.light_map.get_width(), self.light_map.get_height()), flags=pygame.HWSURFACE) for obj in self.objects: # type: Object if isinstance(obj, BackedLightObject): tmp_light_map.fill((255, 255, 255)) position = obj.position.copy() position.x -= obj.light_image.get_width() / 2 position.y -= obj.light_image.get_height() / 2 tmp_light_map.blit(obj.light_image, position.list()) Shadow.optimized_shadows( self.collisions, obj.position.copy(), tmp_light_map, box_borders=[ Vector2D(0, 0), Vector2D(self.light_map.get_width(), 0), Vector2D(self.light_map.get_width(), self.light_map.get_height()), Vector2D(0, self.light_map.get_height()) ], color=(255, 255, 255)) self.light_map.blit(tmp_light_map, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)
def render_collisions(self): self.collisions = [] for x in range(0, len(self.room_map)): for y in range(0, len(self.room_map[0])): if self.get(x, y) != RoomTiles.WALL or self.get( x, y + 1) != RoomTiles.WALL: continue self.collisions.append( Polygon.Polygon(Vector2D(x * 8 * 4, y * 8 * 4), [ Vector2D(0, 0), Vector2D(8 * 4, 0), Vector2D(8 * 4, 8 * 4), Vector2D(0, 8 * 4) ]))
def __init__(self, obj_data, cam): Object.__init__(self, obj_id=0, camera=cam) InteractiveObject.__init__(self) BackedLightObject.__init__( self, pygame.image.load("game_data/images/light/default.png").convert()) self.position = Vector2D(0, 0, lst=obj_data["pos"]) self.animation_base_folder = "game_data/sprites/objects/pod" self.animations_to_load = [{ "name": "static", "scale": 4, "loop": True, "fps": 8 }] self.load_animations() self.set_animation("static") self.font = pygame.font.Font("game_data/fonts/press_start_2p.ttf", 20) self.font2 = pygame.font.Font("game_data/fonts/press_start_2p.ttf", 12) self.explanation_text = self.font.render( "Capsule from where you emerged", False, (255, 255, 255)) self.exit_text = self.font2.render("Press ESC to exit", False, (255, 255, 255)) self.background_size = 10 self.gradient = pygame.Surface( (self.explanation_text.get_width() + self.background_size * 2, self.explanation_text.get_height() + self.exit_text.get_height() + 10 + self.background_size * 2)) self.gradient.set_alpha(220) self.gradient.fill((0, 0, 0))
def __init__(self, game_manager): # type: (GameManager.GameManager) -> None self.game_manager = game_manager # type: GameManager.GameManager # self.rendered_image = self.world_gen.get_current_room() # type: pygame.Surface # self.current_room_rendered = self.world_gen.get_current_room() # type: RoomRenderer self.cam = Camera.Camera(self.game_manager) self.world_gen = WorldGenerator.WorldGenerator( self.game_manager, "game_data/config/world.json", "game_data/worlds/test_world", camera=self.cam) self.player = Player.PlayerObject( self.game_manager, self.world_gen, position=Vector2D(1280 / 2, 720 / 2), camera=self.cam, obj_data=self.world_gen.load_player()) self.cam.position = self.player.position.copy() self.cam.target(self.player.position)
def __init__(self, game_manager, world_configurations, world_folder, seed=None, camera=None): # type: (GameManager.GameManager, str, str, int, Camera) -> None self.game_manager = game_manager self.camera = camera if not os.path.isfile(world_configurations): raise Exception("Missing world configurations") world_configurations_file = open(world_configurations, "rb") self.world_configurations = json.loads( world_configurations_file.read()) world_configurations_file.close() # World Configuration self.world_size = self.world_configurations["world_size"] self.world_bounds = [ int(-self.world_size[0] / 2), int(-self.world_size[1] / 2), int(self.world_size[0] / 2), int(self.world_size[1] / 2) ] self.max_room_size = self.world_configurations["max_room_size"] self.world_folder = world_folder if not os.path.isdir(self.world_folder): os.mkdir(self.world_folder) self.new_world(seed) self.world_data_file = open(self.world_folder + "/world_data.json", "rb") self.world_data = json.loads(self.world_data_file.read()) self.world_data_file.close() self.seed = self.world_data["seed"] if not os.path.isfile(self.world_folder + "/rooms/room_0_0.json") or True: self.room_0_gen() self.current_room = Vector2D(0, 0) self.current_room_obj = None
def __init__(self, game_manager): # type: (GameManager.GameManager) -> None self.game_manager = game_manager # type: GameManager.GameManager self.cam = Camera.Camera(self.game_manager) self.world_gen = WorldGenerator.WorldGenerator(self.game_manager, "game_data/config/world.json", "game_data/worlds/test_world", camera=self.cam) self.player = Player.PlayerObject(self.game_manager, self.world_gen, position=Vector2D(1280 / 2, 720 / 2), camera=self.cam, obj_data=self.world_gen.load_player()) self.cam.position = self.player.position.copy() self.cam.target(self.player.position)
def __init__(self, game_manager, world_generator, camera, obj_data=None, position=Vector2D(0, 0)): RealtimeLightObject.__init__( self, pygame.image.load("game_data/images/light/small.png").convert(), Vector2D(0, 0)) Object.__init__(self, 65, camera=camera) if obj_data is None: self.position = position self.screen = Vector2D(0, 0) else: self.position = Vector2D(0, 0, lst=obj_data["position"]) self.screen = Vector2D(0, 0, lst=obj_data["screen"]) self.animation_base_folder = "game_data/sprites/player" self.animations_to_load = [{ "name": "wake_up", "scale": 4, "loop": False, "fps": 12 }, { "name": "idle", "scale": 4, "loop": True, "fps": 2 }] self.font = pygame.font.Font("game_data/fonts/press_start_2p.ttf", 20) self.load_animations() self.set_animation("wake_up") self.world_generator = world_generator # type: WorldGenerator self.current_room = None self.current_screen_text = None self.change_current_room(self.screen.x, self.screen.y) self.game_manager = game_manager # type: GameManager.GameManager self.move_speed = 100 self.interacting_distance = 100 self.interacting = False self.interacting_object = 0 self.interactive_close = False self.interactive_close_num = 0 self.interactive_ui_animation = Animation( "game_data/sprites/ui/interact_text", loop=True, scale=2, frames_per_second=2) # Fade in self.fade_in_surface = pygame.Surface( self.game_manager.screen.get_size()) self.fade_in_surface.fill((0, 0, 0))
def inner_rooms_doors(self, rectangles): # Every one represents a room and it's connection with its sorroundings inner_room_connections = [ InnerRoomConnections() for rectangle in rectangles ] for rectangle in rectangles: for rectangle2 in rectangles: if rectangle == rectangle2: continue # We add a connection to both involved rooms because a door is two directional # Top door if rectangle[1] == rectangle2[1] + rectangle2[3]: if rectangle[0] >= rectangle2[0] and rectangle[ 0] + rectangle[2] <= rectangle2[0] + rectangle2[2]: position = Vector2D( (rectangle[0] * 2 + rectangle[2]) / 2, rectangle[1]) inner_room_connections[rectangles.index( rectangle)].add_connection(inner_room_connections[ rectangles.index(rectangle2)], position, vertical=True) inner_room_connections[rectangles.index( rectangle2)].add_connection(inner_room_connections[ rectangles.index(rectangle)], position, vertical=True) # Bottom door if rectangle2[1] == rectangle[1] + rectangle[3]: if rectangle[0] >= rectangle2[0] and rectangle[ 0] + rectangle[2] <= rectangle2[0] + rectangle2[2]: position = Vector2D( (rectangle[0] * 2 + rectangle[2]) / 2, rectangle2[1]) inner_room_connections[rectangles.index( rectangle)].add_connection(inner_room_connections[ rectangles.index(rectangle2)], position, vertical=True) inner_room_connections[rectangles.index( rectangle2)].add_connection(inner_room_connections[ rectangles.index(rectangle)], position, vertical=True) # Left door if rectangle[0] == rectangle2[0] + rectangle2[2]: if rectangle[1] >= rectangle2[1] and rectangle[ 1] + rectangle[3] <= rectangle2[1] + rectangle2[3]: position = Vector2D(rectangle[0], (rectangle[1] * 2 + rectangle[3]) / 2) inner_room_connections[rectangles.index( rectangle)].add_connection(inner_room_connections[ rectangles.index(rectangle2)], position, vertical=False) inner_room_connections[rectangles.index( rectangle2)].add_connection(inner_room_connections[ rectangles.index(rectangle)], position, vertical=False) # Right door if rectangle2[0] == rectangle[0] + rectangle[2]: if rectangle[1] >= rectangle2[1] and rectangle[ 1] + rectangle[3] <= rectangle2[1] + rectangle2[3]: position = Vector2D(rectangle2[0], (rectangle[1] * 2 + rectangle[3]) / 2) inner_room_connections[rectangles.index( rectangle)].add_connection(inner_room_connections[ rectangles.index(rectangle2)], position, vertical=True) inner_room_connections[rectangles.index( rectangle2)].add_connection(inner_room_connections[ rectangles.index(rectangle)], position, vertical=True) # Connections to process # Once we walk a room, its connections get added to this list to get processed. connections_to_process = [] # Start with the connections from room 0 for connection in inner_room_connections[0].get_connection(): connections_to_process.append(connection) inner_room_connections[0].has_entrance = True # While there are still connections to process. This way we make sure we walk all connections. while len(connections_to_process) > 0: connection = connections_to_process.pop() if connection["obj"].has_entrance: # This connection was in the list but its destination has already an entrance continue connection["obj"].has_entrance = True # We make the door position = connection["position"] self.room_map[position.x][position.y] = RoomTiles.FLOOR if connection["vertical"]: # If the door is vertical we have to clear another position under it because we have a double wall. self.room_map[position.x][position.y + 1] = RoomTiles.FLOOR # We get the connections of the next room we "walk" into. connections_to_add = connection["obj"].get_connection() # We go over all new connections and if their destination has already an entrance we skip that connection. for connection_to_add in connections_to_add: if connection_to_add["obj"].has_entrance: connections_to_add.remove(connection_to_add) # We append the new connections at the front because then we continue creating the doors from the room # we just "walked" into. new_connections_to_process = connections_to_add new_connections_to_process.extend(connections_to_process) connections_to_process = new_connections_to_process
def __init__(self, x, y, world_generator): # type: (int, int, WorldGenerator.WorldGenerator) -> None self.is_connection = False # Is there a connection? # Used to generate random numbers (that way it does not depend on the screen) self.connection_id = 0 # World generator used to get the seed self.world = world_generator # Random for this class self.this_rand = random.Random() # Random (pos x or pos y, depending if it's vertical or horizontal) of the connection self.value = 0 # Special values for spawn room (0, 0) if x == 0 and y == -1: self.value = 26 / 2 self.is_connection = True return if x == -1 and y == -1: self.is_connection = False return if x == 0 and y == 0: self.is_connection = False return if x == 0 and y == -2: self.is_connection = False return # Check that the connection is in the bounds if self.world.world_bounds[0] <= x <= self.world.world_bounds[2]\ and self.world.world_bounds[1] * 2 <= y <= self.world.world_bounds[3] * 2: # Calculate connection id self.connection_id = (x * (world_generator.world_bounds[3] + 1) + y) + self.world.seed self.this_rand.seed(self.connection_id) self.is_connection = self.this_rand.randint(0, 100) > 50 # If it's vertical we check that the screen has at least two entrances or exits. # In case it doesn't, we put a connection. It's very likely that by doing this the room now # has two entrances and the worst case it's a dead end, but the probability of a dead end # gets reduced a lot. if y % 2 == 0 and not self.is_connection: p1 = ConnectionGenerator.is_connection_at( x, y - 2, self.world.world_bounds, self.world.seed) p2 = ConnectionGenerator.is_connection_at( x, y - 1, self.world.world_bounds, self.world.seed) p3 = ConnectionGenerator.is_connection_at( x - 1, y - 1, self.world.world_bounds, self.world.seed) count = 0 if p1: count += 1 if p2: count += 1 if p3: count += 1 if count < 2: self.is_connection = True # If there is a connection, we have a random value between 0 and the maximum size of a room. if self.is_connection: self.value = self.this_rand.randint( 0, self.world.max_room_size[0]) # We make the position equal to x = value and y = value # In RoomGenerator we "stick" it to a side. self.position = Vector2D(self.value, self.value)
def __init__(self, position, world_generator): # type: (Vector2D, WorldGenerator.WorldGenerator) -> None # World generator (seed) self.world_generator = world_generator # Screen position self.position = position.copy() # Seed self.seed = self.world_generator.seed # Random number generator self.this_rand = random.Random() self.this_rand.seed(self.position.x * self.position.y + self.position.y + self.seed) # Is there a screen? self.is_screen = True # Screen Size self.screen_size = Vector2D( self.this_rand.randint(3, self.world_generator.max_room_size[0]), 0) self.screen_size.y = self.this_rand.randint( max(int(self.screen_size.x / 2), 3), self.screen_size.x + int(self.screen_size.x / 2)) # Screen size with borders self.screen_real_size = self.screen_size.copy() # We add the borders self.screen_real_size.x += 6 self.screen_real_size.y += 8 # We make the screen at least as large as the render screen if self.screen_real_size.x < 40: self.screen_real_size.x = 40 if self.screen_real_size.y < 26: self.screen_real_size.y = 26 # We create the map self.room_map = [] for x in range(0, self.screen_real_size.x): self.room_map.append([]) for y in range(0, self.screen_real_size.y): self.room_map[-1].append(0) # Connections self.connections = [] self.connections.append( ConnectionGenerator(position.x, (position.y - 1) * 2, self.world_generator)) # Top self.connections.append( ConnectionGenerator(position.x, position.y * 2, self.world_generator)) # Bottom self.connections.append( ConnectionGenerator(position.x - 1, position.y * 2 - 1, self.world_generator)) # Left self.connections.append( ConnectionGenerator(position.x, position.y * 2 - 1, self.world_generator)) # Right self.connections[0].value %= self.screen_size.x self.connections[0].make_position() self.connections[0].position.x += (self.screen_real_size.x - self.screen_size.x) / 2 self.connections[0].position.y = 0 self.connections[1].value %= self.screen_size.x self.connections[1].make_position() self.connections[1].position.x += (self.screen_real_size.x - self.screen_size.x) / 2 self.connections[1].position.y = self.screen_real_size.y - 1 self.connections[2].value %= self.screen_size.y self.connections[2].make_position() self.connections[2].position.y += (self.screen_real_size.y - self.screen_size.y) / 2 self.connections[2].position.x = 0 self.connections[3].value %= self.screen_size.y self.connections[3].make_position() self.connections[3].position.y += (self.screen_real_size.y - self.screen_size.y) / 2 self.connections[3].position.x = self.screen_real_size.x - 1 # Objects (items...) self.objects = [] # Generate and save the room self.generate() self.save()
def make_position(self): self.position = Vector2D(self.value, self.value)
def main_loop(self, events): # self.game_manager.screen.fill((255, 255, 255)) self.game_manager.screen.blit(self.background, (0, 0)) # self.surface_to_screen.fill((0, 0, 0, 0)) self.surface_to_screen.fill((0, 0, 0)) mouse_pos = Vector2D(0, 0, lst=pygame.mouse.get_pos()) for event in events: if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 5: self.view_angle -= self.view_angle_change * self.game_manager.delta_time elif event.button == 4: self.view_angle += self.view_angle_change * self.game_manager.delta_time elif event.button == 1: self.current_target_point = mouse_pos.copy() keys_pressed = pygame.key.get_pressed() if keys_pressed[pygame.K_w]: self.light_point.y -= self.light_move_speed * self.game_manager.delta_time if keys_pressed[pygame.K_s]: self.light_point.y += self.light_move_speed * self.game_manager.delta_time if keys_pressed[pygame.K_a]: self.light_point.x -= self.light_move_speed * self.game_manager.delta_time if keys_pressed[pygame.K_d]: self.light_point.x += self.light_move_speed * self.game_manager.delta_time """if keys_pressed[pygame.K_q]: self.rotation -= self.rotation_speed * self.game_manager.delta_time if keys_pressed[pygame.K_e]: self.rotation += self.rotation_speed * self.game_manager.delta_time""" self.rotation = (self.light_point.look_at_angle(mouse_pos) + 90) % 360 """if self.light_point.distance_to(self.current_target_point) > 10: movement = Vector2D(0, 1) movement.rotate((self.light_point.look_at_angle(self.current_target_point) + 90) % 360) movement *= self.light_move_speed * self.game_manager.delta_time self.light_point += movement""" if self.view_angle > 40: self.view_angle = 40 elif self.view_angle < 10: self.view_angle = 10 self.view_angle = math2d.to360rotation(self.view_angle) self.rotation = math2d.to360rotation(self.rotation) self.view_distance = (self.distance_angle_inverse_relation / (self.view_angle ** self.smoother)) self.light_point.x = int(self.light_point.x) self.light_point.y = int(self.light_point.y) triangle_point_1_ang = self.rotation + self.view_angle triangle_point_2_ang = self.rotation - self.view_angle triangle_point_1 = Vector2D(0, self.view_distance) triangle_point_2 = Vector2D(0, self.view_distance) triangle_point_1.rotate(triangle_point_1_ang) triangle_point_2.rotate(triangle_point_2_ang) triangle_point_1 += self.light_point triangle_point_2 += self.light_point self.view_distance = int(self.view_distance) polygons = list(self.polygons) pygame.draw.polygon(self.surface_to_screen, (255, 255, 255), [triangle_point_1.list(), triangle_point_2.list(), self.light_point.list()]) Shadow.optimized_shadows(polygons, self.light_point, self.surface_to_screen) """self.surface_to_screen.blit(self.circle_gradient, [self.light_point.x - self.circle_gradient.get_width() / 2, self.light_point.y - self.circle_gradient.get_height() / 2], special_flags=pygame.BLEND_RGB_MULT)""" self.game_manager.screen.blit(self.surface_to_screen, (0, 0), special_flags=pygame.BLEND_RGB_MULT) pygame.draw.circle(self.game_manager.screen, (0, 0, 128), self.light_point.list(), 5)
def __init__(self, game_manager): # type: (GameManager.GameManager) -> None self.game_manager = game_manager # type: GameManager.GameManager self.polygons = [Polygon.Polygon(Vector2D(0, 0), [Vector2D(100, 100), Vector2D(100, 250), Vector2D(200, 200), Vector2D(200, 100)])] self.polygons.append(Polygon.Polygon(Vector2D(200, 0), [Vector2D(100, 100), Vector2D(100, 250), Vector2D(200, 200), Vector2D(200, 100)])) self.polygons.append(Polygon.Polygon(Vector2D(400, 0), [Vector2D(100, 100), Vector2D(100, 250), Vector2D(200, 200), Vector2D(200, 100)])) self.light_point = Vector2D(0, 0) self.light_move_speed = 200 self.view_angle = 60 self.view_angle_change = 360 self.view_distance = 300 self.smoother = 0.25 self.distance_angle_inverse_relation = self.view_angle**self.smoother * self.view_distance self.background = pygame.image.load("game_data/levels/test_level_background.png").convert() self.rotation = 0 self.rotation_speed = 90 self.surface_to_screen = pygame.Surface((self.game_manager.screen.get_width(), self.game_manager.screen.get_height()), pygame.HWSURFACE) self.circle_gradient_size = 100 self.circle_gradient = pygame.Surface([self.circle_gradient_size * 2, self.circle_gradient_size * 2], pygame.HWSURFACE) self.current_target_point = Vector2D(0, 0) for x in range(self.circle_gradient_size*2): for y in range(self.circle_gradient_size*2): d_x = x - self.circle_gradient_size d_y = y - self.circle_gradient_size d = (d_x**2 + d_y**2)**0.5 value = 180 * (1 - (d / self.circle_gradient_size)) if value < 0: self.circle_gradient.set_at((x, y), 0) else: self.circle_gradient.set_at((x, y), (value, value, value)) pygame.image.save(self.circle_gradient, "game_data/images/light/small.png") """self.view_angle = 10