class Qi_base(Kingdom):
    def __init__(self):
        super().__init__()

        self.img = img
        self.name = "qi_base"
        self.x = 980
        self.y = 318
        self.tile = [[1100, 176], [1020, 210], [1060, 210], [1100, 210],
                     [860, 244], [900, 244], [940, 244], [980, 244],
                     [1020, 244], [1060, 244], [1100, 244], [860, 279],
                     [900, 279], [940, 279], [980, 279], [1020, 279],
                     [1060, 279], [1100, 279], [860, 313], [900, 313],
                     [940, 313], [980, 313], [1020, 313], [1060, 313],
                     [1100, 313], [860, 349], [900, 349], [940,
                                                           349], [980, 349],
                     [1020, 349], [1060, 349], [1100, 349]]
        self.rgb = rgb(254, 234, 178)
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(warrior, "kingdom")
        self.menu.add_btn(boat, "kingdom")

    def draw(self, win):
        super().draw(win)
        if self.selected:
            self.menu.x = self.x
            self.menu.y = self.y
            self.menu.update()
            self.menu.draw(win)
class Wei_base(Kingdom):
    def __init__(self):
        super().__init__()

        self.img = img
        self.name = "wei_base"
        self.x = 660
        self.y = 318
        self.tile = [[460, 244], [500, 244], [540, 244], [580,
                                                          244], [620, 244],
                     [660, 244], [700, 244], [460, 279], [500,
                                                          279], [540, 279],
                     [580, 279], [620, 279], [660, 279], [700,
                                                          279], [500, 313],
                     [540, 313], [580, 313], [620, 313], [660,
                                                          313], [700, 313],
                     [500, 349], [540, 349], [580, 349], [620,
                                                          349], [660, 349],
                     [700, 349], [500, 383], [540, 383], [580,
                                                          383], [620, 383],
                     [660, 383], [500, 417], [540, 417], [580, 417],
                     [620, 417], [660, 417]]
        self.rgb = rgb(254, 245, 134)
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(catapult, "kingdom")
        self.menu.add_btn(balista, "kingdom")

    def draw(self, win):
        super().draw(win)
        if self.selected:
            self.menu.x = self.x
            self.menu.y = self.y
            self.menu.update()
            self.menu.draw(win)
