Advertisement
Guest User

kdo (Tkinter tester for sc2022)

a guest
May 14th, 2022
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.13 KB | None | 0 0
  1. import math
  2. from dataclasses import dataclass, field
  3. from enum import Enum
  4. from tkinter import Tk, Canvas, YES, BOTH
  5. from tkinter.ttk import Label
  6. from typing import Any
  7.  
  8. from numpy import array
  9. from scipy.linalg import norm
  10.  
  11.  
  12. class EntityType(Enum):
  13.     SPIDER = 0
  14.     HERO = 1
  15.     BASE = 2
  16.  
  17.  
  18. @dataclass
  19. class Entity:
  20.     x: int
  21.     y: int
  22.     radius: int
  23.     speed: int
  24.     type: EntityType
  25.     health: int
  26.     location: array = field(init=False)  # calculated value after instance creation
  27.     new_location: array = field(init=False)  # calculated value after instance creation
  28.     circle: Any = field(init=False)
  29.  
  30.     def __post_init__(self):
  31.         self.location = array([self.x, self.y], dtype=float)
  32.  
  33.     def dist(self, other):
  34.         return norm(self.location - other.location) if isinstance(other, Entity) else norm(self.location - other)
  35.  
  36.     def move(self, target):
  37.         if isinstance(target, Entity):
  38.             u: array = target.location - self.location
  39.         else:
  40.             u: array = target - self.location
  41.         v: array = u / norm(u) if norm(u) > 0 else 0
  42.         speed: float = min(self.speed, self.dist(target))
  43.         return self.location + speed * v
  44.  
  45.  
  46. @dataclass
  47. class Game:
  48.     root: Tk = Tk()
  49.     canvas: Canvas = None
  50.     dbg_label: Label = None
  51.     hp_label: Label = None
  52.     base: array = None
  53.     spider: Entity = None
  54.     hero: Entity = None
  55.     map_width: int = None
  56.     map_height: int = None
  57.     reduce = None
  58.     speed: int = field(init=False)  # calculated value after instance creation
  59.  
  60.     # def __post_init__(self):
  61.     #     self.reduce = lambda x_list: map(lambda x: x * self.zoom, x_list)
  62.  
  63.  
  64.     def populate(self, hp_spider: int):
  65.         self.base = Entity(health=3, type=EntityType.BASE, x=0, y=0, radius=300, speed=0)
  66.         self.spider = Entity(health=hp_spider, type=EntityType.SPIDER, x=3000, y=3000, radius=400, speed=400)
  67.         self.hero = Entity(health=math.inf, type=EntityType.HERO, x=4000, y=4000, radius=800, speed=800)
  68.  
  69.     def init_tk(self, map_width: int, map_height: int, zoom: int):
  70.         self.canvas = Canvas(width=map_width * zoom, height=map_height * zoom, bg='white')
  71.         self.canvas.bind("<Button-1>", self.callback)
  72.         self.canvas.pack(expand=YES, fill=BOTH)
  73.         self.dbg_label = Label(self.root, text="Hello World!")
  74.         self.dbg_label.pack(pady=20)
  75.         self.hp_label = Label(self.root)
  76.         x, y = self.spider.location
  77.         self.hp_label.place(x=x, y=y)
  78.         self.hp_label['text'] = f"{self.spider.health}"
  79.         self.hp_label.pack(pady=20)
  80.  
  81.         self.reduce = lambda x_list: map(lambda x: x * zoom, x_list)
  82.  
  83.         self.base.circle = self.draw_circle(entity=self.base, color='green')
  84.         self.spider.circle = self.draw_circle(entity=self.spider, color='red')
  85.         self.hero.circle = self.draw_circle(entity=self.hero, color='blue')
  86.         self.root.mainloop()
  87.  
  88.     # All of this would do better as a subclass of Canvas with specialize methods
  89.  
  90.     def draw_circle(self, entity: Entity, color: str):
  91.         # changed this to return the ID
  92.         x, y = entity.location
  93.         oval = x - entity.radius, y - entity.radius, x + entity.radius, y + entity.radius
  94.         x0, y0, x1, y1 = self.reduce(oval)
  95.         return self.canvas.create_oval(x0, y0, x1, y1, width=1, outline=color)
  96.  
  97.     def move_circle(self, entity):
  98.         new_location = entity.move(self.base) if entity.type == EntityType.SPIDER else entity.move(self.spider)
  99.         dx, dy = self.reduce(new_location - entity.location)
  100.         self.canvas.move(entity.circle, dx, dy)
  101.         entity.location = new_location
  102.         if entity.type == EntityType.SPIDER:
  103.             x, y = self.reduce(entity.location)
  104.             self.hp_label.place(x=x, y=y)
  105.             self.hp_label['text'] = f"{entity.health}"
  106.             if entity.dist(self.base) > 300:
  107.                 self.dbg_label['text'] = f'distance spider to base = {round(entity.dist(self.base), 2)}'
  108.             else:
  109.                 self.dbg_label['text'] = f'SPIDER WINS! -> distance spider to base = {round(entity.dist(self.base), 2)}'
  110.                 self.canvas.unbind("<Button-1>", self.callback)
  111.         else:
  112.             if entity.dist(self.spider) <= entity.radius:
  113.                 self.spider.health -= 2
  114.                 if self.spider.health < 0:
  115.                     self.dbg_label['text'] = f'PLAYER WINS! -> distance spider to base = {round(entity.dist(self.base), 2)}'
  116.                     self.canvas.unbind("<Button-1>", self.callback)
  117.  
  118.     def callback(self, event):
  119.         self.move_circle(entity=self.hero)
  120.         self.move_circle(entity=self.spider)
  121.  
  122.  
  123. if __name__ == "__main__":
  124.     MAP_WIDTH, MAP_HEIGHT = 17630, 9000
  125.     mac_display_resolution = 1920, 1080
  126.     ZOOM = 0.1
  127.  
  128.     game: Game = Game()
  129.     print('Enter hit points for Spider: [1-30]')
  130.     hp_spider = input()
  131.     while not isinstance(hp_spider, int) and not 1 <= int(hp_spider) <= 30:
  132.         print('Enter hit points for Spider: [1-30]')
  133.         hp_spider = input()
  134.     game.populate(hp_spider=int(hp_spider))
  135.     game.init_tk(map_width=MAP_WIDTH, map_height=MAP_HEIGHT, zoom=ZOOM)
  136.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement