patternpythonMinor
Beginning of a tower defense game, using pygame
Viewed 0 times
defensebeginninggameusingpygametower
Problem
I'm currently working on my first project and I have been programming in python for 4 days now. I currently have a dilemma where my code is running too slowly. I don't want you to make a full review, I am mostly interested in advice on how to optimise my code. Here is my code:
Note that the comments aren't perfect English :)
```
import sys
import pygame
from pygame.locals import *
from random import randint
# window properties
WINDOWWIDTH = 800
WINDOWHEIGHT = 600
#colors
RED = (150, 0, 0)
LRED = (255, 0, 0)
GREEN = (0, 150, 0)
LGREEN = (0, 255, 0)
BLUE = (0, 0, 150)
LBLUE = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (150, 0, 150)
LPURPLE = (255, 0, 255)
COLORS = [RED, LRED, GREEN, LGREEN, BLUE, LBLUE, WHITE, PURPLE, LPURPLE]
# So i can use pygame things
pygame.init()
Mainclock = pygame.time.Clock()
# images
action_box_image = pygame.image.load('towers/actionbox.png')
background_rectangle = pygame.Rect(0, 0, WINDOWWIDTH, WINDOWHEIGHT)
image_map1 = pygame.image.load('maps/Map1.png')
light_image_map1 = pygame.image.load('maps/Map1_light.png')
fantower_image = pygame.image.load('towers/fan.png')
# function for starting a wave
def wave(quantity, size, distance):
for i in range(quantity):
MainWindow.enemy.append(Enemy(800 + (distance + size)*i, 100- size/2, size, size))
# function that creates texts
def text_objects(text, font):
textSurface = font.render(text, True, WHITE)
return textSurface, textSurface.get_rect()
# used for making some buttons
def button_text(msg, x, y, width, height, mouselse, mouseover, action = None, Text = True):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+width > mouse[0] > x and y+height > mouse[1] > y:
pygame.draw.rect(MainWindow.Gamewindow, mouseover,(x,y,width,height))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(MainWindow.Gamewindow, mouselse,(x,y,width,height))
smallText = pygame.font.F
Note that the comments aren't perfect English :)
```
import sys
import pygame
from pygame.locals import *
from random import randint
# window properties
WINDOWWIDTH = 800
WINDOWHEIGHT = 600
#colors
RED = (150, 0, 0)
LRED = (255, 0, 0)
GREEN = (0, 150, 0)
LGREEN = (0, 255, 0)
BLUE = (0, 0, 150)
LBLUE = (0, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
PURPLE = (150, 0, 150)
LPURPLE = (255, 0, 255)
COLORS = [RED, LRED, GREEN, LGREEN, BLUE, LBLUE, WHITE, PURPLE, LPURPLE]
# So i can use pygame things
pygame.init()
Mainclock = pygame.time.Clock()
# images
action_box_image = pygame.image.load('towers/actionbox.png')
background_rectangle = pygame.Rect(0, 0, WINDOWWIDTH, WINDOWHEIGHT)
image_map1 = pygame.image.load('maps/Map1.png')
light_image_map1 = pygame.image.load('maps/Map1_light.png')
fantower_image = pygame.image.load('towers/fan.png')
# function for starting a wave
def wave(quantity, size, distance):
for i in range(quantity):
MainWindow.enemy.append(Enemy(800 + (distance + size)*i, 100- size/2, size, size))
# function that creates texts
def text_objects(text, font):
textSurface = font.render(text, True, WHITE)
return textSurface, textSurface.get_rect()
# used for making some buttons
def button_text(msg, x, y, width, height, mouselse, mouseover, action = None, Text = True):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+width > mouse[0] > x and y+height > mouse[1] > y:
pygame.draw.rect(MainWindow.Gamewindow, mouseover,(x,y,width,height))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(MainWindow.Gamewindow, mouselse,(x,y,width,height))
smallText = pygame.font.F
Solution
Currently the font for the text is setup multiple times every loop. I would move these lines to the general settings above the functions, or to the init function:
Apparently doublebuffer helps a bit (according to the answer here):
You should avoid having to draw your entire screen every loop. Rather move what needs to be moved and then paint the bg image over all points where stuff moved away from. I haven't done anything in pygame in a while, so I can't give you concrete code to do this here.
You should use
This converts the image's pixel format to be the same as the surface's you are going to blit it on. Otherwise this conversion will have to happen on-the-fly everytime you
If you need transparency, use
smallText = pygame.font.Font("freesansbold.ttf",20)
largeText = pygame.font.Font('freesansbold.ttf',30)Apparently doublebuffer helps a bit (according to the answer here):
from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)You should avoid having to draw your entire screen every loop. Rather move what needs to be moved and then paint the bg image over all points where stuff moved away from. I haven't done anything in pygame in a while, so I can't give you concrete code to do this here.
You should use
.convert() on your images after loading:action_box_image = pygame.image.load('towers/actionbox.png').convert()
image_map1 = pygame.image.load('maps/Map1.png').convert()
light_image_map1 = pygame.image.load('maps/Map1_light.png').convert()
fantower_image = pygame.image.load('towers/fan.png').convert()This converts the image's pixel format to be the same as the surface's you are going to blit it on. Otherwise this conversion will have to happen on-the-fly everytime you
blit(). For more information see here.If you need transparency, use
.convert_alpha() instead.Code Snippets
smallText = pygame.font.Font("freesansbold.ttf",20)
largeText = pygame.font.Font('freesansbold.ttf',30)from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)action_box_image = pygame.image.load('towers/actionbox.png').convert()
image_map1 = pygame.image.load('maps/Map1.png').convert()
light_image_map1 = pygame.image.load('maps/Map1_light.png').convert()
fantower_image = pygame.image.load('towers/fan.png').convert()Context
StackExchange Code Review Q#134646, answer score: 2
Revisions (0)
No revisions yet.