Pygame segmentation fault with import depending on position in code? - python

I know these segmentation fault questions are common, but I couldn't find answer and I am pulling my hair out as the code works without issue in some parts of the code, but not others or in some cases it works the first time then, the next day, it falls over.
Basically, I am importing spritesheets for a simply pygame game. With help, I wrote a small class which allows spritesheets to be imported and, through a few methods turns them into a list using the json file. That program is as follows:
import pygame
import json
pygame.init()
class Spritesheet:
def __init__(self, filename):
self.filename = filename
self.sprite_sheet = pygame.image.load(filename).convert()
self.data_addr = self.filename.replace('png', 'json')
with open(self.data_addr, encoding = 'utf8') as f:
self.data = json.load(f)
f.close()
def check_file(self):
print(self.data)
def get_sprite(self, x, y, w, h):
sprite = pygame.Surface((w, h))
sprite.set_colorkey((0,0,0))
sprite.blit(self.sprite_sheet,(0, 0),(x, y, w, h))
return sprite
def parse(self, index):
sprite = self.data['frames'][index]['frame']
x, y, w, h = sprite["x"], sprite["y"], sprite["w"], sprite["h"]
image = self.get_sprite(x, y, w, h)
return image
def dict_len(self):
length = len(self.data['frames'])
return length
This has worked fine in the main code. I have a player class, an enemy class etc and, upon initiallising, this class is called to create a list of pngs for the graphics (that I can step through etc.) A pertinent cut of the player class is as follows:
class Player(pygame.sprite.Sprite):
def __init__(self, player_posx, health):
super().__init__()
#right facing sprites
self.spritesr = Spritesheet('../graphics/player/players.png')
self.player_spritesr = []
for value in range(self.spritesr.dict_len()):
self.player_spritesr.append(self.spritesr.parse(value))
# left facing sprites
self.spritesl = Spritesheet('../graphics/player/playersl.png')
self.player_spritesl = []
for value in range(self.spritesl.dict_len()):
self.player_spritesl.append(self.spritesl.parse(value))
#static sprites
self.sprites_static = Spritesheet('../graphics/player/player_static.png')
self.player_static = []
for value in range(self.sprites_static.dict_len()):
self.player_static.append(self.sprites_static.parse(value))
self.image_index = 0
self.image = self.player_spritesr[self.image_index]
self.rect = self.image.get_rect()
In this class it works fine with the Spritesheets class. However, when I decided to create new file to import all the graphics in a separate file, I get the segmentation error. The code is simply:
from spritesheets import Spritesheet
test = Spritesheet('../graphics/player/playersl.png')
Calling exactly the same class with the same argument, but I get an error saying:
Fatal Python error: (pygame parachute) Segmentation Fault
Python runtime state: initialized
I really don't understand at all, especially why it runs fine in one file but falls over everywhere else.

The likely problem is that you are doing your import before you have called pygame.init(), so pygame has not been initialized.
Consider doing this in your second file:
from spritesheets import Spritesheet
def get_sprites():
return [
Spritesheet('../graphics/player/players.png'),
Spritesheet('../graphics/player/playersl.png'),
Spritesheet('../graphics/player/players_static.png')
]
Now you can put your import at the top, and call
sprites = xxx.get_sprites()
after you have initialized pygame.

Related

Python function not defined

