When I was programing a basic UFO game in python 2.7 and with pygame I came accross an error, However it didn't come up in the consol. What happend was:
I was programing
Made a little change in the code
The Menu Screen worked fine and I go to play the game
It then keeps restarting.
I edited a few more bits of code so it'd be in a while loop until it would call a command correctly.
And It still wouldent call the command.
If you want to have the Images you can download them and the Sorcecode here:
http://dl.dropbox.com/u/33487921/A%20Problem.zip
Here is the code:
import sys, pygame, random
from pygame.locals import *
from time import gmtime, strftime
pygame.init()
width = int(500*2)
height = int(300*2)
width2 = width + (width/5)
height2 = height + ((height/3)/2)
screen = pygame.display.set_mode((width, height2))
pygame.display.set_caption("MoeTM's UFO Game")
class FlyingObject():
def Restart(self):
self.amount = 0
self.array = []
def New(self, FPS):
self.amount += 1
for i in range(self.amount):
if i == self.amount-1:
self.array.append([])
Strength = random.randrange(1, 101, 1)
if Strength in range(1, 51, 1):
Type = 1
if Strength in range(51, 76, 1):
Type = 2
if Strength in range(76, 88, 1):
Type = 3
if Strength in range(88, 94, 1):
Type = 4
if Strength in range(94, 101, 1):
Type = 5
X = random.randrange(0,1,1)
if X == 0:
XMove = random.randrange(1,6,1)
if X == 1:
XMove = random.randrange(1,6,1)
XMove /= 5.0
Y = random.randrange(0,2,1)
if Y == 0:
YMove = random.randrange(1,6,1)
if Y == 1:
YMove = random.randrange(1,6,1)
YMove /= 5.0
XMove *= 10
YMove *= 10
XMove *= FPS
YMove *= FPS
TLBR = random.randrange(0,4,1)
if TLBR == 0:#top
XIntercept = random.randrange(0,width+1,1)
YIntercept = -5
if TLBR == 1:#left
XIntercept = -5
YIntercept = random.randrange(0,height+1,1)
if TLBR == 2:#bottom
XIntercept = random.randrange(0,width+1,1)
YIntercept = height + 5
if TLBR == 3:#right
XIntercept = width + 5
YIntercept = random.randrange(0,height+1,1)
if XIntercept in range((width/4)*3,width+1,1):
XMove = -XMove
if YIntercept in range((height/4)*3,height+1,1):
YMove = -YMove
if XIntercept in range((width/4),(width/4)*3, 1):
chance = random.randrange(0,2,1)
if chance == 1:
XMove=-XMove
if YIntercept in range((height/4),(height/4)*3, 1):
chance = random.randrange(0,2,1)
if chance == 1:
YMove=-YMove
if XMove < 1 and YMove >= 1:
XMove *= 3
YMove *= 3
if YMove < 1 and XMove >= 1:
XMove *= 3
YMove *= 3
if YMove < 1 and XMove <1:
XMove *= 3
YMove *= 3
self.array[i] = [XMove,YMove,XIntercept,YIntercept,False,False, Type, "image"]
def Move(self, PX, PY, IX, IY):
for i in range(self.amount):
self.array.append([])
if self.array[i][2] > width +10 or self.array[i][2] < -10:
self.array[i][4] = False
self.array[i][5] = True
if self.array[i][3] > height +10 or self.array[i][3] < -10:
self.array[i][4] = False
self.array[i][5] = True
Check = True
if self.array[i][4] == False and self.array[i][5] == True:
Check = False
if Check == True:
self.array[i][2] += self.array[i][0]#XIntercept+=XMove
self.array[i][3] += self.array[i][1]#YIntercept+=Ymove
if self.array[i][2] in range(0,width+1,1) and self.array[i][3] in range(0,height+1,1):
self.array[i][4] = True
self.array[i][5] = True
else:
self.array[i][4] = False
if int(self.array[i][2]+5) in range(PX, PX+IX, 1) and int(self.array[i][3]+5) in range(PY, PY+IY, 1):
self.colide(self.array[i][6])
self.array[i][4] = False
self.array[i][5] = True
def Blit(self):
for i in range(self.amount):
self.array.append([])
Check = True
if self.array[i][4] == False and self.array[i][5] == True:
Check = False
if Check == True:
screen.blit(self.array[i][7], (int(self.array[i][2]), int(self.array[i][3])))
class Bullits(FlyingObject):
def colide(self, damage=1):
Play.Game.Player.Hit(damage)
def Convert(self):
for i in range(self.amount):
self.array.append([])
self.array[i][7]=self.Image = pygame.image.load("images\Bullit"+str(self.array[i][6])+".png")
class Orbs(FlyingObject):
def colide(self, ammount=1):
Play.Game.Player.GotPoint(ammount)
def Convert(self):
for i in range(self.amount):
self.array.append([])
self.array[i][7]=self.Image = pygame.image.load("images\Orb"+str(self.array[i][6])+".png")
class UFO():
def __init__(self):
self.health = 10
self.maxhealth = 50
self.startinghealth = 10
self.maxspeed = 20
self.Image = pygame.image.load("images\UFO.png")
self.Heart0 = pygame.transform.scale(pygame.image.load("images\Heart0.png"), (width/50,height/30))
self.Heart1 = pygame.transform.scale(pygame.image.load("images\Heart1.png"), (width/50,height/30))
self.Heart2 = pygame.transform.scale(pygame.image.load("images\Heart2.png"), (width/50,height/30))
self.Heart3 = pygame.transform.scale(pygame.image.load("images\Heart3.png"), (width/50,height/30))
self.Heart4 = pygame.transform.scale(pygame.image.load("images\Heart4.png"), (width/50,height/30))
self.Heart5 =pygame.transform.scale( pygame.image.load("images\Heart5.png"), (width/50,height/30))
self.ix = 100
self.iy = 40
self.points = 0
self.collection = 0
self.x = (width-self.ix)/2
self.y = (height-self.iy)/2
self.HeartCol= []
self.DA = "New"
for i in range(0,10,1):
self.HeartCol.append([])
dif = int((width/2.5)/10)
higt = int(((height2-height)/2)+height)
self.HeartCol[i] = [dif*i, higt]
def New(self):
print "Starting"
self.health = self.startinghealth
self.x = (width-self.ix)/2
self.y = (height-self.iy)/2
self.DA = "Alive"
print Alive
def Hit(self, damage=1):
self.health -= damage
if self.health <= 0:
self.DA = "Dead"
def GotPoint(self, amount=1):
self.points += amount
if self.points >= 10:
self.points -= 10
self.collection += 1
self.health += 1
if self.health >= self.maxhealth:
self.health = self.maxhealth
def Move(self,mx,my):
if mx >= width - (self.ix/2):
mx = width - self.ix
elif mx <= self.ix/2:
mx = 0
else:
mx = mx - (self.ix/2)
if my >= height - (self.iy/2):
my = height - self.iy
elif my <= self.iy/2:
my = 0
else:
my = my - (self.iy/2)
if mx > self.x:
if mx-self.x > self.maxspeed:
self.x += self.maxspeed
else:
self.x = mx
if mx < self.x:
if self.x-mx > self.maxspeed:
self.x -= self.maxspeed
else:
self.x = mx
if my > self.y:
if my-self.y > self.maxspeed:
self.y += self.maxspeed
else:
self.y = my
if my < self.y:
if self.y-my > self.maxspeed:
self.y -= self.maxspeed
else:
self.y = my
def Blit(self):
screen.blit(self.Image, (self.x, self.y))
def ForBlit(self):
return self.x, self.y, self. ix, self.iy
def Toolbar(self):
pygame.draw.rect(screen, [127,127,127], pygame.Rect(0, height, width, height2))
for i in range(0,10,1):
if self.health >= 41+i:
screen.blit(self.Heart5, (self.HeartCol[i][0], self.HeartCol[i][1]))
elif self.health >= 31+i:
screen.blit(self.Heart4, (self.HeartCol[i][0], self.HeartCol[i][1]))
elif self.health >= 21+i:
screen.blit(self.Heart3, (self.HeartCol[i][0], self.HeartCol[i][1]))
elif self.health >= 11+i:
screen.blit(self.Heart2, (self.HeartCol[i][0], self.HeartCol[i][1]))
elif self.health >= 1+i:
screen.blit(self.Heart1, (self.HeartCol[i][0], self.HeartCol[i][1]))
else:
screen.blit(self.Heart0, (self.HeartCol[i][0], self.HeartCol[i][1]))
def DOA(self):
return self.DA
def New(self):
pass
class Background():
def __init__(self):
self.sr = 5
self.bg = [0,0,0]
def New(self):
self.amountOfStars = random.randrange(10,51,1)
self.stars=[]
for i in range(self.amountOfStars):
x = random.randrange(self.sr*2,width-(self.sr*2)+1,1)
y = random.randrange(self.sr*2,height-(self.sr*2)+1,1)
coulerr = random.randrange(200,256,1)
coulerg = random.randrange(200,256,1)
coulerb = random.randrange(0,56,1)
size = random.randrange(5, 10, 1)
self.stars.append([])
self.stars[i] = [[x,y],[coulerr,coulerg,coulerb],size]
def Blit(self):
screen.fill(self.bg)
for i in range(self.amountOfStars):
self.stars.append([])
pygame.draw.circle(screen,self.stars[i][1],self.stars[i][0],self.stars[i][2])
class Text():
def Text(self, Text, TextSize, Couler):
self.Couler = Couler
self.TextSize = int(TextSize)
self.Text = str(Text)
self.font = pygame.font.Font(None, self.TextSize)
self.text = self.font.render(self.Text, 1, self.Couler)
self.Size = self.text.get_rect()
self.ctext = self.text
self.cCouler = self.Couler
def Position(self, X, Y):
self.X = X
self.Y = Y
self.Position = self.X,self.Y
def Blit(self):
screen.blit(self.ctext, [self.X,self.Y])
def IsItClicked(self, MouseX, MouseY):
if MouseX in range(self.X,self.X+self.Size[2]+1,1) and MouseY in range(self.Y,self.Y+self.Size[3]+1,1):
return True
else:
return False
def Hover(self, MouseX=0, MouseY=0, couler=-1):
if couler == -1:
couler = self.Couler
hover = self.IsItClicked(MouseX, MouseY)
if hover == True:
self.cCouler = couler
self.ctext = self.font.render(self.Text, 1, self.cCouler)
else:
self.cCouler = self.Couler
self.ctext = self.font.render(self.Text, 1, self.cCouler)
class Menu():
def __init__(self):
self.Move = (height2/4)/2
self.move = self.Move*2
self.Menu = Text()
self.Menu.Text("MoeTM's UFO Game", 50, [255,255,0])
self.Menu.Position((width - self.Menu.Size[2])/2,self.Menu.Size[0])
self.Play = Text()
self.Play.Text("Play The Game!", 30, [255,255,0])
self.Play.Position(self.Play.Size[0]+20,self.Play.Size[0]+self.Move)
self.Shop = Text()
self.Shop.Text("Enter the Shop, Why?", 30, [255,255,0])
self.Shop.Position(self.Shop.Size[0]+20,self.Shop.Size[0]+self.move*2-self.Move)
self.Saves = Text()
self.Saves.Text("Save the game, ;P", 30, [255,255,0])
self.Saves.Position(self.Saves.Size[0]+20,self.Saves.Size[0]+self.move*3-self.Move)
self.Options = Text()
self.Options.Text("Options...", 30, [255,255,0])
self.Options.Position(self.Options.Size[0]+20,self.Options.Size[0]+self.move*4-self.Move)
self.Area = "Menu"
def Blit(self, MouseX=0, MouseY=0):
if self.Area == "Menu":
self.Play.Hover(MouseX, MouseY, [192,255,0])
self.Shop.Hover(MouseX, MouseY, [192,255,0])
self.Saves.Hover(MouseX, MouseY, [192,255,0])
self.Options.Hover(MouseX, MouseY, [192,255,0])
self.Play.Blit()
self.Shop.Blit()
self.Saves.Blit()
self.Options.Blit()
if self.Area == "Shop":
pass
if self.Area == "Saves":
pass
if self.Area == "Options":
pass
if self.Area != "Play":
self.Menu.Hover(MouseX, MouseY, [192,255,0])
self.Menu.Blit()
def IsClicked(self, MouseX, MouseY):
if self.Area == "Menu":
play = self.Play.IsItClicked(MouseX, MouseY)
if play == True:
self.Area = "Play"
Shop = self.Shop.IsItClicked(MouseX, MouseY)
if Shop == True:
self.Area = "Shop"
Saves = self.Saves.IsItClicked(MouseX, MouseY)
if Saves == True:
self.Area = "Saves"
Options = self.Options.IsItClicked(MouseX, MouseY)
if Options == True:
self.Area = "Options"
menu = self.Menu.IsItClicked(MouseX, MouseY)
if menu == True:
self.Area = "Menu"
def getArea(self):
return self.Area
class Game():
def __init__(self):
self.Player = UFO()
self.Background = Background()
self.Orbs = Orbs()
self.Bullits = Bullits()
self.Death = pygame.image.load("images\Death.png")
self.Death = pygame.transform.scale(self.Death, (width2, height2))
self.death = 0
def New(self):
while True:
self.Player.New()
Place = self.Player.DOA()
if Place != "New":
self.TotalTime = 0
self.Background.New()
self.Bullits.Restart()
self.Orbs.Restart()
def Blit(self):
self.Bullits.Convert()
self.Orbs.Convert()
self.Background.Blit()
self.Bullits.Blit()
self.Orbs.Blit()
self.Player.Blit()
def Move(self, MX, MY):
self.Player.Move(MX, MY)
PX, PY, IX, IY = self.Player.ForBlit()
self.Bullits.Move(PX, PY, IX, IY)
self.Orbs.Move(PX, PY, IX, IY)
def Updater(self, time):
self.TotalTime += time
def Death(self):
if self.death >= 1: return 0
self.death += 1
time = float(self.TotalTime) * 10
time = int(time)
time /= 10.0
time = str(time)
self.DeadText = Text()
text = "You died in "+time+" seconds"
self.DeadText.Text(text,50,[0,0,0])
self.DeadText.Position((width-self.DeadText.Size[2])/2,(height2-self.DeadText.Size[3])/2)
def DeadBlit(self):
screen.blit(self.Death, (0, 0))
self.DeadText.Blit()
class Main():
def __init__(self):
self.Game = Game()
self.Menu = Menu()
self.DA= ""
self.seconds = 0
self.clock = pygame.time.Clock()
self.FPS = 0.1
self.QUIT = False
self.Place = ["","New"]
self.difficalty1 = 10
self.difficalty2 = 5
def Main(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.QUIT = True
if event.type == KEYDOWN:
if event.key == K_p:
time = strftime("%a, %d %b %Y %H:%M:%S", gmtime())
pygame.image.save(screen, time+".png")
#if event.key == K_DOWN:
#if event.key == K_UP:
if event.type == MOUSEBUTTONDOWN:
self.Menu.IsClicked(MouseX, MouseY)
if self.QUIT == True:
pygame.quit()
break
self.seconds += self.clock.tick()/1000.0
if self.seconds >= self.FPS:
MouseX,MouseY = pygame.mouse.get_pos()
self.Place[0] = self.Menu.getArea()
if self.Place[0] == "Play" and self.Place[1] == "New":
self.Game.New()
screen.fill([0,0,0])
if self.Place[0] != "Play":
self.Menu.Blit(MouseX, MouseY)
if self.Place[0] == "Play":
if self.Place[1] != "Dead":
self.Game.Move(MouseX,MouseY)
self.Game.Updater(self.seconds)
randomChance = random.randrange(0,self.difficalty1,1)
if randomChance in range(0, self.difficalty2, 1):
self.Game.Orbs.New(self.FPS)
randomChance = random.randrange(0,self.difficalty1,1)
if randomChance in range(0, self.difficalty2, 1):
self.Game.Bullits.New(self.FPS)
self.Game.Blit()
self.Place[1] = self.Game.Player.DOA()
if self.Place[1] == "Dead":
self.Game.Death()
self.Game.DeadBlit()
pygame.display.flip()
self.seconds -= self.FPS
Play = Main()
Play.Main()
pygame.quit()
here is the two bits of code that have broke. (I put the class abouve the def's so you know what class there in)
class UFO():
def New(self):
print "Starting"
self.health = self.startinghealth
self.x = (width-self.ix)/2
self.y = (height-self.iy)/2
self.DA = "Alive"
print Alive
class Game():
def New(self):
while True:
self.Player.New()
Place = self.Player.DOA()
if Place != "New":
self.TotalTime = 0
self.Background.New()
self.Bullits.Restart()
self.Orbs.Restart()
if you use the code in IDLE then you will know that it dousent even call self.Player.New() because the Shell dousn't print "Starting" or give an error for me putting print Alive, it just continuosly loops the while loop.
Sorry for the Miles of code, :( But Hopefully it helps, mostly because without some of it you wouldent understand it. Also Thankyou for taking the time to read and try to answer this. And Sorry for all the grammer and spalling mistakes, I can't spell.
Your issues is the While True in your Game.New method, also i have found other issues that make the game to not run.
Below is the diff with the fixed code:
--- ../A Problem-1/Game.pyw 2012-01-25 13:32:00.000000000 -0300
+++ Game.pyw 2012-01-25 11:55:56.000000000 -0300
## -11,6 +11,9 ##
pygame.display.set_caption("MoeTM's UFO Game")
class FlyingObject():
+ def __init__(self):
+ self.amount = 0
+ self.array = []
def Restart(self):
self.amount = 0
self.array = []
## -233,6 +236,7 ##
def __init__(self):
self.sr = 5
self.bg = [0,0,0]
+ self.amountOfStars = 0
def New(self):
self.amountOfStars = random.randrange(10,51,1)
self.stars=[]
## -352,15 +356,15 ##
self.Death = pygame.image.load("images\Death.png")
self.Death = pygame.transform.scale(self.Death, (width2, height2))
self.death = 0
+ self.TotalTime = 0
def New(self):
- while True:
- self.Player.New()
- Place = self.Player.DOA()
- if Place != "New":
- self.TotalTime = 0
- self.Background.New()
- self.Bullits.Restart()
- self.Orbs.Restart()
+ self.Player.New()
+ Place = self.Player.DOA()
+ if Place != "New":
+ self.TotalTime = 0
+ self.Background.New()
+ self.Bullits.Restart()
+ self.Orbs.Restart()
def Blit(self):
self.Bullits.Convert()
self.Orbs.Convert()
Related
I was creating Alien invasion and I encountered this error of " object has no attribute '_sprite__g', please help me
class Game():
def __init__(self, screen, screen_height, screen_width):
self.dir = os.path.dirname(__file__)
self.display_message(screen,"Enter name", 50, WHITE, 600,500)
pygame.display.flip()
self.name = input("Enter your name")
self.player_unshield_image = self.image('Traveller.png',75,75)
self.player_shield_image = self.image('Zhongli.png',75,75)
self.green_slave = self.image('Sara.png', 30,30)
self.blue_slave = self.image('Yae.png',30,30)
self.grey_slave =self.image('Itto.png',50,50)
self.purple_slave = self.image('Raiden.png',120,120)
self.fireball =self.image('Bullet.png',20,40)
self.mango =self.image('YellowBullet.png',30,80)
self.sun = self.image('OrangeBullet.png', 20,90)
self.bullet_dict ={None:self.fireball, 'WideBullet':self.mango, 'PierceBullet':self.sun}
self.powerup_wide =self.image('THICC.png',30,30)
self.powerup_pierce =self.image('Pierce.png',30,30)
self.powerup_shield =self.image('Noelle.png',30,30)
self.powerup_add_score = self.image('Extra.png',30,30)
self.high_score = 0
self.shoot = self.sound('Pew.wav')
self.explode =self.sound('BOOM_BOOM_BAKUDAN.wav')
self.reset()
def reset(self):
self.normal =(2,1, self.green_slave)
self.tank =(1,2,self.blue_slave)
self.rock =(5,3, self.grey_slave)
self.boss =(7,10, self.purple_slave)
self.all_sprites = pygame.sprite.Group()
self.Slaves = pygame.sprite.Group()
self.Ammo = pygame.sprite.Group()
self.Powerup =pygame.sprite.Group()
self.game_active =False
self.Score = 0
self.ammo_powerup =None
self.Max_level =10
self.level =0
self.level_text_timer = 0
self.max_ammo = 6
self.ammo_num =self.max_ammo
self.ammo_reload_timer = 0
self.ammo_text =WHITE
self.game_played =False
self.clock = pygame.time.Clock()
self.clock.tick(FPS)
self.player =Player(self.player_unshield_image, self.player_shield_image)
self.all_sprites.add(self.player)
for i in range(2) :
powerup = Powerups(self.powerup_shield, self.powerup_pierce, self.powerup_add_score, self.powerup_wide)
self.all_sprites.add(powerup)
self.Powerup.add(powerup)
def image(self, image_name, width, height):
image_dir =os.path.join(self.dir, 'Images')
image = pygame.image.load(os.path.join(image_dir, image_name)).convert()
scaled_image =pygame.transform.scale(image,(width,height))
return scaled_image
def sound(self, sound_name):
sound_dir=os.path.join(self.dir, 'Sounds')
return pygame.mixer.Sound(os.path.join(sound_dir, sound_name))
def create_slaves(self, width, height, offset_a, offset_b, distance, slave_info):
speed =slave_info[0]
health =slave_info[1]
slave_image =slave_info[2]
for x in range (width):
for y in range(height):
d= Slaves(offset_a +x*distance, offset_b +y*distance, speed, health, slave_image)
self.Slaves.add(d)
self.all_sprites.add(d)
def display_message(self, surf, message, size, color, j, k):
font = pygame.font.SysFont("Arial", size)
message_surface = font.render(message, True, color)
message_rect = message_surface.get_rect()
message_rect.midtop = (j, k)
surf.blit(message_surface, message_rect)
def instructions(self):
print('''Welcome to space invaders!
Use Arrow keys to shoot, collect the coming powerups to gain special buffs
figure out the point distribution yourself
powerups include:
pierce bullet, wide bullet, extra score addition
the game has 10 levels, there are no extra lives
last but most important, the game is over when you lose
good luck!(probably)''')
def get_events(self, button):
for event in pygame.event.get():
if event.type == QUIT:
with open(os.path.join(self.dir, 'high_scores.txt'), 'a+') as score_file:
score_file.write(self.name + "," + str(self.high_score)+ "," + (self.level)+ "\n")
return False
elif event.type == KEYDOWN:
if event.key == K_SPACE and self.ammo_num > 0:
img =self.bullet_dict[self.ammo_powerup]
ammo = Ammo(self.player.rect.center, self.player.rect.top, self.ammo_powerup, img)
self.ammo_powerup = None
self.all_sprites.add(ammo)
self.Ammo.add(ammo)
self.ammo_num -=1
self.shoot.play()
else:
pass
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y =pygame.mouse.get_pos()
self.check(button, mouse_x, mouse_y)
return True
def check(self, button, x, y):
clicked = button.rect.collidepoint(x,y)
if clicked and not self.game_active:
self.all_sprites.empty()
self.Slaves.empty()
self.Ammo.empty
self.reset()
self.game_active = True
pygame.mouse.set_visible = False
def start(self):
self.all_sprites.update()
if len(self.Slaves) ==0:
self.Ammo.empty()
self.level +=1
self.level_text_timer = 0
if self.level ==1:
self.create_slaves(10,5, 300, 40, 60, self.normal)
self.game_played =True
elif self.level ==2:
self.create_slaves(10,4,300,45,60,self.normal)
self.create_slaves(20,5, 400, 55,70, self.normal)
elif self.level ==3:
self.create_slaves(12,3,300,45,60, self.normal)
self.create_slaves(20,5,400,55,70, self.normal)
self.create_slaves(15,5,350,45,65, self.tank)
self.max_ammo = 5
elif self.level ==4 :
self.create_slaves(13,4,300,45,65, self.normal)
self.create_slaves(20,5,400,55,70, self.tank)
self.create_slaves(15,5,400, 55,80, self.rock)
elif self.level == 5:
self.create_slaves(14,4,300,45,60, self.normal)
self.create_slaves(11,3,250,35,60, self.normal)
self.create_slaves(15,4,350,40,55, self.rock)
self.create_slaves(13,5,400,35,65,self.rock)
elif self.level == 6:
self.create_slaves(12,4,300,45,60, self.normal)
self.create_slaves(15,3,300,45,60, self.tank)
self.create_slaves(15,4,350,35,50, self.rock)
self.create_slaves(14,5,350,35,50, self.normal)
elif self.level ==7:
self.create_slaves(13,3,350,50,45, self.normal)
self.create_slaves(15,3,300,45,60, self.tank)
self.create_slaves(15,4,350,35,50, self.rock)
self.create_slaves(17,4,400,45,50, self.rock)
elif self.level ==8:
self.create_slaves(12,4,300,45,60, self.normal)
self.create_slaves(15,3,300,45,60, self.tank)
self.create_slaves(15,4,350,35,50, self.rock)
self.create_slaves(14,5,350,35,50, self.tank)
self.create_slaves(12,3,300,45,55, self.normal)
elif self.level == 9:
self.create_slaves(16,3,300,45,60, self.tank)
self.create_slaves(15,3,300,45,60, self.tank)
self.create_slaves(15,4,350,35,50, self.rock)
self.create_slaves(14,5,350,35,50, self.normal)
self.create_slaves(16,7, 350,60,70, self.boss)
self.max_ammo = 8
elif self.level ==10:
self.game_active =False
self.ammo_num = self.max_ammo
for slave in self.Slaves:
attacks = pygame.sprite.collide_rect(self.player, slave)
if attacks:
slave.kill()
if self.player.shielded:
self.explode.play()
self.player.unshield()
self.Score += slave.worth
if self.Score >self.high_score:
self.high_score = self.Score
else:
self.game_active =False
if slave.rect.bottom > Height:
self.game_active =False
for ammo in self.Ammo:
ammo_hit = pygame.sprite.collide_rect(ammo, slave)
if ammo_hit:
ammo_health_decrease = slave.slave_hp
slave.slave_hp -= ammo.ammo_health
ammo.ammo_health = ammo_health_decrease
if ammo.ammo_health <= 0 :
ammo.kill()
for slave in self.Slaves:
if slave.slave_hp <= 0:
slave.kill()
self. explode.play()
self.Score +=slave.worth
if self.Score > self.high_score:
self.high_score = self.Score
for pu in self.Powerup:
hits_pu = pygame.sprite.spritecollide(pu, self.Ammo, False, False)
if hits_pu:
if pu.Powerup == 'shield':
self.player.shield()
elif 'ammo' in pu.powerup:
self.ammo_powerup = pu.powerup
elif pu.powerup == 'Score':
self.Score += 5
if self.Score >self.high_score:
self.high_score = self.Score
pu.include_shield = not self.player.shielded
pu.randomize()
if self.ammo_num < self.max_ammo:
self.ammo_reload_timer +=1
if self.ammo_reload_timer >= 40 :
self.ammo_num += 1
self.ammo_reload_timer = 0
if self.level >= self.Max_level:
self.game_active = False
def display(self, screen, button):
screen.fill(BLACK)
if not self.game_active:
if self.game_played:
self.end_game(screen)
button.draw_button()
pygame.mouse.set_visible(True)
else:
self.display_message(screen, "Score:" + str(self.Score), 28, BLUE, 110,110 )
self.display_message(screen, "High Score:" + str(self.high_score), 30, ORANGE, 120,120)
self.display_message(screen, "Level:" + str(self.level), 25, MAGENTA, 100,100)
if self.ammo_powerup == None:
self.ammo_text_color = WHITE
elif self.ammo_powerup == 'WideBullet':
self.ammo_text_color = ORANGE
elif self.ammo_powerup == 'PierceBullet':
self.ammo_text_color = RED
self.display_message(screen, str(self.ammo_num) + "/" + str(self.ammo_reload_timer), 20, GRAY, 500,500)
self.level_text_timer += 1
if self.level_text_timer < 600 :
self.display_message(screen, 'Level:' + str(self.level), 25, WHITE, 500,500 )
self.level_text_timer += 1
pygame.display.flip()
def end_game(self, screen):
screen.fill(BLACK)
self.display_message(screen, "YOU DIED!", 58, MAGENTA, 650,700)
self.display_message(screen, "Final Score:" + str(self.Score), 30, ORANGE, 450,500)
self.display_message(screen, "High Score:" + str(self.high_score), 40, CYAN, 500,550)
self.display_message(screen, "Higest Floor Reached:" + str(self.level) + "/" +str(self.Max_level), 30, WHITE, 500,500)
here is the Screenshot of the error:
This is the picture of the error
Any suggestions are helpful, please help
The Error is present in "def create_Slaves()" and on the line, self.Slaves.add(d)
Please try this in your init function
class Game(pygame.sprite.Sprite):
def __init__((self, screen, screen_height, screen_width):
super(Sprite, self).__init__()
Maybe your only problem is that you have to call it from the parent function
I'm really a beginner and I'm looking for a mistake.
This is a condition in the Game class in the "collision" method.
I need to detect a collision between a missile and an enemy.
Problem: When a missile is at the same coordinate as the enemy, a collision is detected. However, if one of the shots is outside the X coordinate, another collision is not detected until the shot outside the enemy's X coordinate disappears beyond the top edge of the screen.
import pygame
import os
import sys
import random
from pygame.locals import *
pygame.init()
pygame.font.init()
DIR = os.path.dirname(os.path.realpath(__file__)) # získání cesty k adresáři se soubory
OKNO_X = 1024
OKNO_Y = 768
CLOCK = pygame.time.Clock()
SCREEN = pygame.display.set_mode((OKNO_X, OKNO_Y))
BACKGROUND = pygame.image.load(os.path.join(DIR, "universe.jpg"))
DEBUGFONT = pygame.font.SysFont("Comic Sans MS", 20)
class Spaceship():
def __init__(self, x=510, y=OKNO_Y-50):
self.x = x
self.y = y
def vykresli(self):
ship = pygame.image.load(os.path.join(DIR, "spaceship.png"))
SCREEN.blit(ship, (self.x, self.y))
def pohyb(self, x, y):
self.x += x
self.y += y
if self.x < 0: self.x = 0
if self.x > OKNO_X - 50: self.x = OKNO_X - 54
if self.y < 0: self.y = 0
if self.y > OKNO_Y - 50: self.y = OKNO_Y - 54
class Enemies():
def __init__(self):
self.enem_x = []
self.enem_y = []
self.enem_invader = []
self.enem_speed = []
def vygeneruj(self):
#generování nepřátel
invader_green = pygame.image.load(os.path.join(DIR, "invader_green.png"))
invader_blue = pygame.image.load(os.path.join(DIR, "invader_blue.png"))
invader_yellow = pygame.image.load(os.path.join(DIR, "invader_yellow.png"))
invader_red = pygame.image.load(os.path.join(DIR, "invader_red.png"))
if random.randrange(0, 50) == 1:
#self.enem_x.append(random.randrange(50, 970))
self.enem_x.append(510)
self.enem_y.append(0)
self.enem_invader.append(random.choice([invader_green, invader_blue, invader_yellow, invader_red]))
self.enem_speed.append(random.randrange(1,5))
#self.enem_speed.append(10)
def vykresli(self):
#vykreslení nepřátel
for i in range(len(self.enem_invader)):
SCREEN.blit(self.enem_invader[i], (self.enem_x[i], self.enem_y[i]))
self.enem_y[i] += self.enem_speed[i]
##############DEBUG################x
label_d1 = DEBUGFONT.render(str(self.enem_x[i]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.enem_x[i], self.enem_y[i]-10))
label_d1 = DEBUGFONT.render(str(self.enem_y[i]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.enem_x[i]+30, self.enem_y[i]-10))
#smazání nepřátel, co přeletěly za hranu
e = 0
pocet_enemies = len(self.enem_invader)
while e < pocet_enemies:
if self.enem_y[e] > OKNO_Y:
del self.enem_x[e]
del self.enem_y[e]
del self.enem_invader[e]
del self.enem_speed[e]
pocet_enemies -= 1
e += 1
class Game():
def __init__(self):
self.sestreleno = 0
def kolize(self):
#vyhodnocuje střet střely s enemies
x, y = 0, 0
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
while y < pocet_shots:
while x < pocet_enemies:
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
del shot.x[y]
del shot.y[y]
del enemies.enem_x[x]
del enemies.enem_y[x]
del enemies.enem_invader[x]
del enemies.enem_speed[x]
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
break
x += 1
y += 1
def skore(self):
myfont_skore = pygame.font.SysFont("Comic Sans MS", 30)
label_skore = myfont_skore.render("Sestřeleno: " + str(self.sestreleno), 1, (100,100,100))
SCREEN.blit(label_skore, (10, 10))
class Shot():
def __init__(self):
self.x = []
self.y = []
self.missile = pygame.image.load(os.path.join(DIR, "missile.png"))
def vystrel(self, x, y):
#přidání střely do seznamu střel
self.x.append(x)
self.y.append(y)
def strela(self):
#vykreslení střely
for m in range(len(self.x)):
SCREEN.blit(self.missile, (self.x[m]+23, self.y[m]-50))
self.y[m] -= 5
##############DEBUG################x
label_d1 = DEBUGFONT.render(str(self.x[m]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m], self.y[m]-10))
label_d1 = DEBUGFONT.render(str(self.y[m]), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m]+30, self.y[m]-10))
label_d1 = DEBUGFONT.render(str(m), 1, (255,255,255))
SCREEN.blit(label_d1, (self.x[m]+40, self.y[m]-20))
#smazání střely ze seznamu pokud vletí za hranu screenu
for s in range(len(self.y)):
if self.y[s] <= 0:
del self.x[s]
del self.y[s]
break
#print(self.x)
#instance
spaceship = Spaceship()
enemies = Enemies()
shot = Shot()
game = Game()
while True:
SCREEN.blit(BACKGROUND, (0, 0, OKNO_X, OKNO_Y)) # překreslení pozadí
KEY = pygame.key.get_pressed()
if KEY[pygame.K_LEFT]:
spaceship.pohyb(-10, 0)
if KEY[pygame.K_RIGHT]:
spaceship.pohyb(+10, 0)
if KEY[pygame.K_UP]:
spaceship.pohyb(0, -10)
if KEY[pygame.K_DOWN]:
spaceship.pohyb(0, +10)
if KEY[pygame.K_ESCAPE]:
pygame.quit()
sys.exit()
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_SPACE:
shot.vystrel(spaceship.x, spaceship.y+30)
if event.type == KEYUP:
if event.key == K_p:
pygame.time.wait(5000)
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
spaceship.vykresli()
enemies.vygeneruj()
enemies.vykresli()
shot.strela()
game.kolize()
game.skore()
CLOCK.tick(30) # rychlost FPS
pygame.display.update() # obnovení obrazovky
Instead of a method,
def kolize(self):
#vyhodnocuje střet střely s enemies
x, y = 0, 0
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
while y < pocet_shots:
while x < pocet_enemies:
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
del shot.x[y]
del shot.y[y]
del enemies.enem_x[x]
del enemies.enem_y[x]
del enemies.enem_invader[x]
del enemies.enem_speed[x]
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
break
x += 1
y += 1
I had to use this method.
def kolize(self):
#vyhodnocuje střet střely s invaderem
myBreak = False
pocet_enemies = len(enemies.enem_x)
pocet_shots = len(shot.x)
for y in range(pocet_shots):
for x in range(pocet_enemies):
if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y]-23 >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+27):
game.explosion(enemies.enem_x[x], enemies.enem_y[x]) # předání souřadnic výbuchu
game.delShots(y)
game.delEnem(x)
pocet_enemies -= 1
pocet_shots -= 1
self.sestreleno += 1
if spaceship.health < 50: spaceship.health += 1
myBreak = True
break
if myBreak == True:
myBreak = False
break
I needed to conditionally jump out of the nested loop and out of the main loop.
I've read other answered questions relating to this topic and they all refer to the nested loops "axis" but in my case, I have used the inbuilt index by just using a single value.
import random, pygame, numpy
#window setup aswell as global variable
pygame.init()
screen_size = 400
global window
window = pygame.display.set_mode((screen_size,screen_size))
pygame.display.set_caption("evolution simulator")
window.fill((255,255,255))
pygame.display.update()
def draw_Window():
global grid
blockSize = 20
# grid = []
for row in range(20):#NO IT ISNT
for column in range(20):
grid = numpy.zeros((20,20))
rect = pygame.Rect(row*blockSize, column*blockSize,blockSize, blockSize)
pygame.draw.rect(window,(0,0,0), rect, 1)
#0 EMPTY
#1 spurgs
#2 FOOD
class spurgs:
def __init__(self,age,hunger,speed,gender,x,y,race):
# 1 for male, 2 for female
self.hunger = hunger
self.speed = speed
self.gender = gender
self.age = age
self.race = race
self.x = x
self.y = y
self.size = 8
self.death = False
def update(self):
if self.death == False:
self.age = self.age + 1
self.draw()
if self.age <= 100:
coin_flip = random.randint(1,2)
if coin_flip == 1:
self.death == True
if grid[self.x,self.y] == 0:
grid[self.x,self.y] = 1
self.sense()
#MATRIX
#SURVIVAL ELEMENTS
def eat(self):
self.hunger +=1
def breed(self,mate):
# In the generation class, make a list for the next generation and append baby to the list
pass
# SENSE
def sense(self):
self.senses = 1
if grid[self.x,self.y] == grid[20,self.y]:
right = False
else:
right = True
if grid[self.x+self.senses,self.y] == 2 and right:#Right
self.move("right")
if grid[self.x,self.y] == grid[0,self.y]:
left = False
else:
left = True
if grid[self.x-self.senses,self.y] == 2 and left:#left
self.move("left")
if grid[self.x,self.y] == grid[self.x,20]:
down = False
else:
down = True
if grid[self.x,self.y-self.senses] ==2 and up:
self.move("down")
if grid[self.x,self.y] == grid[self.x,0]:
up = False
else:
up = True
if grid[self.x,self.senses+self.y] == 2:
self.move("up")
#MOVEMENT
def move(self,dir):
if self.death == False:
if dir == "right":
self.x += self.senses
self.update()
if self.death == False:
if dir == "left":
self.x -= self.senses
self.update()
if self.death == False:
if dir == "up":
self.y += self.senses
self.update()
if self.death == False:
if dir == "down":
self.y -= self.senses
self.update()
#DRAWING
def draw(self):
# x =1 , y =4
#for grid system
if self.death ==False:
#{Pixel Converter}
self.d_x = self.x * 20 - 10
self.d_y = self.y * 20 - 10
pygame.draw.circle(window,self.race,(self.d_x,self.d_y),self.size)
# GENERATION class
class generation:
def __init__(self,size):
self.size = size + 1
self.currentGen = []
def makeGeneration(self):
for i in range(self.size):
self.seed_mutations = random.randint(0,20)
self.x = random.randint(0,20)
self.y = random.randint(0,20)
self.gender = random.randint(1,2)
#Race chooser
race = random.randint (1,4)
if race == 1:
self.color_race = (0, 110, 255)
elif race == 2:
self.color_race = (255, 234, 0)
if race == 3:
self.color_race = (132, 0, 255)
if race == 4:
self.color_race = (242, 53, 53)
self.currentGen.append(spurgs(1,self.seed_mutations,self.seed_mutations,self.gender,self.x,self.y,self.color_race))
def update(self):
for s in self.currentGen:
s.update()
class food:
def __init__(self,type):
self.type = type
if self.type == "m":
self.hunger_val = 2
elif self.type == "a":
self.hunger_val = 1
self.eaten = False
self.x = random.randint(0,20)
self.y = random.randint(0,20)
def draw(self):
if self.eaten == False:
x = self.x * 20 - 10
y = self.y * 20 - 10
if self.type =="m":
pygame.draw.circle(window,(10,255,50),(x,y),self.hunger_val*5)
elif self.type == "a":
pygame.draw.circle(window,(0,0,0),(x,y),self.hunger_val*5)
def update(self):
if self.eaten == False:
self.draw()
if grid[self.x,self.y] == 0:
grid[self.x,self.y] = 2
elif grid[self.x,self.y] == 1:
grid[self.x,self.y] = 1
self.eaten = False
a = food("m")
a.draw()
gen_1 = generation(8)
gen_1.makeGeneration()
run = True
while run:
#WINDOW
window.fill((255,255,255))
draw_Window()
#QUIT CONDITION
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("closing the loop")
run = False
#TESTING
gen_1.update()
a.update()
print("getting here")
#FINAL LOOP
pygame.display.update()
pygame.time.delay(1000)
pygame.quit()
This is the error :
if grid[self.x+self.senses,self.y] == 2 and right:#Right
IndexError: index 21 is out of bounds for axis 0 with size 20
index 20 is out of bounds for axis 0 with size 20?
Yes of course. The indices start at 0. Therefor the indices from 0 to 19 are valid, but 20 is out of bounds.
The last element in the array si addressed with 19 rather than 20:
if grid[self.x,self.y] == grid[20,self.y]:
if grid[self.x,self.y] == grid[19,self.y]:
if grid[self.x,self.y] == grid[self.x,20]:
if grid[self.x,self.y] == grid[self.x,19]:
self.x = random.randint(0,20)
self.x = random.randint(0,19)
Alternatively, you can use random.randrange instead of random.randint:
self.x = random.randrange(20)
To supplement #Rabbid76 's answer:
>>> x = [1, 6, 2, 3, 7, 2, 8, 9, 5, 4]
>>> for idx, val in enumerate(x):
... print(f"index: {idx}, value: {val}")
...
index: 0, value: 1
index: 1, value: 6
index: 2, value: 2
index: 3, value: 3
index: 4, value: 7
index: 5, value: 2
index: 6, value: 8
index: 7, value: 9
index: 8, value: 5
index: 9, value: 4
>>> len(x)
10
I'm trying to code a little Jump´n´Run game in tkinter with canvas and so far its working pretty well, but I have a problem that I cant´t wrap my head around.
Look at these three pictures: on the first the collision works fine - I can jump from one paddle to the other.
On the second picture, you can see that whenever I get under the paddle it doesn't fall down and jumping up is also not possible, probably because i have self.y = 0 in the self.brick collision detection. How could I get this working such that even when its under the paddle it bounces off, because that's important, for example when I start to add the second line of paddles.
My Collision code:
def brick_hit(self, pos):
for brick_line in self.bricks:
for brick in brick_line:
brick_pos = self.gamerootCanvas.coords(brick.id)
try:
if pos[3] > brick_pos[1]:
if pos[2] > brick_pos[0] and pos[0] < brick_pos[2]:
return True
except:
continue
return False
My Full code:
def jump_and_run():
gameroot = Toplevel()
gameroot.title("Game Root")
gameroot.resizable(0, 0)
gameroot.wm_attributes("-topmost", 1)
gamerootCanvas = Canvas(gameroot, width=1800, height=800, bd=0, highlightthickness=0)
gameroot_Background = PhotoImage(file="jumpnrunbackground.png")
gamerootCanvas.create_image(500, 250, image=gameroot_Background)
gamerootCanvas.pack()
gamerootCanvas.update()
class Player:
def __init__(self, gamerootCanvas, bricks, color):
self.gamerootCanvas = gamerootCanvas
self.id = gamerootCanvas.create_rectangle(25,25,0,0, fill=color)
self.gamerootCanvas.move(self.id, 5, 650)
self.bricks = bricks
self.x = 0
self.y = 0
self.gravity = 0.1
self.gamerootCanvas_height = gamerootCanvas.winfo_height()
self.gamerootCanvas_width = gamerootCanvas.winfo_width()
self.gamerootCanvas.bind_all("<KeyPress-Right>", self.move_right)
self.gamerootCanvas.bind_all("<KeyRelease-Right>", self.move_right_stop)
self.gamerootCanvas.bind_all("<KeyPress-Left>", self.move_left)
self.gamerootCanvas.bind_all("<KeyRelease-Left>", self.move_left_stop)
self.gamerootCanvas.bind_all("<KeyPress-Up>", self.jump_)
self.gamerootCanvas.bind_all("<KeyRelease-Up>", self.jump_stop)
self.jump_counter = 0
self.move_counter = 0
def move_player(self):
self.gamerootCanvas.move(self.id, self.x, self.y)
pos = self.gamerootCanvas.coords(self.id)
self.y += self.gravity
if pos[0] <= 0:
self.x = 1
elif pos[2] >= self.gamerootCanvas_width:
self.x = -1
elif pos[1] <= 0:
self.y = 1
elif pos[3] >= self.gamerootCanvas_height:
self.y = 0
elif self.brick_hit(pos) == True:
self.y = 0
def move_right(self, evt):
self.x = 2
def move_right_stop(self, evt):
self.x = 0
def move_left(self, evt):
self.x = -2
def move_left_stop(self, evt):
self.x = 0
def jump_(self, evt):
if self.jump_counter < 2:
self.y = -6
self.jump_counter += 2
def jump_stop(self, evt):
self.y = 0
self.jump_counter = 0
def brick_hit(self, pos):
for brick_line in self.bricks:
for brick in brick_line:
brick_pos = self.gamerootCanvas.coords(brick.id)
try:
if pos[3] > brick_pos[1]:
if pos[2] > brick_pos[0] and pos[0] < brick_pos[2]:
return True
except:
continue
return False
class Bricks1:
def __init__(self, gamerootCanvas, color):
self.gamerootCanvas = gamerootCanvas
self.id = gamerootCanvas.create_rectangle(50, 15, 0, 0, fill=color, width=2)
self.gamerootCanvas.move(self.id, 5, 700)
def generate_bricks():
global bricks
bricks = []
for i in range(0, 1):
b = []
for j in range(0, 14):
Bricks_1 = Bricks1(gamerootCanvas, "Blue")
b.append(Bricks_1)
bricks.append(b)
for i in range(0, 1):
for j in range(0, 14):
gamerootCanvas.move(bricks[i][j].id, 158.2 * j, 40 * i)
generate_bricks()
player1 = Player(gamerootCanvas, bricks, "Red")
while True:
gameroot.update_idletasks()
player1.move_player()
gameroot.update()
gameroot.after(5)
play_gameloop_sound()
gameUI.mainloop()
You should offset yourself from the brick to prevent becoming stuck. When resting on a brick, you should also have an altered state to prevent jittering.
I created an AI in python/pygame but even after spending hours of debugging, I could not find why the individuals(dots) are not getting mutated. After few generations, all the individuals just overlap each other and follow the same exact path. But after mutation they should move a little bit differently.
Here is what a population size of 10 looks like after every 2-3 generations..
Image 1 Image 2 Image 3
As you can see, just after few generations they just overlap and all the individuals in the population move together, following exact same path! We need mutations!!!
I would be really grateful to you if you could find any mistake. Thank!
I saw the code from: https://www.youtube.com/watch?v=BOZfhUcNiqk&t
and tried to make it in python. Here's my code
import pygame, random
import numpy as np
pygame.init()
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("The Dots")
FPS = 30
clock = pygame.time.Clock()
gameExit = False
grey = [30, 30, 30]
white = [255, 255, 255]
black = [0, 0, 0]
red = [255, 0, 0]
goal = [400, 10]
class Dot():
def __init__(self):
self.x = int(width/2)
self.y = int(height - 150)
self.r = 3
self.c = black
self.xVel = self.yVel = 0
self.xAcc = 0
self.yAcc = 0
self.dead = False
self.steps = 0
self.reached = False
self.brain = Brain(200)
def show(self):
pygame.draw.circle(screen, self.c, [int(self.x), int(self.y)], self.r)
def update(self):
if (self.x >= width or self.x <= 0 or self.y >= height or self.y <= 0):
self.dead = True
elif (np.sqrt((self.x-goal[0])**2 + (self.y-goal[1])**2) < 5):
self.reached = True
if not self.dead and not self.reached:
if len(self.brain.directions) > self.steps:
self.xAcc = self.brain.directions[self.steps][0]
self.yAcc = self.brain.directions[self.steps][1]
self.steps += 1
self.xVel += self.xAcc
self.yVel += self.yAcc
if self.xVel > 5:
self.xVel = 5
if self.yVel > 5:
self.yVel = 5
self.x += self.xVel
self.y += self.yVel
else: self.dead = True
def calculateFitness(self):
distToGoal = np.sqrt((self.x-goal[0])**2 + (self.y-goal[1])**2)
self.fitness = 1/(distToGoal**2)
return self.fitness
def getChild(self):
child = Dot()
child.brain = self.brain
return child
class Brain():
def __init__(self, size):
self.size = size
self.directions = []
self.randomize()
def randomize(self):
self.directions.append((np.random.normal(size=(self.size, 2))).tolist())
self.directions = self.directions[0]
def mutate(self):
for i in self.directions:
rand = random.random()
if rand < 1:
i = np.random.normal(size=(1, 2)).tolist()[0]
class Population():
def __init__(self, size):
self.size = size
self.dots = []
self.fitnessSum = 0
for i in range(self.size):
self.dots.append(Dot())
def show(self):
for i in self.dots:
i.show()
def update(self):
for i in self.dots:
i.update()
def calculateFitness(self):
for i in self.dots:
i.calculateFitness()
def allDead(self):
for i in self.dots:
if not i.dead and not i.reached:
return False
return True
def calculateFitnessSum(self):
self.fitnessSum = 0
for i in self.dots:
self.fitnessSum += i.fitness
def SelectParent(self):
rand = random.uniform(0, self.fitnessSum)
runningSum = 0
for i in self.dots:
runningSum += i.fitness
if runningSum > rand:
return i
def naturalSelection(self):
newDots = []
self.calculateFitnessSum()
for i in self.dots:
parent = self.SelectParent()
newDots.append(parent.getChild())
self.dots = newDots
def mutate(self):
for i in self.dots:
i.brain.mutate()
test = Population(100)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
screen.fill(white)
if test.allDead():
#Genetic Algorithm
test.calculateFitness()
test.naturalSelection()
test.mutate()
else:
test.update()
test.show()
pygame.draw.circle(screen, red, goal, 4)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
Thanks for any help!
I didn't go through the whole code, but over here
def mutate(self):
for i in self.directions:
rand = random.random()
if rand < 1:
i = np.random.normal(size=(1, 2)).tolist()[0]
you are trying to assign a new value to i (which is an iterater), so it won't change anything, which explains why you'r having trouble with the mutations.
You should have something like this:
def mutate(self):
for i in range(len(self.directions)):
rand = random.random()
if rand < 1:
self.directions[i] = np.random.normal(size=(1, 2)).tolist()[0]
or you can use list comprehensions
https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions