I have many different classes including Main, Enemy and Tower, in these classes i have methods and such, and i am trying to run a for loop provided by someone else on stack overlow (Thank you so much if your reading this), and i keep getting the same error local variable tower refferenced before assignment and i dont understand it.
import sys
import pygame
from pygame.locals import *
from random import *
WIDTH = 800
HEIGHT = 600
RED = (150, 0, 0)
LRED = (255, 0, 0)
GREEN = (0, 150, 0)
LGREEN = (0, 255, 0)
BLUE = (0, 0, 150)
LBLUE = (0, 0, 255)
CYAN = (0, 225, 230)
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]
pygame.init()
Mainclock = pygame.time.Clock()
light_image_map1 = pygame.image.load('Kami_lookout.png')
light_image_map1 = pygame.transform.scale(light_image_map1, (840, 630))
action_box_image = pygame.image.load('goku.png')
background_rectangle = pygame.Rect(0, 0, WIDTH, HEIGHT)
fantower_image = pygame.image.load('saibaman1.png')
fantower_image = pygame.transform.scale(fantower_image, (30, 40))
tower1 = pygame.image.load('goku.png')
def wave(quantity, size, distance):
global saiba
hh = True
for i in range(quantity):
saiba = Enemy(800 + (distance + size)*i, 100- size/2, size, size)
MainWindow.enemy.append(saiba)
def text_objects(text, font):
textSurface = font.render(text, True, WHITE)
return textSurface, textSurface.get_rect()
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.Font("freesansbold.ttf", 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(width/2)), (y+(height/2)))
MainWindow.Gamewindow.blit(textSurf, textRect)
def button_tower(x, y, width, height, mouse, click, image, action = None):
if x+width > mouse[0] > x and y+height > mouse[1] > y:
if click[0] == 1 and action != None:
MainWindow.action_box = action
def tower(width=30, height=30):
global goku
goku = Tower(MainWindow.mouse[0], MainWindow.mouse[1], width, height)
MainWindow.tower.append(goku)
class Main:
def __init__(self, width = WIDTH+100, height = HEIGHT + 100):
pygame.display.set_caption('DBZ Tower Defense')
self.startwave = False
self.width = width
self.height = height
self.Gamewindow = pygame.display.set_mode((self.width, self.height))
def wave(self):
self.startwave = True
def Intro(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.Gamewindow.fill(BLACK)
largeText = pygame.font.Font('freesansbold.ttf', 30)
TextSurf, TextRect = text_objects("simple tower defense game", largeText)
TextRect = (100, 100)
self.Gamewindow.blit(TextSurf, TextRect)
button_text("New game", 100, 200, 400, 50, GREEN, LGREEN, MainWindow.MainLoop)
button_text("Continue", 100, 300, 400, 50, RED, LRED)
button_text("Exit", 100, 400, 400, 50, BLUE, LBLUE, quit)
pygame.display.update()
def MainLoop(self):
self.enemy = []
self.tower = []
self.action_box = None
while True:
Mainclock.tick(60)
self.mouse = pygame.mouse.get_pos()
self.click = pygame.mouse.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == ord('t'):
tower()
if self.startwave == True and len(self.enemy)==0:
wave(10, 20, 8)
self.startwave = False
for index,ene in enumerate(self.enemy):
ene.update()
ene.move()
if ene.rect.left <= 0:
del self.enemy[index]
self.Gamewindow.fill(CYAN)
self.Gamewindow.blit(light_image_map1, background_rectangle)
button_tower(800, 0, 50, 50, self.mouse, self.click, fantower_image, tower)
if pygame.mouse.get_pressed()[0] == 1 and self.action_box != None:
rectangle30 = pygame.Rect(self.mouse[0]-15, self.mouse[1]-15, 30, 30)
self.Gamewindow.blit(action_box_image, rectangle30)
elif self.action_box != None:
self.action_box()
self.action_box = None
for object_enemy in self.enemy:
self.Gamewindow.blit(fantower_image, object_enemy.rect)
for object_tower in self.tower:
self.Gamewindow.blit(object_tower.image, object_tower.rect)
button_text("Start next wave", 0, 600, WIDTH, 100, PURPLE, LPURPLE, MainWindow.wave)
**#This is where the problem is**
**for tower in self.tower:
tower_rect = tower.get_rect()
for enemy in self.enemy:
if ( enemy.collidesWith( tower_rect ) ):
# Make enemy dead
enemy.die()**
**#There might be a problem here in future too**
**for i in range( len( self.enemy ) - 1, -1, -1): # note: loop backwards
if ( self.enemy[i].isDead() ):
del( self.enemy[i] )**
pygame.display.update()
class Enemy:
def __init__(self, x, y, width, height):
self.dead = False
self.rect = pygame.Rect(x, y, width, height)
self.dir = 4
self.movement = [(810, 100, 2), (810, 300, 4), (575, 300, 8), (575, 230, 4), (385, 230, 2), (385, 300, 4), (276, 300, 2), (276, 392, 4), (70, 392, 8), (70, 300, 4)]
def move(self):
if self.dir == 8:
self.rect.centery -= 1
if self.dir == 4:
self.rect.centerx -= 1
if self.dir == 6:
self.rect.centerx += 1
if self.dir == 2:
self.rect.centery += 1
def update(self):
for pos in self.movement:
if self.rect.center == (pos[0], pos[1]):
self.dir = pos[2]
def color(self, colorid):
return COLORS[colorid]
def die( self, action=True ):
self.dead = action
def isDead( self ):
return self.dead
def collidesWith( self, other_rect ):
""" Return true, if other_rect overlaps my rect """
result = self.rect.colliderect( other_rect )
def get_rect( self ):
""" Get a copy of the rect, in PyGame style """
return self.rect.copy()
class Tower:
def __init__(self, x, y, width, height):
self.rect = pygame.Rect(x-15, y-15, width, height)
self.image = pygame.transform.scale(tower1, (50, 50))
def colliderec(self):
if self.rect.collidedict(self.rect):
print("true")
#if Enemy.rect.collideRect(Tower.rect):
# print("true")
class GameInformation:
def __init__(self, money, health, x, y):
self.screen_X = x
self.screen_Y = y
self.money = money
self.health = health
def display_text(win, text, x, y):
pygame.font.init()
myfont = pygame.font.SysFont('Comic Sans MS', 30)
textsurface = myfont.render(text, False, (0, 0, 0))
win.blit(textsurface, (x, y))
class Collide:
def __init__(self, pos_x, pos_y, size_x, size_y):
self.pos_x = pos_x
self.pos_y = pos_y
self.size_x = size_x
self.size_y = size_y
self.hitbox_rect = Rect(pos_x, pos_y, size_x, size_y) # rectangle hitbox
MainWindow = Main()
MainWindow.Intro()