Python Forum

Full Version: Help with collisions.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
import pygame, sys, random
from pygame.locals import *
from pygame_functions import *

pygame.init()

clock = pygame.time.Clock()
fps = 30

DisplaySurface_Width = 480
DisplaySurface_Height = 640
DisplaySurface = pygame.display.set_mode((DisplaySurface_Height, DisplaySurface_Width))
pygame.display.set_caption("Boat Game")

boatIMG = pygame.image.load("boatIMG.png")
backgroundIMG = pygame.image.load("water_background.png")
heartIMG = pygame.image.load("heart.png")
enemy_bullet = pygame.image.load("bullet_enemy.png")



def bullet(bX, bY):
    DisplaySurface.blit(enemy_bullet, (bX,bY))


def boat(x, y):
    DisplaySurface.blit(boatIMG,(x,y))

game_Exit = False

def game_loop():

    boatx = 400
    boaty = 400
    bulletX = random.randint(200, 500)
    bulletY = -100
    bullet_Speed = 5

    while not game_Exit:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys, exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                boatx -= 5
            elif event.key == pygame.K_RIGHT:
                boatx += 5
            elif event.key == pygame.K_UP:
                boaty -= 5
            elif event.key == pygame.K_DOWN:
                boaty += 5

            if boatx == 120:
                boatx = 125
            elif boatx == 460:
                boatx = 455
            elif boaty == 300:
                boaty = 305
            elif boaty == 410:
                boaty = 405

        DisplaySurface.blit(backgroundIMG, (0, 0))
        boat(boatx, boaty)
        bullet(bulletX, bulletY)
        hit = pygame.sprite.spritecollide(boatIMG, enemy_bullet, False)

        if hit:
            pass #Game over

        if bulletY == 480:
            bulletX = random.randint(200, 500)
            bulletY = -100


        bulletY += bullet_Speed
        pygame.display.update()
        clock.tick(fps)

game_loop()
pygame.quit()
quit()
Error:
AttributeError: 'pygame.Surface' object has no attribute 'rect'
I'm trying to end the game once the boat collides with the bullet. I've tried many tutorials on how to do this, but I just can't seem to figure it out. Any tips or tricks are appreciated :).
Tip. Convert images to pygame format. It will help with speed and pygame doesn't have to do it on the fly.
boatIMG = pygame.image.load("boatIMG.png").convert()
if alpha
boatIMG = pygame.image.load("boatIMG.png").convert_alpha()
Since you didn't put images in sprite class. Use pygame.Rect.
hit = boatIMG.get_rect().colliderect(enemy_bullet.get_rect())
(Mar-10-2019, 08:08 PM)Windspar Wrote: [ -> ]Tip. Convert images to pygame format. It will help with speed and pygame doesn't have to do it on the fly.
boatIMG = pygame.image.load("boatIMG.png").convert()
if alpha
boatIMG = pygame.image.load("boatIMG.png").convert_alpha()
Since you didn't put images in sprite class. Use pygame.Rect.
hit = boatIMG.get_rect().colliderect(enemy_bullet.get_rect())

You are the best. Thank You!
(Mar-10-2019, 08:08 PM)Windspar Wrote: [ -> ]Tip. Convert images to pygame format. It will help with speed and pygame doesn't have to do it on the fly.
boatIMG = pygame.image.load("boatIMG.png").convert()
if alpha
boatIMG = pygame.image.load("boatIMG.png").convert_alpha()
Since you didn't put images in sprite class. Use pygame.Rect.
hit = boatIMG.get_rect().colliderect(enemy_bullet.get_rect())

Could you show me how to do this using a class? I'm still a noob to python lol.
Just writing it up without running it...

class Boat:
    def __init__(self):
        self.image = pygame.image.load("boatIMG.png")
        self.rect = self.image.get_rect()
    def draw(self, surf):
        self.blit(self.image, self.rect)
    def event_loop(self):
        #move ship based on keypresses

