def update(self, dt): Drawable.handle_deletion(self.entities) if self.chest: self.chest.update(dt) offset = 0 if self.spawn_exit: offset = self.game.dungeon_offset / self.game.TILE_WIDTH for entity in self.entities: entity.update(dt) super().update(dt) if self.spawn_exit and self.game.world.state_dt > 4 and self.game.world.progression == self.game.world.FREE_ROAM and abs( self.game.world.character.tx - offset - self.tx) < 0.6 and abs(self.game.world.character.ty - offset - self.ty - 0.5) < 0.6: if len(self.game.world.textbox.text) == 0 or self.game.keys[key.E]: self.game.world.textbox.text = ["Press E to exit the crevice."] self.game.world.textbox.faces = [None] if self.game.keys[key.E]: self.game.world.move_to = self.game.world.OVERWORLD
def update(self, dt): Drawable.handle_deletion(self.entities[self.state]) self.state_dt += dt if self.move_to == self.DUNGEON: self.move_to_dungeon() self.move_to = None self.state_dt = 0 elif self.move_to == self.OVERWORLD: self.move_to_overworld() self.move_to = None self.state_dt = 0 if self.character.health <= 0: self.move_to_overworld() self.character.health = 8 self.textbox.text = ["That was close! I've saved you this time, but don't test your luck."] self.textbox.faces = [2] if self.progression == self.SKULLS_FOUND and len(self.textbox.text) == 0: self.progression = self.TITLE_COMPLETE self.sprites[self.title_i].visible = True self.sprites_rel[self.title_i] = (self.character.x - 30, self.character.y - 80) self.need_pos_update = True if self.progression == self.TITLE and self.game.keys[key.SPACE]: self.sprites[self.title_i].visible = False self.progression = self.INTRO self.textbox.text = ["It's another sunny day in your hometown.", "Your uncle Jim has left you to look after his goat farm.", "Choose the grass seeds and LEFT CLICK to use."] if self.progression == self.USED_SEEDS and self.textbox and len(self.textbox.text) == 0: self.progression_dt += dt if self.progression_dt > 8: self.progression_dt = 0 self.progression = self.ENCOUNTER if self.progression == self.ENCOUNTER: if self.dungeon_entry is None and self.character.ty > 2 and self.character.tx > 1 and self.character.tx + 2 < self.WIDTH[self.OVERWORLD] and self.character.ty + 1 < self.HEIGHT[self.OVERWORLD]: self.dungeon_entry = DungeonEntry(self.game, self.character.tx+1, self.character.ty-1, self.group_for(self.character.ty-1)) if self.dungeon_entry and self.dungeon_entry.progress == 3 and self.dungeon_entry.char_dt >= 2: self.progression = self.ENCOUNTER_TEXT self.textbox.text = ["MORTAL! What are you doing on my grounds?!", "!!!", "I.. this is my uncle's property! I'm sorry!", "Ah. I see. Well, since it isn't your fault, I have a deal for you.", "I need to sacrifice a goat. In exchange, I will give you rewards beyond your wildest dreams.", "What? I can't. That would be cruel!", "LEFT CLICK a goat to choose a sacrifice."] self.textbox.faces = [2, 1, 1, 2, 2, 1, None] if self.progression == self.ENCOUNTER_TEXT and self.textbox and len(self.textbox.text) == 0: self.progression = self.SACRIFICING self.sacrifice_mode = True if self.progression == self.INTRO and self.textbox and len(self.textbox.text) == 0: self.progression = self.USE_SEEDS self.inventory = Inventory(self.game, self.game.camera.width / self.game.camera.zoom - Inventory.WIDTH - 10, 10, self.hud_group) if self.progression == self.SACRIFICING_TEXT and self.textbox and len(self.textbox.text) == 2: self.game.camera.target = self.character if self.progression == self.SACRIFICING_TEXT and self.textbox and len(self.textbox.text) == 0: self.inventory.add_item(WaterGem(self.game, 25)) self.textbox.text = ["How strange. Maybe I should check out that crevice.."] self.textbox.faces = [1] self.dungeon_entry.remove_character = True self.progression = self.FREE_ROAM #if self.progression == self.FREE_ROAM and self.state == self.OVERWORLD: # self.progression_dt += dt # if self.progression_dt > 5: # self.progression_dt = 0 if not self.has_init[self.OVERWORLD] and self.state == self.OVERWORLD: for i in range(random.randint(10, 30)): tx = (random.random() * self.WIDTH[self.OVERWORLD] - 1) + 1 ty = (random.random() * self.HEIGHT[self.OVERWORLD] - 1) + 1 self.entities[self.OVERWORLD].append(Goat(self.game, tx, ty, self.group_for(ty))) for ty in range(self.HEIGHT[self.OVERWORLD]): for tx in range(self.WIDTH[self.OVERWORLD]): self.tiles[self.OVERWORLD].append(GrassTile(self.game, tx, ty, self.group_for(ty+1))) self.has_init[self.OVERWORLD] = True if not self.has_init[self.DUNGEON] and self.state == self.DUNGEON: rooms = image.load('sprites/dungeon_rooms.png') raw_image = rooms.get_image_data() img_format = 'RGB' pitch = raw_image.width * len(img_format) pixels = raw_image.get_data(img_format, pitch) room_width = DungeonTemplate.WIDTH room_height = DungeonTemplate.HEIGHT dungeon_templates = [] for i in range(raw_image.width // room_width): room_pixels = [] for j in range(room_height): for ii in range(room_width): room_pixels.append(tuple([int(pixels[p + len(img_format) * (j * raw_image.width + i*room_width + ii)]) for p in range(len(img_format))])) for rot in range(4): if rot > 0: room_pixels_temp = [] for y in range(room_height): for x in range(room_width): # 90 degrees rotation CW j = x * room_width + (room_height - y - 1) room_pixels_temp.append(room_pixels[j]) room_pixels = room_pixels_temp template = DungeonTemplate(self.game, copy.copy(room_pixels), i, i == 0) dungeon_templates.append(template) room_instances = [copy.copy(dungeon_templates[0])] tx, ty = self.WIDTH[self.DUNGEON] // 2, self.HEIGHT[self.DUNGEON] // 2 room_instances[0].tx = tx room_instances[0].ty = ty if self.first_dungeon_visit: room_instances[0].can_spawn_entity = False room_instances[0].clear_chest_spawns() room_instances[0].set_chest_spawn(1, 3, True) self.first_dungeon_visit = False exits_uncovered = [(tx, ty)] occupied = [(tx, ty)] while len(exits_uncovered) > 0: random.shuffle(dungeon_templates) tx, ty = exits_uncovered.pop(0) for instance in room_instances: if (instance.tx, instance.ty) == (tx, ty): missed_exits = instance.exit_walls() missed_walls = [len(missed_exits[i]) > 0 for i in range(4)] for (ix, iy) in instance.exits: if not missed_walls[instance.exit_wall_index(ix, iy)]: continue for template in dungeon_templates: if template.i == instance.i: continue found_match = False new_coords = False for (ex, ey) in template.exits: if ix == 0 and ey == iy and ex == room_width - 1: found_match = (-1, 0) elif iy == 0 and ex == ix and ey == room_height - 1: found_match = (0, -1) elif ix == room_width - 1 and ey == iy and ex == 0: found_match = (1, 0) elif iy == room_height - 1 and ex == ix and ey == 0: found_match = (0, 1) if found_match: new_coords = (tx + found_match[0] * room_width, ty + found_match[1] * room_height) if new_coords in occupied: found_match = False else: break if found_match: break if found_match and new_coords: new_instance = copy.copy(template) new_instance.tx, new_instance.ty = new_coords if new_instance.tx >= 0 and new_instance.tx + 5 < self.WIDTH[self.DUNGEON] and new_instance.ty >= 0 and new_instance.ty + 5 < self.HEIGHT[self.DUNGEON]: room_instances.append(new_instance) exits_uncovered.append(new_coords) occupied.append(new_coords) dungeon_templates.remove(template) missed_walls[instance.exit_wall_index(ix, iy)] = False missed_exits[instance.exit_wall_index(ix, iy)].remove((ix, iy)) new_instance.exits.remove((ex, ey)) found_match = False new_coords = False for i in range(len(missed_exits)): for ix, iy in missed_exits[i]: instance.remove_exit(ix, iy) temp_tiles = [None for _ in range(self.HEIGHT[self.DUNGEON]) for _ in range(self.WIDTH[self.DUNGEON])] count = 0 for instance in room_instances: for x in range(room_width): for y in range(room_height): tx = x + instance.tx ty = y + instance.ty j = ty*self.WIDTH[self.DUNGEON] + tx i = y*room_width + x temp_tiles[j] = DungeonTile(self.game, tx, ty, self.group_for(ty, self.DUNGEON), instance.tile_types[i]) temp_tiles[j].can_spawn_entity = instance.can_spawn_entity self.tiles[self.DUNGEON] = temp_tiles for tile in self.tiles[self.DUNGEON]: if tile: tile.init_tile() self.has_init[self.DUNGEON] = True self.change_state(self.DUNGEON) if self.last_hover: self.hover_dt += dt if self.last_hover and self.hover_dt >= 0.05 and self.sacrifice_mode and self.state == self.OVERWORLD: mouse_hover = self.update_hover() self.hover_dt = 0 self.last_hover = None self.game.cursor = self.game.window.CURSOR_HAND if mouse_hover else self.game.window.CURSOR_DEFAULT for drawable in self.tiles[self.state] + self.entities[self.state] + [self.textbox, self.inventory, self.character, self.dungeon_entry]: if drawable: drawable.update(dt) super().update(dt)
def update(self, dt): self.target_reached = False if self.do_bounce: self.anim_dt += dt sprite = self.get_visible_sprite() sprite.color = self.col red_color = (255, 160, 160) if self.health_anim_dt < 0.3: self.col = red_color self.health_anim_dt += dt elif self.col == red_color: self.col = (255, 255, 255) if self.anim_dt >= 0.8 and sprite: sprite.scale_y = int(self.stretched) * 0.06 + 1 self.stretched = not self.stretched self.anim_dt = 0 if self.target: self.target_update_dt += dt if self.target and self.target_update_dt >= 0.15: self.target_update_dt = random.random() * 0.075 dx = self.target.tx - self.tx self.last_dx = dx dy = self.target.ty - self.ty - 0.1 self.last_dy = dy if (abs(dx) > self.target_min_dist or abs(dy) > self.target_min_dist) and ( abs(dx) < self.target_max_dist or abs(dy) < self.target_max_dist): angle = math.atan2(dy, dx) self.vx = math.cos(angle) * self.speed self.vy = math.sin(angle) * self.speed else: self.vx = 0 self.vy = 0 if abs(dx) <= self.target_min_dist and abs( dy) <= self.target_min_dist: self.target_reached = True Drawable.handle_deletion(self.particle_groups) for group in self.particle_groups: group.base_tx = self.tx - (512 if self.game.world.state == self.game.world.DUNGEON else 0) group.base_ty = self.ty - (512 if self.game.world.state == self.game.world.DUNGEON else 0) group.update(dt) self.shove_x *= 0.9 self.shove_y *= 0.9 self.move((self.vx + self.shove_x) * dt, 0) self.move(0, (self.vy + self.shove_y) * dt) self.need_pos_update = True super().update(dt)
def update(self, dt): Drawable.handle_deletion(self.grass_tufts) for tuft in self.grass_tufts: tuft.update(dt)