Probleme de sol avec python

ZHNN - 7 mai 2023 à 14:23
Gandalfix Messages postés 84 Date d'inscription vendredi 12 juin 2020 Statut Non membre Dernière intervention 18 avril 2024 - 8 mai 2023 à 07:01

Bonjour,

je souhaiterai changer la position du sol quand le score est sup ou égal à 10. Donc la la position passe à 350, mais le probleme c'est que quand le joueur descend de certinas types d'obstacles, il descend plus bas que 350 (en fait il revient au sol initial pour ensuite remonter en mode incognito a 350). Qqn aurait une solution pour qu'il reste à 350 et pas en dessous ?
Merci

import pygame
import random
import time

pygame.font.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_COLOR = 0, 0, 0

SOL_Y = 550

PLAYER_COLOR = 255, 255, 255
PLAYER_HEIGHT = 30
PLAYER_WIDTH = 30
EVENT_OBSTACLE_SPAWN = pygame.USEREVENT + 1
police = pygame.font.Font(None, 50)
FPS = 95
BAR_WIDTH = 800
BAR_HEIGHT = 30
EVENT_PROGRESS_BAR = pygame.USEREVENT + 2


class Sol(pygame.sprite.Sprite):
    def __init__(self, y):
        super().__init__()
        self.image = pygame.Surface((SCREEN_RECT.w, 350))
        self.image.fill((0, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.topleft = 0, y

    class Sol(pygame.sprite.Sprite):
        def __init__(self, y):
            super().__init__()
            self.image = pygame.Surface((SCREEN_RECT.w, 350))
            self.image.fill((0, 0, 0))
            self.rect = self.image.get_rect()
            self.rect.topleft = 0, y


class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill(PLAYER_COLOR)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y
        self.x = x
        self.y = y
        self.jumping = False
        self.jump_count = 20

    def move(self, amount):
        self.rect.x += amount

    def jump(self):
        self.jumping = True

    def collision(self, sprites):  # gère les collisions
        for sprite in sprites:

            if isinstance(sprite, Triangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right

            elif isinstance(sprite, Rectangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right

            elif isinstance(sprite, DoubleTriangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top
                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

            elif isinstance(sprite, Plateforme):

                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right

        # Retourne les sprites en collision avec le joueur
        return tuple(s for s in sprites if s.rect.colliderect(self.rect))

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] or keys[pygame.K_UP]:
            self.jump()

        if self.jumping:
            step = -(0.05 * self.jump_count ** 2) * (70 / FPS)
            if self.jump_count > 0:
                step *= -1
            self.rect.y -= step
            self.jump_count -= 1
            if self.rect.bottom >= self.y:
                self.rect.bottom = self.y
                self.jumping = False
                self.jump_count = 20
        else:
            if self.rect.bottom < SOL_Y:
                self.rect.bottom += 6
            if score.score >= 10 and self.rect.bottom > 350:
                self.rect.bottom = 350  # Empêche le joueur de descendre en dessous de 350
            elif self.rect.bottom > SOL_Y:
                self.rect.bottom = SOL_Y  # Empêche le joueur de dépasser SOL_Y
                
class ProgressBar(pygame.sprite.Sprite):
    def __init__(self, width, height, color):
        super().__init__()
        self.image = pygame.Surface((width, height), pygame.SRCALPHA).convert_alpha()
        self.rect = self.image.get_rect()
        self.color = color
        self._percent = 0

    def is_full(self):
        return self._percent == 100

    def increase(self, percent):
        if self._percent == 100:
            return
        self._percent += percent
        self._percent = min(100, self._percent)
        width = self.rect.w / 100 * self._percent
        pygame.draw.rect(self.image, self.color, (0, 0, width, self.rect.h))


# score
class ScoreBoard(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.score = 0
        self.font = pygame.font.SysFont('Arial', 30)  # police
        self.color = (255, 255, 255)
        self.image = self.font.render('0', True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = x, y
        self.last_update_time = time.time()  # enregistre l'heure de la dernière mise à jour du score

    def update1(self):
        # Vérifie si 5 secondes se sont écoulées depuis la dernière mise à jour du score
        current_time = time.time()
        if current_time - self.last_update_time >= 5:
            self.add(5)  # Ajoute 5 points au score, qui augmente toutes les 5 secondes
            self.last_update_time = current_time

    def add(self, amount):  # ajoute
        self.score += amount
        self.image = self.font.render(str(self.score), True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = self.x, self.y


class Obstacle(pygame.sprite.Sprite):  # classe pour les obstacles
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height), pygame.SRCALPHA)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y

    def update(self):
        self.rect.x -= 6


class Triangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        pygame.draw.polygon(self.image, (0, 255, 0), ((30, 0), (0, 60), (60, 60)))  # formation du triangle


class Rectangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 70, 135)
        pygame.draw.rect(self.image, (12, 48, 255), (5, 5, 130, 130))


class BasPlateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 252, 60)
        pygame.draw.rect(self.image, (88, 35, 255), (10, 10, 670, 50))


class DoubleTriangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        self.image = pygame.Surface((240, 60), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, (255, 255, 0), ((30, 0), (0, 60), (60, 60)))
        pygame.draw.polygon(self.image, (255, 255, 0), ((90, 0), (60, 60), (120, 60)))
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y


class Plateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 187, 187)
        pygame.draw.rect(self.image, (185, 235, 255), (10, 10, 670, 50))


# le spawn ; c'est une sorte de création en direct d'objets ou de personnages (ici ça va être les obstacles)
def obstacle_spawn():
    # Choix de l'obstacle (tu choisis si tu veux plus de triangles ou de cercles)
    obstacle_class = \
        random.choices((Triangle, Rectangle, DoubleTriangle, Plateforme, BasPlateforme), (11, 14, 15, 14, 12))[0]
    obstacle = obstacle_class(SCREEN_RECT.w, SOL_Y)
    draw_group.add(obstacle)
    obstacles_group.add(obstacle)


def spawn_timer():
    ms = random.randrange(490, 750)  # temps en millisecondes, determine le temps d'espace entre les obstacles
    pygame.time.set_timer(EVENT_OBSTACLE_SPAWN, ms)


def sprites_clear(surface, rect):
    surface.fill(SCREEN_COLOR, rect)


# application
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
SCREEN_RECT = screen.get_rect()
pygame.mouse.set_visible(False)
pygame.display.set_caption("Geo")

draw_group = pygame.sprite.RenderUpdates()
obstacles_group = pygame.sprite.Group()

player = Player(100, SOL_Y)
draw_group.add(player)

sol = Sol(SOL_Y)
draw_group.add(sol)

score = ScoreBoard(SCREEN_RECT.right - 10, 10)  # position ou y aura le score sur l'écran
score.update()
draw_group.add(score)

progress_bar = ProgressBar(BAR_WIDTH, BAR_HEIGHT, (0, 255, 0))
progress_bar.rect.topleft = 0, 0
draw_group.add(progress_bar)

screen.fill(SCREEN_COLOR)
pygame.display.update()

clock = pygame.time.Clock()
running = True
points = 0
spawn_timer()

pygame.time.set_timer(EVENT_PROGRESS_BAR, 100)
all_sprites = pygame.sprite.Group()

# boucle principale
while running:
    clock.tick(FPS)
    score.update1()
    screen.blit(score.image, score.rect)

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP or pygame.K_SPACE and not player.jumping:  # touches pour sauter
                player.jump()
        elif event.type == EVENT_OBSTACLE_SPAWN:  # generations obstacles
            obstacle_spawn()
            spawn_timer()
            draw_group.remove(player)
            draw_group.add(player)
        elif event.type == EVENT_PROGRESS_BAR:
            progress_bar.increase(0.5)

        elif event.type == pygame.QUIT:
            running = False

    # Vérification de la collision entre le joueur et la plateforme
    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, Plateforme) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, BasPlateforme) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, Rectangle) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    # Collision obstacles avec le joueur
    for sprite in player.collision(obstacles_group.sprites()):
        obstacles_group.remove(sprite)
        draw_group.remove(sprite)

    # Suppression des sprites hors écran
    for sprite in obstacles_group.copy().sprites():
        if sprite.rect.right < SCREEN_RECT.x:
            obstacles_group.remove(sprite)
            draw_group.remove(sprite)

    if score.score >= 10:
        SOL_Y = 350

    draw_group.clear(screen, sprites_clear)
    draw_group.update()
    rects = draw_group.draw(screen)
    pygame.display.update(rects)

    pygame.display.flip()

pygame.quit()

1 réponse

Gandalfix Messages postés 84 Date d'inscription vendredi 12 juin 2020 Statut Non membre Dernière intervention 18 avril 2024 7
8 mai 2023 à 07:01

Bonjour,

Je n'y connais pas grand chose en pygame.

Mais pourquoi avoir mis une classe Sol (ligne 31 à 37) dans une classe Sol qui débute ligne 23 ?


0
Rejoignez-nous