Esempio n. 1
0
class TenTower(Tower):
    """
    Add extra range to each surrounding tower
    """
    def __init__(self, x, y):
        super().__init__(x, y)
        self.range = 60
        self.effect = [0.1, 0.2, 0.3]
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.menu.add_btn(sell_btn, "Sell")
        self.base_imgs = base_imgs4[:]
        self.width = 40
        self.height = 44
        self.name = "ten"
        self.sell_price = [80, 120, 240]
        self.price = [160, 300, 9999]

    def get_upgrade_cost(self):
        """
        gets the upgrade cost
        :return: int
        """
        return self.menu.get_item_cost()

    def draw(self, win):
        # super().draw_radius(win)
        super().draw_rectangle(win)
        super().draw(win)

    def support(self, towers):
        """
        will modify towers according to abillity
        :param towers: list
        :return: None
        """
        effected = []
        for tower in towers:
            x = tower.x
            y = tower.y

            dis = math.sqrt((self.x - x)**2 + (self.y - y)**2)

            if dis <= self.range + tower.width / 2:
                effected.append(tower)

        for tower in effected:
            tower.range = tower.original_range + round(
                tower.range * self.effect[self.level - 1])
Esempio n. 2
0
class ArcherTowerLong(Tower):
    def __init__(self, x,y):
        super().__init__(x, y)
        self.tower_imgs = tower_imgs1[:]
        self.archer_imgs = archer_imgs1[:]
        self.archer_count = 0
        self.range = 200
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.damage = 1
        self.original_damage = self.damage
        self.width = self.height = 90
        self.moving = False
        self.name = "archer"

        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, 5000,"MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")

    def get_upgrade_cost(self):
        """
        gets the upgrade cost
        :return: int
        """
        return self.menu.get_item_cost()

    def draw(self, win):
        """
        draw the arhcer tower and animated archer
        :param win: surface
        :return: int
        """
        super().draw_radius(win)
        super().draw(win)

        if self.inRange and not self.moving:
            self.archer_count += 1
            if self.archer_count >= len(self.archer_imgs) * 10:
                self.archer_count = 0
        else:
            self.archer_count = 0

        archer = self.archer_imgs[self.archer_count // 10]
        if self.left == True:
            add = -25
        else:
            add = -archer.get_width() + 10
        win.blit(archer, ((self.x + add), (self.y - archer.get_height() - 25)))

    def change_range(self, r):
        """
        change range of archer tower
        :param r: int
        :return: None
        """
        self.range = r

    def attack(self, enemies):
        """
        attacks an enemy in the enemy list, modifies the list
        :param enemies: list of enemies
        :return: None
        """
        money = 0
        self.inRange = False
        enemy_closest = []
        for enemy in enemies:
            x = enemy.x
            y = enemy.y
            dis = math.sqrt((self.x - 86/2 - x)**2 + (self.y - 86/2 - y)**2)
            if dis < self.range:
                self.inRange = True
                enemy_closest.append(enemy)

        enemy_closest.sort(key=lambda x: x.path_pos)
        enemy_closest = enemy_closest[::-1]
        if len(enemy_closest) > 0:
            first_enemy = enemy_closest[0]
            if self.archer_count == 50:
                if first_enemy.hit(self.damage) == True:
                    money = first_enemy.money * 2
                    enemies.remove(first_enemy)

            if first_enemy.x > self.x and not(self.left):
                self.left = True
                for x, img in enumerate(self.archer_imgs):
                    self.archer_imgs[x] = pygame.transform.flip(img, True, False)
            elif self.left and first_enemy.x < self.x:
                self.left = False
                for x, img in enumerate(self.archer_imgs):
                    self.archer_imgs[x] = pygame.transform.flip(img, True, False)

        return money
Esempio n. 3
0
class Tower:
	"""
	Abstract class for towers
	"""
	def __init__(self, x, y):
		self.x = x
		self.y = y
		self.width = self.height = 96
		self.sell_price = [0,0,0]
		self.price = [0,0,0]
		self.level = 1
		self.range = 200
		self.original_range = self.range # Not sure if this should be in here
		self.selected = False
		# define menu and buttons
		self.menu = Menu(self.x, self.y, self, menu_bg, [2000, 5000, 9000, 12000, "MAX"])
		self.menu.add_button(upgrade_button, "Upgrade")
		self.moving = False
		self.tower_imgs = []
		self.damage = 1
		self.place_color = (0,0,255, 100)

	def draw(self, win):
		"""
		draws the tower
		:param win: surface
		:return: None
		"""
		img = self.tower_imgs[self.level - 1]
		win.blit(img, (self.x-img.get_width()//2, self.y-img.get_height()//2))

		# draw menu
		if self.selected:
			self.menu.draw(win)

	def draw_radius(self, win):
		# draw range circle if selected
		if self.selected:	
			surface = pygame.Surface((self.range*2, self.range*2), pygame.SRCALPHA, 32)
			pygame.draw.circle(surface, (128, 128, 128, 100), (self.range, self.range), self.range, 0)

			win.blit(surface, (self.x - self.range, self.y - self.range))

	def draw_placement(self, win):
		# draw range circle
		surface = pygame.Surface((self.range*2, self.range*2), pygame.SRCALPHA, 32)
		pygame.draw.circle(surface, self.place_color, (58, 58), 58, 0) # 58 = 96/2 + 10

		win.blit(surface, (self.x - 58, self.y - 58))

	def click(self, X, Y):
		"""
		returns if tower has been clicked on
		and select tower if it was clicked
		:param X: int
		:param Y: int
		:return: bool
		"""
		img = self.tower_imgs[self.level - 1]
		if X  <= self.x - img.get_width()//2 + self.width and X >= self.x - img.get_width()//2:
			if Y <= self.y + self.height - img.get_height()//2 and Y >= self.y - img.get_height()//2:
				return True
		return False

	def sell(self):
		"""
		call to sell the tower, returns sel price
		:retutn: int
		"""
		return self.sell_price[self.level - 1]

	def upgrade(self):
		"""
		upgrades the tower for a given cost
		:return: None
		"""
		if self.level < len(self.tower_imgs):
			self.level += 1
			self.damage += 1

	def get_upgrade_cost(self):
		"""
		gets the upgrade cost
		:return: int
		"""
		return self.menu.get_item_cost()

	def move(self, x, y):
		"""
		moves tower to given x and y
		:param x: int
		:param y: int
		:return: None
		"""
		self.x = x
		self.y = y
		self.menu.x = x
		self.menu.y = y
		self.menu.update()

	def collide(self, otherTower):
		x2 = otherTower.x
		y2 = otherTower.y

		dis = math.sqrt((x2 - self.x)**2 + (y2 - self.y)**2)

		return True if dis <= 116 else False # width and height of the towers are equals to 96 and adding 10 from both sides = 116
class Fortress(Tower):
    """
    Add extra range to each surrounding tower
    """
    def __init__(self, x, y):
        super().__init__(x,y)
        self.range = 60
        self.effect = [100, 200, 400]
        self.price = [400, 750, 9999]
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.menu.add_btn(sell_btn, "Sell")
        self.base_imgs = base_imgs6[:]
        self.animation_imgs = animation_imgs6[:]
        self.width = 40
        self.height = 44
        self.name = "fortress"
        self.max_health = 500
        self.health = self.max_health
        self.collapse = False
        self.price = [0, 0, 0]
        self.collided = []

    def get_upgrade_cost(self):
        """
        gets the upgrade cost
        :return: int
        """
        return self.menu.get_item_cost()

    def resist(self, enemy):
        """
        will resist according to health and nearby enemies
        :param towers: list
        :return: None
        """
        if enemy.name == "wei_catapult":
            coef = 2
        elif enemy.name == "wei_balista":
            coef = 2
        elif enemy.name == "zao_riboku":
            coef = 10
        else:
            coef = 1
        self.health -= 1*coef
        if self.health <= 0:
            return False
        return True

    def draw(self, win):
        """
        draw the fortress base and fortress
        :param win: surface
        :return: int
        """
        super().draw_radius(win)
        super().draw(win)

        fortress = self.animation_imgs[self.level-1]
        add_x = 2
        add_y = 5
        win.blit(fortress, ((self.x - fortress.get_width()/2 + add_x), (self.y - fortress.get_height()/2 - add_y)))
        self.draw_health_bar(win)

    def draw_health_bar(self, win):
        """
        draw health bar above enemy
        :param win: surface
        :return: None
        """
        length = 30

        health_bar = length*(1-((self.max_health-self.health)/self.max_health))
        add_y = 15
        pygame.draw.rect(win, (255, 26, 26), (self.x - 13, self.y - 55 + add_y, length, 5), 0) # red rectangle
        pygame.draw.rect(win, (102, 255, 51), (self.x - 13, self.y - 55 + add_y, health_bar, 5), 0) # green rectangle
        pygame.draw.rect(win, (77, 77, 77), (self.x - 13, self.y - 55 + add_y, health_bar, 5), 1) # grey rectangle border
class ShinTower(Tower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.base_imgs = base_imgs1[:]
        self.animation_imgs = animation_imgs1[:]
        self.animation_count = 0
        self.range = 85
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.timer = time.time()
        self.damage = 1
        self.original_damage = self.damage
        self.width = 40
        self.height = 44
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.menu.add_btn(sell_btn, "Sell")
        self.moving = False
        self.sound = "sword.wav"
        self.name = "shin"
        self.sell_price = [30, 80, 200]
        self.price = [100, 300, 9999]
        self.distribution = [0.89, 0.1, 0.01]
        self.original_distribution = self.distribution[:]
        self.gold_drop = 0
        self.coord = (0, 0)
        self.speed = 4
        self.attacked_enemy = None

    def get_upgrade_cost(self):
        """
        gets the upgrade cost
        :return: int
        """
        return self.menu.get_item_cost()

    def draw(self, win):
        """
        draw the shin tower base and animated shin
        :param win: surface
        :return: int
        """
        super().draw_radius(win)
        super().draw(win)

        if self.inRange and not self.moving:
            self.animation_count += 1
            if self.animation_count >= len(
                    self.animation_imgs) * (5 - self.speed):
                self.animation_count = len(self.animation_imgs)
        else:
            self.animation_count = 0

        shin = self.animation_imgs[self.animation_count // (5 - self.speed)]
        add_x = 2
        add_y = 5
        win.blit(shin, ((self.x - shin.get_width() / 2 + add_x),
                        (self.y - shin.get_height() / 2 - add_y)))

    def change_range(self, r):
        """
        change range of shin tower
        :param r: int
        :return: None
        """
        self.range = r

    def attack(self, enemies):
        """
        attacks an enemy in the enemy list, modifies the list
        :param enemies: list of enemies
        :return: None
        """
        money = 0
        self.attacked_enemy = None
        self.gold_drop = 0

        self.inRange = False
        enemy_closest = []
        for enemy in enemies:
            x = enemy.x
            y = enemy.y - 36
            dis = math.sqrt((self.x - x)**2 + (self.y - y)**2)
            if dis < self.range:
                self.inRange = True
                enemy_closest.append(enemy)

        enemy_closest.sort(key=lambda x: x.path_pos)
        enemy_closest = enemy_closest[::-1]
        if len(enemy_closest) > 0:
            first_enemy = enemy_closest[0]

            if self.animation_count == len(self.animation_imgs):

                if self.name == "ouhon":
                    if not first_enemy.frozen:
                        pygame.mixer.Channel(1).play(pygame.mixer.Sound(
                            os.path.join("game_assets/sounds/", self.sound)),
                                                     maxtime=600)
                        first_enemy.frozen = True
                        first_enemy.vel = first_enemy.vel / self.freeze_power
                else:
                    pygame.mixer.Channel(1).play(pygame.mixer.Sound(
                        os.path.join("game_assets/sounds/", self.sound)),
                                                 maxtime=600)

                if first_enemy.hit(self.damage, self.name) == True:
                    pygame.mixer.Channel(1).play(pygame.mixer.Sound(
                        os.path.join("game_assets/sounds/",
                                     first_enemy.sound)),
                                                 maxtime=600)

                    # give money, drop reward (low probability), remove died enemy
                    self.attacked_enemy = first_enemy
                    money = first_enemy.money * 2
                    self.random_reward(first_enemy)
                    if self.gold_drop > 0:
                        self.coord = (first_enemy.x, first_enemy.y)
                    enemies.remove(first_enemy)

        return money

    def random_reward(self, enemy):
        """
        Return an amount of reward, with low probability
        :return: 1-sized list   
        """
        gold_list = [0, enemy.money, enemy.money * 3]
        drop = random.choices(gold_list, self.distribution)
        self.gold_drop = drop[0]
        return self.gold_drop
class ArcherTowerLong(Tower):
    is_game_pause = True

    def __init__(self, x, y):
        super().__init__(x, y)
        self.tower_imgs = tower_imgs.images[:]
        self.archer_imgs = archer_imgs.images[:]
        self.archer_count = 0
        self.price = 500
        self.range = 150
        self.original_range = self.range

        self.in_range = False
        self.left = False
        self.damage = 2
        self.original_damage = self.damage
        self.width = self.height = 90
        self.moving = False
        self.paused = False
        self.name = "archer_long"

        # define menu and buttons
        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, 5000, "Max"])
        self.menu.add_btn(upgrade_btn, "Upgrade")

    def get_upgrade_cost(self):
        """
        Gets the upgrade cost
        :return: int
        """
        return self.menu.get_item_cost()

    def draw(self, win):
        """
        Draw the archer tower and animated archer
        :param win: surface
        :return: int
        """
        super().draw_radius(win)
        super().draw(win)

        if self.in_range and not self.moving and not ArcherTowerLong.is_game_pause:
            self.archer_count += 1
            if self.archer_count >= len(self.archer_imgs) * 10:
                self.archer_count = 0
        else:
            self.archer_count = 0

        archer = self.archer_imgs[self.archer_count // 10]
        win.blit(archer, (self.x - 22, self.y - archer.get_height() - 18))

    def change_range(self, r):
        """
        Change range for archer tower
        :param r: int
        :return: None
        """
        self.range -= r

    def attack(self, enemies):
        """
        Attacks an enemy in the enemy list, modifies the list
        :param enemies: list of enemies
        :return: None
        """
        money = 0
        self.in_range = False
        enemy_closest = []

        for enemy in enemies:
            enemy_x, enemy_y = enemy.x, enemy.y

            dis = math.sqrt((self.x - enemy_x)**2 + (self.y - enemy_y)**2)
            if dis < self.range:
                self.in_range = True
                enemy_closest.append(enemy)

        enemy_closest.sort(key=lambda x: x.health)
        # enemy_closest = enemy_closest[::-1]
        if len(enemy_closest) > 0:
            first_enemy = enemy_closest[0]
            if self.archer_count == 50:
                if first_enemy.hit(self.damage):
                    money = first_enemy.money * 2
                    # enemies.remove(first_enemy)
                    first_enemy.to_dying()

            if first_enemy.x < self.x and not self.left:
                self.left = True
                for index, img in enumerate(self.archer_imgs):
                    self.archer_imgs[index] = pygame.transform.flip(
                        img, True, False)
            elif self.left and first_enemy.x > self.x:
                self.left = False
                for index, img in enumerate(self.archer_imgs):
                    self.archer_imgs[index] = pygame.transform.flip(
                        img, True, False)

        return money
Esempio n. 7
0
class ArcherTowerLong(Tower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.tower_imgs = tower_imgs1[:]
        self.archer_imgs = archer_imgs1[:]
        self.archer_count = 0
        self.range = 200
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.damage = 1
        self.original_damage = self.damage
        self.width = self.height = 90
        self.moving = False
        self.name = "archer"

        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, 5000, "MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")

    def get_upgrade_cost(self):
        """
        Pobierz koszt ulepszenia
        :return: int
        """
        return self.menu.get_item_cost()

    def draw(self, win):
        """
        narysuj wieżę łuczników i animacje łucznika
        :param win: surface
        :return: int
        """
        super().draw_radius(win)
        super().draw(win)

        if self.inRange and not self.moving:
            self.archer_count += 1
            if self.archer_count >= len(self.archer_imgs) * 10:
                self.archer_count = 0
        else:
            self.archer_count = 0

        archer = self.archer_imgs[self.archer_count // 10]
        if self.left == True:
            add = -25
        else:
            add = -archer.get_width() + 10
        win.blit(archer, ((self.x + add), (self.y - archer.get_height() - 25)))

    def change_range(self, r):
        """
        Zmiana zasięgu wiezy luczniczej
        :param r: int
        :return: None
        """
        self.range = r

    def attack(self, enemies):
        """
        atakuje wroga z listy wrogów, modyfikuje listę
        :param enemies: lista wrogów
        :return: None
        """
        money = 0
        self.inRange = False
        enemy_closest = []
        for enemy in enemies:
            x = enemy.x
            y = enemy.y

            dis = math.sqrt((self.x - x)**2 + (self.y - y)**2)
            if dis < self.range:
                self.inRange = True
                enemy_closest.append(enemy)

        enemy_closest.sort(key=lambda x: x.x)
        if len(enemy_closest) > 0:
            first_enemy = enemy_closest[0]
            if self.archer_count == 6:
                if first_enemy.hit(self.damage) == True:
                    money = first_enemy.money
                    enemies.remove(first_enemy)

            if first_enemy.x > self.x and not (self.left):
                self.left = True
                for x, img in enumerate(self.archer_imgs):
                    self.archer_imgs[x] = pygame.transform.flip(
                        img, True, False)
            elif self.left and first_enemy.x < self.x:
                self.left = False
                for x, img in enumerate(self.archer_imgs):
                    self.archer_imgs[x] = pygame.transform.flip(
                        img, True, False)

        return money