Advertisement
here2share

# Tk_HungryDotBots.py

Apr 27th, 2017
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.05 KB | None | 0 0
  1. # Tk_HungryDotBots.py
  2.  
  3. from Tkinter import *
  4. import time
  5. import random
  6. import math
  7.  
  8.  
  9. class PsType:
  10.  
  11.     def __init__(self, max_ps):
  12.         self.list = [0] * max_ps
  13.         self.l = 0
  14.         self.r = 0
  15.  
  16.     def first(self):
  17.         if self.l == self.r:
  18.             return time.time() - 1
  19.         return self.list[self.l]
  20.  
  21.     def check(self, time):
  22.         while self.l != self.r and self.list[self.l] < time - 1:
  23.             self.l = (self.l + 1) % len(self.list)
  24.  
  25.     def add(self, time):
  26.         self.check(time)
  27.         self.list[self.r] = time
  28.         self.r = (self.r + 1) % len(self.list)
  29.  
  30.     def size(self):
  31.         if self.l <= self.r:
  32.             return self.r - self.l
  33.         else:
  34.             return len(self.list) + self.r - self.l
  35.  
  36.  
  37. class Entity:
  38.  
  39.     def __init__(self):
  40.         self.score = 0
  41.         self.add_score = 0
  42.  
  43.     def __iadd__(self, other):
  44.         self.add_score += other
  45.         return self
  46.  
  47.     def add(self):
  48.         cores = 1000
  49.  
  50.         max_add = int(self.score / cores) + 1
  51.  
  52.         if self.add_score > max_add:
  53.             self.add_score -= max_add
  54.             self.score += max_add
  55.             self.size = 50 + math.sqrt(self.score)
  56.         elif self.add_score == 1:
  57.             self.score += self.add_score
  58.             self.add_score = 0
  59.  
  60.  
  61. class Player(Entity):
  62.  
  63.     def __init__(self, name):
  64.         self.score = 0
  65.         self.add_score = 0
  66.         self.name = name
  67.         self.size = 50
  68.         self.static_size = 50
  69.         self.score = 0
  70.         self.x = 0
  71.         self.y = 0
  72.         self.sp_x = 0
  73.         self.sp_y = 0
  74.  
  75.     def draw(self, canvas):
  76.         global w, h
  77.         canvas.create_oval(w//2 - self.static_size, h//2 - self.static_size,
  78.                            w//2 + self.static_size, h//2 + self.static_size, fill="#228B22", outline="#228B22")
  79.         canvas.create_text(w // 2, h // 2, offset=CENTER, text=self.name, font="Arial 14", justify=CENTER,
  80.                            fill="black")
  81.  
  82.  
  83. class Other(Entity):
  84.  
  85.     def __init__(self, name, x, y):
  86.         self.score = 0
  87.         self.add_score = 0
  88.         self.name = name
  89.         self.size = 50
  90.         self.x = x
  91.         self.y = y
  92.         self.sp_x = 0
  93.         self.sp_y = 0
  94.         self.score = 0
  95.         self.static_size = 50
  96.  
  97.     def draw(self, canvas):
  98.         global w, h, player
  99.         koeff = player.static_size / player.size
  100.         l_w = w // 2 + (self.x - player.x) * koeff
  101.         l_h = h // 2 + (self.y - player.y) * koeff
  102.         if - self.size * koeff < l_w < w + self.size * koeff and - self.size * koeff < l_h < h + self.size * koeff:
  103.             canvas.create_oval((l_w - self.size * koeff, l_h - self.size * koeff),
  104.                                (l_w + self.size * koeff, l_h + self.size * koeff), fill="red", outline="red")
  105.             canvas.create_text(l_w, l_h, offset=CENTER, text=self.name, font="Arial 14", justify=CENTER,
  106.                                fill="black")
  107.             canvas.create_text(l_w, l_h + 18, offset=CENTER, text=str(self.score), font="Arial 10", justify=CENTER,
  108.                                fill="black")
  109.  
  110.     def move(self):
  111.         if random.randint(0, 49) == 0:
  112.             x = random.randint(-100, 100)
  113.             y = random.randint(-100, 100)
  114.             r = math.sqrt(x ** 2 + y ** 2)
  115.             if r == 0:
  116.                 self.sp_x = 0
  117.                 self.sp_y = 0
  118.             else:
  119.                 self.sp_x = x / r
  120.                 self.sp_y = y / r
  121.  
  122.  
  123. class Food:
  124.  
  125.     def __init__(self, x, y, static_size):
  126.         self.x = x
  127.         self.y = y
  128.         self.static_size = static_size
  129.  
  130.     def draw(self, canvas):
  131.         global w, h, player
  132.         koeff = player.static_size / player.size
  133.         if abs(self.x - player.x) * koeff <= w and abs(self.y - player.y) * koeff <= h:
  134.             canvas.create_oval((w // 2 + (self.x - player.x - self.static_size) * koeff,
  135.                                 h // 2 + (self.y - player.y - self.static_size) * koeff),
  136.                                (w // 2 + (self.x - player.x + self.static_size) * koeff,
  137.                                 h // 2 + (self.y - player.y + self.static_size) * koeff),
  138.                                fill="yellow", outline="green")
  139.  
  140.  
  141. def mouse_motion(event):
  142.     global w, h, player
  143.     l_x = event.x - w // 2
  144.     l_y = event.y - h // 2
  145.     if l_x ** 2 + l_y ** 2 > player.static_size ** 2:
  146.         player.sp_x = l_x / math.sqrt(l_x ** 2 + l_y ** 2)
  147.         player.sp_y = l_y / math.sqrt(l_x ** 2 + l_y ** 2)
  148.     else:
  149.         player.sp_x = 0
  150.         player.sp_y = 0
  151.  
  152.  
  153. def tick():
  154.     global ent, root, map_w, map_h, h, w, food, player, tps, speed, status, add_time_tps, local_tps
  155.     tick_time = 1000 // tps
  156.     t = time.time()
  157.  
  158.     if status == "game":
  159.  
  160.         if len(ent) == 1:
  161.             status = "menu"
  162.             root.after(add_time_tps, tick)
  163.             return
  164.  
  165.         for elem in ent:
  166.             elem.add()
  167.  
  168.             if elem != player:
  169.                 elem.move()
  170.             elem.x = max(0, min(map_w, elem.x + speed * elem.sp_x))
  171.             elem.y = max(0, min(map_w, elem.y + speed * elem.sp_y))
  172.  
  173.             tmp = set()
  174.             for f in food:
  175.                 if abs(elem.x - f.x) + abs(elem.y - f.y) <= elem.size + f.static_size:
  176.                     if (elem.x - f.x) ** 2 + (elem.y - f.y) ** 2 <= (elem.size + f.static_size) ** 2:
  177.                         tmp.add(f)
  178.                         elem += f.static_size
  179.             for i in range(len(tmp)):
  180.                 new_food(food)
  181.             food = food.difference(tmp)
  182.  
  183.         tmp_ent = list(ent)
  184.         for i in range(len(tmp_ent) - 1):
  185.             for j in range(i + 1, len(tmp_ent)):
  186.                 elem = tmp_ent[i]
  187.                 f = tmp_ent[j]
  188.                 if abs(elem.x - f.x) + abs(elem.y - f.y) <= max(elem.size, f.size):
  189.                     if (elem.x - f.x) ** 2 + (elem.y - f.y) ** 2 <= (max(elem.size, f.size)) ** 2:
  190.                         if elem.size > f.size:
  191.                             elem += f.score
  192.                             delete(f)
  193.                         elif elem.size < f.size:
  194.                             f += elem.score
  195.                             delete(elem)
  196.  
  197.     local_tps.add(time.time())
  198.  
  199.     dt = tick_time - (time.time() - t) * 1000 - 1
  200.     add_time_tps = max(int(dt), 0)
  201.  
  202.     root.after(add_time_tps, tick)
  203.  
  204.  
  205. def delete(e):
  206.     global ent, status, player
  207.     if e == player:
  208.         status = "menu"
  209.         return
  210.     tmp = set()
  211.     tmp.add(e)
  212.     ent = ent.difference(tmp)
  213.     new_ent(ent, rand_size=int(player.score * 1.5), rand_left=int(player.score * 0.5))
  214.  
  215.  
  216. def drawer():
  217.     global canvas, ent, player, fps, add_time_tps, local_tps, local_fps, add_time_fps
  218.     tick_time = 1000 // fps
  219.     t = time.time()
  220.  
  221.     canvas.delete("all")
  222.  
  223.     if status == "menu":
  224.         draw_menu(player.score + player.add_score)
  225.  
  226.     elif status == "game":
  227.         draw()
  228.  
  229.     elif status == "pause":
  230.         draw()
  231.         draw_pause()
  232.  
  233.     local_fps.add(time.time())
  234.  
  235.     canvas.create_text(1, h - 24, text=str(local_fps.size()) + " FPS   " + str(int(add_time_fps)) + " ms",
  236.                        font="Arial 10 bold", anchor="w", fill="green")
  237.     canvas.create_text(1, h - 8, text=str(local_tps.size()) + " TPS   " + str(int(add_time_tps)) + " ms",
  238.                        font="Arial 10 bold", anchor="w", fill="green")
  239.     canvas.create_text(w, 10, text="Score: " + str(player.score), font="Arial 14 bold", anchor="e", fill="green")
  240.  
  241.     canvas.update()
  242.  
  243.     dt = tick_time - (time.time() - t) * 1000 - 1
  244.     add_time_fps  = max(int(dt), 0)
  245.  
  246.     root.after(add_time_fps, drawer)
  247.  
  248.  
  249. def key_press(event):
  250.     global canvas, status
  251.  
  252.     if status == "menu":
  253.         if event.keycode == 13:
  254.             new_game()
  255.             status = "game"
  256.         return
  257.  
  258.     if status == "pause":
  259.         if event.keycode == 13:
  260.             status = "game"
  261.         return
  262.  
  263.     if event.keycode == 80 or event.keycode == 27:
  264.         status = "pause"
  265.         draw_pause()
  266.  
  267.  
  268. def length(x1, y1, x2, y2):
  269.     return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
  270.  
  271.  
  272. def draw_scene():
  273.     global h, w, canvas, player, map_h, map_w
  274.     real_size = 100
  275.     size = real_size * (player.static_size / player.size)
  276.  
  277.     ch = (player.x // real_size + player.y // real_size) % 2
  278.  
  279.     for i in range(- 1 - int((w//2) / size), 2 + int((w//2) / size)):
  280.         l_x = i * size + w // 2 - (player.x % real_size) * (player.static_size / player.size)
  281.         for j in range(- 1 - int((h//2) / size), 2 + int((h//2) / size)):
  282.             l_y = j * size + h // 2 - (player.y % real_size) * (player.static_size / player.size)
  283.             if 0 <= i * real_size + player.x < map_w and 0 <= j * real_size + player.y < map_h:
  284.                 if (ch + i + j) % 2 == 1:
  285.                     canvas.create_polygon((l_x, l_y), (l_x + size, l_y), (l_x + size, l_y + size), (l_x, l_y + size),
  286.                                           fill="#cccccc")
  287.  
  288.  
  289. def draw_ent():
  290.     global ent, canvas
  291.     for elem in ent:
  292.         elem.draw(canvas)
  293.  
  294.  
  295. def draw_food():
  296.     global food, canvas
  297.     for elem in food:
  298.         elem.draw(canvas)
  299.  
  300.  
  301. def draw():
  302.     check_eating()
  303.     draw_scene()
  304.     draw_food()
  305.     draw_ent()
  306.     draw_scores()
  307.  
  308.  
  309. def size(obj):
  310.     return obj.size
  311.  
  312.  
  313. def draw_scores():
  314.     global canvas, w, h, ent
  315.     tmp_ent = list(ent)
  316.     tmp_ent.sort(key=size)
  317.     i = 0
  318.     canvas.create_text(1, 10, text="Scores:", font="Arial 14", anchor="w", fill="Blue")
  319.     while i < min(5, len(tmp_ent)):
  320.         canvas.create_text(1, 30 + i * 20, text=tmp_ent[-1 - i].name + ": " + str(tmp_ent[-1 - i].score), font="Arial 14",
  321.                            anchor="w", fill="Blue")
  322.         i += 1
  323.  
  324.  
  325. def draw_pause():
  326.     global canvas, w, h
  327.     canvas.create_text(w // 2 - 100, h // 2, text="Press enter to continue", font="Arial 14", anchor="w",
  328.                        justify=LEFT, fill="black")
  329.  
  330.  
  331. def check_eating():
  332.     pass
  333.  
  334.  
  335. def draw_menu(score=0):
  336.     global canvas, w, h
  337.     canvas.create_text(w // 2, h // 2, text="Press enter to start", font="Arial 14", fill="black")
  338.     if score != 0:
  339.         canvas.create_text(w // 2, h // 2 + 20, text="Score: " + str(score), font="Arial 14", fill="black")
  340.  
  341.  
  342. def new_food(food):
  343.     a = 3
  344.     b = 10
  345.     tmp = Food(random.randint(0, map_w), random.randint(0, map_h), random.randint(a, b))
  346.     food.add(tmp)
  347.  
  348.  
  349. def new_ent(ent, rand_size=0, tries=0, rand_left=0):
  350.     global status
  351.     if tries > 1:
  352.         return
  353.     global names_of_bots, map_w, map_h, player
  354.     tmp = Other(str(names_of_bots), random.randint(0, map_w), random.randint(0, map_h))
  355.     for elem in ent:
  356.         if abs(elem.x - tmp.x) + abs(elem.y - tmp.y) <= elem.size * 2:
  357.             if (elem.x - tmp.x) ** 2 + (elem.y - tmp.y) ** 2 <= (elem.size * 2) ** 2:
  358.                 return new_ent(ent, rand_size=rand_size, tries=tries+1, rand_left=rand_left)
  359.     tmp.score = random.randint(rand_left, rand_size)
  360.     tmp.size = 50 + math.sqrt(tmp.score)
  361.     ent.add(tmp)
  362.     names_of_bots += 1
  363.  
  364.  
  365. def new_game():
  366.     global ent, food, names_of_bots, status, map_w, map_h, player
  367.     ent = set()
  368.     food = set()
  369.     status = "menu"
  370.     player = Player("player")
  371.     player.x = map_w // 2 + 0.01
  372.     player.y = map_h // 2 + 0.01
  373.     ent.add(player)
  374.     for i in range(num_of_food):
  375.         new_food(food)
  376.     names_of_bots = 1
  377.     for i in range(num_of_bots):
  378.         new_ent(ent, rand_size=250)
  379.  
  380.  
  381. w = 1000
  382. h = 500
  383. map_w = 2000
  384. map_h = 2000
  385. num_of_food = 200
  386. num_of_bots = 10
  387.  
  388. new_game()
  389.  
  390. fps = 30
  391. tps = 120  # количество тиков в секунду
  392. speed = 3
  393.  
  394. local_fps = PsType(fps * 2)
  395. local_tps = PsType(tps * 2)
  396. add_time_fps = 1000 // fps
  397. add_time_tps = 1000 // tps
  398.  
  399. root = Tk()
  400. root.bind("<KeyPress>", key_press)
  401. root.bind("<Motion>", mouse_motion)
  402. root.geometry('1000x500')
  403. canvas = Canvas(root, width=w, height=h)
  404. canvas.place(x=0, y=0)
  405.  
  406. root.after(100, tick)
  407. root.after(100, drawer)
  408.  
  409. root.mainloop()
  410. status = "end"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement