[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Sprites false positive collision - newbie alert



Hi Adam,

> What is the easiest way of detecting the collision between enemy and
> player?
>
> TIA
>
> My whole code is visible at:
> https://github.com/kabads/zoomr/blob/master/zoomr.py

I went through your code and found it to be a bit strange. I guess you started
using PyGame without sprites and have kept some bad habits.

In particular, this means:

 * A sprite having an iamge attribute, but then using some other atribute
   (your il) for drawing it with your own draw method makes no sense.
 * Always update sprites with their update method
 * Always keep the sprite's rect in sync with the sprite's position
 * Always have all sprites in some group (also your player in a player group)
 * Draw groups as a whole, not every single sprite

Also, please take a look at RenderClear and how to use the clear() method for
clearing the screen surface more efficiently than drawing a solid background.

Find attached your code, amended with the things I said, but leaving its
structure intact. There are also some things about your general Python that
come to mind - if you care, I can send you a completely cleand-up version.

Cheers,
Nik
# /bin/bash python2
# Zoomr - a pygame platform
# (c) 2014 A Cripps
# See README and LICENSE for more information

import pygame, random, sys
from pygame.locals import *

# set up some constant variables
FPS = 15
WINWIDTH = 680
WINHEIGHT = 480
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255, 0, 0)
GREEN = (50,155,0)
BLUE = (0,0,255)
movex, movey=0,0
all_sprite_list = pygame.sprite.Group()

class Player(pygame.sprite.Sprite):
    """This represents the moving player"""
    def __init__(self, x,y):
        """Constructor"""
        pygame.sprite.Sprite.__init__(self)
        self.health = 100
        self.image = pygame.image.load("blue.jpg")
        self.rect = self.image.get_rect()
        self.rect.topleft = [x, y]

    def checkBounds(self):
        if self.x >= 670:
            self.x = 670
        elif self.x <=0:
            self.x = 0
        if self.y >= 470:
            self.y = 470
        elif self.y<=0:
            self.y=0

    def update(self):
        self.rect.move_ip([movex, movey])

    def damage(self):
        self.health -= 10
        #"you're hit"
        #if self.health <=0:
            #print "you died"
            #terminate()




class Enemy(pygame.sprite.Sprite):
    """This is a static block that I will try to avoid"""
    def __init__(self):
        """Constructor"""
        x = random.randint(0,680-10)
        y = random.randint(0,480-10)
        pygame.sprite.Sprite.__init__(self)
        self.health = random.randint(0,100)
        self.image = pygame.image.load("red.jpg")
        self.rect = self.image.get_rect()
        self.rect.topleft = [x, y]


enemy_list = pygame.sprite.Group()
player_list = pygame.sprite.Group()

def main():
    global FPSCLOCK, DISPLAYSURF, BASICFONT, movex, movey, enemy, player, enemy_list
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
    BASICFONT = pygame.font.Font('freesansbold.ttf', 20)
    pygame.display.set_caption('Zoomr - where can you go today?')

    # Let's make the background green for now, and then draw everything afterwards.
    DISPLAYSURF.fill(GREEN)

    # Here is the player - protagonist
    player = Player(680/2, 480/2)
    player_list.add(player)
    all_sprite_list.add(player)

    # And here are some enemies - -don't touch them (still to come)
    for x in range (20):
        o = Enemy()
        enemy_list.add(o)
        all_sprite_list.add(o)
        pygame.display.flip()
    while True:
        runGame()
hits = []
def runGame():
    global movex, movey, enemy, player, enemy_list, hits

    for event in pygame.event.get():
        if event.type == QUIT:
            terminate()
        if event.type == KEYDOWN:
            if event.key== K_ESCAPE:
                terminate()
            if event.key ==K_a:
               movex = -1 #playerStartx-
            if event.key==K_d:
                movex = 1 #playerStartx+
            if event.key==K_w:
                movey = -1 #playerStarty-
            if event.key==K_s:
                movey = 1 #playerStarty+


        if (event.type==KEYUP):
            if (event.key==K_a):
                movex = 0
            if (event.key==K_d):
                movex =0
            if (event.key==K_w):
                movey = 0
            if (event.key==K_s):
                movey=0

    # Let's start to draw everything back on the screen - always starting with the background
    DISPLAYSURF.fill(GREEN)

    enemy_list.update()
    player_list.update()

    enemy_list.draw(DISPLAYSURF)
    player_list.draw(DISPLAYSURF)

    # Draw the enemies and check for a collision
    # However, I'm so stupid, because these should never live above the DISPLAYSURF.fill
    for o in enemy_list:
        if pygame.sprite.groupcollide(player_list, enemy_list, False, False):
            print "careful " + str(player.health)
            player.damage()
    #hits = pygame.sprite.spritecollide(player, enemy_list, True)
        #print "collision"
    #for i in hits:
    #    player.damage()

    #hits = pygame.sprite.spritecollide(player, enemy_list, True)
    #print "hits is this long: " + str(len(hits))
    #for i in hits:
    #    player.damage()
    # update the whole shebang
    pygame.display.flip()

def getRandomCoords():
    x = random.randint(0,680)
    y = random.randint(0,480)
    return x, y

def terminate():
    pygame.quit()
    sys.exit()


if __name__ == '__main__':
    main()

Attachment: signature.asc
Description: This is a digitally signed message part.