» »

pygame problem 2

pygame problem 2

dejco_h ::

dober dan spet jaz.
Skratka delam enako igrico kot pred parimi tedni in sem naletel na problem...in sicer problem je ta da ko collidam playera in fllor in hočem pritisnit tipko space(za skok mi player kar izgine) in tudi ni picture perfect collison saj player pristane rahlo pod florom in ne čisto na njem...mi lahko kdo pomaga razrešit nastal problem?? hvala vsem za odgovore ter sugestije


import pygame
import random
import math
import os
from os import listdir
from os.path import isfile,join

pygame.init()
pygame.display.set_caption("platformer game")
WIDTH,HEIGTH=1000,800
win=pygame.display.set_mode((WIDTH,HEIGTH))
FPS=60
Player_Vel=3


def flip(sprites):
    return [pygame.transform.flip(sprite,True,False)for sprite in sprites]

def load_sprite_sheet(dir1,dir2,width,heigth,direction=False):
    path=join("Assets",dir1,dir2)
    images=[f for f in listdir(path) if isfile(join(path,f))]
    all_sprites={}
    for image in images:
        sprite_sheet=pygame.image.load(join(path,image)).convert_alpha()
        sprites=[]
        for i in range(sprite_sheet.get_width()//width):
            surface=pygame.Surface((width,heigth),pygame.SRCALPHA,32)
            rect=pygame.Rect(i*width,0,width,heigth)
            surface.blit(sprite_sheet,(0,0),rect)
            sprites.append(pygame.transform.scale2x(surface))
            if direction:
                all_sprites[image.replace(".png","")+"_right"]=sprites
                all_sprites[image.replace(".png", "") + "_left"] = flip(sprites)
            else:
                all_sprites[image.replace(".png","")]=sprites
    return all_sprites


def load_block(size):
    path=join("Assets","Terrain","terrain.png")
    image=pygame.image.load(path).convert_alpha()
    surface=pygame.Surface((size,size),pygame.SRCALPHA,32)
    rect=pygame.Rect(96,0,size,size)
    surface.blit(image,(0,0),rect)
    return pygame.transform.scale2x(surface)

class Object(pygame.sprite.Sprite):
    def __init__(self,x,y,width,heigth,name=None):
        super().__init__()
        self.rect=pygame.Rect(x,y,width,heigth)
        self.image=pygame.Surface((width,heigth),pygame.SRCALPHA)
        self.width=width
        self.heigth=heigth
        self.name=name
    def draw(self,win):
        win.blit(self.image,(self.rect.x,self.rect.y))

class Block(Object):
    def __init__(self,x,y,size):
        super().__init__(x,y,size,size)
        block=load_block(size)
        self.image.blit(block,(0,0))
        self.mask=pygame.mask.from_surface(self.image)


def get_background(name):
    image=pygame.image.load(join("Assets","Background",name))
    _,_,width,height=image.get_rect()
    tiles=[]
    for i in range(WIDTH//width+1):
        for j in range(HEIGTH//height+1):
            pos=(i*width,j*height)
            tiles.append(pos)
    return tiles,image
def draw(win,backGround,backg,player,objects):
    for bckg in backGround:
        win.blit(backg,bckg)
    for obj in objects:
        obj.draw(win)
    player.draw(win)
    pygame.display.update()



class Player(pygame.sprite.Sprite):
    GRAVITY=1
    COLOR = 255, 0, 255
    DELAY=3
    SPRITES=load_sprite_sheet("MainCharacters","MaskDude",32,32,True)
    def __init__(self,x,y,width,heigth):
        super().__init__()
        self.rect=pygame.Rect(x,y,width,heigth)
        self.x_vel=0
        self.y_vel=0
        self.mask=None
        self.direction='left'
        self.animation_count=0
        self.fall_count=0
        self.jump_count=0

    def jump(self):
        self.y_vel=-self.GRAVITY*6
        self.animation_count=0
        self.jump_count+=1
        if self.jump_count==1:
            self.fall_count=0

    def move(self,dx,dy):
        self.rect.x+=dx
        self.rect.y+=dy

    def move_left(self,Vel):
        self.x_vel-=Vel

        if self.direction!='left':
            self.direction='left'
            self.animation_count=0
    def move_right(self,VEL):
        self.x_vel+=VEL

        if self.direction!='right':
            self.direction='right'
            self.animation_count=0

    def update_sprite(self):
        sprite_sheet = "idle"
        if self.y_vel < 0:
            if self.jump_count == 1:
                sprite_sheet = "jump"
            elif self.jump_count == 2:
                sprite_sheet = "double_jump"
        elif self.y_vel > self.GRAVITY * 2:
            sprite_sheet = "fall"
        elif self.x_vel != 0:
            sprite_sheet = "run"
        if self.x_vel != 0:
            sprite_sheet = "run"
        sprite_sheet_name = sprite_sheet + "_" + self.direction
        sprites = self.SPRITES[sprite_sheet_name]
        sprite_index = (self.animation_count // self.DELAY) % len(sprites)
        self.sprite = sprites[sprite_index]
        self.animation_count += 1
        self.update()

    def update(self):
        rect=self.sprite.get_rect(topleft=(self.rect.x,self.rect.y))
        self.mask=pygame.mask.from_surface(self.sprite)


    def loop(self,FPS):
        self.y_vel+=min(1,(self.fall_count/FPS)*self.GRAVITY)
        self.move(self.x_vel,self.y_vel)
        self.fall_count+=1
        self.update_sprite()
    def landed(self):
        self.fall_count=0
        self.y_vel=0
        self.jump_count=0

    def hit_head(self):
        self.fall_count=0
        self.y_vel*=-1



    def draw(self,win):
        win.blit(self.sprite,(self.rect.x,self.rect.y))


def handle_move(player,object):
    player.x_vel=0
    keys=pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.move_left(Player_Vel)
    if keys[pygame.K_RIGHT]:
        player.move_right(Player_Vel)
    handle_vertical_collison(player,object,player.y_vel)


def handle_vertical_collison(player,object,dy):
    collided_objects=[]
    for obj in object:
        if pygame.sprite.collide_mask(player,obj):
            if dy>0:
                player.rect.bottom=obj.rect.top
                player.landed()
            elif dy<0:
                player.rect.top=obj.rect.bottom
                player.hit_head()
            collided_objects.append(obj)

    return collided_objects


def main():
    run = True

    clock = pygame.time.Clock()
    background,backg=get_background("Purple.png")
    player=Player(100,100,50,50)
    block_size=96
    floor = [Block(i * block_size, HEIGTH - block_size, block_size) for i in
             range(-WIDTH // block_size, (WIDTH * 2) // block_size)]

    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                run=False
                break
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE and player.jump_count<2:
                    player.jump()


        player.loop(FPS)
        handle_move(player,floor)
        draw(win,background,backg,player,floor)

if __name__ == '__main__':
    main()