Beispiel #1
0
 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
Beispiel #2
0
    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)
Beispiel #3
0
    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?")
Beispiel #4
0
    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)
Beispiel #5
0
    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