示例#1
0
def test_weapon_attack():
    big_stick = Weapon("Overwhelming Stick", 200)
    test_runs = 100
    for _ in range(0, test_runs):
        attack = big_stick.attack()
        assert attack <= 200 and attack >= 100
示例#2
0
class Player(PS.DirtySprite):
    IMAGES = None
    IMAGES_RIGHT = None
    IMAGES_LEFT = None
    IMAGES_FRONT = None
    IMAGES_BACK = None
    IMAGES_RIGHT_DMG = None
    IMAGES_LEFT_DMG = None
    IMAGES_FRONT_DMG = None
    IMAGES_BACK_DMG = None
    # attack images
    IMG_ATTACK_D = None  # 100 x 150 dimensions
    IMG_ATTACK_U = None
    IMG_ATTACK_R = None
    IMG_ATTACK_L = None
    # Animation cycle variables
    CYCLE = 0.5
    ADCYCLE = .05
    WIDTH = 100
    HEIGHT = 100

    def __init__(self, fps=1):
        # Call the parent class (Sprite) constructor
        PS.DirtySprite.__init__(self)
        self.image = PI.load("FPGraphics/MC/MCwalk/MCFront.png") \
            .convert_alpha()
        self.rect = self.image.get_rect()
        self.rect_copy = self.rect
        self.rect.x = 100
        self.rect.y = 100
        self.face = 'd'
        self.load_images()
        # self.speed both determines the speed of the player &
        # ensures the the player moves at an integer distance
        # during play (arbitrary value)
        self.speed = 1
        self.time = 0.0
        self.frame = 0
        self.got_key = False
        # will turn to True once you've run into the yellow block
        # collision conditions, if true, we will not move in that direction
        self.health = 20
        self.dmg_count = 0
        self.invincibility_frame = PI.load("FPGraphics/emptyImg.png") \
            .convert_alpha()
        self.weapon = Weapon()
        self.moved = False
        self.interval = 0
        self.modified_map = False
        self.banner = -1 #holds the ID of the sign that the player just read
        self.pill = False
        self.at_door_num = -1  # allows player to open door if player has key
        self.at_sign_num = -1  # if player is at a sign, allow sign msg to appear on space
        self.attack_pose = False

        #eating sound
#        self.eatEffect = PM.Sound("music/soundeffects/eating.mod")
#        self.eated = False
        self.EatR = PI.load("FPGraphics/MC/MCwalk/MCRightEat.png")\
                .convert_alpha()
        self.EatL = PI.load("FPGraphics/MC/MCwalk/MCLeftEat.png")\
            .convert_alpha()
        self.EatF = PI.load("FPGraphics/MC/MCwalk/MCFrontEat.png")\
            .convert_alpha()
        self.EatB = PI.load("FPGraphics/MC/MCwalk/MCBackEat.png")\
            .convert_alpha()

        self.items_of_killed = []
        # Item Variables
        self.grab_item = False
        self.item = False
        self.item_img = None
        self.item_use_count = 0
        self.item_type = 0
        self.item_health = 0
        #projectile movement
        self.pdx = 0
        self.pdy = 0
        self.player_items = []
        self.player_traps = []
        self.player_projectiles = []
        self.can_eat = True
        self.eat_item = False
        #consider changing this for MC general img poses...?
        self.eat_time = 50
        self.eat_timer = 0

        self.effect_time = -1
        self.change_invincibility = False
        # self.burger_capacity = random.randint(1, 15)
        self.burger_capacity = 1
        self.enemy_ID = -1

        self.can_attack = True

        ##joystick##
        self.joy = Joystick()
        self.joyOn = False