示例#3
0
class DamageTower(Tower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.range = 150
        self.effect = [2, 4]
        self.imgs = damage_imgs[:]
        self.width = self.height = 128
        self.price = [1300, 0]
        temp = []
        for x in range(len(self.price) - 1):
            temp.append(str(self.price[x]))
        temp.append("MAX")
        self.menu = Menu(self, self.x, self.y, menu_bg, temp)
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.name = "damageTower"

    def get_upgrade_cost(self):
        return self.price[self.level - 1]


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

    def support(self, towers):
        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.damage = tower.oryginal_damage * self.effect[self.level - 1]
示例#4
0
class KyoukaiTower(TenTower):
    """
    add damage to surrounding towers
    """
    def __init__(self, x, y):
        super().__init__(x, y)
        self.range = 60
        self.base_imgs = base_imgs5[:]
        self.effect = [1, 2, 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.name = "kyoukai"
        self.sell_price = [80, 120, 240]
        self.price = [160, 300, 9999]

    def support(self, towers):
        """
        will modify towers according to ability
        :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.damage = tower.original_damage + round(
                tower.original_damage * self.effect[self.level - 1])
示例#5
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])
示例#6
0
class ArcherTowerShort(ArcherTowerLong):
    def __init__(self, x,y):
        super().__init__(x, y)
        self.tower_imgs = tower_imgs[:]
        self.archer_imgs = archer_imgs[:]
        self.archer_count = 0
        self.range = 120
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.damage = 2
        self.original_damage = self.damage

        self.menu = Menu(self, self.x, self.y, menu_bg, [2500, 5500, "MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.name = "archer2"
class Zao_base(Kingdom):
    def __init__(self):
        super().__init__()

        self.img = img
        self.name = "zao_base"
        self.x = 700
        self.y = 145
        self.tile = [[20, 40], [60, 40], [100, 40], [140, 40], [180, 40],
                     [220, 40], [260, 40], [300, 40], [340, 40], [380, 40],
                     [420, 40], [460, 40], [500, 40], [540, 40], [580, 40],
                     [620, 40], [660, 40], [700, 40], [740, 40], [20, 74],
                     [60, 74], [100, 74], [140, 74], [180, 74], [220, 74],
                     [260, 74], [300, 74], [340, 74], [380, 74], [420, 74],
                     [460, 74], [500, 74], [540, 74], [580, 74], [620, 74],
                     [660, 74], [700, 74], [740, 74], [20, 108], [60, 108],
                     [100, 108], [140, 108], [180, 108], [220,
                                                          108], [260, 108],
                     [300, 108], [340, 108], [540, 108], [580,
                                                          108], [620, 108],
                     [660, 108], [700, 108], [740, 108], [540,
                                                          142], [580, 142],
                     [620, 142], [660, 142], [700, 142], [740,
                                                          142], [540, 176],
                     [580, 176], [620, 176], [660, 176], [700,
                                                          176], [740, 176],
                     [540, 210], [580, 210], [620, 210], [660,
                                                          210], [700, 210],
                     [740, 210], [780, 210], [820, 210], [740,
                                                          244], [780, 244],
                     [820, 244], [740, 279], [780, 279], [820,
                                                          279], [740, 313],
                     [780, 313], [820, 313], [740, 349], [780, 349],
                     [820, 349], [820, 383]]
        self.rgb = rgb(250, 160, 150)
        self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
        self.menu.add_btn(warrior, "kingdom")
        self.menu.add_btn(riboku, "kingdom")

    def draw(self, win):
        super().draw(win)
        if self.selected:
            self.menu.x = self.x
            self.menu.y = self.y
            self.menu.update()
            self.menu.draw(win)
class ArcherTowerShort(ArcherTowerLong):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.tower_imgs = tower_imgs_sibling.images[:]
        self.archer_imgs = archer_imgs_sibling.images[:]
        self.archer_count = 0
        self.range = 120
        self.price = 750
        self.original_range = self.range
        self.in_range = False
        self.left = False
        self.damage = 4
        self.original_damage = self.damage
        self.width = self.height = 100
        self.name = "archer_short"

        # define menu and buttons
        self.menu = Menu(self, self.x, self.y, menu_bg, [2500, 5500, "Max"])
        self.menu.add_btn(upgrade_btn, "Upgrade")
class KankiTower(ShinTower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.base_imgs = base_imgs3[:]
        self.animation_imgs = animation_imgs3[:]
        self.animation_count = 0
        self.range = 65
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.damage = 1
        self.original_damage = self.damage
        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.sound = "sword2.wav"
        self.name = "kanki"
        self.sell_price = [60, 100, 200]
        self.price = [120, 250, 9999]
        self.distribution = [0.89, 0.1, 0.01]
class Han_base(Kingdom):
	
	def __init__(self):
		super().__init__()

		self.img = img
		self.name = "han_base"
		self.x = 740
		self.y = 388
		self.tile = [[700,383],[740,383],[780,383],[700,417],[740,417],[780,417],[700,453],[740,453],[780,453],[700,489],[740,489],[780,489],[700,523],[740,523]]
		self.rgb = rgb(253, 143, 66)
		self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
		self.menu.add_btn(warrior, "kingdom2")

	def draw(self, win):
		super().draw(win)
		if self.selected:
			self.menu.x = self.x
			self.menu.y = self.y
			self.menu.update()
			self.menu.draw(win)
示例#11
0
class Chu3_base(Kingdom):
	
	def __init__(self):
		super().__init__()

		self.img = img
		self.name = "chu3_base"
		self.x = 820
		self.y = 564
		self.tile = [[860,383],[900,383],[940,383],[980,383],[1020,383],[1060,383],[1100,383],[820,417],[860,417],[900,417],[940,417],[980,417],[1020,417],[1060,417],[1100,417],[500,453],[540,453],[580,453],[620,453],[660,453],[820,453],[860,453],[900,453],[940,453],[980,453],[1020,453],[1060,453],[1100,453],[500,489],[540,489],[580,489],[620,489],[660,489],[820,489],[860,489],[900,489],[940,489],[980,489],[1020,489],[1060,489],[1100,489],[140,523],[180,523],[220,523],[260,523],[300,523],[340,523],[380,523],[420,523],[460,523],[500,523],[540,523],[580,523],[620,523],[660,523],[780,523],[820,523],[860,523],[900,523],[940,523],[980,523],[1020,523],[1060,523],[1100,523],[20,559],[60,559],[100,559],[140,559],[180,559],[220,559],[260,559],[300,559],[340,559],[380,559],[420,559],[460,559],[500,559],[540,559],[580,559],[620,559],[660,559],[700,559],[740,559],[780,559],[820,559],[860,559],[900,559],[940,559],[980,559],[1020,559],[1060,559],[1100,559],[20,593],[60,593],[100,593],[140,593],[180,593],[220,593],[260,593],[300,593],[340,593],[380,593],[420,593],[460,593],[500,593],[540,593],[580,593],[620,593],[660,593],[700,593],[740,593],[780,593],[820,593],[860,593],[900,593],[940,593],[980,593],[1020,593],[1060,593],[1100,593],[20,627],[60,627],[100,627],[140,627],[180,627],[220,627],[260,627],[300,627],[340,627],[380,627],[420,627],[460,627],[500,627],[540,627],[580,627],[620,627],[660,627],[700,627],[740,627],[780,627],[820,627],[860,627],[900,627],[940,627],[980,627],[1020,627],[1060,627],[1100,627],[20,661],[60,661],[100,661],[140,661],[180,661],[220,661],[260,661],[300,661],[340,661],[380,661],[420,661],[460,661],[500,661],[540,661],[580,661],[620,661],[660,661],[700,661],[740,661],[780,661],[820,661],[860,661],[900,661],[940,661],[980,661],[1020,661],[1060,661],[1100,661]]
		self.rgb = rgb(176, 134, 105)
		self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
		self.menu.add_btn(boat, "kingdom2")
		
	def draw(self, win):
		super().draw(win)
		if self.selected:
			self.menu.x = self.x
			self.menu.y = self.y
			self.menu.update()
			self.menu.draw(win)
class MoubuTower(ShinTower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.base_imgs = base_imgs2[:]
        self.animation_imgs = animation_imgs2[:]
        self.animation_count = 0
        self.range = 65
        self.original_range = self.range
        self.inRange = False
        self.left = True
        self.damage = 2
        self.original_damage = self.damage
        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.sound = "club.wav"
        self.name = "moubu"
        self.sell_price = [90, 150, 200]
        self.price = [180, 300, 9999]
        self.distribution = [0.89, 0.1, 0.01]
        self.original_distribution = self.distribution[:]
示例#13
0
class RyoTower(TenTower):
    """
    enhance rewards surrounding towers
    """
    def __init__(self, x, y):
        super().__init__(x, y)
        self.range = 100
        self.base_imgs = base_imgs6[:]
        self.effect = [1, 2, 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.name = "ryo"
        self.sell_price = [80, 120, 240]
        self.price = [160, 300, 9999]

    def support(self, towers):
        """
        will modify towers according to ability
        :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:
            for i in range(1, 3):
                tower.distribution[i] = tower.original_distribution[i] + round(
                    tower.original_distribution[i] *
                    self.effect[self.level - 1], 3)
            tower.distribution[0] = 1 - (tower.distribution[1] +
                                         tower.distribution[2])
class Yan_base(Kingdom):
	
	def __init__(self):
		super().__init__()

		self.img = img
		self.name = "yan_base"
		self.x = 940
		self.y = 111
		self.tile = [[780,40],[820,40],[860,40],[900,40],[940,40],[980,40],[1020,40],[1060,40],[1100,40],[780,74],[820,74],[860,74],[900,74],[940,74],[980,74],[1020,74],[1060,74],[1100,74],[780,108],[820,108],[860,108],[900,108],[940,108],[980,108],[1020,108],[1060,108],[1100,108],[780,142],[820,142],[860,142],[900,142],[940,142],[980,142],[1020,142],[1060,142],[1100,142],[780,176],[820,176],[860,176],[900,176],[940,176],[980,176],[1020,176],[1060,176],[860,210],[900,210],[940,210],[980,210]]
		self.rgb = rgb(170, 250, 140)
		self.menu = Menu(self, self.x, self.y, menu_bg, self.price)
		self.menu.add_btn(warrior, "kingdom")
		self.menu.add_btn(boat, "kingdom")

	def draw(self, win):
		super().draw(win)
		if self.selected:
			self.menu.x = self.x
			self.menu.y = self.y
			self.menu.update()
			self.menu.draw(win)
示例#15
0
class Tower:
    """
    Klasa abstrakcyjna dla wież
    """
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.sell_price = [0,0,0]
        self.price = [0,0,0]
        self.level = 1
        self.selected = False
        #definiuje menu i przyciski
        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, "MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")


        self.tower_imgs = []
        self.damage = 1

    def draw(self, win):
        """
        Rysowanie wieży
        :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))

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

    def draw_radius(self, win):
        if self.selected:
            # rysowanie okręgu zasięgu
            surface = pygame.Surface((self.range*4, self.range*4), 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 click(self, X, Y):
        """
        Zwraca gdy kliknięto na wieżę
        i zaznacza wieżę gdy jest kliknięta
        :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):
        """
        wezwanie do sprzedazy wiezy, zwraca koszt sprzedaży
        :return:int
        """
        return self.sell_price[self.level-1]

    def upgrade(self):
        """
        ulepsza wieżę za określony koszt
        :return: None
        """
        if self.level + 1 < len(self.tower_imgs):
            self.level += 1
            self.damage += 1

    def get_upgrade_cost(self):
        """
        zwraca koszt ulepszenia, jeśli 0, to nie może  ulepszać
        :return: int
        """
        return self.price[self.level-1]

    def move(self, x, y):
        """
        Przesuwa wieze do podanego x i 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()
示例#16
0
class Tower(PositionalObject, ILocation, IUpgradable):
    """
    Abstract class for towers
    """
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.price = 0
        self.level = 1
        self.range = 0
        self.selected = False
        self.is_collide = False

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

        self.tower_imgs = []
        self.damage = 1
        self.sell_price = []

        self.place_color = (0, 255, 0, 100)

    def get_position(self):
        return self.x, self.y

    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):
        if self.selected:
            # Draw range circle
            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):
        surface = pygame.Surface((self.range * 2, self.range * 2),
                                 pygame.SRCALPHA, 32)
        pygame.draw.circle(surface, self.place_color, (45, 45), 45, 0)
        win.blit(surface, (self.x - 45, self.y - 45))

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

    def sell(self):
        """
        Call to sell the tower, returns sell cost
        :return: int
        """

        return self.sell_price[self.level - 1]

    def get_upgrade_cost(self):
        """
        Return the upgrade cost, if 0 then can't upgrade anymore
        :return:
        """
        return self.price

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

    def move(self, x, y):
        """
        Moves tower to given x and y position
        :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, other_tower):
        x2 = other_tower.x
        y2 = other_tower.y

        dis = math.sqrt((x2 - self.x)**2 + (y2 - self.y)**2)
        if dis >= 90:
            return False
        else:
            return True
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 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
示例#19
0
class Tower:
    """
    Abstract class for towers
    """
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.sell_price = [0, 0, 0]
        self.price = [0, 0, 0]
        self.level = 1
        self.selected = False
        # define menu and buttons
        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, "MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")

        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):
        if self.selected:
            # draw range circle
            surface = pygame.Surface((self.range * 4, self.range * 4),
                                     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 * 4, self.range * 4),
                                 pygame.SRCALPHA, 32)
        pygame.draw.circle(surface, self.place_color, (50, 50), 50, 0)

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

    def click(self, X, Y):
        """
        returns if tower has been clicked on
        and selects 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 sell price
        :return: 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):
        """
        returns the upgrade cost, if 0 then can't upgrade anymore
        :return: int
        """
        return self.price[self.level - 1]

    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)
        if dis >= 100:
            return False
        else:
            return True
class Tower:
    """
    Abstract class for towers
    """
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.sell_price = [0, 0, 0]
        self.price = [100, 300, 9999]
        self.level = 1
        self.selected = False
        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 = []
        self.animation_imgs = []
        self.damage = 1
        self.speed = 4

    def draw(self, win):
        """
        draws the tower
        :param win: surface
        :return: None
        """
        img = self.base_imgs[self.level - 1]
        # find the closest tile
        self.x = min(tile_x, key=lambda x: abs(x - self.x))
        self.y = min(tile_y, key=lambda y: abs(y - self.y))
        tile_key = (self.x, self.y)
        if self.name == "fortress":
            if dict_tile_fortress[tile_key] == 0:
                win.blit(img, (self.x - img.get_width() // 2,
                               self.y - img.get_height() // 2))
        else:
            if dict_tile[tile_key] == 0:
                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):
        if self.selected:
            # draw range circle
            size = (self.range * 2, self.range * 2)
            radius = self.range
            surface = pygame.Surface(size, pygame.SRCALPHA, 32)
            pygame.draw.circle(surface, rgb(204, 255, 255), (radius, radius),
                               radius, 0)
            win.blit(surface, (self.x - radius, self.y - radius))

    def draw_rectangle(self, win):
        if self.selected:
            # draw range rectangle
            surface = pygame.Surface((self.range * 4, self.range * 4),
                                     pygame.SRCALPHA, 32)
            pygame.draw.rect(surface, rgb(204, 255, 255),
                             (self.range * 2, self.range * 2, self.range * 2,
                              self.range * 1.8), 0)
            win.blit(surface,
                     (self.x - 3 * self.range, self.y - 2.6 * self.range))

    def click(self, X, Y):
        """
        returns if tower has been clicked on
        and selects tower if it was clicked
        :param X: int
        :param Y: int
        :return: bool
        """
        img = self.base_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 sell price
        :return: int
        """
        return self.sell_price[self.level - 1]

    def upgrade(self):
        """
        upgrades the tower for a given cost
        :return: None
        """
        if self.name == "fortress":
            if self.level < len(self.animation_imgs):
                self.level += 1
                self.max_health += self.max_health
                self.health += self.health
        elif self.name == "ouhon":
            if self.level < len(self.base_imgs):
                self.level += 1
                self.freeze_power += 0.5
        else:
            if self.level < len(self.base_imgs):
                self.level += 1
                self.damage += 1

    def get_upgrade_cost(self):
        """
        returns the upgrade cost, if 0 then can't upgrade anymore
        :return: int
        """
        return self.price[self.level - 1]

    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

        # find closest tile
        x2 = min(
            tile_x, key=lambda x: abs(x - x2)
        )  # set x2 at the x coordinate of tyle_x which has the minimum distance from x2
        y2 = min(
            tile_y, key=lambda y: abs(y - y2)
        )  # set y2 the y coordinate of tyle_y which has the minimum distance from y2
        tile_key = (x2, y2)

        # distance between the object and the closest tile
        dis = math.sqrt((x2 - self.x)**2 + (y2 - self.y)**2)

        # check if first tower of the game collides with forbidden tile
        if self == otherTower:
            if self.name == "fortress":
                # tile is available
                if dict_tile_fortress[tile_key] == 0:
                    return False  # collide == False
                # tile is not available (collision with outside path)
                else:
                    return True  # collide == True
            else:
                # tile is available
                if dict_tile[tile_key] == 0:
                    return False  # collide == False
                # tile is not available (collision with path)
                else:
                    return True  # collide == True

        # check if moving object collides with towers, fortress or forbidden tile
        else:
            if self.name == "fortress":
                # tile is possibly available
                if dict_tile_fortress[tile_key] == 0:
                    # when not already occupied by another fortress
                    if dis >= 10:
                        return False  # collide == False
                    # tile is already occupied by another fortress
                    else:
                        return True  # collide == True
            # tile is not available (collision with outside path)
                else:
                    return True  # collide == True
            else:
                # tile is possibly available
                if dict_tile[tile_key] == 0:
                    # when not already occupied by another object
                    if dis >= 10:
                        return False  # collide == False
                    # tile is already occupied by another object
                    else:
                        return True  # collide == True
                # tile is not available (collision with path)
                else:
                    return True  # collide == True
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
示例#22
0
class LongRangeTower(Tower):
    def __init__(self, x, y):
        super().__init__(x, y)
        self.imgs = []
        self.oryginal_range = 150
        self.range = self.oryginal_range
        self.inRange = False
        self.left = True
        self.timer = time.time()
        self.oryginal_damage = 1
        self.damage = self.oryginal_damage
        self.width = self.height = 128
        self.price = [2000, 4000, 0]
        temp = []
        for x in range(len(self.price) - 1):
            temp.append(str(self.price[x]))
        temp.append("MAX")
        self.menu = Menu(self, self.x, self.y, menu_bg, temp)
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.name = "longRangeTower"
        self.moving = False

        self.imgs.append(
            pygame.transform.scale(
                pygame.image.load(
                    os.path.join("game_assets/towers/", "base1.png")),
                (50, 100)))

    def get_upgrade_cost(self):
        return self.price[self.level - 1]

    def draw(self, win):
        super().draw_radius(win)
        super().draw(win)
        base = self.imgs[0]

    def change_range(self, r):
        self.range = r

    def attack(self, enemies):
        """"""
        self.inRange = False
        enemy_closest = []
        for enemy in enemies:
            en_x = enemy.x
            en_y = enemy.y
            dis = math.sqrt((self.x - en_x)**2 + (self.y - en_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]
        # to bedzie przydatne w lucznikach.
        # flipowanie obrazka w zaleznosci czy przeciwnik jest z lewej lub prawej strony
        # """
        if len(enemy_closest) > 0:
            first_enemy = enemy_closest[0]
            if time.time() - self.timer > 0.5:
                self.timer = time.time()
                if first_enemy.hit(self.damage) == True:
                    income = first_enemy.worth
                    enemies.remove(first_enemy)
                    return income

            if first_enemy.x > self.x and not (self.left):
                self.left = True
                for x, img in enumerate(self.imgs):
                    self.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.imgs):
                    self.imgs[x] = pygame.transform.flip(img, True, False)
        return 0
示例#23
0
class Tower:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.range = 0
        self.price = [0, 0, 0]
        self.level = 1
        self.selected = False
        # define menu and buttons
        self.menu = Menu(self, self.x, self.y, menu_bg, [2000, "MAX"])
        self.menu.add_btn(upgrade_btn, "Upgrade")
        self.imgs = []
        self.damage = 1
        self.place_color = (0, 0, 255, 100)

    def draw(self, win):
        # TODO: dodaj wiecej spritow zeby pokazac ulepszanie wiez, ustawione normalnie na self.level - 1
        img = self.imgs[0]
        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):
        if self.selected:
            # draw range circle
            circle_surface = pygame.Surface((self.range * 2, self.range * 2),
                                            pygame.SRCALPHA, 32)
            pygame.draw.circle(circle_surface, (128, 128, 128, 100),
                               (self.range, self.range), self.range, 0)

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

    def draw_placement(self, win):
        # draw range circle
        surface = pygame.Surface((self.range * 4, self.range * 4),
                                 pygame.SRCALPHA, 32)
        pygame.draw.circle(surface, self.place_color, (50, 50), 50, 0)

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

    def click(self, X, Y):
        """Returns if tower has been clicked on
        and selects tower if it was clicked"""
        # tu zmienione również z self.level - 1 na 0 z powodu brakow spritow
        img = self.imgs[0]
        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 upgrade(self):
        """Upgrades towers to higher tier at given cost"""
        # instead of next sprites is only block by number
        if self.level < len(self.price):
            self.level += 1
            self.damage += 1
            return True
        else:
            return False

    def get_upgrade_cost(self):
        return self.price[self.level - 1]

    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)
        if dis >= 100:
            return False
        else:
            return True
示例#24
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
示例#25
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