python - Pygame: Accessing colliding sprite's properties using spritecollide() -
i building top down shooter in style of raiden 2. need know how access enemy object when detect collision using 'spritecollide'.
the reason need enemy object can lower energy level every bullet hits them.
this dictionary have work with:
enemycollisions = pygame.sprite.groupcollide(shipbulletgroup, enemygroup, true, false)
here's bullet class:
class bullet(entity): def __init__(self, ship, angle): entity.__init__(self) self.speed = 8 self.level = 0 self.image = pygame.surface((bullet_dimensions, bullet_dimensions)).convert() self.rect = self.image.get_rect() self.rect.x = ship.rect.centerx self.rect.y = ship.rect.top self.angle = angle def update(self, enemygroup): if self.rect.bottom < 0: self.kill() else: self.rect.y -= self.speed
here's unfinished enemy class:
class enemy_1(entity): def __init__(self): entity.__init__(self) self.speed = (1, 1) self.energy = 10 self.begin = false self.run = false self.image = pygame.surface((win_w/5, win_h/15)).convert() self.image.fill((70, 70, 70)) self.rect = self.image.get_rect() self.rect.centerx = win_w/1.333 self.rect.y = -win_h/15 def shoot(self): bullet_1 = bullet(self, 270) bullet_2 = bullet(self, 225) bullet_3 = bullet(self, 315) def update(self, enemygroup, timer): if timer == 300: self.begin = true elif timer == 900: self.run = true elif timer > 900 , self.rect.x > win_w: self.remove(enemygroup) if self.run: self.rect.x += self.speed[0] self.rect.y += self.speed[1] elif self.begin: self.rect.y += self.speed[1] if self.rect.y > win_h/4: self.rect.y = win_h/4 if self.energy == 0: self.kill()
here's complete program:
import sys, pygame, os, random, math ast import literal_eval # force static position of screen os.environ['sdl_video_centered'] = '1' # constants left = 'left' right = 'right' black = (0, 0, 0) white = (255, 255, 255) pill_width = 5 pill_height = 20 win_w = 500 win_h = 800 ship_width = win_w/15 ship_height = win_h/15 bullet_dimensions = 5 timer = 0 class entity(pygame.sprite.sprite): def __init__(self): pygame.sprite.sprite.__init__(self) class text(entity): def __init__(self, text, size, color, position, font=none): entity.__init__(self) self.color = color self.font = pygame.font.font(font, size) self.text = text self.set(text, position) def set(self, text, position): self.image = self.font.render(str(text), 1, self.color) self.rect = self.image.get_rect() self.rect.move_ip(position[0]-self.rect.width/2, (position[1]-self.rect.height)/2) class ship(entity): def __init__(self, container): entity.__init__(self) self.speed = 5 self.score = 0 self.image = pygame.surface((ship_width, ship_height)).convert() self.rect = self.image.get_rect() self.rect.centerx = container.centerx self.rect.y = container.centery def update(self, bulletgroup): key = pygame.key.get_pressed() if key[pygame.k_w]: self.rect.centery -= self.speed if key[pygame.k_s]: self.rect.centery += self.speed if key[pygame.k_d]: self.rect.centerx += self.speed if key[pygame.k_a]: self.rect.centerx -= self.speed if key[pygame.k_space]: if timer % 7 == 0: bullet = bullet(self, 90, 'friend') bulletgroup.add(bullet) # ship movement boundaries if self.rect.y < win_h/25: self.rect.y = win_h/25 if self.rect.y > win_h - ship_height: self.rect.y = win_h - ship_height if self.rect.x < 0: self.rect.x = 0 if self.rect.x > win_w - ship_width: self.rect.x = win_w - ship_width class bullet(entity): def __init__(self, ship, angle, type): entity.__init__(self) self.speed = 8 self.level = 0 self.image = pygame.surface((bullet_dimensions, bullet_dimensions)).convert() self.rect = self.image.get_rect() self.dx = math.cos(math.radians(angle)) * self.speed self.dy = math.sin(math.radians(angle)) * self.speed self.setxy(ship, type) def setxy(self, ship, type): self.rect.x = ship.rect.centerx if type == 'friend': self.rect.y = ship.rect.top elif type == 'enemy': self.rect.y = ship.rect.bottom def update(self): if self.rect.bottom < 0: self.kill() else: self.rect.x -= self.dx self.rect.y -= self.dy if type == 'friend': self.rect.y = -self.rect.y self.rect.x = -self.rect.x class powerup(entity): def __init__(self, xden, pillcount): entity.__init__(self) self.speed = 3 self.density = xden self.image = pygame.surface((pill_width, pill_height)).convert() self.rect = self.image.get_rect() self.rect = self.rect.move(100,100) def restart(self): pass def update(self): if self.rect.y > win_h: del self else: self.rect = self.rect.move((0, self.speed)) class enemy(entity): def __init__(self): entity.__init__(self) self.begin = false self.run = false self.color = (153, 0, 76) class planes(enemy): def __init__(self, speed, energy, size, location): enemy.__init__(self) self.speed = speed self.energy = energy self.image = pygame.surface(size).convert() self.image.fill(self.color) self.rect = self.image.get_rect() self.rect.centerx = location[0] self.rect.y = location[1] def shoot(self, enemybulletgroup): bullet_1 = bullet(self, 240, 'enemy') bullet_2 = bullet(self, 270, 'enemy') bullet_3 = bullet(self, 300, 'enemy') enemybulletgroup.add(bullet_1, bullet_2, bullet_3) def update(self, enemygroup, enemybulletgroup): if timer == 300: self.begin = true elif timer == 900: self.run = true elif self.rect.x > win_w or self.energy == 0: self.kill() if self.run: self.rect.x += self.speed[0] self.rect.y += self.speed[1] if timer % 100 == 0: self.shoot(enemybulletgroup) elif self.begin: self.rect.y += self.speed[1] if self.rect.y > win_h/4: self.rect.y = win_h/4 if timer % 100 == 0: self.shoot(enemybulletgroup) def main(): # initialize pygame.init() global timer fps = 60 lleft = lright = lup = ldown = shoot = false clock = pygame.time.clock() play = true pygame.display.set_caption('pong') screen = pygame.display.set_mode((win_w, win_h), pygame.srcalpha) # create game objects ship = ship(pygame.rect.rect(0, 0, win_w, win_h)) score1 = text("score: " + str(ship.score), 40, black, (win_w/2, (win_h/25))) enemy_1 = planes((1, 1), 10, (win_w/5, win_h/15), (win_w/1.4, -win_h/15)) # create groups powerupgroup = pygame.sprite.group() shipgroup = pygame.sprite.group() shipgroup.add(ship) textgroup = pygame.sprite.group() textgroup.add(score1) shipbulletgroup = pygame.sprite.group() enemybulletgroup = pygame.sprite.group() enemygroup = pygame.sprite.group() enemygroup.add(enemy_1) # gameplay while play: # checks if window exit button pressed event in pygame.event.get(): if event.type == pygame.quit: sys.exit() elif event.type == pygame.keydown: if event.key == pygame.k_escape: pygame.quit() sys.exit() # update powerupgroup.update() ship.update(shipbulletgroup) shipbulletgroup.update() textgroup.update() enemygroup.update(enemygroup, enemybulletgroup) enemybulletgroup.update() enemycollisions = pygame.sprite.groupcollide(shipbulletgroup, enemygroup, true, false) key in enemycollisions: print enemycollisions[key].energy # print background/sprites screen.fill(white) powerupgroup.draw(screen) shipgroup.draw(screen) shipbulletgroup.draw(screen) textgroup.draw(screen) enemygroup.draw(screen) enemybulletgroup.draw(screen) # print score bar hori_partition = pygame.surface((win_w, 1)) screen.blit(hori_partition, (0, win_h/25)) timer += 1 # limits frames per iteration of while loop clock.tick(fps) # writes main surface pygame.display.flip() if __name__ == "__main__": main()
the pygame.sprite.groupcollide()
function returns dictionary values list objects:
every sprite inside group1 added return dictionary. value each item list of sprites in group2 intersect.
thats reason why calling print enemycollisions[key].energy
when iterating on return dict fails, since list object -- value of enemycollisions[key]
-- not have energy()
method.
to access values of dictionary in python 2.x use .itervalues()
method of dict instance. each colliding sprite, iterate again on these values:
enemycollisions = pygame.sprite.groupcollide(shipbulletgroup, enemygroup, true, false) #iterate on values of enemycollisions dict enemycollisions in enemycollisions.itervalues(): #access enemies collided shipbullet enemy in enemycollisions: print enemy.energy
Comments
Post a Comment