I am doing my best to keep this code clean and fast, but as I add more to the game, it seems to get harder to maintain a frame-rate higher than 200! I believe that the culprit is a somewhat large for
loop inside of the main loop. It performs all of the actions for the tiles inside of the world, and as more tiles are added, the game gets slower.
import pygame
from pygame.locals import *
from random import choice
from math import sqrt
#inits
pygame.init()
font=pygame.font.Font(None, 18)
screen=pygame.display.set_mode((640,480))
pygame.display.set_caption('City Game | Pre-Alpha')
clock=pygame.time.Clock()
#sprites
curspr=pygame.image.load('curs.png').convert()
curspr.set_alpha(100)
grassspr=pygame.image.load('grass.png').convert()
roadspr=pygame.image.load('road.png').convert()
forestspr=pygame.image.load('forest.png').convert()
water1=pygame.image.load('water1.png').convert()
water2=pygame.image.load('water2.png').convert()
power1=pygame.image.load('power1.png').convert()
power2=pygame.image.load('power2.png').convert()
res=pygame.image.load('res.png').convert()
house1_0=pygame.image.load('house1_0.png').convert()
house1_1=pygame.image.load('house1_1.png').convert()
res.set_alpha(215)
#vars and lists
taxrateR=8
tilelist=[grassspr,roadspr,forestspr,water1,res,power1]
namelist=['Grass','Road','Forest','Water','Residental','Power Plant']
costlist=[5,10,20,50,100,250]
tiles=[]
sel=0
money=10000
mse=(0,0)
tileframe=2000
pop=0
month=1
year=1
monthtime=0
R=1
C=1
I=1
def Dist(set1,set2):
vec=(set2[0]-set1[0],set2[1]-set1[1])
dist=(vec[0]**2+vec[1]**2)
return sqrt(dist)
class Tile(object):
def __init__(self,pos,spr,typ):
self.typ=typ
self.spr=spr
self.pos=pos
self.rect=pygame.rect.Rect(pos[0],pos[1],32,32)
self.adv=0
self.haspower=0
while True:
pygame.display.set_caption(str(clock.get_fps()))
screen.fill((2,110,200))
key=pygame.key.get_pressed()
othertiles=[x for x in tiles if x.spr==power1 or x.spr==power2]
for e in pygame.event.get():
if e.type==QUIT:
exit()
if e.type==KEYUP:
if key[K_s]:
if e.key==K_e:
sel+=1
if sel==len(tilelist):
sel=0
if e.key==K_q:
sel-=1
if sel==-1:
sel=len(tilelist)-1
if e.type==MOUSEMOTION:
mse=pygame.mouse.get_pos()
if key[K_LSHIFT] or key[K_RSHIFT]:
if pygame.mouse.get_pressed()==(1,0,0):
tilesatmouse=[t for t in tiles if t.rect.collidepoint(mse)]
if not tilesatmouse:
if sel==4:
money-=costlist[sel]
tiles.append(Tile((mse[0] & 0x7fffffe0,mse[1] & 0x7fffffe0),tilelist[sel],'res'))
else:
money-=costlist[sel]
tiles.append(Tile((mse[0] & 0x7fffffe0,mse[1] & 0x7fffffe0),tilelist[sel],'tile'))
elif pygame.mouse.get_pressed()==(0,0,1):
for t in tiles:
if t.rect.collidepoint(mse):
money-=5
tiles.remove(t)
if e.type==MOUSEBUTTONUP:
if e.button==1:
tilesatmouse=[t for t in tiles if t.rect.collidepoint(mse)]
if not tilesatmouse:
if sel==4:
money-=costlist[sel]
tiles.append(Tile((mse[0] & 0x7fffffe0,mse[1] & 0x7fffffe0),tilelist[sel],'res'))
else:
money-=costlist[sel]
tiles.append(Tile((mse[0] & 0x7fffffe0,mse[1] & 0x7fffffe0),tilelist[sel],'tile'))
if e.button==3:
for t in tiles:
if t.rect.collidepoint(mse):
money-=5
tiles.remove(t)
for t in tiles:
if t.spr==water1 or t.spr==water2:
if tileframe>999:
t.spr=water1
else:
t.spr=water2
if t.spr==power1 or t.spr==power2:
if tileframe>999:
t.spr=power1
else:
t.spr=power2
if t.typ=='res':
for x in othertiles:
distance=Dist((t.pos[0],t.pos[1]),(x.pos[0],x.pos[1]))
if distance<2500:
t.haspower=1
else:
t.haspower=0
if othertiles==[]:
t.haspower=0
if t.haspower==0:
t.spr.set_alpha(100)
else:
t.spr.set_alpha(255)
if t.adv>=0:
t.adv+=R
if t.adv==2000:
t.spr=house1_0
if t.adv==4000:
t.spr=house1_1
pop+=choice([4,6,8,10])
t.adv=-1
screen.blit(t.spr,t.pos)
if monthtime<10000:
monthtime+=1
else:
month+=1
money+=20
monthtime=0
if month==13:
month=0
money+=pop/2*taxrateR
year+=1
screen.blit(curspr, (mse[0] & 0x7fffffe0,mse[1] & 0x7fffffe0))
if key[K_s]:
pygame.draw.rect(screen, (0,0,0), (0,0,640,80), 0)
moneydraw=font.render('Funds: '+str(money), 1, (255,255,255))
yeardraw=font.render('Year: '+str(year), 1, (255,255,255))
monthdraw=font.render('Month: '+str(month), 1, (255,255,255))
namedraw=font.render(namelist[sel],1,(255,255,255))
screen.blit(moneydraw, (2,2))
screen.blit(namedraw, (2,18))
screen.blit(yeardraw, (2,34))
screen.blit(monthdraw, (2,50))
clock.tick(999)
tileframe-=1
if tileframe==0:tileframe=2000
pygame.display.flip()