I have been making a python 3d game in ursina. So far so good but for one error:
File "C:\Users\my name\AppData\Local\Programs\Python\Python39\lib\site-packages\ursina\main.py", line 117, in _update
__main__.update()
File "c:\Users\my name\Desktop\game456.py", line 14, in update
release()
NameError: name 'release' is not defined```
I dont understand this error. I have seen others run code like this too. This code is inspired by another person making a game in ursina so i copied a little bit of code myself. i tried googling an answer but it's just about a variable not being defined,etc. View code below.
from ursina import*
from ursina.prefabs.first_person_controller import FirstPersonController
gamebyme = Ursina()
def update():
if held_keys["left mouse"]:
shoot()
else:
release()
class Voxel(Button):
def __init__(self, position = (0,0,0)):
super().__init__(
parent = scene,
position = position,
model = 'map',
origin_y = 0.5,
texture = texture,
color = color.color(0,0,random.uniform(0.9,1)),
scale = 0.1)
class Gun(Entity):
def __init__(self):
super().__init__(
parent=camera.ui,
model='ak_47',
position=Vec2(0.8,-0.1),
color=color.gray,
scale=0.3)
def shoot(self):
self.rotation=Vec3(0,0,10)
def release(self):
self.rotation=None
def reload(self):
self.rotation=Vec3(0,0,0)
plr = FirstPersonController()
gun = Gun()
vxl = Voxel()
gamebyme.run()
In this function
def update():
if held_keys["left mouse"]:
shoot()
else:
release()
you should specify the Gun type object you want to call the functions from, eg:
def update(gun):
if held_keys["left mouse"]:
gun.shoot()
else:
gun.release()

can't serialized pygame.Surface objects with pickle

I am developing a game with python 3.6, I want in its multiplayer version to send to the server objects modified by the client ( the player) I thought to serialize them for transfer. I use pygame and thus pygame.Surface in my objects
I have objects with this structure:
class Cargo(Bateau):
dictCargos = dict()
def __init__(self, map, nom, pos, armateur=None):
Bateau.__init__(self, map, nom, armateur, pos)
self.surface = pygame.image.load(f"images/{self.nom}.png").convert_alpha()
self.rect = self.map.blit(self.surface, self.pos)
...
Cargo.dictCargos[self.nom] = self
When I serialize another object without pygame instance it's ok
But with the object described above I get this error message:
import pickle as pickle
pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
Traceback (most recent call last):
File "./pytransit.py", line 182, in <module>
encreG(joueur, event)
File "/home/patrick/Bureau/PyTransit/modulesJeu/tests.py", line 25, in encreG
pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
TypeError: can't pickle pygame.Surface objects
Do you have any idea how to transport these items to the server. Or bypass this pickle restriction?
The same problem would arise if I wanted to save a part, so save these objects
Here is an example of what #IonicSolutions pointed to in the comments:
import pickle
import pygame
class Test:
def __init__(self, surface):
self.surface = surface
self.name = "Test"
def __getstate__(self):
state = self.__dict__.copy()
surface = state.pop("surface")
state["surface_string"] = (pygame.image.tostring(surface, "RGB"), surface.get_size())
return state
def __setstate__(self, state):
surface_string, size = state.pop("surface_string")
state["surface"] = pygame.image.fromstring(surface_string, size, "RGB")
self.__dict__.update(state)
t = Test(pygame.Surface((100, 100)))
b = pickle.dumps(t)
t = pickle.loads(b)
print(t.surface)
To see what modes you can use to store the data as a string (here "RGB") look into the documentation
Based on the answer by #MegaIng, I develop his/her answer, so that you can just use the pygame.Surface normally, but with the pickle feature added. It shouldn't disturb any of your code. I have tested it on python 3.7, 64 bit, and it works properly. Also have tried/implement it on my project, nothing had been disturbed.
import pygame as pg
pgSurf = pg.surface.Surface
class PickleableSurface(pgSurf):
def __init__(self, *arg,**kwarg):
size = arg[0]
# size given is not an iterable, but the object of pgSurf itself
if (isinstance(size, pgSurf)):
pgSurf.__init__(self, size=size.get_size(), flags=size.get_flags())
self.surface = self
self.name='test'
self.blit(size, (0, 0))
else:
pgSurf.__init__(self, *arg, **kwarg)
self.surface = self
self.name = 'test'
def __getstate__(self):
state = self.__dict__.copy()
surface = state["surface"]
_1 = pg.image.tostring(surface.copy(), "RGBA")
_2 = surface.get_size()
_3 = surface.get_flags()
state["surface_string"] = (_1, _2, _3)
return state
def __setstate__(self, state):
surface_string, size, flags = state["surface_string"]
pgSurf.__init__(self, size=size, flags=flags)
s=pg.image.fromstring(surface_string, size, "RGBA")
state["surface"] =s;
self.blit(s,(0,0));self.surface=self;
self.__dict__.update(state)
And here's an example
pg.Surface = PickleableSurface
pg.surface.Surface = PickleableSurface
surf = pg.Surface((300, 400), pg.SRCALPHA|pg.HWSURFACE)
# Surface, color, start pos, end pos, width
pg.draw.line(surf, (0,0,0), (0,100), (200, 300), 2)
from pickle import loads, dumps
dump = dumps(surf)
loaded = loads(dump)
pg.init()
screen = pg.display.set_mode((300, 400))
screen.fill((255, 255, 255))
screen.blit(loaded, (0,0))
pg.display.update()
Then on my screen:
Thank you #MegaIng
P.s:
I also added feature to convert unpickle-able pygame surface into a pickle-able surface, by doing newSurface = PickleableSurface(PygameSurface)
However, it just tested once, so there are maybe some bugs. Just feel free to let me know if you find one! I hope it would help you! :D

What is a 'rect style object' and how do I implement it into my code?

I am trying to learn python by making a space game where you travel around the map fighting enemies(drones) that are randomly placed around the map. So far I have been successful in moving the playable spaceship around the map(with rotation), firing lasers, and blitting drones around the map(The drones follow the spaceship around). Though I don't entirely understand classes, I seem to have been able to pull it off so far.
Now, I want to input enemy hp with Laser/Drone collision. I gave the Drone class self.rect = self.image.get_rect() and called an instance of it in the Laser1 class using self.c = pygame.Rect.colliderect(drone.rect) but it just gives me this:
Traceback (most recent call last):
File "space.py", line 85, in <module>
blist.append(Laser1 (beamx, beamy))
File "space.py", line 79, in __init__
self.c = pygame.Rect.colliderect(drone.rect)
TypeError: Argument must be rect style object
I have searched a lot online for a way to fix this but I don't understand it much and nothing seems to work for me. Any help would be greatly appreciated!
Here is my code:
class Drone:
def __init__(self, dronex, droney):
self.x = dronex
self.y = droney
self.hp = dronehp
self.image = pygame.image.load("Androne.png").convert_alpha()
self.rect = self.image.get_rect()
dlist = []
for i in range(10):
dronex = random.randint(0, 7700)
droney = random.randint(0, 4520)
dronehp = 3
dlist.append(Drone (dronex, droney))
drone = Drone(dronex, droney) #-----------instance i think...
class Roid:
def __init__(self, roidx, roidy):
self.x = roidx
self.y = roidy
self.type = random.randint(0, 2)
rlist = []
for i in range(811):
roidx = random.randint(-1000, 9104)
roidy = random.randint(-800, 7200)
rlist.append(Roid (roidx, roidy))
class Laser1:
def __init__(self, beamx, beamy):
self.x = beamx
self.y = beamy
self.laser1 = pygame.image.load("laser1.png").convert_alpha()
self.rect = self.laser1.get_rect()
self.c = pygame.Rect.colliderect(drone.rect) #---line 79...
blist = []
for i in range(2):
beamx = batx
beamy = baty
blist.append(Laser1 (beamx, beamy)) #---line 85...
class Laser2:
def __init__(self, beamx2, beamy2):
self.x2 = beamx2
self.y2 = beamy2
self.laser1 = pygame.image.load("laser1.png").convert_alpha()
self.rect = self.laser1.get_rect()
self.c = pygame.Rect.colliderect(drone.rect)
b2list = []
for i in range(2):
beamx2 = batx
beamy2 = baty
b2list.append(Laser2 (beamx2, beamy2))
Also, this is my first question to ask on here. If there is anything I can do to make this question better do tell. I will except any and all feedback!
To answer the title: A rect style object is a pygame.Rect, a tuple or a list with 4 elements. So you can usually pass a 4-tuple or list to methods that expect a pygame.Rect as well.
As Paul Cornelius mentioned, the exception is raised because you use the colliderect method of the pygame.Rect class, but should instead use the colliderect of the self.rect instance.
self.c = self.rect.colliderect(drone.rect)
You can actually use pygame.Rect.colliderect directly and pass the two rects that you want to check, but that's unusual and would be a bit confusing for everyone else.
# `self.rect` is passed as the `self` argument.
self.c = pygame.Rect.colliderect(self.rect, drone.rect)
Paul Cornelius is in the right direction. Since you're learning python I'll explain briefly. The colliderect method is implemented in C:
static PyObject*
rect_colliderect (PyObject* oself, PyObject* args)
{
PyRectObject* self = (PyRectObject*)oself;
GAME_Rect *argrect, temp;
if (!(argrect = GameRect_FromObject (args, &temp)))
return RAISE (PyExc_TypeError, "Argument must be rect style object");
return PyInt_FromLong (DoRectsIntersect (&self->r, argrect));
}
Since you called it through the class definition and not an instance, drone.rect was assigned to oself by the python wrapper to this method, and args was probably assigned some equivalent of NULL. Hence the error message you saw (and not a 'missing required positional argument' as one would expect).
Don't have any experience with Pygame, but with a little searching it seems the problem you are having is a result of passing an improper argument to your pygame.Rect.colliderect() on line 79. The object you are passing the pygame.Rect.colliderect() method is not being read as a Rectangle object. Try printing the object drone.rect data and object type to see where the problem might be.

Pygame: Save a list of objects/classes/surfaces

I am working on a game, in which you can create mazes. You place blocks on a 16x16 grid, while choosing from a variety of block to make the level with. Whenever you create a block, it adds this class:
class Block(object):
def __init__(self,x,y,spr):
self.x=x
self.y=y
self.sprite=spr
self.rect=self.sprite.get_rect(x=self.x,y=self.y)
to a list called instances.
I tried shelving it to a .bin file, but it returns some error dealing with surfaces. How can I go about saving and loading levels?
Any help is appreciated! :)
Here is the whole code for reference:
import pygame
from pygame.locals import *
#initstuff
pygame.init()
screen=pygame.display.set_mode((640,480))
pygame.display.set_caption('PiMaze')
instances=[]
#loadsprites
menuspr=pygame.image.load('images/menu.png').convert()
b1spr=pygame.image.load('images/b1.png').convert()
b2spr=pygame.image.load('images/b2.png').convert()
currentbspr=b1spr
curspr=pygame.image.load('images/curs.png').convert()
curspr.set_colorkey((0,255,0))
#menu
menuspr.set_alpha(185)
menurect=menuspr.get_rect(x=-260,y=4)
class MenuItem(object):
def __init__(self,pos,spr):
self.x=pos[0]
self.y=pos[1]
self.sprite=spr
self.pos=(self.x,self.y)
self.rect=self.sprite.get_rect(x=self.x,y=self.y)
class Block(object):
def __init__(self,x,y,spr):
self.x=x
self.y=y
self.sprite=spr
self.rect=self.sprite.get_rect(x=self.x,y=self.y)
while True:
#menu items
b1menu=b1spr.get_rect(x=menurect.left+32,y=48)
b2menu=b2spr.get_rect(x=menurect.left+64,y=48)
menuitems=[MenuItem(b1menu,b1spr),MenuItem(b2menu,b2spr)]
screen.fill((20,30,85))
mse=pygame.mouse.get_pos()
key=pygame.key.get_pressed()
placepos=((mse[0]/16)*16,(mse[1]/16)*16)
if key[K_q]:
if mse[0]<260:
if menurect.right<255:
menurect.right+=1
else:
if menurect.left>-260:
menurect.left-=1
else:
if menurect.left>-260:
menurect.left-=1
for e in pygame.event.get():
if e.type==QUIT:
exit()
if menurect.right<100:
if e.type==MOUSEBUTTONUP:
if e.button==1:
to_remove = [i for i in instances if i.rect.collidepoint(placepos)]
for i in to_remove:
instances.remove(i)
if not to_remove:
instances.append(Block(placepos[0],placepos[1],currentbspr))
for i in instances:
screen.blit(i.sprite,i.rect)
if not key[K_q]:
screen.blit(curspr,placepos)
screen.blit(menuspr,menurect)
for item in menuitems:
screen.blit(item.sprite,item.pos)
if item.rect.collidepoint(mse):
if pygame.mouse.get_pressed()==(1,0,0):
currentbspr=item.sprite
pygame.draw.rect(screen, ((255,0,0)), item, 1)
pygame.display.flip()
You can't serialize/pickle/shelve pygame's Surface objects (at least not without a lot of effort). So the answer to your question is: just don't try to serialize your surfaces (it will just waste disk space anyway).
You could for example create a simple dict to store your surfaces, and let your classes just store the key, for example:
menuspr=pygame.image.load('images/menu.png').convert()
b1spr=pygame.image.load('images/b1.png').convert()
b2spr=pygame.image.load('images/b2.png').convert()
currentbspr=b1spr
curspr=pygame.image.load('images/curs.png').convert()
curspr.set_colorkey((0,255,0))
# create a dict to store all surfaces
surf_dict = {'b1spr': b1spr,
'b2spr': b2spr,
'currentbspr': currentbspr,
'curspr': curspr}
...
class Block(object):
def __init__(self,x,y,spr):
self.x=x
self.y=y
self.sprite=spr
# self.sprite is no longer a Surface, but a str
self.rect=surf_dict[self.sprite].get_rect(x=self.x,y=self.y)
...
...
# don't pass the surface to the Block, just the key
instances.append(Block(placepos[0],placepos[1], 'currentbspr'))
...
for i in instances:
# get the Surface from the dict, not from the instance itself
screen.blit(surf_dict[i.sprite],i.rect)
Now you can savely try to pickle/shelve all Block-instances (I see you have asked a related question here).
I found a way around it myself. I used python's built in open(fname,mode) to create a level file.
Whenever a block is created, it takes the sprite-name and coordinates of the block, and adds it to the save file in a .bin format:
f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).')
Then I created a function to read this, and create the level accordingly:
def CreateLevel(levelname):
f=open(levelname,'r')
obj=f.read()
f.close()
obj=obj.split('.')
for b in obj:
instances.append(eval(b))
And it worked with flying colors!
Here is the whole code, and thank you guys for the help.
import pygame
from pygame.locals import *
#initstuff
pygame.init()
screen=pygame.display.set_mode((640,480))
pygame.display.set_caption('PiMaze')
instances=[]
level='save.bin'
#loadsprites
menuspr=pygame.image.load('images/menu.png').convert()
b1spr=pygame.image.load('images/b1.png').convert()
b2spr=pygame.image.load('images/b2.png').convert()
b3spr=pygame.image.load('images/b3.png').convert()
currentbspr=b1spr
curspr=pygame.image.load('images/curs.png').convert()
curspr.set_colorkey((0,255,0))
#menu
menuspr.set_alpha(185)
menurect=menuspr.get_rect(x=-260,y=4)
class MenuItem(object):
def __init__(self,pos,spr):
self.x=pos[0]
self.y=pos[1]
self.sprite=spr
self.pos=(self.x,self.y)
self.rect=self.sprite.get_rect(x=self.x,y=self.y)
class Block(object):
def __init__(self,x,y,spr):
self.x=x
self.y=y
self.sprite=spr
self.rect=self.sprite.get_rect(x=self.x,y=self.y)
def CreateLevel(levelname):
f=open(levelname,'r')
obj=f.read()
f.close()
obj=obj.split('.')
for b in obj:
instances.append(eval(b))
try:
CreateLevel(level)
except:
pass
f=open(level,'a+')
while True:
#menu items
b1menu=b1spr.get_rect(x=menurect.left+32,y=48)
b2menu=b2spr.get_rect(x=menurect.left+64,y=48)
b3menu=b3spr.get_rect(x=menurect.left+96,y=48)
menuitems=[MenuItem(b1menu,b1spr),MenuItem(b2menu,b2spr),MenuItem(b3menu,b3spr)]
screen.fill((20,30,85))
mse=pygame.mouse.get_pos()
key=pygame.key.get_pressed()
placepos=((mse[0]/16)*16,(mse[1]/16)*16)
if key[K_q]:
if mse[0]<260:
if menurect.right<255:
menurect.right+=1
else:
if menurect.left>-260:
menurect.left-=1
else:
if menurect.left>-260:
menurect.left-=1
for e in pygame.event.get():
if e.type==QUIT:
f.close()
exit()
if menurect.right<100:
if key[K_LSHIFT]:
if pygame.mouse.get_pressed()==(1,0,0):
to_remove = [i for i in instances if i.rect.collidepoint(placepos)]
if not to_remove:
instances.append(Block(placepos[0],placepos[1],currentbspr))
f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).')
to_remove = []
if not key[K_LSHIFT] or key[K_RSHIFT]:
if e.type==MOUSEBUTTONUP:
if e.button==1:
to_remove = [i for i in instances if i.rect.collidepoint(placepos)]
for i in to_remove:
instances.remove(i)
if not to_remove:
instances.append(Block(placepos[0],placepos[1],currentbspr))
f.write('Block('+str(placepos[0])+','+str(placepos[1])+',b1spr).')
if key[K_RSHIFT]:
if pygame.mouse.get_pressed()==(1,0,0):
to_remove = [i for i in instances if i.rect.collidepoint(placepos)]
for i in to_remove:
instances.remove(i)
to_remove=[]
for i in instances:
screen.blit(i.sprite,i.rect)
if not key[K_q]:
screen.blit(curspr,placepos)
screen.blit(menuspr,menurect)
for item in menuitems:
screen.blit(item.sprite,item.pos)
if item.rect.collidepoint(mse):
if pygame.mouse.get_pressed()==(1,0,0):
currentbspr=item.sprite
pygame.draw.rect(screen, ((255,0,0)), item, 1)
pygame.display.flip()

Calling class functions through list

I was attempting to place certain class variables within a list. Each class has a method known as update and considering they each do the exact same thing I though it would be allot more convenient to simply place them in a list and call the method that way.
The method I am trying to call is known as update and this is the error that I get:
Traceback (most recent call last):
File "C:\Users\GoodPie\Desktop\New Game Dev\main.py", line 177, in <module>
initialize_game()
File "C:\Users\GoodPie\Desktop\New Game Dev\main.py", line 61, in initialize_game
start_menu(debugging, screen, clock, image_cache)
File "C:\Users\GoodPie\Desktop\New Game Dev\main.py", line 88, in __init__
self.init_start_screen()
File "C:\Users\GoodPie\Desktop\New Game Dev\main.py", line 115, in init_start_screen
self.update_group.append[New_Game_Button, Load_Game_Button, Quit_Game_Button, Settings_Button]
TypeError: 'builtin_function_or_method' object is not subscriptable
Here is the code I am trying to use
Entities.py:
class Quit_Game_Button(Entity):
def __init__(self, x, y, image_cache):
Entity.__init__(self)
self.image_cache = image_cache
self.image = function.get_image("images/Quit_Game.png", self.image_cache)
self.image.convert()
self.rect = Rect(x, y, 150, 30)
def update(self, mouse_position):
if self.rect.collidepoint(mouse_position):
self.image = function.get_image("images/Quit_Game_Hover.png", self.image_cache)
else:
self.image = function.get_image("images/Quit_Game.png", self.image_cache)
def check_click(self, clicked, mouse_position):
quit = False
if self.rect.collidepoint(mouse_position):
if clicked:
quit = True
return quit
class Settings_Button(Entity):
def __init__(self, x, y, image_cache):
Entity.__init__(self)
self.image_cache = image_cache
self.image = function.get_image("images/Settings_Button.png", self.image_cache)
self.image.convert()
self.rect = Rect(x, y, 50, 50)
def update(self, mouse_position):
if self.rect.collidepoint(mouse_position):
self.image = function.get_image("images/Settings_Button_Hover.png", self.image_cache)
else:
self.image = function.get_image("images/Settings_Button.png", self.image_cache)
main.py
self.update_group.append[New_Game_Button, Load_Game_Button, Quit_Game_Button, Settings_Button]
mouse_position = pygame.mouse.get_pos()
#Updating Entities on the screen
for entity in self.update_group:
entity.update(mouse_position)
Just so it's clear, the functions do exist. I was just wondering if I was going about calling methods the write way through a list/array? If not could someone please point me in the right direction? :)
You are trying to assign one to one(1) and two to two(), that results in a referenced before assignment error So change the class Names to something more suitable like One and Two
Also It is strictly recommended(for CapWords convention see pg4 here) to always start a python class name with a uppercase character
Corrected code would look like: (I've implemented the str method)
class One:
def __init__(self, x):
self.x = x
def update(self):
self.x += 1
def __str__(self):
return str(self.x)
class Two:
def __init__(self, x):
self.x = x
def update(self):
self.x += 1
def __str__(self):
return str(self.x)
def test():
one = One(1)
two = Two(2)
update_list = [one, two]
for i in update_list:
i.update()
print i
test()
Output:
2
3
This is a simple error.
self.update_group.append[New_Game_Button, Load_Game_Button, Quit_Game_Button, Settings_Button]
should be
self.update_group.extend([New_Game_Button, Load_Game_Button, Quit_Game_Button, Settings_Button])
You're trying to index append where you should call it. Second point is, that append takes only one parameter, so you should use extend.
But you're still operating on the classes, not instances of the classes.
The issue did not lie within the actual for loop for calling the update function within the class, it occurred through the appending off the class instances to the list. Therefore to solve this problem I tried:
self.update_group = [New_Game_Button, Load_Game_Button, Quit_Game_Button, Settings_Button]
and it worked perfectly. I don't know what the issue is with the appending to the array, but having a fixed list/array seems to work just fine for me. Credits to #Matthias for actually making me look at the method for adding the instances to the array.

Categories