Reputation: 491
Update 12/7
Finally i found the reason why i cant use Group
to calling the methods , for the method name must update()
so that the Group
can calling.
in my codes i modify like this then it worked!!
def update(self):
self.x =self.rect.x + self.speed
self.rect.x = self.x
def position(aliens):
aliens.update()
=============================================
Edit the question make it clearly
def update(self):
self.x =self.ai.setting.alien_speed_factor
self.rect.x = self.x
def update_aliens(aliens):
aliens.update()
These two from the book, and i use it in my codes, for the aliens is a Group it called error #AttributeError: 'Group' object has no attribute 'position'
How to make Group
aliens to execute update()
???
I am writing script to make the alien group to move, one for my own way and another is from the book, when i refer to the book i found a mistake, i am not sure whether is it wrong.
Book "Python Crash Course" page 243
I use
def update(aliens):
for alien in aliens:
alien.position()
instead of the code from book:
def update(aliens):
aliens.position()
which returns
>> AttributeError: 'Group' object has no attribute 'position'
then the runing the script is correct, so is this a mistake in book? or i use the wrong way to run the original codes?
here's my code:
#!/usr/bin/python
import sys
import pygame as p
class Setting():
def __init__(self,width,height):
self.w=width
self.h=height
self.flag=p.RESIZABLE
self.screen=p.display.set_mode((self.w,self.h),self.flag)
p.display.set_caption("Muhaha")
class Alien(p.sprite.Sprite):
def __init__(self):
super().__init__()
pic=p.image.load("../image/ship.jpg").convert_alpha()
self.image=p.transform.smoothscale(pic,(100,100))
self.rect=self.image.get_rect()
self.x = float(self.rect.x)
self.rect.x=(self.rect.width)
self.speed=1
def create(self,setting,aliens):
spacex=setting.w-(self.rect.x)*2
spacey=(setting.h)/2-self.rect.y
alien_number=int(spacex/(2*(self.rect.width)))
alien_row=int(spacey/(2*(self.rect.height)))
for row in range(alien_row):
for number in range(alien_number):
alien=Alien()
alien.rect.x=alien.rect.x+2*alien.rect.width*number
alien.rect.y=alien.rect.y+2*alien.rect.height*row
aliens.add(alien)
def position(self):
self.x =self.rect.x + self.speed
self.rect.x = self.x
def update(aliens):
aliens.position() #AttributeError: 'Group' object has no attribute 'position'
#i think the correct code is>> for alien in aliens:
# alien.position()
def blit(setting,aliens):
aliens.draw(setting.screen)
def game():
p.init()
setting=Setting(1200,800)
alien=Alien()
aliens=p.sprite.Group()
alien.create(setting,aliens)
while True:
for event in p.event.get():
if event.type == p.QUIT:
sys.exit()
setting.screen.fill((255,0,0))
Alien.blit(setting,aliens)
Alien.update(aliens)
p.display.flip()
game()
Upvotes: 1
Views: 236
Reputation: 101122
Yes, it seems like a bug. And to be honest, the entire code looks horrible.
As a first step, remove the blit
and position
functions from the Alien
class, change the update
function to this:
def update(self):
self.x = self.rect.x + self.speed
self.rect.x = self.x
and in the main loop, instead of
Alien.blit(setting,aliens)
Alien.update(aliens)
do
aliens.update()
aliens.draw(setting.screen)
Calling update
on a Group
will call the update
of all Sprite
instances in that Group
, so there's not need to iterate over all sprites manually.
In the same vein, calling draw
on a Group
will draw all sprites in that Group
to the Surface
passed as argument (usually the screen surface). Again, there's no need to do this in the Alien
class, which is supposed to represent a single sprite.
Some other issues:
Alien
sprite is loaded from disk every time an new instance is createdAlien
is created to just create more instances with the create
instance method, and then the update
function is used like a class methodUpvotes: 1