Probleme de transition
Justin -
Bonjour. Je fais pour moi-même un jeu (simple) et j'ai un problème. En fait, je souhaiterais creer une une ligne sur laquelle le joueur sera pendant 2 secondes, avant de jouer lui même (c'est une sorte de base). J'ai ma ligne, là ça va, et un de mes amis m'a dit qu'on ne pouvait pas supprimer de l'écran un dessin "rect" (je sais plus exactement ce qu'il a dit). Donc c'est pas grave, mon nouveau but est que des que les 2 secondes sont passées, j'aiemerai que la ligne soit soit très basse, soit très haute, juste qu'elle ne gene pas le joueur, qui peut jouer tranquillement.
Le probleme c'est que la ligne (special floor) reste quand même, mais je ne sait pas pourquoi.
voici mon code :
import pygame
import time
import random
# Initialisation de Pygame
pygame.init()
# Constantes
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BACKGROUND_COLOR = (255, 105, 180)
PLAYER_COLOR = (255, 255, 255)
OBSTACLE_COLOR = (255, 255, 255)
SPECIAL_FLOOR_COLOR = (50, 205, 50)
PLAYER_SIZE = 25
PLAYER_START_X = 100
PLAYER_START_Y = 200
GRAVITY = 0.4
JUMP_VELOCITY = -10
OBSTACLE_WIDTH = 50
OBSTACLE_HEIGHT = 250
OBSTACLE_GAP = 175
OBSTACLE_VELOCITY = -3
OBSTACLE_GENERATION_DELAY = 1.5
FPS = 100
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
game_over = False
player_y = PLAYER_START_Y
player_velocity = 0
obstacles = []
obstacle_last_generation_time = 0
score = 0
font = pygame.font.Font(None, 36)
start_time = time.time()
# Fonctions
def reset_game():
global game_over, player_y, player_velocity, obstacles, obstacle_last_generation_time, score
game_over = False
player_y = PLAYER_START_Y
player_velocity = 0
obstacles = []
obstacle_last_generation_time = 0
score = 0
def creer_obstacles():
gap_center_y = random.randint(150, SCREEN_HEIGHT - 150 - OBSTACLE_GAP)
obstacle_top_y = gap_center_y - OBSTACLE_GAP / 2 - OBSTACLE_HEIGHT
obstacle_bottom_y = gap_center_y + OBSTACLE_GAP / 2
obstacle_top_rect = pygame.Rect(SCREEN_WIDTH, obstacle_top_y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT)
obstacle_bottom_rect = pygame.Rect(SCREEN_WIDTH, obstacle_bottom_y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT)
obstacles.append((obstacle_top_rect, obstacle_bottom_rect))
def update_obstacles():
for i, obstacle_pair in enumerate(obstacles):
obstacle_top_rect, obstacle_bottom_rect = obstacle_pair
obstacle_top_rect.move_ip(OBSTACLE_VELOCITY, 0)
obstacle_bottom_rect.move_ip(OBSTACLE_VELOCITY, 0)
if obstacle_top_rect.right < 0:
obstacles.pop(i)
def draw_player():
player_rect = pygame.Rect(PLAYER_START_X, player_y, PLAYER_SIZE, PLAYER_SIZE)
pygame.draw.rect(screen, PLAYER_COLOR, player_rect)
# dessiner le sol spécial
if time.time() - start_time < 2:
special_floor_rect = pygame.Rect(0, SCREEN_HEIGHT - 270, SCREEN_WIDTH, 2)
pygame.draw.rect(screen, SPECIAL_FLOOR_COLOR, special_floor_rect)
else:
special_floor_rect = pygame.Rect(0, SCREEN_HEIGHT - 500, SCREEN_WIDTH, 0)
pygame.draw.rect(screen, SPECIAL_FLOOR_COLOR, special_floor_rect)
def draw_obstacles():
for obstacle_pair in obstacles:
obstacle_top_rect, obstacle_bottom_rect = obstacle_pair
pygame.draw.rect(screen, OBSTACLE_COLOR, obstacle_top_rect)
pygame.draw.rect(screen, OBSTACLE_COLOR, obstacle_bottom_rect)
def check_collision():
global game_over
player_rect = pygame.Rect(PLAYER_START_X, player_y, PLAYER_SIZE, PLAYER_SIZE)
for obstacle_pair in obstacles:
obstacle_top_rect, obstacle_bottom_rect = obstacle_pair
if player_rect.colliderect(obstacle_top_rect) or player_rect.colliderect(
obstacle_bottom_rect):
game_over = True
def handle_events():
global player_velocity
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE or pygame.K_UP:
if game_over:
reset_game()
else:
player_velocity = JUMP_VELOCITY
def update_player():
global player_y, player_velocity, game_over
player_y += player_velocity
player_velocity += GRAVITY
if player_y < 0 or player_y + PLAYER_SIZE > SCREEN_HEIGHT - 100:
game_over = True #jeu s'arrete si le joueur est en dehors de l'écran
if player_y + PLAYER_SIZE >= SCREEN_HEIGHT - 270 and player_y < SCREEN_HEIGHT - 270 + PLAYER_SIZE:
player_y = SCREEN_HEIGHT - 270 - PLAYER_SIZE
player_velocity = 0
for obstacle_pair in obstacles:
obstacle_top_rect, obstacle_bottom_rect = obstacle_pair
if obstacle_top_rect.right < PLAYER_START_X and obstacle_top_rect.right + OBSTACLE_VELOCITY >= PLAYER_START_X:
score += 1
clock=pygame.time.Clock()
# Boucle principale du jeu
while True:
screen.fill(BACKGROUND_COLOR)
FPS = 100
clock.tick(FPS)
# Gérer les événements
handle_events()
# maj joueur & obstacles
if not game_over:
update_player()
current_time = time.time()
if current_time - obstacle_last_generation_time > OBSTACLE_GENERATION_DELAY:
creer_obstacles()
obstacle_last_generation_time = current_time
update_obstacles()
check_collision()
# Dessiner les éléments du jeu
draw_player()
draw_obstacles()
# Calculer le temps écoulé depuis le début du jeu
temps_ecoule = time.time() - start_time
# Augmenter le score toutes les 5 secondes de 5
if temps_ecoule >= 5:
score += 5
start_time = time.time()
# Afficher le score en haut à droite
score_text = font.render(format(score), True, (255, 255, 255))
score_rect = score_text.get_rect()
score_rect.topright = (SCREEN_WIDTH - 10, 10)
screen.blit(score_text, score_rect)
pygame.time.Clock().tick(100)
pygame.display.update()
# Vérifier les collisions
if not game_over:
check_collision()
if game_over:
menu_en_cours = True
draw_group.clear(screen, sprites_clear)
draw_group.update()
rects = draw_group.draw(screen)
pygame.display.update(rects)
Merci :)
- Probleme de transition
- Transition imovie télécharger - Télécharger - TV & Vidéo
- Transition capcut - Télécharger - Montage & Édition
- Logiciel transition musique automatique ✓ - Forum Enregistrement / Traitement audio
- Télécharger transition morphose powerpoint gratuit - Forum Powerpoint
- Recherche logiciel audio fondu enchainé - Forum Audio
4 réponses
Bonsoir.
Ton ami se trompe ;) Ce qui est affiché à l'écran, c'est toi qui le décide.
Quant à ton problème, ce n'est pas clair. Tout ce que l'on peut constater est que tu initialises au début de ton code une variable start_time (qui devrait être une constante), puis que tu en changes la valeur dans la boucle de ton jeu.
# Augmenter le score toutes les 5 secondes de 5
if temps_ecoule >= 5:
score += 5
start_time = time.time()
Donc, normal que cette ligne passe de bas en haut et inversement. dans la fonction draw_player.
Mais à quoi sert cette ligne ? Pourquoi ne pas simplement remplir d'une couleur ce qui est en dessous du joueur afin de simuler le sol ?
merci de me répondre :))
(xd je lui dirai)
Oui c'est vrai que mon problème n'est pas ce qu'il y a de plus clair. Jvais essayer de le reformuler :
- ma ligne est là au milieu parce que en fait ce 'mini jeu' est la suite d'un autre 'mini jeu'
- en fait l'idée c'est qu'elle serve de transition et que le joueur ne soit pas perdu quand il arrive sur ce jeu (qu'il ait quelques secondes - parce que s'il ne le connait pas, il ne s'y attend pas forcément et dès que ca bascule sur ce jeu, il perd instantanément parce qu'il n'a pas sauté)
- l'idéal serait que ma ligne disparaisse complètement après les 2 secondes (pas simplement qu'elle se camoufle au background)
- la je l'avait faite changer de position parce que je pensait que si tu la baissais ou la montait, elle ne serait plus la, mais en fait si elle est toujours la dasn la version actuelle. Ce que je veux dire c'est que y en a une autre, mais y a toujours l'originale qui est camouflée au bg, donc ca ne va pas
J'avais effectivement penser a faire un sol, mais nan en fait l'idéal serait vraiment d'avoir une sorte de ligne
Tu saurais comment on pourrait modifier ça ?
Salut.
Comme je t'ai signalé, tu utilises une même variable pour faire 2 choses sans rapport (affichage d'un élément, mise à jour d'un score), c'est ça qui ne va pas.
D'abord supprimer cette variable start_game et la remplacer par 2 disctinctes, comme :
score_time = time.time() game_start_time = time.time()
Puis :
def draw_player():
player_rect = pygame.Rect(PLAYER_START_X, player_y, PLAYER_SIZE, PLAYER_SIZE)
pygame.draw.rect(screen, PLAYER_COLOR, player_rect)
# dessiner le sol spécial
# print(time.time() - start_time)
if time.time() - game_start_time < 2:
special_floor_rect = pygame.Rect(0, SCREEN_HEIGHT - 270, SCREEN_WIDTH, 2)
pygame.draw.rect(screen, SPECIAL_FLOOR_COLOR, special_floor_rect)
Plus besoin du else.
Ensuite, si nécessaire la réinitialiser lors du redémarrage :
def reset_game():
global ..., game_start_time
# ...
game_start_time = time.time()
Ne reste plus que ce qu'il y a dans la boucle :
# Calculer le temps écoulé depuis le début du jeu
temps_ecoule = time.time() - score_time
# Augmenter le score toutes les 5 secondes de 5
if temps_ecoule >= 5:
score += 5
score_time = time.time()
Et voilà, en utilisant 2 variables, plus de problème d'interférence.
Je m'ennuie, alors j'ai refais à peu de choses près ce que fait ton code en reprenant quelques petites parties de ton code.
En utilisant des sprites, groupes de sprites et surtout des timers qui servent à créer des événements utilisateurs, ça permet de simplifier certaines choses, notamment comme pour ne plus afficher le sol.
import pygame as pg
import math
import random
FPS = 60
GRAVITY = 0.3
GAME_RESTART_EVENT = pg.USEREVENT
GAME_RESTART_DELAY = 1500
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_COLOR = pg.Color(255, 90, 180, 255)
PLAYER_SIZE = 32
PLAYER_BG_COLOR = pg.Color('yellow')
PLAYER_FG_COLOR = pg.Color('red')
PLAYER_EDGE_COLOR = pg.Color('yellowgreen')
PLAYER_VELOCITY = 8
GROUND_HEIGHT = 250
GROUND_COLOR = pg.Color(34, 139, 34, 0)
GROUND_HIDE_DELAY = 3000
GROUND_HIDE_EVENT = pg.USEREVENT + 1
OBSTACLE_COLORS = pg.Color(70, 130, 180, 0), pg.Color(72, 61, 139, 0)
OBSTACLE_WIDTH = 50
OBSTACLE_DELTAS = 150, 200
OBSTACLE_SPAWN_DELAYS = 1000, 1800
OBSTACLE_VELOCITY = 5
OBSTACLE_EVENT = pg.USEREVENT + 2
SCORE_COLOR = pg.Color(178, 34, 34, 0)
class Obstacle(pg.sprite.Sprite):
def __init__(self, y, y2):
super().__init__()
self.image = pg.Surface((OBSTACLE_WIDTH, y2 - y)).convert()
self.rect = self.image.get_rect()
self.rect.topleft = SCREEN_WIDTH, y
self.image.fill(OBSTACLE_COLORS[0])
pg.draw.line(
self.image, OBSTACLE_COLORS[1], (0, 0), (0, self.rect.h), 3
)
pg.draw.line(
self.image,
OBSTACLE_COLORS[1],
(self.rect.w - 2, 0),
(self.rect.w - 2, self.rect.h),
3,
)
def update(self):
self.rect.x -= OBSTACLE_VELOCITY
class ObstacleTop(Obstacle):
def __init__(self, y, y2):
super().__init__(y, y2)
pg.draw.rect(
self.image,
OBSTACLE_COLORS[1],
(0, self.rect.bottom - 20, self.rect.w, 20),
)
class ObstacleBottom(Obstacle):
def __init__(self, y, y2):
super().__init__(y, y2)
pg.draw.rect(self.image, OBSTACLE_COLORS[1], (0, 0, self.rect.w, 20))
class Ground(pg.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pg.Surface((SCREEN_WIDTH, GROUND_HEIGHT)).convert()
self.image.fill(SCREEN_COLOR)
self.rect = self.image.get_rect()
self.rect.top = SCREEN_HEIGHT - GROUND_HEIGHT
pg.draw.rect(self.image, GROUND_COLOR, (0, 0, self.rect.w, 2))
class Player(pg.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pg.Surface((PLAYER_SIZE,) * 2, pg.SRCALPHA).convert_alpha()
self.rect = self.image.get_rect()
wm = int(self.rect.w / 2)
wt = int(self.rect.w / 3)
pg.draw.circle(self.image, PLAYER_BG_COLOR, (wm, wm), wm, wm - 1)
pg.draw.circle(self.image, PLAYER_EDGE_COLOR, (wm, wm), wm, 2)
pg.draw.circle(self.image, PLAYER_FG_COLOR, (wt, wt), 2)
pg.draw.circle(
self.image, PLAYER_FG_COLOR, (int(self.rect.w / 3 * 2), wt), 2
)
pg.draw.arc(
self.image,
PLAYER_FG_COLOR,
self.rect.inflate(-wm, -wt),
math.radians(220),
math.radians(-40),
2,
)
self.rect.bottomleft = x, y
self.ground_top = y
self._move = False
self.jumping = False
def update(self):
if self.jumping:
self.rect.y -= self.velocity
self.velocity -= GRAVITY
if self.rect.bottom > self.ground_top:
self.jumping = False
self.rect.bottom = self.ground_top
elif self.rect.top < 0:
self.rect.top = 0
def jump(self):
if self._move:
self.jumping = True
self.velocity = PLAYER_VELOCITY
move = property(
lambda self: self._move, lambda self, b: setattr(self, '_move', b)
)
class Score(pg.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.x = x
self.y = y
self.score = 0
self.font = pg.font.SysFont('serif', 42, True)
self.set_image()
def set_image(self):
self.image = self.font.render(
str(self.score),
True,
SCORE_COLOR
).convert_alpha()
self.rect = self.image.get_rect()
self.rect.topright = self.x, self.y
def increase(self):
self.score += 1
self.set_image()
def reset(self):
self.score = 0
self.set_image()
class Obstacles:
def __init__(self, *groups, kill_callback):
self.groups = groups
self.kill_callback = kill_callback
def spawn(self):
y, y2 = self.get_random_pos()
obstacles = (ObstacleTop(0, y), ObstacleBottom(y2, SCREEN_HEIGHT))
for sprite in obstacles:
sprite.add(self.groups)
def get_random_pos(self):
y_center = random.randint(GROUND_HEIGHT - 125, GROUND_HEIGHT - 50)
y_delta = random.randint(*OBSTACLE_DELTAS) / 2
return y_center - y_delta, y_center + y_delta
def set_timer(self, ms=-1):
if ms == -1:
ms = random.randrange(*OBSTACLE_SPAWN_DELAYS)
pg.time.set_timer(OBSTACLE_EVENT, ms)
def update(self):
killed = False
for sprite in self.groups[1].copy().sprites():
if isinstance(sprite, Obstacle) and sprite.rect.right < 0:
sprite.kill()
killed = True
if killed:
self.kill_callback()
class Game:
def __init__(self):
pg.init()
self.screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
self.screen.convert()
self.screen.fill(SCREEN_COLOR)
pg.display.update()
self.display_group = pg.sprite.LayeredUpdates()
self.obstacles_group = pg.sprite.Group()
self.ground = Ground()
self.player = Player(50, self.ground.rect.top)
self.player.move = True
self.score = Score(SCREEN_WIDTH - 10, 10)
self.display_group.add(self.ground, self.player, self.score)
self.obstacles = Obstacles(
self.display_group,
self.obstacles_group,
kill_callback=self.score.increase,
)
self.obstacles.set_timer()
pg.time.set_timer(GROUND_HIDE_EVENT, GROUND_HIDE_DELAY)
def stop(self):
self.player.move = False
self.obstacles.set_timer(0)
pg.sprite.groupcollide(
self.display_group, self.obstacles_group, False, True
)
pg.time.set_timer(GAME_RESTART_EVENT, GAME_RESTART_DELAY)
def restart(self):
pg.time.set_timer(GAME_RESTART_EVENT, 0)
pg.time.set_timer(GROUND_HIDE_EVENT, GROUND_HIDE_DELAY)
self.display_group.add(self.ground)
self.score.reset()
self.obstacles.set_timer()
self.player.move = True
def _clear(self, surf, rect):
surf.fill(SCREEN_COLOR, rect)
def run(self):
clock = pg.time.Clock()
running = True
while running:
for evt in pg.event.get():
if evt.type == pg.QUIT:
running = False
elif evt.type == OBSTACLE_EVENT:
self.obstacles.spawn()
self.obstacles.set_timer()
elif evt.type == pg.KEYDOWN:
if evt.key == pg.K_SPACE or pg.K_UP:
self.player.jump()
elif evt.type == GAME_RESTART_EVENT:
self.restart()
elif evt.type == GROUND_HIDE_EVENT:
self.display_group.remove(self.ground)
pg.time.set_timer(GROUND_HIDE_EVENT, 0)
self.obstacles.update()
self.display_group.update()
if pg.sprite.spritecollide(
self.player, self.obstacles_group, False
):
self.stop()
self.display_group.clear(self.screen, self._clear)
rects = self.display_group.draw(self.screen)
pg.display.update(rects)
clock.tick(FPS)
pg.quit()
game = Game()
game.run()
Bon, c'est de l'objet, et je ne suis pas certain que tu sois bien à l'aise avec, mais ça peut te donner des idées afin d'améliorer ton code.
Le système de points est différent, le score est augmenté à chaque obstacles franchis.