Why "NameError: name 'draw_Objects' is not defined" occurs - python

I am making a small game using pygame.
I have defined a function called draw_Objects() but Name Error occurs as if I didn't define the function. What should I do?
The code is part of the module
I have tried to change the draw_Objects() function but I couldn't solve it.
import pygame
from const import *
class item(pygame.sprite.Sprite):
def __init__(self,game):
super().__init__()
self.game=game
#self.screen=screen
self.width=WIDTH
self.height=HEIGHT
#potion 사진 불러옴
self.image=pygame.image.load("tile/red-potion.png")
self.rect = self.image.get_rect()
self.red_potion=pygame.image.load("tile/red-potion.png")
self.blue_potion=pygame.image.load("tile/blue-potion.png")
self.mask=pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
redItem=[50,530,300,50,850,100,600,280,800,400]
def __call__(self):
print (" ")
def item_display(self,screen):
#아이템 화면에 표시
screen.blit(self.red_potion,(50,530)) #red1
screen.blit(self.blue_potion,(30,530))
screen.blit(self.blue_potion,(30,460))
screen.blit(self.red_potion,(300,50)) #red2
screen.blit(self.blue_potion,(400,150))
screen.blit(self.image,(850,100)) #red3
screen.blit(self.red_potion,(600,280)) #red4
screen.blit(self.red_potion,(800,400)) #red5
screen.blit(self.blue_potion,(600,370))
def draw_Objects(myList=[]):
for i in myList:
x=myList[i]
y=myList[i+1]
screen.blit(self.red_potion,(x,y))
i+=1
def item_eat(self,screen):
item__=item(self)
#red2 item
self.rect.x=300
self.rect.y=50
#item과 player 충돌 검사
hits_item=pygame.sprite.spritecollide(self,self.game.player_group,False,pygame.sprite.collide_mask)
if hits_item :
screen.blit(self.red_potion,(50,530)) #red1
screen.blit(self.blue_potion,(30,530))
screen.blit(self.blue_potion,(30,460))
screen.blit(self.blue_potion,(400,150))
screen.blit(self.red_potion,(850,100)) #red3
screen.blit(self.red_potion,(600,280)) #red4
screen.blit(self.red_potion,(800,400)) #red5
screen.blit(self.blue_potion,(600,370))
else:
#item__.item_display(self.screen)
draw_Objects(redItem)

this line
draw_Objects(redItem)
is looking for a global function named draw_Objects which does not exist. you need to call
self.draw_Objects(redItem)
However, you would also need to include self as a parameter in the function definition like so
def draw_Objects(self, myList=[]):

draw_Objects is not a global function, it is an attribute of the class and can be called with self.
def item_eat(self,screen):
item__=item(self)
#red2 item
self.rect.x=300
self.rect.y=50
#item과 player 충돌 검사
hits_item=pygame.sprite.spritecollide(self,self.game.player_group,False,pygame.sprite.collide_mask)
if hits_item :
screen.blit(self.red_potion,(50,530)) #red1
screen.blit(self.blue_potion,(30,530))
screen.blit(self.blue_potion,(30,460))
screen.blit(self.blue_potion,(400,150))
screen.blit(self.red_potion,(850,100)) #red3
screen.blit(self.red_potion,(600,280)) #red4
screen.blit(self.red_potion,(800,400)) #red5
screen.blit(self.blue_potion,(600,370))
else:
#item__.item_display(self.screen)
self.draw_Objects(redItem) # Change this line to reference draw_Objects

It's rather simple.
def draw_Objects(self):
myList=[]
for i in myList:
x=myList[i]
y=myList[i+1]
screen.blit(self.red_potion,(x,y))
i+=1
Then call it like:
self.draw_Objects()

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()

Python: Class: Calling a function in the same class

Good day..
I'm kinda struggling in my learning process in Class. Let me show my code, and what is happening.
from random import randint
print "Start"
class Simulation (object):
def __init__(self):
self.bankroll= 5000
self.bet=0
self.betLevel= 0
self.betList=[5,5,5,10,15,25,40,65,100]
self.wlist=[]
self.my_file=open("output.txt","w")
self.winningNumber=0
self.myNumber=[4,5,7,8]
self.testCase=1
self.my_file.write("Test case Bet Number Outcome Bankroll")
def gamble(self):
self.bet=self.betList[self.betLevel]
if self.bankroll < 1000 :
self.bet= 5
self.winningNumber= randint(0,36)
if self.winningNumber in self.myNumber:
win()
else:
lose()
def win(self):
self.bankroll +=(17*self.bet)
self.wlist= [self.testCase,self.bet,self.winningNumber,"WIN",self.bankroll]
self.betLevel=0
write()
def lose(self):
self.bankroll -=self.bet
self.wlist= [self.testCase,self.bet,self.winningNumber,"LOSE",self.bankroll]
self.betLevel +=1
write()
def write(self):
self.my_file.write(" ".join(self.wlist))
def startSimulation(self):
for i in range (100):
gamble()
closeFile()
def closeFile(self):
self.my_file.close()
mySimulation= Simulation()
mySimulation.startSimulation()
print "DONE"
So in this code, I'm trying to simulating a roulette game, using a weird betting system. It works like Martingale, but instead of doubling, I follows Fibonacci sequence.
So my problem is that I got this error:
Traceback (most recent call last):
File "D:\Roulette simulation\python 3.py", line 44, in <module>
mySimulation.startSimulation()
File "D:\Roulette simulation\python 3.py", line 38, in startSimulation
gamble()
NameError: global name 'gamble' is not defined
My question. Why? I mean, I'm calling a function in the same class? Why I got the global error?
Within a method, you have self as a reference to your instance. You can access methods on that instance through that reference:
self.gamble()
There is no global gamble function here; the method is part of the Simulation class. This applies to all methods; you'll have to call closeFile, lose, win and write on self as well, for example.
Try running
self.gamble()
in class functions,self means class itself(someone use 'cls' instead of 'self'), so self.gamble means gamble function of this class
if you want to run a function in the position of class attribution
>>> class P:
name = 'name'
def getage(self):
return 18
age = property(getage)
>>> p = P()
>>> p.age
18
>>>

Can't seem to reference an instance variable, getting "global name ... is not defined"

I wrote this to create button like functionality using pygame gaming library to learn how to use Python. In using the function push() I get the error "global name 'next' is not defined" when trying to reference an instance variable.
I don't really understand how variables in classes work, I assume the environment is automatically global due to using the self keyboard: it's global by the fact its a member of self. And then anything else is simply in a local scope. I guess that's wrong. So how do I define a "global name" before its used?
Button:
class Button(object):
def __init__(self,x,y,dimx,dimy,color,phrase):
self.is_clicked = False
self.has_next = False
self.next = None
self.x=x
self.y=y
self.dim_x=dimx
self.dim_y=dimy
self.e_x=x+dimx
self.e_y=y+dimy
self.color=color
self.color2=color
self.phrase=phrase
def mypush(self,btn):
if not (self.has_next):
self.next=btn
self.has_next=True
else:
next.mypush(btn) """ === right here === """
def checkhit(self,x,y):
if ((x>= self.x) or (x<=self.e_x)):
if((y>= self.y) or (y<=self.e_y)):
self.is_clicked = True
self.color = (255,255,255)
return self.phrase
elif (self.has_next == True):
return self.next.checkhit(x,y)
else:
return None
def release(self):
if(self.is_clicked == True):
self.is_clicked=False
self.color=self.color2
elif(self.has_next == True):
self.next.release()
def mydraw(self,the_game,scrn):
the_game.draw.rect(scrn,self.color,[self.x, self.y, self.dim_x,self.dim_y])
if(self.has_next):
self.next.mydraw(the_game,scrn)
...
Where function push is used:
for x in range(2, 10):
btn = Button(10+50*x,470,45,20,(128,64,224),"Button ".join(num[x-1]))
my_button.mypush(btn)
result:
Traceback (most recent call last):
File "testbutton1.py", line 83, in <module>
my_button.mypush(btn)
File "testbutton1.py", line 22, in mypush
next.mypush(btn)
NameError: global name 'next' is not defined
you need to refer to the member variable
self.next.mypush(btn)
not the global variable
next

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.

Using getattr to work with a method from another class

pI am working on a bit of code that does nothing important, but one of the things I am trying to make it do is call a function from another class, and the class name is pulled out of a list and put into a variable. Mind you I have literally just learned python over the last 2 weeks, and barely know my way around how to program.
What I believe that this should do is when getattr() is called, it will pass the attribute 'run_question' that is contained in the respective class with the same name as what is in question_type, and then pass it onto 'running_question'. I know there are probably better ways to do what I am attempting, but I want to know why this method doesn't work how I think it should.
#! /usr/bin/python
rom random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['Addition', 'Subtraction', 'Division', 'Multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(question_type, 'run_question' )
except AttributeError:
print question_type
print "Attribute error:Attribute not found"
else: running_question()
class Question(object):
pass
class Multiplication(Question):
def run_question(self):
print "*"
class Division(Question):
def run_question(self):
print "/"
class Subtraction(Question):
def run_question(self):
print "-"
class Addition(Question):
def run_question(self):
print "+"
test = QuestionRunner()
test.run_questions()
This outputs:
[david#leonid mathtest] :( $ python mathtest.py
Division
Attribute error:Attribute not found
[david#leonid mathtest] :) $
Which indicates that I am not getting the run_question attribute as I expect.
I should note that when I put the functions into the QuestionRunner class in the following way, everything works as expected. The main reason I am using classes where it really isn't needed it to actually get a good grasp of how to make them do what I want.
#! /usr/bin/python
from random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['addition', 'subtraction', 'division', 'multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(self, question_type)
except AttributeError:
exit(1)
else: running_question()
def multiplication(self):
print "*"
def division(self):
print "/"
def addition(self):
print "+"
def subtraction(self):
print "-"
test = QuestionRunner()
test.run_questions()
Any help on why this isn't working would be great, and I appreciate it greatly.
Any help on why this isn't working would be great, and I appreciate it greatly.
Ah, I have found out the missing concept that was causing my logic to be faulty. I assumed that I could pass the name of an object to getattr, when in reality I have to pass the object itself.

Categories