#        self.mvJoy = (0, 0)
        self.mvD = False
        self.mvR = False
        self.mvL = False
        self.mvU = False

    def set_attacking_rect(self):
        self.attacking_rect = self.rect
        self.rect = self.rect_copy

    def reset_attacking_rect(self):
        self.rect = self.attacking_rect

    def update_camera(self):
        if self.attack_pose:
            return False
        return True

        self.enemy_ID = -1

    def has_item(self):
        return self.item

    def get_item_img(self):
        return self.item_img

    def remove_player_item(self, item):
        self.player_items.remove(item)

    def remove_player_trap(self, item):
        self.player_traps.remove(item)

    def get_player_items(self):
        return self.player_items

    def drop_item(self, surface):
        if self.item_type == 1:
            self.player_items.append(Item.IceCreamScoop(self.rect.x,
                                                        self.rect.y, surface))

    def chng_invincibility(self):
        ret = self.change_invincibility
        self.change_invincibility = False
        return ret


    def get_invincibility(self):
        return self.new_invincibility

    def get_item(self):
        # if ice cream scoop
        if self.item_type == 1:
            self.item_img = PI.load("FPGraphics/drops/DropIceCream.png").convert_alpha()
        # if bread drop = faster
        elif self.item_type == 2:
            self.item_img = PI.load("FPGraphics/drops/breadDrop.png").convert_alpha()
            self.speed = 2
        # if lettuce drop = trap
        elif self.item_type == 3:
            self.item_img = PI.load("FPGraphics/drops/lettuceDrop.png").convert_alpha()
        # if meat drop = longer invincibility
        elif self.item_type == 4:
            self.item_img = PI.load("FPGraphics/drops/meatDrop.png").convert_alpha()
            self.change_invincibility = True
            self.new_invincibility = Globals.DEFAULT_INVINCIBILITY*2
        # if burger drop
        elif self.item_type == 5:
            self.burger_capacity -= 1
            if self.burger_capacity == 0:
                self.health = 0
            self.item_img = PI.load("FPGraphics/drops/burgerDrop.png").convert_alpha()
        # if lettuce drop = trap
        elif self.item_type == 6:
            self.item_img = PI.load("FPGraphics/drops/creamDrop.png").convert_alpha()

    def is_item_usable(self):
        if self.item:
            if self.item_type == 1 or self.item_type == 3 or self.item_type == 5 or self.item_type == 6:
                return True
            else: 
                return False

    def restore_normal(self):
        self.speed = 1
        self.item = False
        self.change_invincibility = True
        self.new_invincibility = Globals.DEFAULT_INVINCIBILITY

    def drop_trap(self, surface):
        rect = self.item_img.get_rect()
        rect.x = self.rect.x
        rect.y = self.rect.y
        self.player_traps.append(Trap(surface,         # surface to be drawn in
                                     rect,             # rect of the image 
                                     self.item_img,   # the type of trap
                                     'P',              # Player is the user 
                                     1600,             # lifetime 
                                     self.item_img,            # image 
                                     False))           # if the trap will be animated

    def get_player_traps(self):
        return self.player_traps

    def throw_LC(self):
        self.player_projectiles.append(LettuceCutter(self));

    def throw_CC(self):
        self.player_projectiles.append(CreamCutter(self));

    def get_player_projectiles(self):
        return self.player_projectiles

    def get_items_of_killed(self):
        return self.items_of_killed

    def get_modified_map(self):
        returned = self.modified_map
        self.modified_map = False
        return returned

    def get_rect_if_moved(self):
        if self.moved:
            return self.rect
        else:
            return None

    def get_health(self):
        return self.health

    def set_health(self, new_health, check_start=False):
        self.health = new_health
        if check_start:
            self.check_starting_health()

    def check_starting_health(self):
        if self.health >= 20:
            self.health = 20

    def decrement_health(self, enemy_ID):
        if self.health > 0:
            self.health -= 1
        self.dmg_count = 3

    def invincibility_frames(self):
        self.image = self.invincibility_frame

    def get_face(self):
        return self.face

    def player_got_key(self):
        return self.got_key

    def get_coordinates(self):
        coordinates = [self.rect.x, self.rect.y]
        return coordinates

    def open_door(self, bg):  # pass the enire block group.
#        self.eated = False
        self.eat_timer = self.eat_time
        for block in bg:
            if block.get_type() == self.at_door_num:
                block.kill()