class Bullet:
    def __init__(self):
        self.image = pygame.image.load("bullet_enemy.png")
        self.rect = self.image.get_rect(topleft=(random.randint(200, 500), -100))
    def update(self):
        self.rect.y += bullet_Speed
    def draw(self, surf):
        surf.blit(self.image, self.rect)
then you would check for collision

boat = Boat()
bullets = [Bullet() for i in range(10)]
 
for bullet in bullets:
    if bullet.colliderect(boat.rect):
        #ship is hit
Here a quick example.
import pygame
import random

class BoatSprite(pygame.sprite.Sprite):
    def __init__(self, group):
        # Init parent class
        pygame.sprite.Sprite.__init__(self, group)

        self.tick = 0
        self.interval = 30

        # Default sprite variables.
        #self.image = pygame.image.load("boatIMG.png").convert()
        self.image = pygame.Surface((40, 20))
        self.image.fill(pygame.Color("dodgerblue"))
        self.rect = self.image.get_rect()

class BulletSprite(pygame.sprite.Sprite):
    def __init__(self, group):
        # Init parent class
        pygame.sprite.Sprite.__init__(self, group)

        self.speed = 5
        self.tick = 0
        self.interval = 40

        # Default sprite variables.
        #self.image = pygame.image.load("bullet)enemy.png").convert()
        self.image = pygame.Surface((2, 4))
        self.image.fill(pygame.Color("firebrick"))
        self.rect = self.image.get_rect()

        self.rect.x = random.randint(200, 500)
        self.rect.y = -100

    def update(self):
        if self.rect.y > 480:
            self.rect.x = random.randint(200, 500)
            self.rect.y = -100

class Scene:
    def __init__(self, game):
        self.game = game
        self.boat_group = pygame.sprite.Group()
        self.bullet_group = pygame.sprite.Group()

        self.boat = BoatSprite(self.boat_group)
        self.boat.rect.topleft = 400, 400

        self.bullet = BulletSprite(self.bullet_group)

        #self.background_iamge = pygame.image.load("water_background.png").convert()
        self.background_image = pygame.Surface(game.rect.size)
        self.background_image.fill(pygame.Color('darkblue'))

    def draw(self, surface):
        surface.blit(self.background_image, (0,0))
        self.boat_group.update()
        self.bullet_group.update()
        self.boat_group.draw(surface)
        self.bullet_group.draw(surface)

    def event(self, event):
        pass

    def update(self, ticks):
        if ticks > self.boat.tick:
            self.boat.tick += self.boat.interval

            # Tracking key held down
            keys = pygame.key.get_pressed()
            if keys[pygame.K_LEFT]:
                self.boat.rect.x -= 5
            elif keys[pygame.K_RIGHT]:
                self.boat.rect.x += 5
            elif keys[pygame.K_UP]:
                self.boat.rect.y -= 5
            elif keys[pygame.K_DOWN]:
                self.boat.rect.y += 5

            # Keep boat within
            self.boat.rect.clamp_ip(pygame.Rect(125, 305, 340, 100))

        if ticks > self.bullet.tick:
            self.bullet.tick + self.bullet.interval
            self.bullet.rect.y += self.bullet.speed

        # Colliding
        hit = pygame.sprite.spritecollide(self.boat, self.bullet_group, False)
        if len(hit) > 0:
            self.game.running = False

class Game:
    def __init__(self, caption, width, height):
        # Basic pygame setup
        pygame.display.set_caption(caption)
        self.rect = pygame.Rect(0, 0, width, height)
        self.surface = pygame.display.set_mode(self.rect.size)
        self.clock = pygame.time.Clock()

        # Scene
        self.scene = Scene(self)

    def mainloop(self):
        self.running = True

        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                else:
                    self.scene.event(event)

            self.scene.update(pygame.time.get_ticks())

            # Draw code here
            self.scene.draw(self.surface)

            pygame.display.flip()
            self.clock.tick(30)

if __name__ == '__main__':
    pygame.init()
    game = Game('Example', 640, 480)
    game.mainloop()
    pygame.quit()