diff --git a/.idea/CASTLE_WAR.iml b/.idea/CASTLE_WAR.iml
index d0876a7..1be71fe 100644
--- a/.idea/CASTLE_WAR.iml
+++ b/.idea/CASTLE_WAR.iml
@@ -1,8 +1,10 @@
-
-
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0baf0bb..735c5e5 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/font/pixel.ttf b/font/pixel.ttf
new file mode 100644
index 0000000..cf6fdf4
Binary files /dev/null and b/font/pixel.ttf differ
diff --git a/implementable/Functions.py b/implementable/Functions.py
new file mode 100644
index 0000000..82b0449
--- /dev/null
+++ b/implementable/Functions.py
@@ -0,0 +1,316 @@
+import time
+
+import pygame as pg
+
+from objects.Constants import *
+from objects.Wall import Wall
+from objects.players.Archer import Archer
+from objects.players.SwordsMan import SwordsMan
+from objects.players.Worker import Worker
+
+pg.font.init()
+
+
+def attack(soldiers, soldier_index, soldier_counter):
+ if len(soldiers) > 0:
+ if soldier_index >= len(soldiers):
+ soldier_index = 0
+ soldier = soldiers[soldier_index]
+ soldier_index += 1
+ if soldier.ready_to_dispatch and isinstance(soldier, (Archer, SwordsMan)):
+ soldier.deploy = True
+ soldier.run = True
+ if isinstance(soldier, Archer):
+ if not soldier.shooting:
+ soldier.load_run()
+ else:
+ soldier.ready_to_shoot()
+ else:
+ soldier.load_run()
+ soldier_counter -= 1
+ if soldier_counter <= 0:
+ soldier_counter = 0
+ return soldier_index, soldier_counter
+
+
+def run_to_mine(workers):
+ for worker in workers and workers:
+ if worker.ready_to_dispatch and not worker.digging:
+ worker.deploy = True
+ worker.run = True
+ worker.run_to_mine = True
+ worker.digging = False
+ worker.repairing = False
+ worker.run_to_wall = False
+ worker.to_mine()
+
+
+def at_mine(workers):
+ if all(worker.digging for worker in workers):
+ return False
+ else:
+ return True
+
+
+def run_to_wall(workers):
+ for worker in workers and workers:
+ # if worker.ready_to_dispatch and worker.player.castle.wall.health < Wall.MAX_HEALTH:
+ if worker.ready_to_dispatch and not worker.repairing and worker.player.castle.wall.health < Wall.MAX_HEALTH:
+ worker.deploy = True
+ worker.run = True
+ worker.digging = False
+ worker.repairing = False
+ worker.run_to_mine = False
+ worker.run_to_wall = True
+ worker.to_wall()
+
+
+def at_wall(workers):
+ if all(worker.repairing for worker in workers):
+ return False
+ else:
+ return True
+
+
+def deploy_all(soldiers):
+ if all(soldier.deploy for soldier in soldiers):
+ return False
+ else:
+ return True
+
+
+def deploy(units):
+ for i, soldier in enumerate(units):
+ if soldier.deploy:
+ if soldier.run:
+ soldier.move()
+ soldier.update()
+
+
+def check_added(units, num_units, count_units, total):
+ if isinstance(units, list):
+ for i in range(len(units)):
+ if isinstance(units[i], (Archer, SwordsMan, Worker)):
+ if units[i].ready_to_dispatch and not units[i].added:
+ units[i].added = True
+ num_units += 1
+ count_units -= 1
+ if total is not None:
+ total += 1
+ return num_units, count_units, total
+
+
+def add_to_queue(military_unit, units, count_soldiers, player_type):
+ if isinstance(units, list):
+ for i in range(count_soldiers):
+ match player_type:
+ case "a_p1":
+ soldier = Archer("p1")
+ if len(units) > 0:
+ prev_soldier = units[len(units) - 1]
+ if prev_soldier.ready_to_dispatch and prev_soldier.added:
+ units.append(soldier)
+ military_unit.append(soldier)
+ else:
+ units.append(soldier)
+ military_unit.append(soldier)
+
+ case "a_p2":
+ soldier = Archer("p2")
+ if len(units) > 0:
+ prev_soldier = units[len(units) - 1]
+ if prev_soldier.ready_to_dispatch and prev_soldier.added:
+ units.append(soldier)
+ military_unit.append(soldier)
+ else:
+ units.append(soldier)
+ military_unit.append(soldier)
+
+ case "s_p1":
+ soldier = SwordsMan("p1")
+ if len(units) > 0:
+ prev_soldier = units[len(units) - 1]
+ if prev_soldier.ready_to_dispatch and prev_soldier.added:
+ units.append(soldier)
+ military_unit.append(soldier)
+ else:
+ units.append(soldier)
+ military_unit.append(soldier)
+
+ case "s_p2":
+ soldier = SwordsMan("p2")
+ if len(units) > 0:
+ prev_soldier = units[len(units) - 1]
+ if prev_soldier.ready_to_dispatch and prev_soldier.added:
+ units.append(soldier)
+ military_unit.append(soldier)
+ else:
+ units.append(soldier)
+ military_unit.append(soldier)
+ case "w_p1":
+ worker = Worker(military_unit)
+ if len(units) > 0:
+ prev_worker = units[len(units) - 1]
+ if prev_worker.ready_to_dispatch and prev_worker.added:
+ units.append(worker)
+ else:
+ units.append(worker)
+ case "w_p2":
+ worker = Worker(military_unit)
+ if len(units) > 0:
+ prev_worker = units[len(units) - 1]
+ if prev_worker.ready_to_dispatch and prev_worker.added:
+ units.append(worker)
+ else:
+ units.append(worker)
+
+
+def collide(soldiers, target_unit):
+ if isinstance(soldiers, list):
+ for soldier in soldiers:
+ if isinstance(soldier, Archer):
+ if soldier.range.colliderect(
+ target_unit.range if not isinstance(target_unit,
+ Wall) else target_unit.rect):
+ soldier.run = False
+ soldier.ready_to_shoot()
+ if soldier.shooting:
+ soldier.move_arrows(target_unit)
+ elif isinstance(soldier, SwordsMan):
+ if soldier.rect.colliderect(target_unit.rect):
+ soldier.run = False
+ soldier.attack()
+ if soldier.attacking:
+ soldier.target_unit = target_unit
+
+
+def tower_collide(tower, target_unit):
+ if abs(tower.rect.centerx - target_unit.rect.centerx) <= tower.RANGE and not isinstance(target_unit, Wall):
+ tower.attacking = True
+ tower.resting = False
+ else:
+ tower.attacking = False
+ tower.resting = True
+
+
+def training(units):
+ if isinstance(units, list):
+ for i in range(len(units)):
+ if units[i].ready_to_dispatch is False:
+ units[i].train()
+
+
+def check_dead(soldiers):
+ for i, soldier in enumerate(soldiers):
+ if isinstance(soldier, (Archer, SwordsMan)):
+ if soldier.dead and soldier.rest(3):
+ del soldiers[i]
+
+
+def check_health(soldiers):
+ for i, soldier in enumerate(soldiers):
+ if isinstance(soldier, (Archer, SwordsMan)):
+ if soldier.health <= 0:
+ soldier.run = False
+ if isinstance(soldier, Archer):
+ soldier.arrows.clear()
+ soldier.shooting = False
+ soldier.attacking = False
+ soldier.falling = True
+
+ soldier.load_dead()
+
+
+def check_worker_action(units):
+ for i, unit in enumerate(units):
+ if unit.digging:
+ unit.dig()
+ elif unit.repairing:
+ unit.repair()
+
+
+def draw(units, screen):
+ for i in range(len(units)):
+ if units[i].ready_to_dispatch:
+ units[i].draw(screen)
+
+
+def loadImage(image_map, num_img, flip):
+ images = {}
+ for i in range(num_img):
+ image = pg.image.load(image_map['root'] + str(i) + image_map['extension'])
+ if flip:
+ image = pg.transform.flip(image, True, False)
+ images[i] = image
+ return images
+
+
+def redraw_window(player1, player2, game_over, screen, winner, pause):
+ screen.blit(BG, (0, 0))
+
+ # player1 labels
+ ready_archers_label_1 = DEFAULT_FONT.render(f"Ready Archers: {player1.num_archer}", True, (255, 0, 255))
+ ready_swordsmen_label_1 = DEFAULT_FONT.render(f"| Ready Swordsmen: {player1.num_swordsmen}", True,
+ (255, 0, 255))
+ ready_workers_label_1 = DEFAULT_FONT.render(f" | Total Workers: {player1.num_workers}", True, (255, 0, 255))
+
+ archers_in_training_1 = DEFAULT_FONT.render(f"Issued archers: {player1.count_archer}", True, (255, 0, 255))
+ swordsmen_in_training_1 = DEFAULT_FONT.render(f"| Issued swordsmen: {player1.count_sword}", True, (255, 0, 255))
+ workers_in_training_1 = DEFAULT_FONT.render(f" | Issued workers: {player1.count_workers}", True, (255, 0, 255))
+ player1_resource_label = RESOURCE_FONT.render(f"Resource: {player1.player_resource}", True, (255, 0, 0))
+ tot_soldiers_p1_label = DEFAULT_FONT.render(f"Total number of soldiers: {player1.total_soldiers}",
+ 1, (0, 0, 0))
+ screen.blit(player1_resource_label, (10, 5))
+ screen.blit(ready_archers_label_1, (10, 35))
+ screen.blit(ready_swordsmen_label_1, (ready_archers_label_1.get_width() + 15, 35))
+ screen.blit(archers_in_training_1, (10, 45))
+ screen.blit(swordsmen_in_training_1, (archers_in_training_1.get_width() + 15, 45))
+ screen.blit(ready_workers_label_1,
+ (ready_archers_label_1.get_width() + ready_swordsmen_label_1.get_width() + 15, 35))
+ screen.blit(workers_in_training_1,
+ (archers_in_training_1.get_width() + swordsmen_in_training_1.get_width() + 15, 45))
+ screen.blit(tot_soldiers_p1_label, (10, 60))
+ # player 2 labels
+ ready_archers_label_2 = DEFAULT_FONT.render(f"Ready Archers: {player2.num_archer}", True, (255, 0, 255))
+ ready_swordsmen_label_2 = DEFAULT_FONT.render(f"| Ready Swordsmen: {player2.num_swordsmen}", True,
+ (255, 0, 255))
+ ready_workers_label_2 = DEFAULT_FONT.render(f" | Total Workers: {player2.num_workers}", True, (255, 0, 255))
+
+ archers_in_training_2 = DEFAULT_FONT.render(f"Issued archers: {player2.count_archer}", True, (255, 0, 255))
+ swordsmen_in_training_2 = DEFAULT_FONT.render(f"| Issued swordsmen: {player2.count_sword}", True, (255, 0, 255))
+ workers_in_training_2 = DEFAULT_FONT.render(f" | Issued workers: {player2.count_workers}", True, (255, 0, 255))
+
+ player2_resource_label = RESOURCE_FONT.render(f"Resource: {player2.player_resource}", True, (255, 0, 0))
+ tot_soldiers_p2_label = DEFAULT_FONT.render(f"Total number of soldiers: {player2.total_soldiers}",
+ 1, (0, 0, 0))
+ screen.blit(player2_resource_label, (SCREEN_WIDTH - player2_resource_label.get_width(), 5))
+ screen.blit(ready_archers_label_2, (
+ SCREEN_WIDTH - ready_archers_label_2.get_width() - ready_swordsmen_label_2.get_width() - ready_workers_label_2.get_width() - 20,
+ 35))
+ screen.blit(ready_swordsmen_label_2,
+ (SCREEN_WIDTH - ready_archers_label_2.get_width() - ready_swordsmen_label_2.get_width() - 20, 35))
+ screen.blit(ready_workers_label_2, (SCREEN_WIDTH - ready_archers_label_2.get_width() - 20, 35))
+ screen.blit(archers_in_training_2, (
+ SCREEN_WIDTH - archers_in_training_2.get_width() - swordsmen_in_training_2.get_width() - workers_in_training_2.get_width() - 10,
+ 45))
+ screen.blit(swordsmen_in_training_2,
+ (SCREEN_WIDTH - archers_in_training_2.get_width() - swordsmen_in_training_2.get_width() - 20, 45))
+ screen.blit(workers_in_training_2, (SCREEN_WIDTH - archers_in_training_2.get_width() - 20, 45))
+ screen.blit(tot_soldiers_p2_label, (SCREEN_WIDTH - tot_soldiers_p2_label.get_width() - 5, 60))
+
+ player1.draw(screen)
+ player2.draw(screen)
+ if game_over:
+ game_over_label = GAME_OVER_FONT.render(f"{winner} player wins", True, (0, 0, 0))
+ game_over_label_rect = game_over_label.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 3))
+ screen.blit(game_over_label, game_over_label_rect)
+ press_any_key_label = PRESS_ANY_KEY_FONT.render("Press any key to start over", True, (0, 0, 0))
+ press_any_keyRect = press_any_key_label.get_rect(center=(SCREEN_WIDTH // 2, (SCREEN_HEIGHT // 3) + 50))
+ screen.blit(press_any_key_label, press_any_keyRect)
+ if pause:
+ pause_label = PRESS_ANY_KEY_FONT.render(f"Game has been pause, press space to resume o R to restart", True,
+ (0, 100, 0))
+ pause_label_rect = pause_label.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 3))
+ screen.blit(pause_label, pause_label_rect)
+
+ pg.display.update()
diff --git a/main.py b/main.py
index 97ff754..bc0bd8f 100644
--- a/main.py
+++ b/main.py
@@ -1,55 +1,85 @@
-import time
+import sys
import pygame as pg
-import random
-from objects.players.Archer import Archer
+from implementable import Functions
+from implementable.Functions import redraw_window
+from objects.Constants import SCREEN_WIDTH, SCREEN_HEIGHT, PLAYER1_KEY_COMMANDS, PLAYER2_KEY_COMMANDS
+from objects.Inputs import Inputs
+from objects.players.Player import Player
-WIDTH, HEIGHT = 1000, 250
+pg.init()
-INITIAL_RESOURCE = 1000
-
-screen = pg.display.set_mode((WIDTH, HEIGHT))
+screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pg.time.Clock()
-BG = pg.transform.scale(pg.image.load("sprites/background/BG.jpg"), (WIDTH, HEIGHT))
+
+player1, player2 = None, None
def main():
- archers = []
+ global player1, player2
+ game_over = False
+ restarted = False
+ winner = None
+ pause = False
- player1_resource = INITIAL_RESOURCE
- player2_resource = INITIAL_RESOURCE
+ player1_inputs = Inputs(PLAYER1_KEY_COMMANDS)
+ player2_inputs = Inputs(PLAYER2_KEY_COMMANDS)
- def redraw_window():
- screen.blit(BG, (0, 0))
+ player1 = Player("p1", player1_inputs)
+ player2 = Player("p2", player2_inputs)
- for archer in archers:
- archer.draw(screen)
+ player1.opponent = player2
+ player2.opponent = player1
- pg.display.update()
+ loop = True
- loop = 1
while loop:
- clock.tick(10)
- redraw_window()
- keys = pg.key.get_pressed()
-
- if keys[pg.K_t]:
- archer = Archer(100, random.randrange(10, 30), 165, False, screen)
- player1_resource -= archer.COST
- archers.append(archer)
- if keys[pg.K_d]:
- for archer in archers:
- archer.deploy = True
+
+ clock.tick(60)
+ redraw_window(player1, player2, game_over, screen, winner, pause)
for event in pg.event.get():
- if event.type == pg.QUIT:
- loop = 0
- for archer in archers:
- if archer.deploy is True:
- archer.move()
- archer.update()
+ if event.type == pg.QUIT:
+ sys.exit()
+ if event.type == pg.KEYDOWN:
+ if not pause:
+ player1.key_events(event.key)
+ player2.key_events(event.key)
+ if event.key == pg.K_SPACE:
+ pause = not pause
+ if event.key == pg.K_r and pause:
+ restarted = True
+ pause = False
+ if game_over and not restarted:
+ if event.type == pg.KEYDOWN:
+ restarted = True
+ game_over = False
+
+ if not game_over:
+ if restarted:
+ player1 = Player("p1", player1_inputs)
+ player2 = Player("p2", player2_inputs)
+ player1.opponent = player2
+ player2.opponent = player1
+ winner = None
+ restarted = False
+ elif not restarted and not pause:
+ game_over = player1.update(game_over)
+ game_over = player2.update(game_over)
+ elif pause:
+ pass
+
+ elif game_over:
+ player1.soldiers.clear()
+ player1.workers.clear()
+ player2.soldiers.clear()
+ player2.workers.clear()
+ if player1.castle.wall.health <= 0:
+ winner = "BLUE"
+ elif player2.castle.wall.health <= 0:
+ winner = "RED"
if __name__ == '__main__':
diff --git a/objects/Arrow.py b/objects/Arrow.py
index 31683a2..ddef91f 100644
--- a/objects/Arrow.py
+++ b/objects/Arrow.py
@@ -1,12 +1,49 @@
-from abc import abstractmethod, ABC
+import math
+import pygame as pg
-class Arrow(ABC):
- def __init__(self, arrow_speed, position_X, position_Y):
- self.arrow_speed = arrow_speed
- self.position_X = position_X
- self.position_Y = position_Y
- @abstractmethod
- def hit(self, position_X, position_Y, target_X, target_Y ):
- ...
\ No newline at end of file
+class Arrow:
+ SPEED = 5
+
+ def __init__(self, position_X, position_Y, image_map, player, angle):
+ self.shoot = False
+ self.x = position_X
+ self.y = position_Y
+ self.a_count = 0
+ self.speedX = self.SPEED * math.cos(angle) if player else -self.SPEED * math.cos(angle)
+ self.speedY = self.SPEED * math.sin(angle)
+ if angle == 0:
+ self.image_type = 'arrow_hor/arrowhor-'
+ elif 0 < angle <= ((math.pi / 2) - (math.pi / 6)):
+ self.image_type = 'arrow_diag/arrowdiag-'
+ else:
+ self.image_type = 'arrow_vert/arrowvert-'
+
+ self.animation = self.load_arrows(image_map['root'], image_map['extension'], 2)
+ self.image = self.animation[0]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def load_arrows(self, img_root, img_extension, num_img):
+ images = {}
+ for i in range(num_img):
+ self.image = pg.image.load(img_root + self.image_type + str(i) + img_extension)
+ images[i] = self.image
+ return images
+
+ def update_arrow(self):
+ self.a_count += 0.2
+ if self.a_count >= 1:
+ self.a_count = 0
+ self.image = self.animation[int(self.a_count)]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def move_arrow(self):
+ self.update_arrow()
+ if self.shoot:
+ self.x += self.speedX
+ self.y += self.speedY
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def draw_arrows(self, screen):
+ screen.blit(self.image, self.rect)
diff --git a/objects/Barracks.py b/objects/Barracks.py
new file mode 100644
index 0000000..d60de3b
--- /dev/null
+++ b/objects/Barracks.py
@@ -0,0 +1,10 @@
+from objects.Constants import SCREEN_HEIGHT, GROUND_HEIGHT
+
+
+class Barracks:
+ def __init__(self, img, barrack_x):
+ self.img = img
+ self.rect = self.img.get_rect(midbottom=(barrack_x, SCREEN_HEIGHT - GROUND_HEIGHT))
+
+ def draw(self, screen):
+ screen.blit(self.img, self.rect)
diff --git a/objects/Castle.py b/objects/Castle.py
new file mode 100644
index 0000000..1ff98f5
--- /dev/null
+++ b/objects/Castle.py
@@ -0,0 +1,28 @@
+from objects.Barracks import Barracks
+from objects.Constants import WALL_POS, BARRACKS_POS, MINE_POS, SCREEN_WIDTH, P1_SPRITES, P2_SPRITES
+from objects.Mine import Mine
+from objects.Tower import Tower
+from objects.Wall import Wall
+
+
+class Castle:
+ def __init__(self, player):
+ wall_x = WALL_POS if player.player_type == "p1" else SCREEN_WIDTH - WALL_POS
+ barracks_x = BARRACKS_POS if player.player_type == "p1" else SCREEN_WIDTH - BARRACKS_POS
+ mine_x = MINE_POS if player.player_type == "p1" else SCREEN_WIDTH - MINE_POS
+ tower_x = WALL_POS if player.player_type == "p1" else SCREEN_WIDTH - WALL_POS
+ building_sprites = P1_SPRITES if player.player_type == "p1" else P2_SPRITES
+
+ self.wall = Wall(building_sprites['building']['wall'], wall_x)
+ self.barracks = Barracks(building_sprites['building']['barracks'], barracks_x)
+ self.mine = Mine(building_sprites['building']['mine'], mine_x)
+ self.tower = Tower(building_sprites['building']['tower'], tower_x, player.player_type)
+
+ def update(self, target):
+ self.tower.update(target)
+
+ def draw(self, screen):
+ self.mine.draw(screen)
+ self.barracks.draw(screen)
+ self.tower.draw(screen)
+ self.wall.draw(screen)
diff --git a/objects/Constants.py b/objects/Constants.py
new file mode 100644
index 0000000..6932d6b
--- /dev/null
+++ b/objects/Constants.py
@@ -0,0 +1,95 @@
+import pygame
+
+pygame.init()
+
+PLAYER_START_RESOURCES = 100
+
+PLAYER1_KEY_COMMANDS = {
+ "worker_train": "q",
+ "sword_train": "w",
+ "archer_train": "e",
+ "to_mine": "a",
+ "to_wall": "s",
+ "sword_attack": "d",
+ "archer_attack": "f",
+ "unleash": "z"
+}
+
+PLAYER2_KEY_COMMANDS = {
+ "worker_train": "p",
+ "sword_train": "o",
+ "archer_train": "i",
+ "to_mine": "l",
+ "to_wall": "k",
+ "sword_attack": "j",
+ "archer_attack": "h",
+ "unleash": "m"
+}
+
+# ARCHER CONTANTS
+ARCHER_COST = 5
+ARCHER_TRAIN = 2
+ARCHER_SPEED = 2
+ARCHER_DAMAGE = 20
+ARCHER_RANGE = 100
+ARCHER_REST = 2
+ARCHER_HEALTH = 100
+
+# SWORD CONTANTS
+SWORD_COST = 5
+SWORD_TRAIN = 2
+SWORD_SPEED = 2
+SWORD_DAMAGE = 20
+SWORD_RANGE = 10
+SWORD_REST = 2
+
+# WORKER CONTANTS
+WORKER_COST = 5
+WORKER_TRAIN = 2
+WORKER_SPEED = 1
+WORKER_PROD = 3
+WORKER_REPAIR = 10
+
+# GLOBAL
+SCREEN_WIDTH = 1000
+SCREEN_HEIGHT = 300
+GROUND_HEIGHT = 70
+WALL_POS = 180
+WALL_WIDTH = 62
+WALL_HEIGHT = 80
+WALL_HEALTH = 1000
+MINE_POS = 40
+MINE_WIDTH = 58
+MINE_HEIGHT = 37
+BARRACKS_POS = 106
+BARRACKS_WIDTH = 62
+BARRACKS_HEIGHT = 50
+TOWER_HEIGHT = 160
+
+# SPRITE MAPS
+
+P1_SPRITES = {"building":
+ {
+ "barracks": pygame.image.load("./sprites/player1/building/barracks.png"),
+ "mine": pygame.image.load("./sprites/player1/building/mine.png"),
+ "tower": pygame.image.load("./sprites/player1/building/tower.png"),
+ "wall": pygame.image.load("./sprites/player1/building/wall.png")
+ }
+}
+
+P2_SPRITES = {"building":
+ {
+ "barracks": pygame.image.load("./sprites/player2/building/barracks.png"),
+ "mine": pygame.image.load("./sprites/player2/building/mine.png"),
+ "tower": pygame.image.load("./sprites/player2/building/tower.png"),
+ "wall": pygame.image.load("./sprites/player2/building/wall.png")
+ }
+}
+
+BG = pygame.transform.scale(pygame.image.load("sprites/background/BG.jpg"), (SCREEN_WIDTH, SCREEN_HEIGHT))
+
+# Fonts
+DEFAULT_FONT = pygame.font.SysFont("comicsans", 12)
+RESOURCE_FONT = pygame.font.SysFont("comicsans", 20)
+GAME_OVER_FONT = pygame.font.Font('font/pixel.ttf', 40)
+PRESS_ANY_KEY_FONT = pygame.font.Font('font/pixel.ttf', 25)
\ No newline at end of file
diff --git a/objects/GameObject.py b/objects/GameObject.py
deleted file mode 100644
index dd673e2..0000000
--- a/objects/GameObject.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from abc import (
- ABC,
- abstractmethod
-)
-
-import pygame as pg
-
-
-class GameObject(ABC):
- def __init__(self, health, x, y):
- super().__init__()
- self.health = health
- self.x = x
- self.y = y
diff --git a/objects/Inputs.py b/objects/Inputs.py
new file mode 100644
index 0000000..dfa214a
--- /dev/null
+++ b/objects/Inputs.py
@@ -0,0 +1,13 @@
+import pygame as pg
+
+
+class Inputs:
+ def __init__(self, inputs):
+ self.worker_train_key = pg.key.key_code(inputs['worker_train'])
+ self.sword_train_key = pg.key.key_code(inputs['sword_train'])
+ self.archer_train_key = pg.key.key_code(inputs['archer_train'])
+ self.to_mine_key = pg.key.key_code(inputs['to_mine'])
+ self.to_wall_key = pg.key.key_code(inputs['to_wall'])
+ self.sword_attack_key = pg.key.key_code(inputs['sword_attack'])
+ self.archer_attack_key = pg.key.key_code(inputs['archer_attack'])
+ self.unleash_key = pg.key.key_code(inputs['unleash'])
diff --git a/objects/Mine.py b/objects/Mine.py
new file mode 100644
index 0000000..6eb46d2
--- /dev/null
+++ b/objects/Mine.py
@@ -0,0 +1,10 @@
+from objects.Constants import SCREEN_HEIGHT, GROUND_HEIGHT
+
+
+class Mine:
+ def __init__(self, img, mine_x):
+ self.img = img
+ self.rect = self.img.get_rect(midbottom=(mine_x, SCREEN_HEIGHT - GROUND_HEIGHT))
+
+ def draw(self, screen):
+ screen.blit(self.img, self.rect)
diff --git a/objects/PlayerArrow.py b/objects/PlayerArrow.py
deleted file mode 100644
index f1c2b23..0000000
--- a/objects/PlayerArrow.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from objects.Arrow import Arrow
-
-
-class PlayerArrow(Arrow):
- def hit(self, x, y, t_X, t_Y):
- ...
-
diff --git a/objects/Tower.py b/objects/Tower.py
new file mode 100644
index 0000000..ac7008e
--- /dev/null
+++ b/objects/Tower.py
@@ -0,0 +1,67 @@
+import math
+import time
+
+import pygame as pg
+
+from objects.Arrow import Arrow
+from objects.Constants import GROUND_HEIGHT, SCREEN_HEIGHT
+
+
+class Tower:
+ RANGE = 200
+ TOWER_HIT = 10
+ TOWER_REST = 1
+
+ PLAYER1_ARROW = {"root": f"sprites/player1/bow/", "extension": ".png"}
+ PLAYER2_ARROW = {"root": f"sprites/player2/bow/", "extension": ".png"}
+
+ def __init__(self, img, tower_x, player_type):
+ self.start_action = 0
+ self.current_time = 0
+ self.target_unit = None
+ self.img = img
+ self.player_type = True if player_type == "p1" else False
+ self.rect = self.img.get_rect(midbottom=(tower_x, SCREEN_HEIGHT - GROUND_HEIGHT))
+ self.arrows = []
+ self.resting = True
+ self.attacking = False
+
+ self.range = pg.Rect(0, 0, self.rect.w + (self.RANGE * 2), self.rect.h)
+ self.range.midbottom = self.rect.midbottom
+
+ def update(self, target):
+ if self.attacking and not self.resting:
+ if self.rest(1):
+ x = abs(self.rect.centerx - target.rect.centerx)
+ y = target.rect.centery - self.rect.top
+ arrow_angle = math.atan(y / x)
+ arrow = Arrow(self.rect.centerx, self.rect.top,
+ self.PLAYER1_ARROW if self.player_type else self.PLAYER2_ARROW,
+ self.player_type, arrow_angle)
+ arrow.shoot = True
+ self.start_action = time.time()
+ self.arrows.append(arrow)
+
+ self.move_arrows(target)
+
+ def rest(self, rest_amount):
+ if rest_amount > (self.current_time - self.start_action):
+ self.current_time = time.time()
+ return False
+ else:
+ return True
+
+ def move_arrows(self, obj):
+ self.target_unit = obj
+ for i, arrow in enumerate(self.arrows):
+ arrow.move_arrow()
+ if arrow.rect.colliderect(obj.rect) and self.arrows:
+ obj.health -= self.TOWER_HIT
+ del self.arrows[i]
+ if arrow.y > SCREEN_HEIGHT - GROUND_HEIGHT:
+ del self.arrows[i]
+
+ def draw(self, screen):
+ screen.blit(self.img, self.rect)
+ for arrow in self.arrows:
+ arrow.draw_arrows(screen)
diff --git a/objects/Wall.py b/objects/Wall.py
new file mode 100644
index 0000000..9cda9f5
--- /dev/null
+++ b/objects/Wall.py
@@ -0,0 +1,30 @@
+import pygame as pg
+
+from objects.Constants import GROUND_HEIGHT, SCREEN_HEIGHT, WALL_HEALTH
+
+
+class Wall:
+ MAX_HEALTH = WALL_HEALTH
+
+ def __init__(self, img, wall_x):
+ self.img = img
+ self.x = wall_x
+ self.rect = self.img.get_rect(midbottom=(wall_x, SCREEN_HEIGHT - GROUND_HEIGHT))
+ self.health = self.MAX_HEALTH
+ self.dead = self.health <= 0
+ self.hb_width = 50
+
+ def draw_health_bar(self, screen):
+ red_hb_rect = pg.Rect(0, 0, self.hb_width, 6)
+ red_hb_rect.center = (self.rect.centerx, (self.rect.top // 2) - 15)
+ pg.draw.rect(screen, (255, 0, 0), red_hb_rect)
+
+ green_hb_rect = pg.Rect(0, 0, self.hb_width * (self.health / self.MAX_HEALTH), 6)
+ green_hb_rect.topleft = red_hb_rect.topleft
+ pg.draw.rect(screen, (0, 255, 0), green_hb_rect)
+
+ def draw(self, screen):
+ screen.blit(self.img, self.rect)
+
+ if self.health < self.MAX_HEALTH:
+ self.draw_health_bar(screen)
diff --git a/objects/players/Archer.py b/objects/players/Archer.py
index 19b528f..b328a6a 100644
--- a/objects/players/Archer.py
+++ b/objects/players/Archer.py
@@ -1,42 +1,196 @@
-import os
+import random
+import time
+
import pygame as pg
-from objects.players.Player import Player
+from implementable import Functions
+from objects.Arrow import Arrow
+from objects.Constants import BARRACKS_POS, SCREEN_WIDTH, GROUND_HEIGHT, SCREEN_HEIGHT, ARCHER_SPEED, ARCHER_DAMAGE, \
+ ARCHER_TRAIN, ARCHER_RANGE, ARCHER_REST, ARCHER_COST, ARCHER_HEALTH
+from objects.Wall import Wall
-class Archer(Player, pg.sprite.Sprite):
+class Archer:
+ TRAIN_TIME = ARCHER_TRAIN
+ RANGE = ARCHER_RANGE
+ HIT_DAMAGE = ARCHER_DAMAGE
+ REST = ARCHER_REST
+ COST = ARCHER_COST
+ SPEED = ARCHER_SPEED
+ MAX_HEALTH = ARCHER_HEALTH
- TRAIN_TURNS = 3
- RANGE = 10
- HIT_DAMAGE = 3
- REST = 1
- COST = 3
- SPEED = 5
+ PLAYER1_READY = "sprites/player1/bow/ready.png"
+ PLAYER2_READY = "sprites/player2/bow/ready.png"
+ PLAYER1_RUN = {"root": "sprites/player1/bow/run/run-", "extension": ".png"}
+ PLAYER2_RUN = {"root": "sprites/player2/bow/run/run-", "extension": ".png"}
+ PLAYER1_SHOOT = {"root": "sprites/player1/bow/shoot/shoot-", "extension": ".png"}
+ PLAYER2_SHOOT = {"root": "sprites/player2/bow/shoot/shoot-", "extension": ".png"}
+ PLAYER1_FALLEN = {"root": "sprites/player1/bow/fallen/fallen-", "extension": ".png"}
+ PLAYER2_FALLEN = {"root": "sprites/player2/bow/fallen/fallen-", "extension": ".png"}
+ PLAYER1_ARROW = {"root": "sprites/player1/bow/", "extension": ".png"}
+ PLAYER2_ARROW = {"root": "sprites/player2/bow/", "extension": ".png"}
- def __init__(self, health, x, y, deploy, screen):
- super().__init__(health, x, y, deploy)
+ def __init__(self, player_type):
+ self.hb_width = 15
+ self.target_unit = None
+ self.animation = None
+ self.deploy = False
+ self.ready_to_dispatch = False
+ self.health = Archer.MAX_HEALTH
+ self.falling = False
+ self.run = False
+ self.wait = True
+ self.dead = False
+ self.enemy_killed = False
self.a_count = 0
- self.deploy = deploy
- self.animation = self.loadImage()
- self.rect = self.image.get_rect()
- self.draw(screen)
-
- def loadImage(self):
- images = {}
- for i in range(11):
- print(str(i))
- self.image = pg.image.load("sprites/player1/bow/run/run-" + str(i) + ".png")
- images[i] = self.image
- return images
+ self.x = BARRACKS_POS if player_type == "p1" else SCREEN_WIDTH - BARRACKS_POS
+ self.y = SCREEN_HEIGHT - GROUND_HEIGHT
+ self.image = pg.image.load(Archer.PLAYER1_READY if player_type == "p1" else Archer.PLAYER2_READY)
+ self.current_time = 0
+ self.start_action = 0
+ self.shooting = False
+ self.added = False
+ self.player_type = player_type
+ self.arrows = []
+
+ self.start_time = time.time()
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ self.range = pg.Rect(0, 0, self.rect.w + (self.RANGE * 2), self.rect.h)
+ self.range.midbottom = self.rect.midbottom
+
+ def load_run(self):
+ if self.run:
+ match self.player_type:
+ case "p1":
+ self.animation = Functions.loadImage(self.PLAYER1_RUN, 11, False)
+ case "p2":
+ self.animation = Functions.loadImage(self.PLAYER2_RUN, 11, False)
+
+ def ready_to_shoot(self):
+ if not self.falling and not self.dead:
+ if not self.run and not self.shooting:
+ self.start_action = time.time()
+ match self.player_type:
+ case "p1":
+ self.image = pg.image.load(self.PLAYER1_READY)
+ if not self.shooting:
+ self.shooting = True
+ self.a_count = 0
+ self.load_shoot(self.PLAYER1_SHOOT)
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ case "p2":
+ self.image = pg.image.load(self.PLAYER2_READY)
+ if not self.shooting:
+ self.shooting = True
+ self.a_count = 0
+ self.load_shoot(self.PLAYER2_SHOOT)
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def load_dead(self):
+ if self.falling:
+ match self.player_type:
+ case "p1":
+ self.animation = Functions.loadImage(self.PLAYER1_FALLEN, 6, False)
+
+ case "p2":
+ self.animation = Functions.loadImage(self.PLAYER2_FALLEN, 6, False)
def update(self):
- self.a_count += 1
- if self.a_count == len(self.animation):
- self.a_count = 0
- self.image = self.animation[self.a_count]
+ self.range.midbottom = self.rect.midbottom
+
+ if not self.dead:
+ if self.shooting and not self.falling and not self.run:
+ arrow = None
+ self.enemy_killed = False
+
+ if self.rest(self.REST):
+ match self.player_type:
+ case "p1":
+ arrow = Arrow(self.rect.right, self.rect.centery, self.PLAYER1_ARROW, True, 0)
+ case "p2":
+ arrow = Arrow(self.rect.left, self.rect.centery, self.PLAYER2_ARROW, False, 0)
+ arrow.shoot = True
+ self.arrows.append(arrow)
+ self.a_count = 1
+ self.image = self.animation[self.a_count]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ self.start_action = time.time()
+ elif self.rest(random.randint(1, 10) * 0.1):
+ self.a_count = 0
+ self.image = self.animation[self.a_count]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ else:
+ self.image = self.animation[int(self.a_count)]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ if not self.falling:
+ self.a_count += 0.2
+ else:
+ self.a_count += 0.1
+ if self.a_count > len(self.animation):
+ self.a_count = 0
+ if self.falling and int(self.a_count) > 4:
+ self.dead = True
+ self.falling = False
+ if self.target_unit is not None and not isinstance(self.target_unit, Wall) and self.target_unit.dead:
+ self.shooting = False
+ self.load_run()
+ if self.rest(random.randint(1, 2)):
+ self.run = True
+ elif not self.enemy_killed and not self.run:
+ self.image = pg.image.load(
+ Archer.PLAYER1_READY if self.player_type == "p1" else Archer.PLAYER2_READY)
def draw(self, screen):
- screen.blit(self.image, (self.x, self.y))
+ screen.blit(self.image, self.rect)
+ for arrow in self.arrows:
+ arrow.draw_arrows(screen)
+ if not self.dead and self.health < self.MAX_HEALTH:
+ self.draw_health_bar(screen)
def move(self):
- self.x += self.SPEED
+ if self.run:
+ match self.player_type:
+ case "p1":
+ self.x += Archer.SPEED
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ case "p2":
+ self.x -= Archer.SPEED
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def move_arrows(self, obj):
+ self.target_unit = obj
+ for i, arrow in enumerate(self.arrows):
+ arrow.move_arrow()
+ if arrow.rect.colliderect(obj.rect) and self.arrows and obj.health > 0:
+ obj.health -= self.HIT_DAMAGE
+ del self.arrows[i]
+ elif obj.health <= 0:
+ self.enemy_killed = True
+ del self.arrows[i]
+
+ def load_shoot(self, image_map):
+ self.animation = Functions.loadImage(image_map, 2, False)
+
+ def rest(self, rest_amount):
+ if rest_amount > (self.current_time - self.start_action):
+ self.current_time = time.time()
+ return False
+ else:
+ return True
+
+ def train(self):
+ if round(self.current_time - self.start_time) < self.TRAIN_TIME:
+ self.current_time = time.time()
+ else:
+ self.ready_to_dispatch = True
+
+ def draw_health_bar(self, screen):
+ red_hb_rect = pg.Rect(self.x, self.y - 5, self.hb_width, 3)
+ red_hb_rect.center = (self.x, self.y - self.rect.h - 5)
+ pg.draw.rect(screen, (255, 0, 0), red_hb_rect)
+
+ green_hb_rect = pg.Rect(self.x, self.y - 5, self.hb_width * (self.health / self.MAX_HEALTH), 3)
+ green_hb_rect.topleft = red_hb_rect.topleft
+ pg.draw.rect(screen, (0, 255, 0), green_hb_rect)
diff --git a/objects/players/Player.py b/objects/players/Player.py
index 4a988a6..d6bd91b 100644
--- a/objects/players/Player.py
+++ b/objects/players/Player.py
@@ -1,15 +1,161 @@
-import os
-from glob import glob
-import pygame as pg
+import time
-from objects.GameObject import GameObject
+from implementable import Functions
+from objects.Castle import Castle
+from objects.Constants import *
+from objects.Wall import Wall
-class Player(GameObject):
- def __init__(self, health, x, y, deploy):
- super().__init__(health, x, y)
- self.deploy = deploy
+class Player:
+ def __init__(self, player_type, keys):
+ self.to_wall = False
+ self.to_mine = False
+ self.targeted_unit = None
+ self.total_soldiers = 0
+ self.deploy_all = False
+ self.total_archer = 0
+ self.swordsmen = []
+ self.archers = []
+ self.worker_index = 0
+ self.num_workers = 0
+ self.start_action = 0
+ self.current_time = 0
+ self.total_swords = 0
+ self.swordsman_index = 0
+ self.num_swordsmen = 0
+ self.archer_index = 0
+ self.num_archer = 0
+ self.count_sword = 0
+ self.count_archer = 0
+ self.count_workers = 0
+ self.image = None
+ self.keys = keys
+ self.player_type = player_type
+ self.castle = Castle(self)
+ self.player_resource = PLAYER_START_RESOURCES
+ self.a_count = 0
+ self.soldiers = []
+ self.workers = []
+ self.opponent = None
+ def choose_target(self):
+ alive_soldiers = [soldier for soldier in self.opponent.soldiers if not soldier.dead]
+ if alive_soldiers:
+ selected_target = min(alive_soldiers, key=lambda unit: abs(self.castle.wall.rect.x - unit.x))
+ self.targeted_unit = selected_target if WALL_POS <= selected_target.rect.centerx <= SCREEN_WIDTH - WALL_POS else self.opponent.castle.wall
+ else:
+ self.targeted_unit = self.opponent.castle.wall
+ def key_events(self, key):
+ if key == self.keys.archer_train_key:
+ if self.player_resource > 0:
+ self.player_resource -= ARCHER_COST
+ self.count_archer += 1
+ else:
+ self.player_resource = 0
+ if key == self.keys.sword_train_key:
+ if self.player_resource > 0:
+ self.player_resource -= SWORD_COST
+ self.count_sword += 1
+ else:
+ self.player_resource = 0
+
+ if key == self.keys.archer_attack_key:
+ if self.num_archer > 0:
+ self.archer_index, self.num_archer = Functions.attack(self.archers, self.archer_index, self.num_archer)
+
+ if key == self.keys.sword_attack_key:
+ if self.num_swordsmen > 0:
+ self.swordsman_index, self.num_swordsmen = Functions.attack(self.swordsmen, self.swordsman_index,
+ self.num_swordsmen)
+
+ if key == self.keys.worker_train_key:
+ if self.player_resource > 0:
+ self.player_resource -= WORKER_COST
+ self.count_workers += 1
+ else:
+ self.player_resource = 0
+
+ if key == self.keys.to_mine_key:
+ self.to_mine = True
+ if key == self.keys.to_wall_key:
+ self.to_wall = True
+ if key == self.keys.unleash_key:
+ self.deploy_all = True
+ self.num_archer = 0
+ self.num_swordsmen = 0
+
+ def update(self, game_over):
+ self.choose_target()
+
+ Functions.add_to_queue(self.soldiers, self.archers, self.count_archer,
+ "a_p1" if self.player_type == "p1" else "a_p2")
+ self.num_archer, self.count_archer, self.total_archer = Functions.check_added(self.archers, self.num_archer,
+ self.count_archer,
+ self.total_soldiers)
+ Functions.add_to_queue(self.soldiers, self.swordsmen, self.count_sword,
+ "s_p1" if self.player_type == "p1" else "s_p2")
+ self.num_swordsmen, self.count_sword, self.total_swords = Functions.check_added(self.swordsmen,
+ self.num_swordsmen,
+ self.count_sword,
+ self.total_soldiers)
+ Functions.add_to_queue(self, self.workers, self.count_workers, "w_p1" if self.player_type == "p1" else "w_p2")
+ self.num_workers, self.count_workers, NoneType = Functions.check_added(self.workers,
+ self.num_workers,
+ self.count_workers,
+ None)
+
+ if self.count_archer <= 0:
+ self.count_archer = 0
+ if self.count_sword <= 0:
+ self.count_sword = 0
+ if self.count_workers <= 0:
+ self.count_workers = 0
+
+ if self.opponent.castle.wall.health <= 0:
+ game_over = True
+ if self.castle.wall.health <= Wall.MAX_HEALTH / 2:
+ self.to_wall = True
+
+ self.total_soldiers = len(self.soldiers)
+
+ if self.deploy_all:
+ if self.rest(0.3):
+ self.start_action = time.time()
+ self.archer_index, self.num_archer = Functions.attack(self.archers, self.archer_index, self.num_archer)
+ self.swordsman_index, self.num_swordsmen = Functions.attack(self.swordsmen, self.swordsman_index,
+ self.num_swordsmen)
+ self.deploy_all = Functions.deploy_all(self.soldiers)
+
+ if self.to_mine:
+ Functions.run_to_mine(self.workers)
+ self.to_mine = Functions.at_mine(self.workers)
+ elif self.to_wall:
+ Functions.run_to_wall(self.workers)
+ self.to_wall = Functions.at_wall(self.workers)
+
+ Functions.training(self.soldiers)
+ Functions.training(self.workers)
+ Functions.collide(self.soldiers, self.targeted_unit)
+ Functions.deploy(self.soldiers)
+ Functions.deploy(self.workers)
+ Functions.check_health(self.soldiers)
+ Functions.check_dead(self.soldiers)
+ Functions.tower_collide(self.castle.tower, self.targeted_unit)
+ Functions.check_worker_action(self.workers)
+ self.castle.update(self.targeted_unit)
+ return game_over
+
+ def draw(self, screen):
+ self.castle.draw(screen)
+ Functions.draw(self.soldiers, screen)
+ Functions.draw(self.workers, screen)
+
+ def rest(self, rest_amount):
+ if rest_amount > (self.current_time - self.start_action):
+ self.current_time = time.time()
+ return False
+ else:
+ return True
diff --git a/objects/players/SwordMan.py b/objects/players/SwordMan.py
deleted file mode 100644
index aa4a108..0000000
--- a/objects/players/SwordMan.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from objects.players.Player import Player
-
-
-class SwordMan(Player):
- def __init__(self, health, x, train_turns, speed, range, hit_damage, rest, cost, resource, deploy):
- super().__init__(health, x, train_turns, speed, range, hit_damage, rest, cost, resource, deploy)
-
-
-
-
diff --git a/objects/players/SwordsMan.py b/objects/players/SwordsMan.py
new file mode 100644
index 0000000..402e2e2
--- /dev/null
+++ b/objects/players/SwordsMan.py
@@ -0,0 +1,160 @@
+import time
+
+import pygame as pg
+
+from implementable import Functions
+from objects.Constants import BARRACKS_POS, SCREEN_WIDTH, GROUND_HEIGHT, SCREEN_HEIGHT, SWORD_RANGE, SWORD_TRAIN, \
+ SWORD_DAMAGE, SWORD_REST, SWORD_COST, SWORD_SPEED
+from objects.Wall import Wall
+
+
+class SwordsMan:
+ TRAIN_TURNS = SWORD_TRAIN
+ RANGE = SWORD_RANGE
+ HIT_DAMAGE = SWORD_DAMAGE
+ REST = SWORD_REST
+ COST = SWORD_COST
+ SPEED = SWORD_SPEED
+ MAX_HEALTH = 100
+ PLAYER1_READY = "sprites/player1/sword/ready.png"
+ PLAYER2_READY = "sprites/player2/sword/ready.png"
+ PLAYER1_RUN = {"root": "sprites/player1/sword/run/run-", "extension": ".png"}
+ PLAYER2_RUN = {"root": "sprites/player2/sword/run/run-", "extension": ".png"}
+ PLAYER1_SHOOT = {"root": "sprites/player1/sword/attack/attack-", "extension": ".png"}
+ PLAYER2_SHOOT = {"root": "sprites/player2/sword/attack/attack-", "extension": ".png"}
+ PLAYER1_FALLEN = {"root": "sprites/player1/sword/fallen/fallen-", "extension": ".png"}
+ PLAYER2_FALLEN = {"root": "sprites/player2/sword/fallen/fallen-", "extension": ".png"}
+
+ def __init__(self, player_type):
+ self.hb_width = 15
+ self.animation = None
+ self.deploy = False
+ self.ready_to_dispatch = False
+ self.health = 100
+ self.falling = False
+ self.run = False
+ self.dead = False
+ self.wait = True
+ self.a_count = 0
+ self.x = BARRACKS_POS if player_type == "p1" else SCREEN_WIDTH - BARRACKS_POS
+ self.y = SCREEN_HEIGHT - GROUND_HEIGHT
+ self.image = pg.image.load(SwordsMan.PLAYER1_READY if player_type == "p1" else SwordsMan.PLAYER2_READY)
+ self.current_time = 0
+ self.start_action = 0
+ self.attacking = False
+ self.added = False
+ self.player_type = player_type
+ self.target_unit = None
+
+ self.start_time = time.time()
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ self.range = pg.Rect(0, 0, self.rect.w + (self.RANGE * 2), self.rect.h)
+ self.range.midbottom = self.rect.midbottom
+
+ def load_run(self):
+ if self.run:
+ match self.player_type:
+ case "p1":
+ self.animation = Functions.loadImage(self.PLAYER1_RUN, 11, False)
+
+ case "p2":
+ self.animation = Functions.loadImage(self.PLAYER2_RUN, 11, False)
+
+ def attack(self):
+ if not self.falling and not self.dead:
+ if not self.run and not self.attacking:
+ self.start_action = 0
+ match self.player_type:
+ case "p1":
+ self.image = pg.image.load(self.PLAYER1_READY)
+ if not self.attacking:
+ self.attacking = True
+ self.a_count = 0
+ self.load_attack(self.PLAYER1_SHOOT)
+ case "p2":
+ self.image = pg.image.load(self.PLAYER2_READY)
+ if not self.attacking:
+ self.attacking = True
+ self.a_count = 0
+ self.load_attack(self.PLAYER2_SHOOT)
+
+ def load_attack(self, image_map):
+ self.animation = Functions.loadImage(image_map, 8, False)
+
+ def load_dead(self):
+ if self.falling:
+ match self.player_type:
+ case "p1":
+ self.animation = Functions.loadImage(self.PLAYER1_FALLEN, 6, False)
+
+ case "p2":
+ self.animation = Functions.loadImage(self.PLAYER2_FALLEN, 6, False)
+
+ def update(self):
+ self.range.midbottom = self.rect.midbottom
+ if not self.dead:
+
+ if self.attacking and self.target_unit.health > 0 and self.a_count >= 6 and not self.run:
+ if self.rest(1):
+ self.target_unit.health -= SwordsMan.HIT_DAMAGE
+ self.a_count = 0
+ self.start_action = time.time()
+
+ else:
+ if self.a_count > len(self.animation):
+ self.a_count = 0
+ if self.falling and int(self.a_count) > 4:
+ self.falling = False
+ self.dead = True
+ self.run = False
+
+ self.image = self.animation[int(self.a_count)]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ if not self.falling:
+ self.a_count += 0.2
+ else:
+ self.a_count += 0.1
+ if self.target_unit is not None and not isinstance(self.target_unit, Wall) and self.target_unit.dead:
+ self.run = True
+ self.attacking = False
+ self.load_run()
+
+ def draw_health_bar(self, screen):
+ red_hb_rect = pg.Rect(self.x, self.y - 5, self.hb_width, 3)
+ red_hb_rect.center = (self.x, self.y - self.rect.h - 5)
+ pg.draw.rect(screen, (255, 0, 0), red_hb_rect)
+
+ green_hb_rect = pg.Rect(self.x, self.y - 5, self.hb_width * (self.health / self.MAX_HEALTH), 3)
+ green_hb_rect.topleft = red_hb_rect.topleft
+ pg.draw.rect(screen, (0, 255, 0), green_hb_rect)
+
+ def draw(self, screen):
+ screen.blit(self.image, self.rect)
+
+ if not self.dead and self.health < self.MAX_HEALTH:
+ self.draw_health_bar(screen)
+
+ def move(self):
+ if self.run:
+ match self.player_type:
+ case "p1":
+ self.x += self.SPEED
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ case "p2":
+ self.x -= self.SPEED
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def train(self):
+ if round(self.current_time - self.start_time) < self.TRAIN_TURNS:
+ self.current_time = time.time()
+ else:
+ self.ready_to_dispatch = True
+
+ def rest(self, rest_amount):
+ if rest_amount > (self.current_time - self.start_action):
+ self.current_time = time.time()
+ return False
+ else:
+ return True
diff --git a/objects/players/Worker.py b/objects/players/Worker.py
new file mode 100644
index 0000000..568de54
--- /dev/null
+++ b/objects/players/Worker.py
@@ -0,0 +1,149 @@
+import time
+
+import pygame as pg
+
+from implementable import Functions
+from objects.Constants import WORKER_PROD, WORKER_REPAIR, WORKER_TRAIN, BARRACKS_POS, SCREEN_WIDTH, GROUND_HEIGHT, \
+ SCREEN_HEIGHT, WORKER_SPEED, WALL_HEALTH
+from objects.Wall import Wall
+
+
+class Worker:
+ PRODUCTION_RATE = WORKER_PROD
+ REPAIR_RATE = WORKER_REPAIR
+ TRAINING_TIME = WORKER_TRAIN
+ SPEED = WORKER_SPEED
+
+ PLAYER1_READY = "sprites/player1/worker/ready.png"
+ PLAYER2_READY = "sprites/player2/worker/ready.png"
+ PLAYER1_RUN = {"root": "sprites/player1/worker/run/run-", "extension": ".png"}
+ PLAYER2_RUN = {"root": "sprites/player2/worker/run/run-", "extension": ".png"}
+ PLAYER1_DIG = {"root": "sprites/player1/worker/dig/dig-", "extension": ".png"}
+ PLAYER2_DIG = {"root": "sprites/player2/worker/dig/dig-", "extension": ".png"}
+ PLAYER1_REPAIR = {"root": "sprites/player1/worker/repair/repair-", "extension": ".png"}
+ PLAYER2_REPAIR = {"root": "sprites/player2/worker/repair/repair-", "extension": ".png"}
+
+ def __init__(self, player):
+ self.production_rate = self.PRODUCTION_RATE
+ self.repair_rate = self.REPAIR_RATE
+ self.speed = Worker.SPEED
+ self.a_count = 0
+ self.start_action = 0
+ self.ready_to_dispatch = False
+ self.added = False
+ self.deploy = False
+ self.start_time = 0
+ self.current_time = 0
+ self.player = player
+ self.x = BARRACKS_POS if player.player_type == "p1" else SCREEN_WIDTH - BARRACKS_POS
+ self.y = SCREEN_HEIGHT - GROUND_HEIGHT
+ self.run = False
+ self.player_type = player.player_type
+ self.animation = None
+ self.image = pg.image.load(Worker.PLAYER1_READY if self.player_type == "p1" else Worker.PLAYER2_READY)
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+ self.run_to_mine = False
+ self.run_to_wall = False
+ self.digging = False
+ self.repairing = False
+ self.start_time = time.time()
+
+ def to_wall(self):
+ self.animation = Functions.loadImage(self.PLAYER1_RUN if self.player_type == "p1" else self.PLAYER2_RUN, 6,
+ False)
+ self.run = True
+ if self.player.castle.wall.rect.centerx > self.rect.centerx:
+ if self.speed < 0 and self.run_to_wall:
+ self.speed *= -1
+
+ elif self.player.castle.wall.rect.centerx < self.rect.centerx:
+ if self.speed < 0 and self.run_to_wall:
+ self.speed *= -1
+
+ def to_mine(self):
+ self.animation = Functions.loadImage(self.PLAYER1_RUN if self.player_type == "p1" else self.PLAYER2_RUN, 6,
+ True)
+ self.run = True
+ if self.player.castle.mine.rect.centerx < self.rect.centerx:
+ if self.speed > 0 and self.run_to_mine:
+ self.speed *= -1
+ elif self.speed < 0 and not self.run_to_mine:
+ self.speed *= -1
+
+ elif self.player.castle.mine.rect.centerx > self.rect.centerx:
+ if self.speed > 0 and self.run_to_mine:
+ self.speed *= -1
+ elif self.speed < 0 and not self.run_to_mine:
+ self.speed *= -1
+ def move(self):
+ if self.run:
+ match self.player_type:
+ case "p1":
+ self.x += self.speed
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ case "p2":
+ self.x -= self.speed
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def dig(self):
+ self.animation = Functions.loadImage(self.PLAYER1_DIG if self.player_type == "p1" else self.PLAYER2_DIG, 9,
+ True)
+
+ def repair(self):
+ self.animation = Functions.loadImage(self.PLAYER1_REPAIR if self.player_type == "p1" else self.PLAYER2_REPAIR,
+ 4,
+ False)
+
+ def update(self):
+
+ if self.rect.collidepoint(self.player.castle.mine.rect.centerx,
+ self.player.castle.mine.rect.centery) and not self.digging:
+ self.run = False
+ self.digging = True
+ self.repairing = False
+ self.run_to_mine = False
+
+ elif self.rect.colliderect(self.player.castle.wall.rect) and not self.repairing:
+ self.run = False
+ self.digging = False
+ self.repairing = True
+ self.run_to_wall = False
+
+ if self.digging and not self.run and self.a_count >= 8:
+ if self.rest(1):
+ self.player.player_resource += self.production_rate
+ self.a_count = 0
+ self.start_action = time.time()
+
+ elif self.repairing and not self.run and self.a_count >= 3:
+ if self.rest(1):
+ self.a_count = 0
+ if self.player.castle.wall.health < Wall.MAX_HEALTH:
+ self.player.castle.wall.health += self.repair_rate
+ self.start_action = time.time()
+ else:
+ if self.run:
+ self.a_count += 0.1
+ else:
+ self.a_count += 0.2
+ if self.a_count > len(self.animation):
+ self.a_count = 0
+ self.image = self.animation[int(self.a_count)]
+ self.rect = self.image.get_rect(midbottom=(self.x, self.y))
+
+ def draw(self, screen):
+ screen.blit(self.image, self.rect)
+
+ def train(self):
+ if round(self.current_time - self.start_time) < self.TRAINING_TIME:
+ self.current_time = time.time()
+ else:
+ self.ready_to_dispatch = True
+
+ def rest(self, rest_amount):
+ if rest_amount > (self.current_time - self.start_action):
+ self.current_time = time.time()
+ return False
+ else:
+ return True
diff --git a/sprites/player1/bow/arrowdiag-0.png b/sprites/player1/bow/arrow_diag/arrowdiag-0.png
similarity index 100%
rename from sprites/player1/bow/arrowdiag-0.png
rename to sprites/player1/bow/arrow_diag/arrowdiag-0.png
diff --git a/sprites/player1/bow/arrowdiag-1.png b/sprites/player1/bow/arrow_diag/arrowdiag-1.png
similarity index 100%
rename from sprites/player1/bow/arrowdiag-1.png
rename to sprites/player1/bow/arrow_diag/arrowdiag-1.png
diff --git a/sprites/player1/bow/arrowhor-0.png b/sprites/player1/bow/arrow_hor/arrowhor-0.png
similarity index 100%
rename from sprites/player1/bow/arrowhor-0.png
rename to sprites/player1/bow/arrow_hor/arrowhor-0.png
diff --git a/sprites/player1/bow/arrowhor-1.png b/sprites/player1/bow/arrow_hor/arrowhor-1.png
similarity index 100%
rename from sprites/player1/bow/arrowhor-1.png
rename to sprites/player1/bow/arrow_hor/arrowhor-1.png
diff --git a/sprites/player1/bow/arrowvert-0.png b/sprites/player1/bow/arrow_vert/arrowvert-0.png
similarity index 100%
rename from sprites/player1/bow/arrowvert-0.png
rename to sprites/player1/bow/arrow_vert/arrowvert-0.png
diff --git a/sprites/player1/bow/arrowvert-1.png b/sprites/player1/bow/arrow_vert/arrowvert-1.png
similarity index 100%
rename from sprites/player1/bow/arrowvert-1.png
rename to sprites/player1/bow/arrow_vert/arrowvert-1.png
diff --git a/sprites/player1/bow/fallen-2.png b/sprites/player1/bow/fallen/fallen-0.png
similarity index 100%
rename from sprites/player1/bow/fallen-2.png
rename to sprites/player1/bow/fallen/fallen-0.png
diff --git a/sprites/player1/bow/fallen-3.png b/sprites/player1/bow/fallen/fallen-1.png
similarity index 100%
rename from sprites/player1/bow/fallen-3.png
rename to sprites/player1/bow/fallen/fallen-1.png
diff --git a/sprites/player1/bow/fallen-0.png b/sprites/player1/bow/fallen/fallen-2.png
similarity index 100%
rename from sprites/player1/bow/fallen-0.png
rename to sprites/player1/bow/fallen/fallen-2.png
diff --git a/sprites/player1/bow/fallen-1.png b/sprites/player1/bow/fallen/fallen-3.png
similarity index 100%
rename from sprites/player1/bow/fallen-1.png
rename to sprites/player1/bow/fallen/fallen-3.png
diff --git a/sprites/player1/bow/fallen-4.png b/sprites/player1/bow/fallen/fallen-4.png
similarity index 100%
rename from sprites/player1/bow/fallen-4.png
rename to sprites/player1/bow/fallen/fallen-4.png
diff --git a/sprites/player1/bow/fallen-5.png b/sprites/player1/bow/fallen/fallen-5.png
similarity index 100%
rename from sprites/player1/bow/fallen-5.png
rename to sprites/player1/bow/fallen/fallen-5.png
diff --git a/sprites/player1/bow/shoot-0.png b/sprites/player1/bow/shoot/shoot-0.png
similarity index 100%
rename from sprites/player1/bow/shoot-0.png
rename to sprites/player1/bow/shoot/shoot-0.png
diff --git a/sprites/player1/bow/shoot-1.png b/sprites/player1/bow/shoot/shoot-1.png
similarity index 100%
rename from sprites/player1/bow/shoot-1.png
rename to sprites/player1/bow/shoot/shoot-1.png
diff --git a/sprites/player1/sword/attack-0.png b/sprites/player1/sword/attack/attack-0.png
similarity index 100%
rename from sprites/player1/sword/attack-0.png
rename to sprites/player1/sword/attack/attack-0.png
diff --git a/sprites/player1/sword/attack-1.png b/sprites/player1/sword/attack/attack-1.png
similarity index 100%
rename from sprites/player1/sword/attack-1.png
rename to sprites/player1/sword/attack/attack-1.png
diff --git a/sprites/player1/sword/attack-2.png b/sprites/player1/sword/attack/attack-2.png
similarity index 100%
rename from sprites/player1/sword/attack-2.png
rename to sprites/player1/sword/attack/attack-2.png
diff --git a/sprites/player1/sword/attack-3.png b/sprites/player1/sword/attack/attack-3.png
similarity index 100%
rename from sprites/player1/sword/attack-3.png
rename to sprites/player1/sword/attack/attack-3.png
diff --git a/sprites/player1/sword/attack-4.png b/sprites/player1/sword/attack/attack-4.png
similarity index 100%
rename from sprites/player1/sword/attack-4.png
rename to sprites/player1/sword/attack/attack-4.png
diff --git a/sprites/player1/sword/attack-5.png b/sprites/player1/sword/attack/attack-5.png
similarity index 100%
rename from sprites/player1/sword/attack-5.png
rename to sprites/player1/sword/attack/attack-5.png
diff --git a/sprites/player1/sword/attack-6.png b/sprites/player1/sword/attack/attack-6.png
similarity index 100%
rename from sprites/player1/sword/attack-6.png
rename to sprites/player1/sword/attack/attack-6.png
diff --git a/sprites/player1/sword/attack-7.png b/sprites/player1/sword/attack/attack-7.png
similarity index 100%
rename from sprites/player1/sword/attack-7.png
rename to sprites/player1/sword/attack/attack-7.png
diff --git a/sprites/player1/sword/fallen-2.png b/sprites/player1/sword/fallen/fallen-0.png
similarity index 100%
rename from sprites/player1/sword/fallen-2.png
rename to sprites/player1/sword/fallen/fallen-0.png
diff --git a/sprites/player1/sword/fallen-3.png b/sprites/player1/sword/fallen/fallen-1.png
similarity index 100%
rename from sprites/player1/sword/fallen-3.png
rename to sprites/player1/sword/fallen/fallen-1.png
diff --git a/sprites/player1/sword/fallen-0.png b/sprites/player1/sword/fallen/fallen-2.png
similarity index 100%
rename from sprites/player1/sword/fallen-0.png
rename to sprites/player1/sword/fallen/fallen-2.png
diff --git a/sprites/player1/sword/fallen-1.png b/sprites/player1/sword/fallen/fallen-3.png
similarity index 100%
rename from sprites/player1/sword/fallen-1.png
rename to sprites/player1/sword/fallen/fallen-3.png
diff --git a/sprites/player1/sword/fallen-4.png b/sprites/player1/sword/fallen/fallen-4.png
similarity index 100%
rename from sprites/player1/sword/fallen-4.png
rename to sprites/player1/sword/fallen/fallen-4.png
diff --git a/sprites/player1/sword/fallen-5.png b/sprites/player1/sword/fallen/fallen-5.png
similarity index 100%
rename from sprites/player1/sword/fallen-5.png
rename to sprites/player1/sword/fallen/fallen-5.png
diff --git a/sprites/player1/sword/run-0.png b/sprites/player1/sword/run/run-0.png
similarity index 100%
rename from sprites/player1/sword/run-0.png
rename to sprites/player1/sword/run/run-0.png
diff --git a/sprites/player1/sword/run-1.png b/sprites/player1/sword/run/run-1.png
similarity index 100%
rename from sprites/player1/sword/run-1.png
rename to sprites/player1/sword/run/run-1.png
diff --git a/sprites/player1/sword/run-10.png b/sprites/player1/sword/run/run-10.png
similarity index 100%
rename from sprites/player1/sword/run-10.png
rename to sprites/player1/sword/run/run-10.png
diff --git a/sprites/player1/sword/run-11.png b/sprites/player1/sword/run/run-11.png
similarity index 100%
rename from sprites/player1/sword/run-11.png
rename to sprites/player1/sword/run/run-11.png
diff --git a/sprites/player1/sword/run-2.png b/sprites/player1/sword/run/run-2.png
similarity index 100%
rename from sprites/player1/sword/run-2.png
rename to sprites/player1/sword/run/run-2.png
diff --git a/sprites/player1/sword/run-3.png b/sprites/player1/sword/run/run-3.png
similarity index 100%
rename from sprites/player1/sword/run-3.png
rename to sprites/player1/sword/run/run-3.png
diff --git a/sprites/player1/sword/run-4.png b/sprites/player1/sword/run/run-4.png
similarity index 100%
rename from sprites/player1/sword/run-4.png
rename to sprites/player1/sword/run/run-4.png
diff --git a/sprites/player1/sword/run-5.png b/sprites/player1/sword/run/run-5.png
similarity index 100%
rename from sprites/player1/sword/run-5.png
rename to sprites/player1/sword/run/run-5.png
diff --git a/sprites/player1/sword/run-6.png b/sprites/player1/sword/run/run-6.png
similarity index 100%
rename from sprites/player1/sword/run-6.png
rename to sprites/player1/sword/run/run-6.png
diff --git a/sprites/player1/sword/run-7.png b/sprites/player1/sword/run/run-7.png
similarity index 100%
rename from sprites/player1/sword/run-7.png
rename to sprites/player1/sword/run/run-7.png
diff --git a/sprites/player1/sword/run-8.png b/sprites/player1/sword/run/run-8.png
similarity index 100%
rename from sprites/player1/sword/run-8.png
rename to sprites/player1/sword/run/run-8.png
diff --git a/sprites/player1/sword/run-9.png b/sprites/player1/sword/run/run-9.png
similarity index 100%
rename from sprites/player1/sword/run-9.png
rename to sprites/player1/sword/run/run-9.png
diff --git a/sprites/player1/worker/dig-0.png b/sprites/player1/worker/dig/dig-0.png
similarity index 100%
rename from sprites/player1/worker/dig-0.png
rename to sprites/player1/worker/dig/dig-0.png
diff --git a/sprites/player1/worker/dig-1.png b/sprites/player1/worker/dig/dig-1.png
similarity index 100%
rename from sprites/player1/worker/dig-1.png
rename to sprites/player1/worker/dig/dig-1.png
diff --git a/sprites/player1/worker/dig-2.png b/sprites/player1/worker/dig/dig-2.png
similarity index 100%
rename from sprites/player1/worker/dig-2.png
rename to sprites/player1/worker/dig/dig-2.png
diff --git a/sprites/player1/worker/dig-3.png b/sprites/player1/worker/dig/dig-3.png
similarity index 100%
rename from sprites/player1/worker/dig-3.png
rename to sprites/player1/worker/dig/dig-3.png
diff --git a/sprites/player1/worker/dig-4.png b/sprites/player1/worker/dig/dig-4.png
similarity index 100%
rename from sprites/player1/worker/dig-4.png
rename to sprites/player1/worker/dig/dig-4.png
diff --git a/sprites/player1/worker/dig-5.png b/sprites/player1/worker/dig/dig-5.png
similarity index 100%
rename from sprites/player1/worker/dig-5.png
rename to sprites/player1/worker/dig/dig-5.png
diff --git a/sprites/player1/worker/dig-6.png b/sprites/player1/worker/dig/dig-6.png
similarity index 100%
rename from sprites/player1/worker/dig-6.png
rename to sprites/player1/worker/dig/dig-6.png
diff --git a/sprites/player1/worker/dig-7.png b/sprites/player1/worker/dig/dig-7.png
similarity index 100%
rename from sprites/player1/worker/dig-7.png
rename to sprites/player1/worker/dig/dig-7.png
diff --git a/sprites/player1/worker/dig-8.png b/sprites/player1/worker/dig/dig-8.png
similarity index 100%
rename from sprites/player1/worker/dig-8.png
rename to sprites/player1/worker/dig/dig-8.png
diff --git a/sprites/player1/worker/repair-0.png b/sprites/player1/worker/repair/repair-0.png
similarity index 100%
rename from sprites/player1/worker/repair-0.png
rename to sprites/player1/worker/repair/repair-0.png
diff --git a/sprites/player1/worker/repair-1.png b/sprites/player1/worker/repair/repair-1.png
similarity index 100%
rename from sprites/player1/worker/repair-1.png
rename to sprites/player1/worker/repair/repair-1.png
diff --git a/sprites/player1/worker/repair-2.png b/sprites/player1/worker/repair/repair-2.png
similarity index 100%
rename from sprites/player1/worker/repair-2.png
rename to sprites/player1/worker/repair/repair-2.png
diff --git a/sprites/player1/worker/repair-3.png b/sprites/player1/worker/repair/repair-3.png
similarity index 100%
rename from sprites/player1/worker/repair-3.png
rename to sprites/player1/worker/repair/repair-3.png
diff --git a/sprites/player1/worker/run-0.png b/sprites/player1/worker/run/run-0.png
similarity index 100%
rename from sprites/player1/worker/run-0.png
rename to sprites/player1/worker/run/run-0.png
diff --git a/sprites/player1/worker/run-1.png b/sprites/player1/worker/run/run-1.png
similarity index 100%
rename from sprites/player1/worker/run-1.png
rename to sprites/player1/worker/run/run-1.png
diff --git a/sprites/player1/worker/run-2.png b/sprites/player1/worker/run/run-2.png
similarity index 100%
rename from sprites/player1/worker/run-2.png
rename to sprites/player1/worker/run/run-2.png
diff --git a/sprites/player1/worker/run-3.png b/sprites/player1/worker/run/run-3.png
similarity index 100%
rename from sprites/player1/worker/run-3.png
rename to sprites/player1/worker/run/run-3.png
diff --git a/sprites/player1/worker/run-4.png b/sprites/player1/worker/run/run-4.png
similarity index 100%
rename from sprites/player1/worker/run-4.png
rename to sprites/player1/worker/run/run-4.png
diff --git a/sprites/player1/worker/run-5.png b/sprites/player1/worker/run/run-5.png
similarity index 100%
rename from sprites/player1/worker/run-5.png
rename to sprites/player1/worker/run/run-5.png
diff --git a/sprites/player2/bow/arrowdiag-0.png b/sprites/player2/bow/arrow_diag/arrowdiag-0.png
similarity index 100%
rename from sprites/player2/bow/arrowdiag-0.png
rename to sprites/player2/bow/arrow_diag/arrowdiag-0.png
diff --git a/sprites/player2/bow/arrowdiag-1.png b/sprites/player2/bow/arrow_diag/arrowdiag-1.png
similarity index 100%
rename from sprites/player2/bow/arrowdiag-1.png
rename to sprites/player2/bow/arrow_diag/arrowdiag-1.png
diff --git a/sprites/player2/bow/arrowhor-0.png b/sprites/player2/bow/arrow_hor/arrowhor-0.png
similarity index 100%
rename from sprites/player2/bow/arrowhor-0.png
rename to sprites/player2/bow/arrow_hor/arrowhor-0.png
diff --git a/sprites/player2/bow/arrowhor-1.png b/sprites/player2/bow/arrow_hor/arrowhor-1.png
similarity index 100%
rename from sprites/player2/bow/arrowhor-1.png
rename to sprites/player2/bow/arrow_hor/arrowhor-1.png
diff --git a/sprites/player2/bow/arrowvert-0.png b/sprites/player2/bow/arrow_vert/arrowvert-0.png
similarity index 100%
rename from sprites/player2/bow/arrowvert-0.png
rename to sprites/player2/bow/arrow_vert/arrowvert-0.png
diff --git a/sprites/player2/bow/arrowvert-1.png b/sprites/player2/bow/arrow_vert/arrowvert-1.png
similarity index 100%
rename from sprites/player2/bow/arrowvert-1.png
rename to sprites/player2/bow/arrow_vert/arrowvert-1.png
diff --git a/sprites/player2/bow/fallen-0.png b/sprites/player2/bow/fallen/fallen-0.png
similarity index 100%
rename from sprites/player2/bow/fallen-0.png
rename to sprites/player2/bow/fallen/fallen-0.png
diff --git a/sprites/player2/bow/fallen-1.png b/sprites/player2/bow/fallen/fallen-1.png
similarity index 100%
rename from sprites/player2/bow/fallen-1.png
rename to sprites/player2/bow/fallen/fallen-1.png
diff --git a/sprites/player2/bow/fallen-2.png b/sprites/player2/bow/fallen/fallen-2.png
similarity index 100%
rename from sprites/player2/bow/fallen-2.png
rename to sprites/player2/bow/fallen/fallen-2.png
diff --git a/sprites/player2/bow/fallen-3.png b/sprites/player2/bow/fallen/fallen-3.png
similarity index 100%
rename from sprites/player2/bow/fallen-3.png
rename to sprites/player2/bow/fallen/fallen-3.png
diff --git a/sprites/player2/bow/fallen-4.png b/sprites/player2/bow/fallen/fallen-4.png
similarity index 100%
rename from sprites/player2/bow/fallen-4.png
rename to sprites/player2/bow/fallen/fallen-4.png
diff --git a/sprites/player2/bow/fallen-5.png b/sprites/player2/bow/fallen/fallen-5.png
similarity index 100%
rename from sprites/player2/bow/fallen-5.png
rename to sprites/player2/bow/fallen/fallen-5.png
diff --git a/sprites/player2/bow/run-0.png b/sprites/player2/bow/run/run-0.png
similarity index 100%
rename from sprites/player2/bow/run-0.png
rename to sprites/player2/bow/run/run-0.png
diff --git a/sprites/player2/bow/run-1.png b/sprites/player2/bow/run/run-1.png
similarity index 100%
rename from sprites/player2/bow/run-1.png
rename to sprites/player2/bow/run/run-1.png
diff --git a/sprites/player2/bow/run-10.png b/sprites/player2/bow/run/run-10.png
similarity index 100%
rename from sprites/player2/bow/run-10.png
rename to sprites/player2/bow/run/run-10.png
diff --git a/sprites/player2/bow/run-11.png b/sprites/player2/bow/run/run-11.png
similarity index 100%
rename from sprites/player2/bow/run-11.png
rename to sprites/player2/bow/run/run-11.png
diff --git a/sprites/player2/bow/run-2.png b/sprites/player2/bow/run/run-2.png
similarity index 100%
rename from sprites/player2/bow/run-2.png
rename to sprites/player2/bow/run/run-2.png
diff --git a/sprites/player2/bow/run-3.png b/sprites/player2/bow/run/run-3.png
similarity index 100%
rename from sprites/player2/bow/run-3.png
rename to sprites/player2/bow/run/run-3.png
diff --git a/sprites/player2/bow/run-4.png b/sprites/player2/bow/run/run-4.png
similarity index 100%
rename from sprites/player2/bow/run-4.png
rename to sprites/player2/bow/run/run-4.png
diff --git a/sprites/player2/bow/run-5.png b/sprites/player2/bow/run/run-5.png
similarity index 100%
rename from sprites/player2/bow/run-5.png
rename to sprites/player2/bow/run/run-5.png
diff --git a/sprites/player2/bow/run-6.png b/sprites/player2/bow/run/run-6.png
similarity index 100%
rename from sprites/player2/bow/run-6.png
rename to sprites/player2/bow/run/run-6.png
diff --git a/sprites/player2/bow/run-7.png b/sprites/player2/bow/run/run-7.png
similarity index 100%
rename from sprites/player2/bow/run-7.png
rename to sprites/player2/bow/run/run-7.png
diff --git a/sprites/player2/bow/run-8.png b/sprites/player2/bow/run/run-8.png
similarity index 100%
rename from sprites/player2/bow/run-8.png
rename to sprites/player2/bow/run/run-8.png
diff --git a/sprites/player2/bow/run-9.png b/sprites/player2/bow/run/run-9.png
similarity index 100%
rename from sprites/player2/bow/run-9.png
rename to sprites/player2/bow/run/run-9.png
diff --git a/sprites/player2/bow/shoot-0.png b/sprites/player2/bow/shoot/shoot-0.png
similarity index 100%
rename from sprites/player2/bow/shoot-0.png
rename to sprites/player2/bow/shoot/shoot-0.png
diff --git a/sprites/player2/bow/shoot-1.png b/sprites/player2/bow/shoot/shoot-1.png
similarity index 100%
rename from sprites/player2/bow/shoot-1.png
rename to sprites/player2/bow/shoot/shoot-1.png
diff --git a/sprites/player2/sword/attack-0.png b/sprites/player2/sword/attack/attack-0.png
similarity index 100%
rename from sprites/player2/sword/attack-0.png
rename to sprites/player2/sword/attack/attack-0.png
diff --git a/sprites/player2/sword/attack-1.png b/sprites/player2/sword/attack/attack-1.png
similarity index 100%
rename from sprites/player2/sword/attack-1.png
rename to sprites/player2/sword/attack/attack-1.png
diff --git a/sprites/player2/sword/attack-2.png b/sprites/player2/sword/attack/attack-2.png
similarity index 100%
rename from sprites/player2/sword/attack-2.png
rename to sprites/player2/sword/attack/attack-2.png
diff --git a/sprites/player2/sword/attack-3.png b/sprites/player2/sword/attack/attack-3.png
similarity index 100%
rename from sprites/player2/sword/attack-3.png
rename to sprites/player2/sword/attack/attack-3.png
diff --git a/sprites/player2/sword/attack-4.png b/sprites/player2/sword/attack/attack-4.png
similarity index 100%
rename from sprites/player2/sword/attack-4.png
rename to sprites/player2/sword/attack/attack-4.png
diff --git a/sprites/player2/sword/attack-5.png b/sprites/player2/sword/attack/attack-5.png
similarity index 100%
rename from sprites/player2/sword/attack-5.png
rename to sprites/player2/sword/attack/attack-5.png
diff --git a/sprites/player2/sword/attack-6.png b/sprites/player2/sword/attack/attack-6.png
similarity index 100%
rename from sprites/player2/sword/attack-6.png
rename to sprites/player2/sword/attack/attack-6.png
diff --git a/sprites/player2/sword/attack-7.png b/sprites/player2/sword/attack/attack-7.png
similarity index 100%
rename from sprites/player2/sword/attack-7.png
rename to sprites/player2/sword/attack/attack-7.png
diff --git a/sprites/player2/sword/fallen-0.png b/sprites/player2/sword/fallen/fallen-0.png
similarity index 100%
rename from sprites/player2/sword/fallen-0.png
rename to sprites/player2/sword/fallen/fallen-0.png
diff --git a/sprites/player2/sword/fallen-1.png b/sprites/player2/sword/fallen/fallen-1.png
similarity index 100%
rename from sprites/player2/sword/fallen-1.png
rename to sprites/player2/sword/fallen/fallen-1.png
diff --git a/sprites/player2/sword/fallen-2.png b/sprites/player2/sword/fallen/fallen-2.png
similarity index 100%
rename from sprites/player2/sword/fallen-2.png
rename to sprites/player2/sword/fallen/fallen-2.png
diff --git a/sprites/player2/sword/fallen-3.png b/sprites/player2/sword/fallen/fallen-3.png
similarity index 100%
rename from sprites/player2/sword/fallen-3.png
rename to sprites/player2/sword/fallen/fallen-3.png
diff --git a/sprites/player2/sword/fallen-4.png b/sprites/player2/sword/fallen/fallen-4.png
similarity index 100%
rename from sprites/player2/sword/fallen-4.png
rename to sprites/player2/sword/fallen/fallen-4.png
diff --git a/sprites/player2/sword/fallen-5.png b/sprites/player2/sword/fallen/fallen-5.png
similarity index 100%
rename from sprites/player2/sword/fallen-5.png
rename to sprites/player2/sword/fallen/fallen-5.png
diff --git a/sprites/player2/sword/run-0.png b/sprites/player2/sword/run/run-0.png
similarity index 100%
rename from sprites/player2/sword/run-0.png
rename to sprites/player2/sword/run/run-0.png
diff --git a/sprites/player2/sword/run-1.png b/sprites/player2/sword/run/run-1.png
similarity index 100%
rename from sprites/player2/sword/run-1.png
rename to sprites/player2/sword/run/run-1.png
diff --git a/sprites/player2/sword/run-10.png b/sprites/player2/sword/run/run-10.png
similarity index 100%
rename from sprites/player2/sword/run-10.png
rename to sprites/player2/sword/run/run-10.png
diff --git a/sprites/player2/sword/run-11.png b/sprites/player2/sword/run/run-11.png
similarity index 100%
rename from sprites/player2/sword/run-11.png
rename to sprites/player2/sword/run/run-11.png
diff --git a/sprites/player2/sword/run-2.png b/sprites/player2/sword/run/run-2.png
similarity index 100%
rename from sprites/player2/sword/run-2.png
rename to sprites/player2/sword/run/run-2.png
diff --git a/sprites/player2/sword/run-3.png b/sprites/player2/sword/run/run-3.png
similarity index 100%
rename from sprites/player2/sword/run-3.png
rename to sprites/player2/sword/run/run-3.png
diff --git a/sprites/player2/sword/run-4.png b/sprites/player2/sword/run/run-4.png
similarity index 100%
rename from sprites/player2/sword/run-4.png
rename to sprites/player2/sword/run/run-4.png
diff --git a/sprites/player2/sword/run-5.png b/sprites/player2/sword/run/run-5.png
similarity index 100%
rename from sprites/player2/sword/run-5.png
rename to sprites/player2/sword/run/run-5.png
diff --git a/sprites/player2/sword/run-6.png b/sprites/player2/sword/run/run-6.png
similarity index 100%
rename from sprites/player2/sword/run-6.png
rename to sprites/player2/sword/run/run-6.png
diff --git a/sprites/player2/sword/run-7.png b/sprites/player2/sword/run/run-7.png
similarity index 100%
rename from sprites/player2/sword/run-7.png
rename to sprites/player2/sword/run/run-7.png
diff --git a/sprites/player2/sword/run-8.png b/sprites/player2/sword/run/run-8.png
similarity index 100%
rename from sprites/player2/sword/run-8.png
rename to sprites/player2/sword/run/run-8.png
diff --git a/sprites/player2/sword/run-9.png b/sprites/player2/sword/run/run-9.png
similarity index 100%
rename from sprites/player2/sword/run-9.png
rename to sprites/player2/sword/run/run-9.png
diff --git a/sprites/player2/worker/dig-0.png b/sprites/player2/worker/dig/dig-0.png
similarity index 100%
rename from sprites/player2/worker/dig-0.png
rename to sprites/player2/worker/dig/dig-0.png
diff --git a/sprites/player2/worker/dig-1.png b/sprites/player2/worker/dig/dig-1.png
similarity index 100%
rename from sprites/player2/worker/dig-1.png
rename to sprites/player2/worker/dig/dig-1.png
diff --git a/sprites/player2/worker/dig-2.png b/sprites/player2/worker/dig/dig-2.png
similarity index 100%
rename from sprites/player2/worker/dig-2.png
rename to sprites/player2/worker/dig/dig-2.png
diff --git a/sprites/player2/worker/dig-3.png b/sprites/player2/worker/dig/dig-3.png
similarity index 100%
rename from sprites/player2/worker/dig-3.png
rename to sprites/player2/worker/dig/dig-3.png
diff --git a/sprites/player2/worker/dig-4.png b/sprites/player2/worker/dig/dig-4.png
similarity index 100%
rename from sprites/player2/worker/dig-4.png
rename to sprites/player2/worker/dig/dig-4.png
diff --git a/sprites/player2/worker/dig-5.png b/sprites/player2/worker/dig/dig-5.png
similarity index 100%
rename from sprites/player2/worker/dig-5.png
rename to sprites/player2/worker/dig/dig-5.png
diff --git a/sprites/player2/worker/dig-6.png b/sprites/player2/worker/dig/dig-6.png
similarity index 100%
rename from sprites/player2/worker/dig-6.png
rename to sprites/player2/worker/dig/dig-6.png
diff --git a/sprites/player2/worker/dig-7.png b/sprites/player2/worker/dig/dig-7.png
similarity index 100%
rename from sprites/player2/worker/dig-7.png
rename to sprites/player2/worker/dig/dig-7.png
diff --git a/sprites/player2/worker/dig-8.png b/sprites/player2/worker/dig/dig-8.png
similarity index 100%
rename from sprites/player2/worker/dig-8.png
rename to sprites/player2/worker/dig/dig-8.png
diff --git a/sprites/player2/worker/repair-0.png b/sprites/player2/worker/repair/repair-0.png
similarity index 100%
rename from sprites/player2/worker/repair-0.png
rename to sprites/player2/worker/repair/repair-0.png
diff --git a/sprites/player2/worker/repair-1.png b/sprites/player2/worker/repair/repair-1.png
similarity index 100%
rename from sprites/player2/worker/repair-1.png
rename to sprites/player2/worker/repair/repair-1.png
diff --git a/sprites/player2/worker/repair-2.png b/sprites/player2/worker/repair/repair-2.png
similarity index 100%
rename from sprites/player2/worker/repair-2.png
rename to sprites/player2/worker/repair/repair-2.png
diff --git a/sprites/player2/worker/repair-3.png b/sprites/player2/worker/repair/repair-3.png
similarity index 100%
rename from sprites/player2/worker/repair-3.png
rename to sprites/player2/worker/repair/repair-3.png
diff --git a/sprites/player2/worker/run-0.png b/sprites/player2/worker/run/run-0.png
similarity index 100%
rename from sprites/player2/worker/run-0.png
rename to sprites/player2/worker/run/run-0.png
diff --git a/sprites/player2/worker/run-1.png b/sprites/player2/worker/run/run-1.png
similarity index 100%
rename from sprites/player2/worker/run-1.png
rename to sprites/player2/worker/run/run-1.png
diff --git a/sprites/player2/worker/run-2.png b/sprites/player2/worker/run/run-2.png
similarity index 100%
rename from sprites/player2/worker/run-2.png
rename to sprites/player2/worker/run/run-2.png
diff --git a/sprites/player2/worker/run-3.png b/sprites/player2/worker/run/run-3.png
similarity index 100%
rename from sprites/player2/worker/run-3.png
rename to sprites/player2/worker/run/run-3.png
diff --git a/sprites/player2/worker/run-4.png b/sprites/player2/worker/run/run-4.png
similarity index 100%
rename from sprites/player2/worker/run-4.png
rename to sprites/player2/worker/run/run-4.png
diff --git a/sprites/player2/worker/run-5.png b/sprites/player2/worker/run/run-5.png
similarity index 100%
rename from sprites/player2/worker/run-5.png
rename to sprites/player2/worker/run/run-5.png