0

im trying to make a camera for my character and i keep getting this when i run the code

import collections
import pygame
from camera import *
from settings import tile_size
from support import import_csv_layout, import_cut_graphics
from tiles import Tile , StaticTile
from player import Player

class Level:
    def __init__(self,level_data,surface):
        self.display_surface = surface
        self.world_shift = 0
        

        player_layout = import_csv_layout(level_data['character'])
        self.player = pygame.sprite.GroupSingle()
        self.goal = pygame.sprite.GroupSingle()
        self.player_setup(player_layout)

        terrain_layout = import_csv_layout(level_data['bricks'])
        self.terrain_sprites = self.create_tile_group(terrain_layout,'bricks')


        spikes_layout = import_csv_layout(level_data['spikes'])
        self.spikes_sprites = self.create_tile_group(spikes_layout,'spikes')

        crate_layout = import_csv_layout(level_data['crate'])
        self.crate_sprites = self.create_tile_group(crate_layout,'crate')

        pillars_layout = import_csv_layout(level_data['pillars'])
        self.pillars_sprites = self.create_tile_group(pillars_layout,'pillars')
        
        coins_layout = import_csv_layout(level_data['coins'])
        self.coins_sprites = self.create_tile_group(coins_layout,'coins')

        lava_layout = import_csv_layout(level_data['lava'])
        self.lava_sprites = self.create_tile_group(lava_layout,'lava')



    def player_setup(self,layout):
        for row_index, row in enumerate(layout):
            for col_index, col in enumerate(row):
                x = col_index * tile_size
                y = row_index * tile_size
                if col == '0':
                    sprite = Player((x,y),self.display_surface)
                    self.player.add(sprite)
                if col == '1':
                    hat_surface = pygame.image.load(r'C:\Users\windows\Desktop\actual game\graphics\hat.png')
                    sprite = StaticTile(tile_size,x,y,hat_surface)
                    self.goal.add(sprite)

    def create_tile_group(self,layout,type):
        sprite_group = pygame.sprite.Group()
        
        for row_index,row in enumerate(layout):
            for cell_index,val in enumerate(row):
                if val != '-1':
                    x = cell_index*tile_size
                    y = row_index*tile_size

                    if type == 'bricks':
                        terrain_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')
                        tile_surface = terrain_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)
                    if type == 'spikes':
                        spikes_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')
                        tile_surface = spikes_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)

                    if type == 'crate':
                        crate_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')    
                        tile_surface = crate_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)
                    
                    if type == 'pillars':
                        pillars_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')    
                        tile_surface = pillars_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)

                    if type == 'coins':
                        coins_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')    
                        tile_surface = coins_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)
                        
                    if type == 'lava':
                        lava_tile_list = import_cut_graphics(r'C:\Users\windows\Desktop\actual game\graphics\terrain\tileset.png')    
                        tile_surface = lava_tile_list[int(val)]
                        sprite = StaticTile(tile_size,x,y,tile_surface)
                        

                    sprite_group.add(sprite)
        return sprite_group





    def veritcal_movement_collision(self):
        player = self.player.sprite
        player.apply_gravity()
        collidable_sprites =self.terrain_sprites.sprites() + self.spikes_sprites.sprites() + self.crate_sprites.sprites()

        for sprite in collidable_sprites:
            if sprite.rect.colliderect(player.rect):
                if player.direction.y <0 :
                    player.rect.top = sprite.rect.bottom
                    player.direction.y = 0
                    player.on_ceiling = True
                elif player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                    player.direction.y = 0
                    player.on_ground = True


            if player.on_ground and player.direction.y < 0 or player.direction.y > 1:
                player.on_ground = False
            if player.on_ceiling and player.direction.y > 0:
                player.on_ceiling = False
                    
    def horizontal_movement_collision(self):
        player = self.player.sprite
        player.rect.x += player.direction.x* player.speed
        collidable_sprites =self.terrain_sprites.sprites() + self.spikes_sprites.sprites() + self.crate_sprites.sprites()

        for sprite in collidable_sprites:
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                    self.on_left = True
                    self.current_x = player.rect.left
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left
                    self.on_right = True
                    self.current_x = player.rect.right
        
        if player.on_left and (player.rect.left < self.current_x or player.direction.x >= 0):
             player.on_left = False
        elif player.on_right and (player.rect.right > self.current_x or player.direction.x <= 0):
            player.on_right = False


    def run(self):
        self.terrain_sprites.draw(self.display_surface)
        self.terrain_sprites.update(self.world_shift)

        self.spikes_sprites.update(self.world_shift)
        self.spikes_sprites.draw(self.display_surface)
        
        self.crate_sprites.update(self.world_shift)
        self.crate_sprites.draw(self.display_surface)

        self.pillars_sprites.update(self.world_shift)
        self.pillars_sprites.draw(self.display_surface)


        self.coins_sprites.update(self.world_shift)
        self.coins_sprites.draw(self.display_surface)

        self.lava_sprites.update(self.world_shift)
        self.lava_sprites.draw(self.display_surface)
        
        self.goal.update(self.world_shift)
        self.goal.draw(self.display_surface)


        self.player.update()
        self.horizontal_movement_collision()
        self.veritcal_movement_collision()
        self.player.draw(self.display_surface)


        self.camera = Camera(self.player)
        self.follow = Follow(self.camera,self.player)
        self.border = Border(self.camera,self.player)
        self.auto = AutoScroll(self.camera,self.player)
        self.camera.setmethod(self.follow)
Thomas
  • 174,939
  • 50
  • 355
  • 478
2k adc
  • 9
  • 2
  • File "c:\Users\windows\Desktop\actual game\code\camera.py", line 14, in __init__ self.CONST = vec(-self.DISPLAY_W / 2 + player.rect.w / 2, -self.player.on_ground +20) AttributeError: 'GroupSingle' object has no attribute 'rect' – 2k adc May 07 '22 at 10:15
  • `self.camera = Camera(self.player.sprite)` instead of `self.camera = Camera(self.player)` – Rabbid76 May 07 '22 at 10:20

1 Answers1

0

The Camera expects a Sprite and not a GroupSingle:

self.camera = Camera(self.player)

self.camera = Camera(self.player.sprite)

I recommend using pygame.sprite.collide_rect:

if pygame.sprite.collide_rect(sprite, self.player.sprite):

or pygame.sprite.spritecollide, where the 2nd argument is a Group:

if pygame.sprite.spritecollide(sprite, self.player, False)

See also How do I detect collision in pygame?.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174