Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Tk_HungryDotBots.py
- from Tkinter import *
- import time
- import random
- import math
- class PsType:
- def __init__(self, max_ps):
- self.list = [0] * max_ps
- self.l = 0
- self.r = 0
- def first(self):
- if self.l == self.r:
- return time.time() - 1
- return self.list[self.l]
- def check(self, time):
- while self.l != self.r and self.list[self.l] < time - 1:
- self.l = (self.l + 1) % len(self.list)
- def add(self, time):
- self.check(time)
- self.list[self.r] = time
- self.r = (self.r + 1) % len(self.list)
- def size(self):
- if self.l <= self.r:
- return self.r - self.l
- else:
- return len(self.list) + self.r - self.l
- class Entity:
- def __init__(self):
- self.score = 0
- self.add_score = 0
- def __iadd__(self, other):
- self.add_score += other
- return self
- def add(self):
- cores = 1000
- max_add = int(self.score / cores) + 1
- if self.add_score > max_add:
- self.add_score -= max_add
- self.score += max_add
- self.size = 50 + math.sqrt(self.score)
- elif self.add_score == 1:
- self.score += self.add_score
- self.add_score = 0
- class Player(Entity):
- def __init__(self, name):
- self.score = 0
- self.add_score = 0
- self.name = name
- self.size = 50
- self.static_size = 50
- self.score = 0
- self.x = 0
- self.y = 0
- self.sp_x = 0
- self.sp_y = 0
- def draw(self, canvas):
- global w, h
- canvas.create_oval(w//2 - self.static_size, h//2 - self.static_size,
- w//2 + self.static_size, h//2 + self.static_size, fill="#228B22", outline="#228B22")
- canvas.create_text(w // 2, h // 2, offset=CENTER, text=self.name, font="Arial 14", justify=CENTER,
- fill="black")
- class Other(Entity):
- def __init__(self, name, x, y):
- self.score = 0
- self.add_score = 0
- self.name = name
- self.size = 50
- self.x = x
- self.y = y
- self.sp_x = 0
- self.sp_y = 0
- self.score = 0
- self.static_size = 50
- def draw(self, canvas):
- global w, h, player
- koeff = player.static_size / player.size
- l_w = w // 2 + (self.x - player.x) * koeff
- l_h = h // 2 + (self.y - player.y) * koeff
- if - self.size * koeff < l_w < w + self.size * koeff and - self.size * koeff < l_h < h + self.size * koeff:
- canvas.create_oval((l_w - self.size * koeff, l_h - self.size * koeff),
- (l_w + self.size * koeff, l_h + self.size * koeff), fill="red", outline="red")
- canvas.create_text(l_w, l_h, offset=CENTER, text=self.name, font="Arial 14", justify=CENTER,
- fill="black")
- canvas.create_text(l_w, l_h + 18, offset=CENTER, text=str(self.score), font="Arial 10", justify=CENTER,
- fill="black")
- def move(self):
- if random.randint(0, 49) == 0:
- x = random.randint(-100, 100)
- y = random.randint(-100, 100)
- r = math.sqrt(x ** 2 + y ** 2)
- if r == 0:
- self.sp_x = 0
- self.sp_y = 0
- else:
- self.sp_x = x / r
- self.sp_y = y / r
- class Food:
- def __init__(self, x, y, static_size):
- self.x = x
- self.y = y
- self.static_size = static_size
- def draw(self, canvas):
- global w, h, player
- koeff = player.static_size / player.size
- if abs(self.x - player.x) * koeff <= w and abs(self.y - player.y) * koeff <= h:
- canvas.create_oval((w // 2 + (self.x - player.x - self.static_size) * koeff,
- h // 2 + (self.y - player.y - self.static_size) * koeff),
- (w // 2 + (self.x - player.x + self.static_size) * koeff,
- h // 2 + (self.y - player.y + self.static_size) * koeff),
- fill="yellow", outline="green")
- def mouse_motion(event):
- global w, h, player
- l_x = event.x - w // 2
- l_y = event.y - h // 2
- if l_x ** 2 + l_y ** 2 > player.static_size ** 2:
- player.sp_x = l_x / math.sqrt(l_x ** 2 + l_y ** 2)
- player.sp_y = l_y / math.sqrt(l_x ** 2 + l_y ** 2)
- else:
- player.sp_x = 0
- player.sp_y = 0
- def tick():
- global ent, root, map_w, map_h, h, w, food, player, tps, speed, status, add_time_tps, local_tps
- tick_time = 1000 // tps
- t = time.time()
- if status == "game":
- if len(ent) == 1:
- status = "menu"
- root.after(add_time_tps, tick)
- return
- for elem in ent:
- elem.add()
- if elem != player:
- elem.move()
- elem.x = max(0, min(map_w, elem.x + speed * elem.sp_x))
- elem.y = max(0, min(map_w, elem.y + speed * elem.sp_y))
- tmp = set()
- for f in food:
- if abs(elem.x - f.x) + abs(elem.y - f.y) <= elem.size + f.static_size:
- if (elem.x - f.x) ** 2 + (elem.y - f.y) ** 2 <= (elem.size + f.static_size) ** 2:
- tmp.add(f)
- elem += f.static_size
- for i in range(len(tmp)):
- new_food(food)
- food = food.difference(tmp)
- tmp_ent = list(ent)
- for i in range(len(tmp_ent) - 1):
- for j in range(i + 1, len(tmp_ent)):
- elem = tmp_ent[i]
- f = tmp_ent[j]
- if abs(elem.x - f.x) + abs(elem.y - f.y) <= max(elem.size, f.size):
- if (elem.x - f.x) ** 2 + (elem.y - f.y) ** 2 <= (max(elem.size, f.size)) ** 2:
- if elem.size > f.size:
- elem += f.score
- delete(f)
- elif elem.size < f.size:
- f += elem.score
- delete(elem)
- local_tps.add(time.time())
- dt = tick_time - (time.time() - t) * 1000 - 1
- add_time_tps = max(int(dt), 0)
- root.after(add_time_tps, tick)
- def delete(e):
- global ent, status, player
- if e == player:
- status = "menu"
- return
- tmp = set()
- tmp.add(e)
- ent = ent.difference(tmp)
- new_ent(ent, rand_size=int(player.score * 1.5), rand_left=int(player.score * 0.5))
- def drawer():
- global canvas, ent, player, fps, add_time_tps, local_tps, local_fps, add_time_fps
- tick_time = 1000 // fps
- t = time.time()
- canvas.delete("all")
- if status == "menu":
- draw_menu(player.score + player.add_score)
- elif status == "game":
- draw()
- elif status == "pause":
- draw()
- draw_pause()
- local_fps.add(time.time())
- canvas.create_text(1, h - 24, text=str(local_fps.size()) + " FPS " + str(int(add_time_fps)) + " ms",
- font="Arial 10 bold", anchor="w", fill="green")
- canvas.create_text(1, h - 8, text=str(local_tps.size()) + " TPS " + str(int(add_time_tps)) + " ms",
- font="Arial 10 bold", anchor="w", fill="green")
- canvas.create_text(w, 10, text="Score: " + str(player.score), font="Arial 14 bold", anchor="e", fill="green")
- canvas.update()
- dt = tick_time - (time.time() - t) * 1000 - 1
- add_time_fps = max(int(dt), 0)
- root.after(add_time_fps, drawer)
- def key_press(event):
- global canvas, status
- if status == "menu":
- if event.keycode == 13:
- new_game()
- status = "game"
- return
- if status == "pause":
- if event.keycode == 13:
- status = "game"
- return
- if event.keycode == 80 or event.keycode == 27:
- status = "pause"
- draw_pause()
- def length(x1, y1, x2, y2):
- return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
- def draw_scene():
- global h, w, canvas, player, map_h, map_w
- real_size = 100
- size = real_size * (player.static_size / player.size)
- ch = (player.x // real_size + player.y // real_size) % 2
- for i in range(- 1 - int((w//2) / size), 2 + int((w//2) / size)):
- l_x = i * size + w // 2 - (player.x % real_size) * (player.static_size / player.size)
- for j in range(- 1 - int((h//2) / size), 2 + int((h//2) / size)):
- l_y = j * size + h // 2 - (player.y % real_size) * (player.static_size / player.size)
- if 0 <= i * real_size + player.x < map_w and 0 <= j * real_size + player.y < map_h:
- if (ch + i + j) % 2 == 1:
- canvas.create_polygon((l_x, l_y), (l_x + size, l_y), (l_x + size, l_y + size), (l_x, l_y + size),
- fill="#cccccc")
- def draw_ent():
- global ent, canvas
- for elem in ent:
- elem.draw(canvas)
- def draw_food():
- global food, canvas
- for elem in food:
- elem.draw(canvas)
- def draw():
- check_eating()
- draw_scene()
- draw_food()
- draw_ent()
- draw_scores()
- def size(obj):
- return obj.size
- def draw_scores():
- global canvas, w, h, ent
- tmp_ent = list(ent)
- tmp_ent.sort(key=size)
- i = 0
- canvas.create_text(1, 10, text="Scores:", font="Arial 14", anchor="w", fill="Blue")
- while i < min(5, len(tmp_ent)):
- canvas.create_text(1, 30 + i * 20, text=tmp_ent[-1 - i].name + ": " + str(tmp_ent[-1 - i].score), font="Arial 14",
- anchor="w", fill="Blue")
- i += 1
- def draw_pause():
- global canvas, w, h
- canvas.create_text(w // 2 - 100, h // 2, text="Press enter to continue", font="Arial 14", anchor="w",
- justify=LEFT, fill="black")
- def check_eating():
- pass
- def draw_menu(score=0):
- global canvas, w, h
- canvas.create_text(w // 2, h // 2, text="Press enter to start", font="Arial 14", fill="black")
- if score != 0:
- canvas.create_text(w // 2, h // 2 + 20, text="Score: " + str(score), font="Arial 14", fill="black")
- def new_food(food):
- a = 3
- b = 10
- tmp = Food(random.randint(0, map_w), random.randint(0, map_h), random.randint(a, b))
- food.add(tmp)
- def new_ent(ent, rand_size=0, tries=0, rand_left=0):
- global status
- if tries > 1:
- return
- global names_of_bots, map_w, map_h, player
- tmp = Other(str(names_of_bots), random.randint(0, map_w), random.randint(0, map_h))
- for elem in ent:
- if abs(elem.x - tmp.x) + abs(elem.y - tmp.y) <= elem.size * 2:
- if (elem.x - tmp.x) ** 2 + (elem.y - tmp.y) ** 2 <= (elem.size * 2) ** 2:
- return new_ent(ent, rand_size=rand_size, tries=tries+1, rand_left=rand_left)
- tmp.score = random.randint(rand_left, rand_size)
- tmp.size = 50 + math.sqrt(tmp.score)
- ent.add(tmp)
- names_of_bots += 1
- def new_game():
- global ent, food, names_of_bots, status, map_w, map_h, player
- ent = set()
- food = set()
- status = "menu"
- player = Player("player")
- player.x = map_w // 2 + 0.01
- player.y = map_h // 2 + 0.01
- ent.add(player)
- for i in range(num_of_food):
- new_food(food)
- names_of_bots = 1
- for i in range(num_of_bots):
- new_ent(ent, rand_size=250)
- w = 1000
- h = 500
- map_w = 2000
- map_h = 2000
- num_of_food = 200
- num_of_bots = 10
- new_game()
- fps = 30
- tps = 120 # количество тиков в секунду
- speed = 3
- local_fps = PsType(fps * 2)
- local_tps = PsType(tps * 2)
- add_time_fps = 1000 // fps
- add_time_tps = 1000 // tps
- root = Tk()
- root.bind("<KeyPress>", key_press)
- root.bind("<Motion>", mouse_motion)
- root.geometry('1000x500')
- canvas = Canvas(root, width=w, height=h)
- canvas.place(x=0, y=0)
- root.after(100, tick)
- root.after(100, drawer)
- root.mainloop()
- status = "end"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement