Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Tk_bots_hungry_for_dots_2017v.py
- # game
- 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)
- l_h = h // 2+(self.y-player.y)
- 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 = 1 #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) <= 50+f.static_size:
- if (elem.x-f.x)**2+(elem.y-f.y)**2 <= (50+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, scene
- size = 100 #real_size*(player.static_size/player.size)
- if not scene:
- for l_x in range(0, (map_w/size)):
- for l_y in range(0, (map_h/size)):
- if (l_x+l_y) % 2 == 1:
- scene.append([l_x*size+(w/2), l_y*size+(h/2)])
- for l_x,l_y in scene:
- l_x -= player.x
- l_y -= player.y
- canvas.create_rectangle((l_x, l_y), (l_x+size, l_y+size), width=0, 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():
- draw_scene()
- draw_food()
- draw_ent()
- draw_scores()
- def size(obj):
- return obj.size
- def draw_scores():
- global canvas, w, h, ent, status
- 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(10, 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
- if time.time()-started < 120:
- canvas.create_text(w // 2, h // 2-100, text=str(120-int((time.time()-started)*100)/100), font="Arial 50", fill="orange")
- else:
- status = "menu"
- def draw_pause():
- global canvas, w, h
- canvas.create_text((w // 2)-200, h // 2, text="Press enter to continue", font="Arial 14", anchor="w",
- justify=LEFT, fill="black")
- def draw_menu(score=0):
- global canvas, w, h, started
- canvas.create_text(w // 2, h // 2, text="Press enter to start", font="Arial 14", fill="black")
- if score != 0:
- if type(started) != type(''):
- started = str(int((time.time()-started)*100)/100)+' seconds'
- canvas.create_text(w // 2, h // 2-100, text="GAME OVER", font="Arial 30", fill="orange")
- def new_food(food):
- a = 5
- b = 30
- 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 names_of_bots, map_w, map_h
- if tries > 1:
- return
- 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, started
- 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)
- started = time.time()
- 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 = 100
- num_of_bots = 20
- started = 0
- scene = []
- new_game()
- fps = 30
- tps = 120
- speed = 6
- 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('%dx%d+10+10'%(w,h))
- 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