#                if self.eated is False:
#                    self.eatEffect.play(50)
#                    self.eated = True
        self.modified_map = True
        self.at_door_num = -1

    def read_sign(self):  # pass the enire block group.
        self.banner = self.at_sign_num

    def handle_collision(self, bg):
        collisions = PS.spritecollide(self, bg, False)

        if len(collisions) == 0:
            self.at_sign_num = -1
            self.at_door_num = -1
            pass

        for collision in collisions:
            # check if collided with an item
            if type(collision.get_type()) is int:
                if self.grab_item:
                    self.item = True
                    self.item_use_count = -1
                    self.effect_time = -1
                    # self.modified_map = True
                    self.item_type = collision.get_type()
                    self.item_health = collision.get_health()
                    # if item is to attack the enemy
                    if self.item_type == 1 or self.item_type == 3 or self.item_type == 5 or self.item_type == 6:
                        self.item_use_count = collision.get_use_count()
                    # if item is for player effects
                    else: 
                        self.effect_time = collision.get_use_count()
                    self.get_item()
                    collision.disappear()
                elif self.eat_item:
                    self.eat_item = False
                    self.eat_timer = self.eat_time
                    self.health += collision.get_health()
                    if self.health > 25:
                        self.health = 25
                    collision.disappear()
            elif collision.get_type() == "K":  # found key
                collision.kill()
                self.pill = True
                # self.open_door(bg)
                self.got_key = True
                self.modified_map = True
            
            elif self.face == 'r' or self.face == 'ra' or self.face == 'rs':
                if(self.rect.x + self.rect.width
                   ) >= collision.rect.left:
                    self.rect.x = collision.rect.left \
                        - self.rect.width
            elif self.face == 'l' or self.face == 'ls':
                if(self.rect.x) <= (collision.rect.left +
                                    collision.rect.width):
                    self.rect.x = (collision.rect.left +
                                   collision.rect.width)
            elif self.face == 'd' or self.face == 'ds':
                if(self.rect.y + self.rect.height
                   ) >= collision.rect.top:
                        self.rect.y = collision.rect.top -\
                            self.rect.height
            elif self.face == 'u' or self.face == 'us':
                if(self.rect.y <= (collision.rect.top +
                                   collision.rect.height)):
                        self.rect.y = collision.rect.top +\
                            collision.rect.height

            if collision.get_type() == '!':  # at a sign
                self.at_sign_num = collision.get_id()
            else:
                self.at_sign_num = -1
            #door
            if isinstance(collision.get_type(), str) and collision.get_type().isdigit():  # at a door
                if self.pill:  # unlockable door
                    self.at_door_num = collision.get_type()
                else:
                    self.at_door_num = -1
            else:
                self.at_door_num = -1

    def eat_frames(self):
        if self.face == 'ds':
            self.image = self.EatF
        if self.face == 'us':
            self.image = self.EatB
        if self.face == 'rs':
            self.image = self.EatR
        if self.face == 'ls':
            self.image = self.EatL

    ###Used when joystick is plugged in. Handled slightly different.
    ##Will try to merge, but considering that calling handle_keys inside handle_joy
    ##throws off the cycle / animation, I want to avoid that :/
    def handle_joy(self, bg, enemy_bg, item_group, screen, interval=0.0065):
        try:
            self.items_of_killed = []
            self.attack_pose = False
            standing = True
            self.grab_item = False
            self.interval = interval
            temp = self.rect.x
            self.rect = self.rect_copy
            hat_dir = (0, 0)
            hat_move = False
            axis_move = False
            axis_dir0 = 0.0
            axis_dir1 = 0.0

            for event in PE.get():
                if event.type in Joystick.JOYSTICK:
                    if event.type == PG.JOYBUTTONUP:
                        self.joy.buttons[event.button] = False
                    elif event.type == PG.JOYBUTTONDOWN:
                        self.joy.buttons[event.button] = True
                    if event.type == PG.JOYHATMOTION:
                        if self.joy.joystick.get_hat(0) == (0, 0):
                            hat_move = False
#                            self.mvJoy = (0, 0)
                            self.mvD = False
                            self.mvU = False
                            self.mvR = False
                            self.mvL = False
                        else:
                            hat_move = True
                            if hat_dir == (0, 0):
                                hat_dir = self.joy.joystick.get_hat(0)
                    if event.type == PG.JOYAXISMOTION:
                        if math.fabs(self.joy.joystick.get_axis(0)) < 0.5 and math.fabs(self.joy.joystick.get_axis(1)) < 0.5:
                            axis_move = False
                        else:
                            axis_move = True
                            if math.fabs(axis_dir0) < 0.5:
                                axis_dir0 = self.joy.joystick.get_axis(0)
                            if math.fabs(axis_dir1) < 0.5:
                                axis_dir1 = self.joy.joystick.get_axis(1)

                    ####Exit
                    if self.joy.buttons[6] is True:  # back button (L7 on peter's joystick)
                        if Globals.SCORE > 0:
                            Globals.PLAYERNAME = str(inbx.ask(Globals.SCREEN, 'Name'))
                        Globals.STATE = 'Menu'

                    #attack
                    elif self.joy.buttons[0] is True:  # A button (1 button)
                        if 'r' in self.face:
                            self.image = self.IMG_ATTACK_R
                            self.attack_rect = self.image.get_rect()
                            self.attack_rect.x = self.rect.x
                            self.attack_rect.y = self.rect.y
                        if 'l' in self.face:
                            self.image = self.IMG_ATTACK_L
                            self.attack_rect = self.image.get_rect()
                            self.attack_rect.x = self.rect.x - 50
                            self.attack_rect.y = self.rect.y
                        if 'd' in self.face:
                            self.image = self.IMG_ATTACK_D
                            self.attack_rect = self.image.get_rect()
                            self.attack_rect.x = self.rect.x
                            self.attack_rect.y = self.rect.y
                        if 'u' in self.face:
                            self.image = self.IMG_ATTACK_U
                            self.attack_rect = self.image.get_rect()
                            self.attack_rect.x = self.rect.x
                            self.attack_rect.y = self.rect.y - 50
                        self.rect = self.attack_rect

                        collisions = PS.spritecollide(self, enemy_bg, False)

                        if self.can_attack:
                            self.can_attack = False
                            killed_enemies = self.weapon.attack(self, self.rect.x, self.rect.y,
                                                                self.face, screen, enemy_bg)
                            for killed in killed_enemies:
                                self.items_of_killed.append(killed.drop_item(screen))
                                killed.decrement_health(1)
                                killed.move_back(self.face, bg)
                                killed.last_hit = 80
                        self.attack_pose = True
                        standing = True

                        #handle signs
                        if self.at_sign_num != -1:
                            self.read_sign()
                        #handle locked doors
                        if self.at_door_num != -1:
                            self.open_door(bg)
                            self.pill = False
                    #pickup
                    elif self.joy.buttons[1] is True:  # B button (2 button)
                        if not self.item:
                            self.grab_item = True
                            self.handle_collision(item_group)
                    #make trap
                    elif self.joy.buttons[2] is True:  # X button (3 button)
                        if self.item and self.can_drop: #can_drop is used to prevent inaccurate key detection
                            if self.item_type == 1 or self.item_type == 5:
                                self.drop_trap(screen)
                            if self.item_type == 3:
                                self.throw_LC()
                            if self.item_type == 6:
                                self.throw_CC()
                            self.can_drop = False
                            self.item_use_count -= 1
                            if self.item_use_count == 0:
                                self.item = False
                    #drop (get rid of held item)
                    elif self.joy.buttons[3] is True:  # Y button (4 button)
                        if self.item and self.can_drop:
                            self.item = False
                    #eat
                    elif self.joy.buttons[4] is True:  # LB button / Left shoulder 1 button (L5)
                        if not self.item and self.can_eat:
                            self.can_eat = False
                            self.eat_item = True
                            self.handle_collision(item_group)

                    ##if event is the
                    ####Event 9-JoyHatMotion (joy = 0 hat = 0)
                    ##move.
