Skip to content

Instantly share code, notes, and snippets.

@Vftdan
Last active May 12, 2017 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vftdan/412a37fcb0799e20ccacab7ec32b2ccd to your computer and use it in GitHub Desktop.
Save Vftdan/412a37fcb0799e20ccacab7ec32b2ccd to your computer and use it in GitHub Desktop.
TKinter canvas game
from tkinter import *
from random import *
from time import sleep
#from multiprocessing import Process
DEBUG = True
HEIGHT = 1080 - 27
WIDTH = 1920
BUBBLE_COUNT = 50
g = 9.8
dt = 0.4
def nop(*args):
pass
def log(*args):
print(' '.join(list(map(str, args))))
def rgb(r, g, b):
s = "#"
for i in (r, g, b):
if(i < 16):
c = "0" + hex(i)
else:
c = hex(i)
s += c
return s
GREEN = rgb(0, 255, 0)
class vec2d:
def __init__(self, x, y):
self.x = x
self.y = y
def __iter__(self):
return (self.x, self.y).__iter__()
def __str__(self):
return "{" + str(self.x) +", " + str(self.y) + "}"
def __abs__(self):
return (self.x * self.x + self.y * self.y) ** 0.5
def __add__(self, v):
return vec2d(self.x + v.x, self.y + v.y)
def __sub__(self, v):
return vec2d(self.x - v.x, self.y - v.y)
def __mul__(self, m):
if(type(m) == int or type(m) == float):
return vec2d(self.x * m, self.y * m)
elif(type(m) == mx2d):
return m.__rmul__(self)
elif(type(m) == vec2d):
return self.x * m.x + self.y * m.y
def angleCos(self, v):
self * v / abs(self) / abs(v)
def sin(self):
return self.y / self.__abs__()
def cos(self):
return self.x / self.__abs__()
def norm(self):
return vec2d(self.cos(), self.sin())
def toRotMx(self):
s = self.sin()
c = self.cos()
return mx2d(c, -s, s, c)
def toTuple(self):
return (self.x, self.y)
def setValues(self, v):
self.x, self.y = v.x, v.y
class mx2d:
def __init__(self, xx = 1, yx = 0, xy = 0, yy = 1):
self.xx, self.yx, self.xy, self.yy = xx, yx, xy, yy
def __mul__(self, m):
if(type(m) == mx2d):
return m.__rmul__(self)
def __rmul__(self, v):
if(type(v) == vec2d):
return vec2d(self.xx * v.x + self.yx * v.y, self.xy * v.x + self.yy * v.y)
elif(type(v) == mx2d):
return mx2d(v.xx * self.xx + v.xy * self.yx, v.yx * self.xx + v.yy * self.yx,
v.xx * self.xy + v.xy * self.yy, v.yx * self.xy + v.yy * self.yy)
def __str__(self):
return str(self.xx) + '\t' + str(self.yx) + '\n' + str(self.xy) + '\t' + str(self.yy)
def __neg__(self):
return mx2d(self.xx, -self.yx, -self.xy, self.yy)
'''
def __getitem__(self, v):
return v * self
'''
def randvec2d(low, hig):
return vec2d(randint(low.x, hig.x), randint(low.y, hig.y))
class Bubble:
#def __getitem__(self, i):
# return i
def getwraprect(self):
return (self.pos - self.r).toTuple() + (self.pos + self.r).toTuple()
def __init__(self):
'''
self.r = randint(5, 50)
self.x = randint(self.r, WIDTH - self.r)
self.y = randint(self.r, HEIGHT - self.r)
self.vx = randint(-5, 5)
self.vy = randint(-5, 5)
self.draw = canvas.create_oval(self.x - self.r, self.y - r, self.x + r, self.y + r, fill = GREEN)
'''
self.exists = True
#R = randint(5, 50)
#self.r = vec2d(R, R)
self.r = randvec2d(vec2d(5, 5), vec2d(50, 50))
self.m = self.r.x * self.r.y
self.pos = randvec2d(self.r, scrSize - self.r)
self.vel = randvec2d(vec2d(-5, -5), vec2d(5, 5))
self.img = canv.create_oval(*self.getwraprect())
#self.moveWait = 0
def move(self):
'''
nx, ny = self.x + self.vx * dt, self.y + self.vy * dt
recalc = False
if(nx + r >= WIDTH or nx - r <= 0):
self.vx *= -1
recalc = True
if(ny + r >= HEIGHT or ny - r <= 0):
self.vy *= -1
recalc = True
if(recalc):
self.move()
else:
canvas.move(self.draw, nx - self.x, ny - self.y)
self.x, self.y = nx, ny
'''
npos = self.pos + self.vel * dt
c_rb = npos + self.r
c_tl = npos - self.r
recalc = False
if(c_rb.x >= WIDTH or c_tl.x <= 0):
self.vel.x *= -1
recalc = True
if(c_rb.y >= HEIGHT or c_tl.y <= 0):
self.vel.y *= -1
recalc = True
#log(recalc, c_tl, c_rb, self.pos, self.vel)
if(recalc):
self.move()
else:
canv.move(self.img, *(npos - self.pos).toTuple())
self.pos = npos
def startMove(self):
#if(self.moveWait):
# self.moveWait -= 1
#else:
self.move()
for i in B:
if(i == self): break
if(not i.exists): continue
e = self.hasCollision(i)
if(e):
Bubble.handleCollision(*e)
'''
i.move()
self.move()
i.moveWait += 1
self.moveWait += 1
'''
canv.after(18, self.startMove)
def hasCollision(b1, b2):
dif = b1.pos - b2.pos
dir = dif.norm()
r1 = abs(vec2d(b1.r.x * dir.x, b1.r.y * dir.y))
r2 = abs(vec2d(b2.r.x * dir.x, b2.r.y * dir.y))
if(r1 + r2 >= abs(dif)):
return (r1, b1.vel, b1.m, r2, b2.vel, b2.m, dif)
else:
return False
def handleCollision(r1, v1, m1, r2, v2, m2, dif):
#log(r1, v1, m1, r2, v2, m2, dif)
if(dif.x == 0 and dif.y == 0):
return
rot = dif.toRotMx()
_ = -rot
u1, u2 = v1 * _, v2 * _
u1.x = abs(u1.x)
u2.x = -abs(u2.x)
e2 = m1 * abs(u1) ** 2 + m2 * abs(u2) ** 2
p = (e2 * m1 * m2 / (m1 + m2)) ** 0.5
v1.setValues(u1.norm() * (p / m1) * rot)
v2.setValues(u2.norm() * (p / m2) * rot)
#a = Bubble()
#b = Bubble()
#a.x = 1
#print(a[1, 2])
mw = Tk()
mw.title("Vftdan CANON BUBBLE")
canv = Canvas(mw, width = WIDTH, height = HEIGHT)
canv.pack()
scrSize = vec2d(WIDTH, HEIGHT)
B = [0] * BUBBLE_COUNT
#log(mx2d()[vec2d(1, 2), vec2d(3, 4)])
for i in range(BUBBLE_COUNT):
B[i] = Bubble()
B[i].startMove()
'''
v = vec2d(1, 2)
m = mx2d(0, 2,
2, 0)
print(mx2d() * m)
print (vec2d(1, 2) - vec2d(5,3))
'''
#ml = Process(target = Tk.mainloop, args = (mw, ))
#ml.start()
#ml.join()
mw.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment