def direction(self, offset, distance): if distance == 0: direction = [ cos_radians(self.angle + offset), -sin_radians(self.angle + offset) ] else: direction = [ cos_radians(self.angle + offset) * distance, (-sin_radians(self.angle + offset)) * distance ] return direction
def control(self, end_pos, origin_pos, other_pos, ray_number, tile_len, player_rect, texture_id, offset, current_tile, vh): if SETTINGS.mode == 1: if tile_len: wall_dist = tile_len * cos_radians(self.beta) else: wall_dist = None return self.render_screen(ray_number, wall_dist, texture_id, int(offset), current_tile, vh, end_pos, origin_pos, other_pos) else: self.draw_line(player_rect, end_pos)
def animate(self, animation): '''== Animate NPC ==\nanimation -> dying, walking, attacking, hurting''' if self.running_animation != animation: self.sprite.current_frame = 0 self.running_animation = animation #walk animation if animation == 'walking': self.sprite.texture = self.get_direction_texture()[self.sprite.current_frame] if self.timer >= self.frame_interval: self.sprite.last_frame = self.sprite.current_frame self.sprite.current_frame += 1 self.timer = 0 if self.sprite.current_frame == len(self.front_texture)-1: self.sprite.current_frame = 0 #die animation elif animation == 'dying': self.sprite.texture = self.die_texture[self.sprite.current_frame] if self.sprite.current_frame == 0 and not self.mein_leben: self.mein_leben = True SOUND.play_sound(random.choice(self.sounds['die']), self.dist) if self.timer >= self.frame_interval and self.sprite.current_frame < len(self.die_texture)-1: self.sprite.current_frame += 1 self.timer = 0 elif self.sprite.current_frame == len(self.die_texture)-1 and self.knockback == 0: self.dead = True self.drop_item() SETTINGS.statistics['last enemies'] += 1 elif self.knockback > 0: self.collide_update(-cos_radians(self.postheta)*self.knockback, 0) self.collide_update(0, sin_radians(self.postheta)*self.knockback) self.knockback = int(self.knockback*0.8) #hurt animation elif animation == 'hurting': self.sprite.texture = self.hurt_texture[0] self.moving = False if self.timer >= self.frame_interval*2: self.side = None self.hurting = False self.timer = 0 SOUND.play_sound(random.choice(self.sounds['damage']), self.dist_from_player) change_direction_conditions = [ self.state == IDLE, self.state == PATROLLING, self.state == FLEEING, self.state == SEARCHING, ] if any(change_direction_conditions): self.change_facing_direction() # attack animation elif animation == ATTACKING: # at the moment the only attack animation # is directly facing the player self.set_side(SIDE_FRONT) self.sprite.texture = self.hit_texture[self.sprite.current_frame] self.moving = False if self.timer >= self.frame_interval: self.sprite.current_frame += 1 self.timer = 0 if self.sprite.current_frame == len(self.hit_texture): SOUND.play_sound(self.sounds['attack'], self.dist) self.sprite.texture = self.stand_texture[0] self.sprite.current_frame = 0 self.attacking = False if random.randint(0,8) != 8: #A chance to miss if self.damage_player(): self.add_message("Did damage to player") self.seen_player() else: self.add_message("tried to attack but I don't have LOS?")
def cast(self, player_rect, angle, ray_number, search_tiles = None, ray_origrin = None): H_hit = False V_hit = False H_offset = V_offset = 0 end_pos = (0, 0) if search_tiles is None: search_tiles = SETTINGS.rendered_tiles # search_tiles = sorted(search_tiles, key=lambda x: (x.type, x.atan, x.distance)) # TODO could probably precompute this in get_ray_values_for_angle cos_radians_angle = cos_radians(angle) tan_radians_angle = tan_radians(angle) if ray_origrin is None: H_x, H_y, V_x, V_y = self.get_ray_origin(angle, player_rect, tan_radians_angle) else: V_x, H_y = ray_origrin[1], ray_origrin[2] H_x, V_y = self.get_ray_origin_for_angle(V_x, H_y, player_rect, tan_radians_angle) passed_offset = ray_origrin[3] #Extend for x in range(0, SETTINGS.render): # let's keep the unmodified by offset values iteration_H_x = H_x iteration_V_y = V_y iteration_V_x = V_x iteration_H_y = H_y H_distance = abs((player_rect.center[0] - H_x) / cos_radians_angle) V_distance = abs((player_rect.center[0] - V_x) / cos_radians_angle) if self.check_hit(V_hit, H_hit, H_distance, V_distance, True): break if len(search_tiles) > 3: reduced_search_tiles = [ tile for tile in search_tiles if (H_y == tile.rect.bottom and H_x >= tile.rect.bottomleft[0] and H_x <= tile.rect.bottomright[0] and player_rect.centery > tile.rect.bottom) or (H_y == tile.rect.top and H_x >= tile.rect.topleft[0] and H_x <= tile.rect.topright[0] and player_rect.centery < tile.rect.top) or (V_x == tile.rect.left and V_y >= tile.rect.topleft[1] and V_y <= tile.rect.bottomleft[1] and player_rect.centerx < tile.rect.left) or (V_x == tile.rect.right and V_y >= tile.rect.topright[1] and V_y <= tile.rect.bottomright[1] and player_rect.centerx > tile.rect.right) ] else: reduced_search_tiles = search_tiles #reduced_search_tiles = sorted(search_tiles, key=lambda x: (x.type, x.atan, x.distance)) for tile in reduced_search_tiles: if self.check_hit(V_hit, H_hit, H_distance, V_distance, False): break if not H_hit: if (H_y == tile.rect.bottom and H_x >= tile.rect.bottomleft[0] and H_x <= tile.rect.bottomright[0]) and player_rect.centery > tile.rect.bottom: H_hit = True H_texture_id = tile.ID self.current_htile = tile if tile.type == 'hdoor': H_y -= self.door_size H_x += self.door_size / tan_radians_angle H_offset = self.find_offset(H_x, ray_number, angle, tile, 'h') if H_offset < 0: H_hit = False H_y += self.door_size H_x -= self.door_size / tan_radians_angle else: H_offset = self.find_offset(H_x, ray_number, angle, tile, 'h') elif (H_y == tile.rect.top and H_x >= tile.rect.topleft[0] and H_x <= tile.rect.topright[0]) and player_rect.centery < tile.rect.top: H_hit = True H_texture_id = tile.ID self.current_htile = tile if tile.type == 'hdoor': H_y += self.door_size H_x -= self.door_size / tan_radians_angle H_offset = self.find_offset(H_x, ray_number, angle, tile, 'h') if H_offset < 0: H_hit = False H_y -= self.door_size H_x += self.door_size / tan_radians_angle else: H_offset = self.find_offset(H_x, ray_number, angle, tile, 'h') if self.check_hit(V_hit, H_hit, H_distance, V_distance, False): break if not V_hit: if (V_x == tile.rect.left and V_y >= tile.rect.topleft[1] and V_y <= tile.rect.bottomleft[1]) and player_rect.centerx < tile.rect.left: V_hit = True V_texture_id = tile.ID self.current_vtile = tile if tile.type == 'vdoor': V_x += self.door_size V_y -= self.door_size * tan_radians_angle V_offset = self.find_offset(V_y, ray_number, angle, tile, 'v') if V_offset < 0: V_hit = False V_x -= self.door_size V_y += self.door_size * tan_radians_angle else: V_offset = self.find_offset(V_y, ray_number, angle, tile, 'v') elif (V_x == tile.rect.right and V_y >= tile.rect.topright[1] and V_y <= tile.rect.bottomright[1]) and player_rect.centerx > tile.rect.right: V_hit = True V_texture_id = tile.ID self.current_vtile = tile if tile.type == 'vdoor': V_x -= self.door_size V_y += self.door_size * tan_radians_angle V_offset = self.find_offset(V_y, ray_number, angle, tile, 'v') if V_offset < 0: V_hit = False V_x += self.door_size V_y -= self.door_size * tan_radians_angle else: V_offset = self.find_offset(V_y, ray_number, angle, tile, 'v') #Extend actual ray if not H_hit: if angle < 180: H_y -= self.tile_size else: H_y += self.tile_size if angle >= 180: H_x -= self.tile_size / tan_radians_angle else: H_x += self.tile_size / tan_radians_angle if not V_hit: if angle > 270 or angle < 90: # -> V_x += self.tile_size else: V_x -= self.tile_size if angle >= 270 or angle < 90: # <- V_y -= self.tile_size * tan_radians_angle else: V_y += self.tile_size * tan_radians_angle if V_hit and H_hit: H_hit, V_hit = False, False if H_distance < V_distance: end_pos = (H_x, H_y) origin_pos = (iteration_H_x, iteration_H_y) other_pos = (V_x, V_y) texture_id = H_texture_id tile_len = H_distance offset = H_offset current_tile = self.current_htile H_hit = True else: end_pos = (V_x, V_y) origin_pos = (iteration_V_x, iteration_V_y) other_pos = (H_x, H_y) texture_id = V_texture_id tile_len = V_distance offset = V_offset current_tile = self.current_vtile V_hit = True elif H_hit and not V_hit: end_pos = (H_x, H_y) origin_pos = (iteration_H_x, iteration_H_y) other_pos = (V_x, V_y) texture_id = H_texture_id tile_len = H_distance offset = H_offset current_tile = self.current_htile elif V_hit and not H_hit: end_pos = (V_x, V_y) origin_pos = (iteration_V_x, iteration_V_y) other_pos = (H_x, H_y) texture_id = V_texture_id tile_len = V_distance offset = V_offset current_tile = self.current_vtile else: end_pos = (SETTINGS.player_rect[0], SETTINGS.player_rect[1]) origin_pos = end_pos other_pos = end_pos texture = None texture_id = None tile_len = None offset = 0 current_tile = None # todo this a is a hack # might need to pass tile_type up to our list of stored slices #if offset == SETTINGS.tile_size - 1 and passed_offset is not None: # offset = passed_offset if V_hit: vh = 'v' else: vh = 'h' #Mode return self.control(end_pos, origin_pos, other_pos, ray_number, tile_len, player_rect, texture_id, offset, current_tile, vh)
def rotate_segment(self, segment): #Rotate array rotseg = copy.deepcopy(segment) rotseg.array = list(zip(*reversed(rotseg.array))) for i in range(len(rotseg.array)): rotseg.array[i] = list(rotseg.array[i]) t = 0 for tile in rotseg.array[i]: if SETTINGS.texture_type[tile] == 'hdoor' or SETTINGS.texture_type[tile] == 'vdoor': for y in range(len(TEXTURES.all_textures)): if y != tile and os.path.samefile(TEXTURES.all_textures[y], TEXTURES.all_textures[tile]): rotseg.array[i][t] = y t += 1 #Rotate doors for i in range(len(rotseg.doors)): rotseg.doors[i] -= 90 if rotseg.doors[i] <= 0: rotseg.doors[i] += 360 #Rotate items origin = [int(len(rotseg.array[0])/2), int(len(rotseg.array)/2)] x = 0 for item in rotseg.items: tempx = item[0][0] - origin[0] tempy = item[0][1] - origin[1] tempx1 = cos_radians(90) * tempx - sin_radians(90) * tempy tempy1 = sin_radians(90) * tempx + cos_radians(90) * tempy tempx1 += origin[0] tempy1 += origin[1] rotseg.items[x] = ([int(tempx1), int(tempy1)], item[1]) x += 1 #rotate npc x = 0 for npc in rotseg.npcs: tempx = npc[0][0] - origin[0] tempy = npc[0][1] - origin[1] tempx1 = cos_radians(90) * tempx - sin_radians(90) * tempy tempy1 = sin_radians(90) * tempx + cos_radians(90) * tempy tempx1 += origin[0] tempy1 += origin[1] tempnpc = npc[1] tempnpc -= 90 if tempnpc < 0: tempnpc += 360 rotseg.npcs[x] = ([int(tempx1), int(tempy1)], tempnpc, npc[2]) x += 1 if rotseg.player_pos: tempx = rotseg.player_pos[0] - origin[0] tempy = rotseg.player_pos[1] - origin[1] tempx1 = cos_radians(90) * tempx - sin_radians(90) * tempy tempy1 = sin_radians(90) * tempx + cos_radians(90) * tempy tempx1 += origin[0] tempy1 += origin[1] rotseg.player_pos = [int(tempx1), int(tempy1)] return rotseg