I just wrote a small text class in python for a game written using pygame and for some reason my default arguments aren't working. I tried looking at the python documentation to see if that might give me an idea what I did wrong, but I didn't fully get the language in the documentation. No one else seems to be having this issue.
Here's the code for the text class:
class Text:
def __init__(self,screen,x_location='center',y_location='center',writeable,color,size=12):
self.font = pygame.font.Font("Milleni Gem.ttf", size)
self.text = self.font.render(writeable,True,color)
self.textRect = self.text.get_rect()
if x_location == "center":
self.textRect.centerx = screen.get_rect().centerx
else:
self.textRect.x = x_location
if y_location == "center":
self.textRect.centery = screen.get_rect().centery
else:
self.textRect.y = y_location
self.update()
def update(self):
screen.blit(self.text,self.textRect)
and here's the code to call it:
from gui import *
Text(screen,75,75,currentweapon.clip)#currentweapon.clip is an integer
The error I get is this:
SyntaxError: non-default argument follows default argument
and points to the def __init__() line in the code. What does this error mean and what am I doing wrong here?
def __init__(self,screen,x_location='center',y_location='center',writeable,color,size=12):
You have defined non-default arguments after default arguments, this is not allowed. You should use:
def __init__(self,screen,writeable,color,x_location='center',y_location='center',size=12):
Related
I'm making a game using the pygame module and I have a player class:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle, walk = None, jump = None):
pygame.sprite.Sprite.__init__(self)
self.name = name
self.idle = idle
self.walk = walk
self.jump = jump
self.image = self.idle[0]
self.movment = movment
self.left, self.right = axsis
self.pos = vec(position[0],position[1])
I am adding my characters using json data type and trying to add animations after calling the class but i can't do it
Sample code
class Game():
def __init__(self,json_file):
self.player_attribute = json_file
def character(self):
self.npc = []
for i in self.player_attribute:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment']))
self.animation()
return self.npc
def add_animation(self):
for i in self.npc:
i.idle = "images\ghost.png"
def main_loop()
self.character
when i try this i get an error
self.image = self.idle[0]
TypeError: init() missing 1 required positional argument: 'idle'
how can i add the variables of the class after calling the class
It is not clear what the 'idle' parameter is supposed to represent in your code. However, the reason for the exception is that you are not passing any argument for 'idle' when constructing the Player object. You need something like:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment'],
i['idle']))
You can either do that or alternatively you can pass a default argument to the Player constructor so that, when initializing you do not need to explicitly pass idle:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle=[1], walk = None, jump = None):
You can modify its content at a later time, however I suggest you are careful what you instantiate that object attribute as, because it might come bite you back later (type error or value error).
If it were me, I would move this out of init, or not build the object until all values and their types are known (see Builder Design Pattern).
Hope this helped :) Cheers!
I'm making a submarine game in python, but when I try to run it, the interpreter gives me very strange error:
"TypeError: argument 1 must be pygame.Surface, not type."
I tried to search the web for my answer, but it seems like this isn't very usual error. I also tried to find error by myself, but everything seemed fine to me. Here 's part of the code that I think error is in:
mina = pygame.image.load('mina.png')
class mina():
def __init__(self, x , y):
self.x = x
self.y = y
self.eksplozija = False
def naris(self):
screen.blit(mina, (self.x, self.y))
igralec = podmornica(150, 300, 10)
eksploziv = mina(700, 350)
metki = []
clock = pygame.time.Clock()
def grafika():
clock.tick(60)
screen.blit(ozadje, (0,0))
igralec.naris()
#line, that doesn't work:
eksploziv.naris()
for metek in metki:
metek.naris(screen)
pygame.display.flip()
The variable mina and the class mina have the same name. The class mina shadows the variable mina. You need to rename one or the other. I recommend to rename the calss mina to Mina, since Python classes use the CapWords convention (PEP 8 -- Style Guide for Python Code):
class mina():
class Mina():
eksploziv = mina(700, 350)
eksploziv = Mina(700, 350)
I have this bit of code here:
from tkinter import *
class player():
def __init__(self, xcoor = 0, ycoor = 0):
self.xcoor = xcoor
def leftKey(self, event):
self.xcoor += 1
print("Right key pressed")
def rightKey(self, event):
self.ycoor += 1
print("Left key pressed")
world = Tk()
p1 = player()
world.bind('<Left>', player.leftKey)
world.bind('<Right>', player.rightKey)
world.mainloop()
When I run this and try the keys, whether right or left, I get this error:
TypeError: leftKey() missing 1 required positional argument: 'event'
Exception in Tkinter callback
I think the error is because (self, event) is wrong, but how do I fix that? I want it such that if an object of this class is created, its xcoor and ycoor will change when calling this function via keybindings.
Bind to the player object’s methods instead:
world.bind('<Left>', p1.leftKey)
world.bind('<Right>', p1.rightKey)
Otherwise, player.leftKey and player.rightKey will refer to the unbound methods that still expect a player object as the first argument (self). By referencing the methods from the player object, that argument is implicitely set. This is the same behavior you get when you just do p1.leftKey(evt) which is really just the same as player.leftKey(p1, evt).
I have a marvellous function here:
def update_config(val):
config = configparser.ConfigParser()
fonts_comb = ""
for i in range(len(fonts)):
if i == len(fonts) - 1:
fonts_comb = fonts_comb + fonts[i]
else:
fonts_comb = fonts_comb + fonts[i] + ", "
config["LISTS"] = {"Fonts": fonts_comb}
config["variables"] = {"font_size": (screen_font_size.var).get(),
"x_offset": (x_offset_spin.var).get(),
"y_offset": (y_offset_spin.var).get(),
"language": language,
"preview_font_size": (preview_font_size_spin.var).get()}
variables = config["variables"]
if (fonts_menu.var).get() != strings[17]:
variables["font"] = (fonts_menu.var).get()
else:
variables["font"] = font
if (preview_fonts.var).get() != strings[18]:
variables["preview_font"] = (preview_fonts.var).get()
else:
variables["preview_font"] = preview_font
with open("config.ini", "w") as configfile:
config.write(configfile)
I don't know if it's relevant, too, but basically it does what the name says - updates the config file.
What I don't like about the function is that it requires an argument (val here, should be self maybe?). And 'cause it requires that argument, I can't call it "properly". Let me demonstrate, the following works just fine:
class OptionMenus(tk.OptionMenu):
def __init__(self, master, status, *fonts):
self.var = tk.StringVar(master)
(self.var).set(status)
(tk.OptionMenu).__init__(self, master, self.var, *fonts,
command = update_config)
However - calling like the following returns this error: TypeError: update_config() takes 0 positional arguments but 1 was given
class Spinboxes(tk.Spinbox):
def __init__(self, master):
self.var = tk.IntVar()
tk.Spinbox.__init__(self, master, textvariable = self.var,
from_ = 0, to = 100, command = update_config)
For now, I have solved it using this:
def crossover():
val = ""
update_config(val)
But it seems to be kind of a monkey-ish way to do things, so is there a better way to call that function?
Use a default argument value:
def update_config(val=None):
# etc.
You could also remove the argument entirely and use a single-argument lambda to call it in a context where that the argument must be passed:
def update_config():
# etc.
# ...
tk.OptionMenu.__init__(self, master, self.var, *fonts,
command=lambda _: update_config())
But I think the first option is simpler.
update_config looks like an instance method, so yes, I recommend using the accepted variable self.
If an error says it takes 0 arguments but 1 was given, that means exactly what it says. This means that calling update_config from the Spinbox object passes it an argument. However, since it works fine from OptionMenus and therefore works without an argument, you need to set it up to handle an optional argument.
Change:
def update_config(val):
to:
def update_config(self, event=None):
and that should fix the issue.
I have the following Python (3.2) code:
from pygame import *
class Application:
def __init__(self):
self.running = True
self.display_surface = None
self.size = self.width, self.height = 640, 480
self.old_ticks = pygame.time.get_ticks
self.new_ticks = None
pygame.init()
self.display_surface = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
def on_event(self, event):
if event.type == pygame.QUIT:
self.running = False
def on_loop(self):
pass
def on_render(self):
pass
def on_cleanup(self):
pygame.quit()
def regulate_time(self):
self.new_ticks = pygame.time.get_ticks
while (self.new_ticks < self.old_ticks + 1000):
pass
self.old_ticks = self.new_ticks
def load_images(self):
pass
while(self.running == True):
for event in pygame.event.get():
self.on_event(event)
self.regulate_time
self.on_loop()
self.on_render()
self.on_cleanup()
test = Application
I'm having a problem with the following line:
while(self.running == True):
which throws me the error : NameError: Name "self" is not defined.
I am pretty much a python newbie and was hoping to use this time to get started on learning python and pygame which I could then use for my college project (two birds with one stone) and I cannot figure out why this error is being thrown at me.
Well, the while(self.running == True) is not in any method (def) so there is no such variable called self in scope (which is what the NameError says)...
...perhaps there is some missing indentation? Although the previous pass makes it look like more than this is missing: maybe def run(self):?
Remember, self is just the conventional (and proper) name given to the first parameter for a method by which the "current instance" is implicitly passed.
Happy coding.