#                    elif event.type == PG.JOYHATMOTION:  # arrow pad
                    elif hat_move is True:
                        standing = False
                        if hat_dir == (-1, 0):  # store these into local variables?
                            self.mvL = True
#                            self.rect.x -= self.speed  # move left
#                            self.face = 'l'
#                            self.pdx = -1
#                            self.pdy = 0
#                            self.handle_collision(bg)
#                            self.rect_copy = self.rect
                        elif hat_dir == (0, -1):
                            self.mvD = True
#                            self.rect.y += self.speed  # move down
#                            self.face = 'd'
#                            self.pdx = 0
#                            self.pdy = 1
#                            self.handle_collision(bg)
#                            self.rect_copy = self.rect
                        elif hat_dir == (1, 0):
                            self.mvR = (1, 0)
#                            self.rect.x += self.speed  # move right
#                            self.face = 'r'
#                            self.pdx = 1
#                            self.pdy = 0
#                            self.handle_collision(bg)
                            self.rect_copy = self.rect
                        elif hat_dir == (0, 1):
                            self.mvU = (0, 1)
#                            self.rect.y -= self.speed  # move up
#                            self.face = 'u'
#                            self.pdx = 0
#                            self.pdy = -1
#                            self.handle_collision(bg)
#                            self.rect_copy = self.rect
                        else:
                            #STANDING
                            standing = True

                        if standing:
#                            self.joy.axishats = [False, False, False]  # not moving at all
                            if self.face == 'd':
                                    self.face = 'ds'
                            if self.face == 'u':
                                    self.face = 'us'
                            if self.face == 'r':
                                    self.face = 'rs'
                            if self.face == 'l':
                                    self.face = 'ls'


                    ####Event 7-JoyAxisMotion (joy = 0 axis 0 for LR, 1 for UD)
#                    elif event.type == PG.JOYAXISMOTION:  # these are for left ball
                    elif axis_move is True:
                        standing = False
                        if axis_dir0 < -0.5 : # left
                            self.rect.x -= self.speed  # move left
                            self.face = 'l'
                            self.pdx = -1
                            self.pdy = 0
                            self.handle_collision(bg)
                            self.rect_copy = self.rect
                        elif axis_dir0 > 0.5: # right
                            self.rect.x += self.speed  # move right
                            self.face = 'r'
                            self.pdx = 1
                            self.pdy = 0
                            self.handle_collision(bg)
                            self.rect_copy = self.rect
                        elif axis_dir1 > 0.5:  # down
                            self.rect.y += self.speed  # move down
                            self.face = 'd'
                            self.pdx = 0
                            self.pdy = 1
                            self.handle_collision(bg)
                            self.rect_copy = self.rect
                        elif axis_dir1 < -0.5:  # up
                            self.rect.y -= self.speed  # move up
                            self.face = 'u'
                            self.pdx = 0
                            self.pdy = -1
                            self.handle_collision(bg)
                            self.rect_copy = self.rect

#                        #STANDING
                        else:
                            #STANDING
                            standing = True

                        if standing:
#                            self.joy.axishats = [False, False, False]  # not moving at all
                            if self.face == 'd':
                                    self.face = 'ds'
                            if self.face == 'u':
                                    self.face = 'us'
                            if self.face == 'r':
                                    self.face = 'rs'
                            if self.face == 'l':
                                    self.face = 'ls'

                    ##Not using Right axis ball
                    if standing:
#                        self.joy.axishats = [False, False, False]  # not moving at all
                        if self.face == 'd':
                                self.face = 'ds'
                        if self.face == 'u':
                                self.face = 'us'
                        if self.face == 'r':
                                self.face = 'rs'
                        if self.face == 'l':
                                self.face = 'ls'
                    if self.joy.buttons[2] is False:
                        self.can_drop = True
                    if self.joy.buttons[4] is False:
                        self.can_eat = True
                    if self.joy.buttons[0] is False:
                        self.can_attack = True

        except IndexError, err:  # if no joystick
            pass