I should have made this a repo a while ago
This commit is contained in:
commit
61b3e77c07
10
enemy.py
Normal file
10
enemy.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Enemy():
|
||||||
|
def __init__(self,x,y):
|
||||||
|
self.x,self.y=x,y
|
||||||
|
|
||||||
|
def draw(self,screen):
|
||||||
|
pygame.draw.circle(screen,'black',(self.x,self.y),8)
|
||||||
|
|
||||||
|
def update(self,events): pass
|
41
game.py
Normal file
41
game.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import pygame
|
||||||
|
pygame.init()
|
||||||
|
import grid as grod
|
||||||
|
import workers
|
||||||
|
import ring
|
||||||
|
|
||||||
|
running=False
|
||||||
|
objs=[]
|
||||||
|
|
||||||
|
def main():
|
||||||
|
screen=pygame.display.set_mode((1280,720))
|
||||||
|
clock=pygame.time.Clock()
|
||||||
|
global running; running=True
|
||||||
|
act=0
|
||||||
|
grid=grod.Grid(8,8,64,12,11)
|
||||||
|
grid.add_worker(workers.behaviours.Cursor)
|
||||||
|
grid.add_worker(workers.behaviours.Average)
|
||||||
|
grid.add_tower(5,5)
|
||||||
|
grid.add_tower(3,4,'cannon',2)
|
||||||
|
objs.append(grid)
|
||||||
|
while running:
|
||||||
|
update()
|
||||||
|
draw(screen)
|
||||||
|
clock.tick(60)
|
||||||
|
pygame.quit()
|
||||||
|
|
||||||
|
def update():
|
||||||
|
events=pygame.event.get()
|
||||||
|
for event in events:
|
||||||
|
if event.type==pygame.QUIT: global running; running=False
|
||||||
|
if event.type==pygame.KEYDOWN: print(event)
|
||||||
|
for obj in objs:
|
||||||
|
obj.update(events)
|
||||||
|
|
||||||
|
def draw(screen):
|
||||||
|
screen.fill((64,128,64))
|
||||||
|
for obj in objs:
|
||||||
|
obj.draw(screen)
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
main()
|
80
grid.py
Normal file
80
grid.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import pygame
|
||||||
|
import workers, towers, ring
|
||||||
|
import random
|
||||||
|
|
||||||
|
boxcols=[(90,90,90),(128,0,0),(0,128,0),(0,0,128)]
|
||||||
|
class Grid():
|
||||||
|
def __init__(self,x,y,spacing,w,h):
|
||||||
|
self.x,self.y,self.spacing,self.w,self.h=x,y,spacing,w,h
|
||||||
|
self.xe,self.ye=x+spacing*w,y+spacing*h
|
||||||
|
self.highlight=None
|
||||||
|
self.act=0
|
||||||
|
self.menu=None
|
||||||
|
self.mx,self.my=0,0
|
||||||
|
self.towers=[] # I'll make this a property later
|
||||||
|
self.workers=[]
|
||||||
|
|
||||||
|
def cell(self,x,y):
|
||||||
|
sx,sy,s,w,h=self.x,self.y,self.spacing,self.w,self.h
|
||||||
|
if not (sx<x<sx+s*w and sy<y<sy+s*h): return None
|
||||||
|
x-=sx; y-=sy
|
||||||
|
return x//s,y//s
|
||||||
|
|
||||||
|
def cell_to_real(self,x,y):
|
||||||
|
if not (0<x<self.w and 0<y<self.h): return 0,0,0
|
||||||
|
s=self.spacing
|
||||||
|
return self.x+s*x,self.y+s*y,s
|
||||||
|
|
||||||
|
def add_tower(self,x,y,*args):
|
||||||
|
self.towers.append(towers.Tower(x,y,self,*args))
|
||||||
|
self.calc_tower_mean()
|
||||||
|
|
||||||
|
def add_worker(self,behaviour):
|
||||||
|
self.workers.append(workers.Worker(int(random.random()*self.spacing*self.w+self.y),int(random.random()*self.spacing*self.h+self.y),behaviour,self))
|
||||||
|
|
||||||
|
def calc_tower_mean(self):
|
||||||
|
coords=list(map(lambda x:(x.x,x.y),self.towers))
|
||||||
|
x=list(map(lambda x:x[0],coords))
|
||||||
|
y=list(map(lambda x:x[1],coords))
|
||||||
|
x=sum(x)/len(x); y=sum(y)/len(y)
|
||||||
|
mx,my,offset=self.cell_to_real(x,y)
|
||||||
|
self.mx,self.my=mx+offset/2,my+offset/2
|
||||||
|
|
||||||
|
def draw(self,screen):
|
||||||
|
x,y,s,w,h=self.x,self.y,self.spacing,self.w,self.h
|
||||||
|
xe,ye=self.xe,self.ye
|
||||||
|
pygame.draw.rect(screen,(90,90,45),(x,y,s*w,s*h))
|
||||||
|
for i in range(h+1):
|
||||||
|
pygame.draw.line(screen,'black',(x,i*s+y),(xe,i*s+y))
|
||||||
|
for i in range(w+1):
|
||||||
|
pygame.draw.line(screen,'black',(i*s+x,y),(i*s+x,ye))
|
||||||
|
for tower in self.towers: tower.draw(screen)
|
||||||
|
if self.highlight is not None:
|
||||||
|
hx,hy,_=self.cell_to_real(*self.highlight)
|
||||||
|
hl=pygame.Surface((s,s))
|
||||||
|
hl.set_alpha(128)
|
||||||
|
pygame.draw.rect(hl,boxcols[self.act],(0,0,s,s))
|
||||||
|
screen.blit(hl,(hx,hy))
|
||||||
|
for worker in self.workers: worker.draw(screen)
|
||||||
|
if self.menu: self.menu.draw(screen)
|
||||||
|
|
||||||
|
def update(self,events):
|
||||||
|
x,y=pygame.mouse.get_pos()
|
||||||
|
if not self.act:
|
||||||
|
self.highlight=self.cell(x,y)
|
||||||
|
if self.menu: self.menu=None
|
||||||
|
elif self.menu is None and self.highlight is not None:
|
||||||
|
self.menu=ring.Ring(x,y,self.spacing*2.5,[ring_wrap(self,'cannon',0),ring_wrap(self,'cannon',1),ring_wrap(self,'cannon',2),ring_wrap(self,'cannon',3)],self)
|
||||||
|
for event in events:
|
||||||
|
if event.type==pygame.KEYUP: self.act=0; continue
|
||||||
|
if event.type!=pygame.KEYDOWN: continue
|
||||||
|
if event.scancode not in [4,7,22]: continue
|
||||||
|
self.act={4:1,22:2,7:3}[event.scancode]
|
||||||
|
for tower in self.towers: tower.update(events)
|
||||||
|
for worker in self.workers: worker.update(events)
|
||||||
|
if self.menu: self.menu.update(events)
|
||||||
|
|
||||||
|
def ring_wrap(grid,ttype,elem):
|
||||||
|
def ring_inner(x,y):
|
||||||
|
grid.add_tower(*grid.cell(x,y),ttype,elem)
|
||||||
|
return ring_inner
|
34
ring.py
Normal file
34
ring.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
thpi=math.pi/3
|
||||||
|
import utils
|
||||||
|
|
||||||
|
colours=[(196,0,0),(0,196,0),(0,0,196)]
|
||||||
|
|
||||||
|
class Ring():
|
||||||
|
def __init__(self,x,y,size,actions,grid):
|
||||||
|
self.x,self.y,self.size,self.grid=x,y,size,grid
|
||||||
|
self.init=0
|
||||||
|
self.selected=-1
|
||||||
|
self.actions=actions
|
||||||
|
self.width=2*math.pi/len(self.actions)
|
||||||
|
|
||||||
|
def draw(self,screen):
|
||||||
|
offset=self.size*self.init*0.5
|
||||||
|
l=len(self.actions)
|
||||||
|
for i in range(l,0,-1):
|
||||||
|
i-=1
|
||||||
|
colour=colours[i%len(colours)]
|
||||||
|
if i==len(colours) and 0==utils.sign((l-1)%3): colour=colours[1]
|
||||||
|
if i==self.selected: colour=tuple(n/2 for n in colour)
|
||||||
|
pygame.draw.arc(screen,colour,(self.x-offset,self.y-offset,offset*2,offset*2),-(i+1)*self.width,-i*self.width,int(offset*2/3))
|
||||||
|
|
||||||
|
def update(self,events):
|
||||||
|
if self.init<1: self.init+=0.05
|
||||||
|
else: self.init=1
|
||||||
|
self.selected=int(utils.get_direction(self.x,self.y,*pygame.mouse.get_pos())//self.width%len(self.actions))
|
||||||
|
mx,my=pygame.mouse.get_pos()
|
||||||
|
if ((self.y-my)**2+(self.x-mx)**2)**0.5<self.size/6: self.selected=-1
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
if self.selected>-1: self.actions[self.selected](self.x,self.y)
|
45
towers.py
Normal file
45
towers.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Tower():
|
||||||
|
def __init__(self,x,y,grid,ttype='null',elem=0):
|
||||||
|
self.x,self.y,self.grid=x,y,grid
|
||||||
|
self.type=ttype
|
||||||
|
self.elem=elem
|
||||||
|
self.target=Mouse()
|
||||||
|
|
||||||
|
def draw(self,screen):
|
||||||
|
x,y,s=self.grid.cell_to_real(self.x,self.y)
|
||||||
|
sprites.get(self.type,'null')(screen,x,y,s,self)
|
||||||
|
|
||||||
|
def update(self,events):
|
||||||
|
self.target.update(events)
|
||||||
|
if self.target: self.tx,self.ty=self.target.x,self.target.y
|
||||||
|
|
||||||
|
class Mouse():
|
||||||
|
def update(self,events):
|
||||||
|
self.x,self.y=pygame.mouse.get_pos()
|
||||||
|
|
||||||
|
shots={}
|
||||||
|
def mkshot(funky):
|
||||||
|
shots[funky.__name__]=funky
|
||||||
|
return funky
|
||||||
|
|
||||||
|
sprites={}
|
||||||
|
def mksprite(funky):
|
||||||
|
sprites[funky.__name__]=funky
|
||||||
|
return funky
|
||||||
|
|
||||||
|
@mksprite
|
||||||
|
def null(screen,x,y,s,t):
|
||||||
|
pygame.draw.rect(screen, (90,90,90), (x,y,s,s))
|
||||||
|
|
||||||
|
@mkshot
|
||||||
|
def null(*args): pass
|
||||||
|
|
||||||
|
@mksprite
|
||||||
|
def cannon(screen,x,y,s,t):
|
||||||
|
pygame.draw.rect(screen, (90+165*(t.elem==0),90+165*(t.elem==1),90+165*(t.elem==2)), (x,y,s,s))
|
||||||
|
pygame.draw.line(screen, (255,0,0), (x+s/2,y+s/2),(t.tx,t.ty))
|
||||||
|
|
||||||
|
@mkshot
|
||||||
|
def cannon(*args): pass
|
12
utils.py
Normal file
12
utils.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
# DIRECTIONS GO BACKWARDS IN THIS GAME
|
||||||
|
# WHY NOT
|
||||||
|
def get_direction(x1,y1,x2,y2):
|
||||||
|
dx,dy=x2-x1,y2-y1
|
||||||
|
if dx==0: return math.pi*(2-sign(dy))/2
|
||||||
|
t=math.atan(dy/dx)
|
||||||
|
return t+math.pi*(sign(dx)<0)
|
||||||
|
|
||||||
|
def sign(num):
|
||||||
|
return (num>=0)*2-1-(num==0)
|
28
workers.py
Normal file
28
workers.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import pygame
|
||||||
|
import enum
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
import utils
|
||||||
|
|
||||||
|
behaviours=enum.Enum('behaviours',['Cursor','Average'])
|
||||||
|
class Worker():
|
||||||
|
def __init__(self,x,y,behaviour,grid):
|
||||||
|
self.x,self.y,self.behaviour,self.grid=x,y,behaviour,grid
|
||||||
|
self.direction=0
|
||||||
|
|
||||||
|
def target(self):
|
||||||
|
if self.behaviour==behaviours.Cursor:
|
||||||
|
return pygame.mouse.get_pos()
|
||||||
|
if self.behaviour==behaviours.Average:
|
||||||
|
return self.grid.mx,self.grid.my
|
||||||
|
|
||||||
|
def draw(self,screen):
|
||||||
|
pygame.draw.circle(screen,'grey',(self.x,self.y),8)
|
||||||
|
pygame.draw.circle(screen,'black',(self.x+math.cos(self.dir)*5,self.y+math.sin(self.dir)*5),3)
|
||||||
|
|
||||||
|
def update(self,events):
|
||||||
|
mx,my=self.target()
|
||||||
|
self.dir=utils.get_direction(self.x,self.y,mx,my)
|
||||||
|
speed=min(5,((mx-self.x)**2+(my-self.y)**2)**0.5*0.1)
|
||||||
|
self.x+=math.cos(self.dir)*speed
|
||||||
|
self.y+=math.sin(self.dir)*speed
|
Loading…
Reference in New Issue
Block a user