Python object orientated not changing values in init function - python

Hi I'm in the process of making a game and I've hit a stumbling block this is part of my code below:
class player(object):
def __init__(self):
self.x = 10
self.y = 10
self.amount = 5
self.answer = 0
def move(self):
self.x += self.amount
self.y += self.amount
while True:
player().move()
print player().x
Its probably a really basic mistake but whatever the move() function does it doesn't ever seem to change value of self.x or self.y can someone poke me in the right direction please! Thanks, I realise I'm probably missing something very basic, I don't have much experience with OO

player().move() # create a player and move it
print player().x # create another player and print its x
What you meant is:
aplayer = player()
aplayer.move()
print aplayer.x
PS: The common practice is to capitalize class names:
class Player(object):
def __init__(self):
self.x = 10
self.y = 10
self.amount = 5
self.answer = 0
def move(self):
self.x += self.amount
self.y += self.amount
player = Player()
player.move()
print player.x
This way it's easy to differentiate between classes and objects.

Ok. what the other person said is that you need to set the "Player" as a variable such as George, then call George.move()
so
class Player(object):
def __init__(self):
self.x = 10
self.y = 10
self.amount = 5
self.answer = 0
def move(self):
self.x += self.amount
self.y += self.amount
While True:
george = Player()
george.move()
print george.x
that should work. and you can change "george" to anything you want, just make sure it is consistent.

Related

TypeError: __init__() takes X positional arguments but X+1 were given

class Game():
def __init__(self):
# here we want to make a player, and start making some attributes
self.player = character(50,50,100, (0,255,0), "Player")
self.enemy = character(55,200,200, (255,0,0), "Enemy")
self.alive = [self.player,self.enemy]
class character(): # this will be the class which can make any
def __init__(self,x,y,health,colour, name):
self.x = x
self.y = y
self.health = health
self.colour = colour
self.width = 90
self.height = 50
self.vel = 0.04
self.name = name
When I try to use or change the colour attribute (of the character) in my Game class, I get an
TypeError: __init__() takes 5 positional arguments but 6 were given
while defining the object player as here:
self.player = character(50,50,100, (0,255,0), "Player")
Why does Python tell me I gave it 6 arguments, when I only gave 5?
I don't know if this will solve the problem seeing as I cannot replicate the error either way but, Empty brackets are not needed on the class definitions.
class Game:
def __init__(self):
# here we want to make a player, and start making some attributes
self.player = character(50,50,100, (0,255,0), "Player")
self.enemy = character(55,200,200, (255,0,0), "Enemy")
self.alive = [self.player,self.enemy]
class character: # this will be the class which can make any
def __init__(self,x,y,health,colour, name):
self.x = x
self.y = y
self.health = health
self.colour = colour
self.width = 90
self.height = 50
self.vel = 0.04
self.name = name

TypeError: unbound method collide() must be called with Enemy instance as first argument (got type instance instead) in processing 3.5.4 [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am getting this error whilst trying to add collision to a game and I have gotten this error for now all I want is for the game to print yes when the target is hit if there better way to detect collision I'm all ears. anything helps.
TypeError: unbound method collide() must be called with Enemy instance as first argument (got type instance instead)
This error comes from this code
Enemy.collide(Bullets)
this is the entire code ~200 lines
import math
class Spacey(object):
def __init__(self,x,y,siz,col):
self.x = x
self.y = y
self.siz = siz
self.col = col
self.body_angle = -90
self.enabled = True
def see(self):
self.move()
self.render()
def show(self):
stroke(250)
point(self.x,self.y)
def move(self):
if(keyPressed and key == CODED):
if(keyCode == LEFT):
self.x += (sin(radians(self.body_angle))*2)
if(keyCode == RIGHT):
self.x -= (sin(radians(self.body_angle))*2)
if(keyCode == UP):
self.y += (sin(radians(self.body_angle))*2)
if(keyCode == DOWN):
self.y -= (sin(radians(self.body_angle))*2)
if(keyCode == SHIFT and self.enabled):
bullet_repeat = Bullets(self.x,self.y,5,stroke(113,195,0))
bullet.append(bullet_repeat)
self.enabled = False
else:
self.enabled = True
def render(self):
pushMatrix()
translate(self.x,self.y)
stroke(113,195,0)
strokeWeight(3)
fill(177,255,72)
beginShape()
vertex(self.x,self.y-40)
vertex(self.x-40,self.y+40)
vertex(self.x+40,self.y+40)
vertex(self.x,self.y-40)
endShape()
popMatrix()
class Bullets(object):
def __init__ (self,x,y,siz,col):
self.x = x
self.y = y
self.startX = int(x)
self.startY = y
self.siz = int(siz)
self.col = col
self.sx = x
def sx():
return int(self.x)
def siza(self):
return int(self.siz)
def colo():
stroke(113,195,0)
def see(self):
self.move()
self.render()
self.sx()
def show(self):
stroke(250)
point(self.x,self.y)
def move(self):
self.y = self.y - 5
for bullets in bullet:
if ((self.x-self.startX)**2 + (self.y-self.startY)**2) > 1000000000:
bullet.remove(bullets)
def render(self):
pushMatrix()
translate(self.x,self.y)
stroke(113,195,0)
beginShape()
circle(self.x,self.y+10,5)
endShape(CLOSE)
popMatrix()
class Enemy(object):
def __init__(self,x,y,siz,col):
self.x = int(x)
self.y = y
self.speed = 2
self.health = 1000
self.siz = int(siz)
self.col = col
def see(self):
self.move()
self.render()
def move(self):
spd = 2
bts = True
for i in range(0, 2, 500):
self.x += 2
if self.x == 500:
self.x = 2
def health(self):
healthy = 20
if collide == True:
health -= 1
if healthy == 0:
next_level()
healthy += 100
def render(self):
pushMatrix()
translate(self.x,self.y)
stroke(113,195,0)
strokeWeight(3)
fill(177,255,72)
beginShape()
vertex(self.x,self.y-40)
vertex(self.x-40,self.y+40)
vertex(self.x+40,self.y+40)
vertex(self.x,self.y-40)
endShape()
popMatrix()
def collide(self,other):
if(self.x + self.siz / 2 >= Bullets.sx() - Bullets.siz / 2 and self.x - self.siz / 2 <= Bullets.sx() + Bullets.siz / 2
and self.y + self.siz / 2 >= Bullets.y - Bullets.siza / 2 and self.y - self.siz / 2 <= Bullets.y + Bullets.siza / 2):
print("YES")
def get_accuracy():
for i in bullet:
accuracy = hitcount / bcount
if accuracy >= 90:
return 'AMAZING'
if accuracy >= 50:
return 'GOOD'
if accuracy >= 10:
return 'OKAY'
if accuracy < 10:
print('NOT GOOD')
spacey = Spacey(250,400, 20,color(113,195,0))
enemy = Enemy(0,20,20,color(113,195,0))
bullet = []
collidesss = []
levels = [1,2,3,4,5,6,7]
def reset():
spacey = spacey(250,400)
enemy = enemy(0,20)
def setup():
size(1000,1000)
def draw():
global bcount, hitcount
background(0,14,47)
for bullet_repeat in bullet:
bullet_repeat.see()
spacey.see()
enemy.see()
for i in bullet:
Enemy.collide(Bullets)
hitcount = 0
bcount = 0
for bullet_repeat in bullet:
bcount += 1
fill(255)
textSize(30)
text(bcount,920,950,)
text('Bullets shot:',730,950,)
This is now edited from the original
The code
for i in bullet:
Enemy.collide(Bullets)
should be
for i in bullet:
enemy.collide(Bullets)
Enemy is the class, enemy is an instance of the class.
In Python, class names are conventionally written with capital first letter, whereas instances/variables are written with lower case first letters.

Remove object particle with kivy condition

What I want is two things:
count the number of enemies on the screen. And remove all enemies from the screen with a contion.
The second chose is to allow enemies to shoot randomly
class Enemy(Particle):
active = False
tex_name = 'ufo'
v = 0
def reset(self, created=False):
self.active = False
self.x = -100
self.y = -100
self.v = 0
def advance(self, nap):
if self.active:
if self.check_hit():
self.reset()
return
self.x -= 200 * nap
if self.x < -50:
self.reset()
return
self.y += self.v * nap
if self.y <= 0:
self.v = abs(self.v)
elif self.y >= self.parent.height:
self.v = -abs(self.v)
elif self.parent.spawn_delay <= 0:
self.active = True
self.x = self.parent.width + 50
self.y = self.parent.height * random()
self.v = randint(-100, 100)
self.parent.spawn_delay += 1
def check_hit(self):
if math.hypot(self.parent.player_x - self.x,
self.parent.player_y - self.y) < 60:
return True
for b in self.parent.bullets:
if not b.active:
continue
if math.hypot(b.x - self.x, b.y - self.y) < 30:
b.reset()
return True
What I want is two things:
count the number of enemies on the screen. And remove all enemies from the screen with a contion.
The second chose is to allow enemies to shoot randomly
You can accomplish the first two of your questions by modifying the PSWidget class. By adding two attributes enemy_count and killall to the class:
class PSWidget(Widget):
indices = []
vertices = []
particles = []
enemy_count = 0
killall = False
And using those attributes in the update_glsl() method:
def update_glsl(self, nap):
self.enemy_count = 0 # initialize enemy count
for p in self.particles:
if isinstance(p, Enemy) and p.active:
if self.killall:
p.reset() # kill this enemy
else:
self.enemy_count += 1 # increment enemy count
p.advance(nap)
p.update()
self.canvas.clear()
with self.canvas:
Mesh(fmt=self.vfmt, mode='triangles',
indices=self.indices, vertices=self.vertices,
texture=self.texture)
# reset killall
self.killall = False
So, anytime you want the count of active enemies, just use the enemy_count attribute of the PSWidget instance. And whenever you want to kill all the active enemies, just set the killall attribute of the PSWidget instance.
As far as your third question, show us your attempt at coding that.
If you are using an answer that I gave in another question, where I suggested using the on_enter() method to start the game updates, then you can use on_leave() to stop the updates. The game movements are faster every time you enter MainScreen because more updates are scheduled on each entry. Here is a modified MainScreen that handles that handles that issue:
class MainScreen(Screen):
started = BooleanProperty(False)
def on_enter(self, *args):
if not self.started:
self.ids.game.initialize()
self.started = True
self.update_event = Clock.schedule_interval(self.ids.game.update_glsl, 1.0/60.0)
def on_leave(self, *args):
if self.update_event is not None:
self.update_event.cancel()

Flickering command prompt screen while making a text based game in python

I am making a text based game and i tried to implement a basic game loop where the map is just being drawn and cleared. However the result is just a flickering mess. When i read through articles about how frames per seocond work, they just say that its how often the computer blits new frames in a second. Now what i dont understand is how do actual game game-libraries like pygame achieve this, while my game running on terminal cannot. This is that my loop looks like:
while True:
game_map.draw()
os.system("cls")
I am certain that python is able to go through this loop enough times so that the flickering is not noticeable. Is there some kind of a limit to refresh rate in command promt? And is there a way to fix this? Thanks in advance. The following is the code i have so far in case there might be something relevant to the question.
import os
import keyboard
class Map:
def __init__(self):
self.map = [[" " for i in range(34)]for i in range(40)]
def update(self, thing, x, y):
self.map[y][x] = thing
def draw(self):
for layer in self.map:
print(layer)
game_map = Map()
class Player:
def __init__(self):
self.x = 1
self.y = 38
self.player = input("Enter your nickname: ").upper()
try:
self.player = self.player[0]
except:
pass
def draw(self):
game_map.update(self.player, self.x, self.y)
def move(self):
if keyboard.is_pressed("RIGHT"):
self.x += 1
game_map.map[self.y][self.x - 1] = " "
if keyboard.is_pressed("LEFT"):
self.x -= 1
game_map.map[self.y][self.x + 1] = " "
if keyboard.is_pressed("UP"):
self.y -= 1
game_map.map[self.y + 1][self.x] = " "
if keyboard.is_pressed("DOWN"):
self.y += 1
game_map.map[self.y - 1][self.x] = " "
def boundries(self):
if self.x >= 33:
self.x = 33
if self.x <= 0:
self.x = 0
if self.y <= 38:
self.y = 38
if self.y >= 39:
self.y = 38
player = Player()
class Bullet:
def __init__(self):
self.x = player.x
self.y = player.y
self.bullet = "*"
class Game:
def __init__(self):
self.bullets = []
def generate_bullet(self):
if keyboard.is_pressed("w"):
self.bullets.append(Bullet())
def shoot(self):
if self.bullets:
for bullet in game.bullets:
game_map.map[bullet.y - 1][bullet.x] = bullet.bullet
game_map.map[bullet.y + 1][bullet.x] = " "
bullet.y -= 1
if bullet.y <= 1:
game_map.map[1][bullet.x] = " "
game_map.map[0][bullet.x] = " "
def bullet_boundries(self):
for b in self.bullets:
if b.x >= 33:
self.bullets.remove(b)
if b.x <= 0:
self.bullets.remove(b)
if b.y <= 0:
self.bullets.remove(b)
if b.y >= 39:
self.bullets.remove(b)
game = Game()
while True:
game_map.draw()
os.system("cls")
player.draw()
player.move()
player.boundries()
game.generate_bullet()
game.shoot()
game.bullet_boundries()

Python: Classes that "talk" to each other

I'm a college student. I'm in my second comp sci class and we haven't got much past simply making classes and functions within them so I haven't really been able to make much use of the complicated jargon I've found on the internet.
I'm making a roach infestation sim, and I need to be able to have a "roach" class be able to detect where a "food" class is in a window. My teacher told me that my best shot might be to make another mastermind-like class that is a middle man between the two, but I don't really know how that would work. Can anyone help me out? I'm using Python through Calico. Here's what I have of the roach class (EDIT: guess I should show the main() etc too):
class Roach:
def __init__(self, win, placex, placey):
self.timer = 320 + (10 *(int(10 *random.random())))
self.speed = 0.2
self.heading = 360
self.win = win
self.x = placex
self.y = placey
self.body = self.makeBody()
self.body.draw(self.win)
def __str__(self):
t = "Roach at ("+str(self.x)+","+str(self.y)+")"
return t
def makeBody(self):
body = Rectangle((-5,-5),(5,5))
body.setFill(Color('Brown'))
body.moveTo(self.x,self.y)
return body
def move(self, win):
self.x = self.x + self.speed *sin(self.heading)
self.y = self.y + self.speed *cos(self.heading)
self.body.moveTo(self.x,self.y)
self.avoid(win)
def avoid(self, win):
Border = False
if self.x >= win.getWidth():
self.setHeading(random.randrange(91, 269))
self.x = win.getWidth() - 1
Border = True
elif self.x <= 0:
self.setHeading(random.randrange(271, 449))
self.x = 1
Border = True
elif self.y >= win.getHeight():
self.setHeading(random.randrange(1, 179))
self.y = win.getHeight() - 1
Border = True
elif self.y <= 0:
self.setHeading(random.randrange(181, 359))
self.y = 1
Border = True
return Border
#Getters
def getSpeed(self):
return self.speed
def getHeading(self):
return self.heading
def getX(self):
return self.x
def getY(self):
return self.y
#Setters
def setSpeed(self, speed):
self.speed = speed
def setHeading(self, heading):
self.heading = heading
self.body.rotateTo(self.heading)
def setX(self, x):
self.x = x
def setY(self, y):
self.y = y
def main():
win = Window(400, 400)
win.setBackground(Color("White"))
Rpop = []
Wpop = []
i = 320
menu(win, Rpop, Wpop)
while getKeyPressed() != 'Escape':
for roach in Rpop:
if roach.avoid(win) == True:
roach.avoid(win)
elif i % roach.timer == 0:
roach.setHeading(360*random.random())
roach.move(win)
if getKeyPressed() == 'm':
menu(win, Rpop, Wpop)
i = i + 1
def menu(win, Rpop, Wpop):
while getKeyPressed() != 's':
if getKeyPressed() == 'r':
Rpop.append(Roach(win,getMouseNow()[0],getMouseNow()[1]))
if getKeyPressed() == 'w':
point1 = getMouse()
dot1 = Circle((point1[0],point1[1]), 3)
dot1.draw(win)
point2 = getMouse()
dot2 = Circle((point2[0],point2[1]), 3)
dot2.draw(win)
Wpop.append(Wall(win, point1[0], point1[1], point2[0], point2[1]))
return
main()
Sorry for the lack of comments and likely juvenile programming. Thank you so much.
Here's a sort of rough outline of how you might use an additional "Master" class to allow two other classes to communicate as is alluded to in the OP:
class Master():
...
def is_food_there(self, coords):
for food_instance in self.food_instances:
if coords == food_instance.coords:
return True
class Food():
def __init__(self, master_instance):
self.coords = ###some coordinates or whatever
master_instance.food_instances.append(self) ### register this food with master
class Roach():
def __init__(self, master_instance):
self.master_instance = master_instance
...
def move(self, newlocation):
if( self.master_instance.is_food_there(newlocation) ): ### check with master for food coords
###do something
The idea is that the we have a Master class which is essentially a container for a list of Food instances, and Roach class knows which Master instance it belongs to, so it can access that master's "is_food_there" function which in turn looks through the Food instances that belong to it. The Master class is "the man in the middle" in this example.

Categories

Resources