I'm trying to devellop a game with powerups, but the smoke powerup doesn't work as intended. If you move after shooting the smoke powerup, you will be teleported onto the powerup, and the smoke cloud will follow you. wich is absolutely not what wass intended. You will be teleported on it only if you move within a certain time frame (about 1 to 2 seconds. it tends to be random), and I don't know why any of that happens. The full code is here: https://drive.google.com/drive/folders/1C4ABYU3ZCtwTySNzQiWJl9qtAhx4AZHI?usp=drive_link If you need extra information, and/or more detailled explanation of the issue, ask me. main.py import pygame from game import Game #imports settings pygame.init() #base variables VERSION = "Beta 2.0" display_info = pygame.display.Info() WIDTH = display_info.current_w #ou 1080 ou 1500 #display_info.current_w HEIGHT = display_info.current_h-60 #ou 720 ou 790 #display_info.current_h-60 game = Game(WIDTH, HEIGHT) print(WIDTH, HEIGHT) TITLE = "Projet Alpha 3 (version: "+VERSION+")" + " Round "+str(game.round) FPS = 60 require_names = False #player names if require_names: game.name1 = input("player1 name >>> ") game.name2 = input("player2 name >>> ") game.name3 = input("player3 name >>> ") game.name4 = input("player4 name >>> ") #screen definition screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.RESIZABLE | pygame.SHOWN) pygame.display.set_caption(TITLE) #other variables running = True Clock = pygame.time.Clock() bg_color = (200, 200, 200) keys = {pygame.K_UP:False, pygame.K_DOWN:False, pygame.K_LEFT:False, pygame.K_RIGHT:False, pygame.K_z:False, pygame.K_s:False, pygame.K_q:False, pygame.K_d:False, pygame.K_KP8:False, pygame.K_KP5:False, pygame.K_KP4:False, pygame.K_KP6:False} #load maze game.generate_maze() game.load_maze() game.load_poteaux() #start loop while running: #FPS limiter Clock.tick(FPS) #check for win game.check_for_win() TITLE = "Projet Alpha 3 (version: "+VERSION+")" + " Round "+str(game.round) pygame.display.set_caption(TITLE) #event detection for event in pygame.event.get(): #close window if event.type == pygame.QUIT: running = False #keyboard inputs if event.type == pygame.KEYDOWN: keys[event.key] = True #player1 shoot if game.alive_players.has(game.player1): if event.key == pygame.K_SPACE: if game.player1.powerups: game.shoot_powerup(game.player1) else: game.player1.shoot() #player2 shoot if game.alive_players.has(game.player2): if event.key == pygame.K_w: if game.player2.powerups: game.shoot_powerup(game.player2) else: game.player2.shoot() #player3 shoot if game.alive_players.has(game.player3): if event.key == pygame.K_KP0: if game.player3.powerups: game.shoot_powerup(game.player3) else: game.player3.shoot() if event.type == pygame.KEYUP: keys[event.key] = False #player1 controls if game.alive_players.has(game.player1): if keys[pygame.K_UP]: game.player1.forward() game.clearance(game.player1, "f") if keys[pygame.K_DOWN]: game.player1.backward() game.clearance(game.player1, "b") if keys[pygame.K_LEFT]: game.player1.left() game.clearance(game.player1, "l") if keys[pygame.K_RIGHT]: game.player1.right() game.clearance(game.player1, "r") #player2 controls if game.alive_players.has(game.player2): if keys[pygame.K_z]: game.player2.forward() game.clearance(game.player2, "f") if keys[pygame.K_s]: game.player2.backward() game.clearance(game.player2, "b") if keys[pygame.K_q]: game.player2.left() game.clearance(game.player2, "l") if keys[pygame.K_d]: game.player2.right() game.clearance(game.player2, "r") #player3 controls if game.alive_players.has(game.player3): if keys[pygame.K_KP8]: game.player3.forward() game.clearance(game.player3, "f") if keys[pygame.K_KP5]: game.player3.backward() game.clearance(game.player3, "b") if keys[pygame.K_KP4]: game.player3.left() game.clearance(game.player3, "l") if keys[pygame.K_KP6]: game.player3.right() game.clearance(game.player3, "r") #spawn powerups game.spawn_powers() #update powerups related stuff game.update_powers() for i in game.powers.balles: i.update() for i in game.powers.particules: i.update() #projectile update for i in game.players: for b in i.own_bullets: b.update() #screen filling screen.fill(bg_color) #sprites drawing game.powerups.draw(screen) for i in game.mines: if i.visible: screen.blit(i.image, i.rect) game.powers.balles.draw(screen) game.alive_players.draw(screen) game.walls.draw(screen) game.poteaux.draw(screen) for i in game.players: i.own_bullets.draw(screen) game.powers.particules.draw(screen) #load HUD game.load_HUD(screen) #tests #bullet collisions game.check_bullet_collisions() game.powers.check_collisions() #refresh screen pygame.display.flip() game.py collision function def check_bullet_collisions(self): for i in self.players: for b in i.own_bullets: b.reversed_x = False b.reversed_y = False #ball-player collisions for player in self.alive_players: if pygame.sprite.collide_rect(b, player): if i == player: if not b.invincible: b.kill() self.alive_players.remove(player) self.dead_players.add(player) else: b.will_invincible = 4 else: b.kill() self.alive_players.remove(player) self.dead_players.add(player) if i == self.player1: self.p1_score += 1 elif i == self.player2: self.p2_score += 1 elif i == self.player3: self.p3_score += 1 elif i == self.player4: self.p4_score += 1 else: b.will_invincible -= 1 if b.will_invincible == 0: b.invincible = False #ball-wall colisions for wall in self.walls: if b.rect.colliderect(wall.uprect) and not b.reversed_y: b.velocity[1] *= -1 b.reversed_y = True elif b.rect.colliderect(wall.downrect) and not b.reversed_y: b.velocity[1] *= -1 b.reversed_y = True elif b.rect.colliderect(wall.leftrect) and not b.reversed_x: b.velocity[0] *= -1 b.reversed_x = True elif b.rect.colliderect(wall.rightrect) and not b.reversed_x: b.velocity[0] *= -1 b.reversed_x = True #ball-poteau collisions for wall in self.poteaux: if b.rect.colliderect(wall.uprect) and not b.reversed_y: b.velocity[1] *= -1 b.reversed_y = True elif b.rect.colliderect(wall.downrect) and not b.reversed_y: b.velocity[1] *= -1 b.reversed_y = True elif b.rect.colliderect(wall.leftrect) and not b.reversed_x: b.velocity[0] *= -1 b.reversed_x = True elif b.rect.colliderect(wall.rightrect) and not b.reversed_x: b.velocity[0] *= -1 b.reversed_x = True #player-powerup collisions for player in self.alive_players: for powerup in self.powerups: if player.rect.colliderect(powerup.rect): powerup.power(player, self) #player-mines collision for mine in self.mines: for player in self.alive_players: if pygame.sprite.collide_rect(mine, player): if not player == mine.owner: self.alive_players.remove(player) self.dead_players.add(player) mine.kill() self.add_point(mine.owner, 1) powers.py import pygame import random from player import Player from wall import Wall from poteau import Poteau from powerup import Powerup from all_powerups.mine import Mine from particule import Particule from balle import Balle class Powers: def __init__(self, game): self.balles = pygame.sprite.Group() self.game = game self.particules = pygame.sprite.Group() def get_particule_image(self, type): if type == "smoke_cloud": return pygame.image.load('assets/smoke_cloud.png') if type == "bullet": return pygame.image.load('assets/projectile2.png') def check_collisions(self): for b in self.balles: b.reversed_x = False b.reversed_y = False #ball-player collisions for player in self.game.alive_players: if pygame.sprite.collide_rect(b, player): if b.owner == player: if not b.invincible: if b.type != "smoke": b.kill() self.game.alive_players.remove(player) self.game.dead_players.add(player) else: b.act() else: b.will_invincible = 4 else: if b.type != "smoke": b.kill() self.game.alive_players.remove(player) self.game.dead_players.add(player) if b.owner == self.game.player1: self.game.p1_score += 1 elif b.owner == self.game.player2: self.game.p2_score += 1 elif b.owner == self.game.player3: self.game.p3_score += 1 elif b.owner == self.game.player4: self.game.p4_score += 1 else: b.act() else: b.will_invincible -= 1 if b.will_invincible == 0: b.invincible = False #ball-wall colisions for wall in self.game.walls: if b.rect.colliderect(wall.uprect) and not b.reversed_y: if b.type != "smoke": b.velocity[1] *= -1 b.reversed_y = True else: b.act() elif b.rect.colliderect(wall.downrect) and not b.reversed_y: if b.type != "smoke": b.velocity[1] *= -1 b.reversed_y = True else: b.act() elif b.rect.colliderect(wall.leftrect) and not b.reversed_x: if b.type != "smoke": b.velocity[0] *= -1 b.reversed_x = True else: b.act() elif b.rect.colliderect(wall.rightrect) and not b.reversed_x: if b.type != "smoke": b.velocity[0] *= -1 b.reversed_x = True else: b.act() #ball-poteau collisions for wall in self.game.poteaux: if b.rect.colliderect(wall.uprect) and not b.reversed_y: if b.type != "smoke": b.velocity[1] *= -1 b.reversed_y = True else: b.act() elif b.rect.colliderect(wall.downrect) and not b.reversed_y: if b.type != "smoke": b.velocity[1] *= -1 b.reversed_y = True else: b.act() elif b.rect.colliderect(wall.leftrect) and not b.reversed_x: if b.type != "smoke": b.velocity[0] *= -1 b.reversed_x = True else: b.act() elif b.rect.colliderect(wall.rightrect) and not b.reversed_x: if b.type != "smoke": b.velocity[0] *= -1 b.reversed_x = True else: b.act() balle.py import pygame from particule import Particule class Balle(pygame.sprite.Sprite): def __init__(self, powers, pos, angle, image, speed, owner, life, type): super().__init__() self.powers = powers self.angle = angle self.type = type self.origin_image = image self.image = pygame.transform.rotozoom(self.origin_image, self.angle, 1) self.pos = pos self.speed = speed self.velocity = pygame.math.Vector2(0, self.speed) self.velocity = self.velocity.rotate(-self.angle) self.rect = self.image.get_rect(center=self.pos) self.lifetime = life if life == "normal": self.lifetime = 900 self.invincible = True self.will_invincible = 4 self.reversed_x = False self.reversed_y = False self.owner = owner def update(self): self.pos -= self.velocity self.rect = self.image.get_rect(center=self.pos) self.lifetime -= 1 if self.lifetime == 0: self.kill() def act(self): if self.type == "smoke": self.powers.particules.add(Particule(self.pos, 0, 0, pygame.transform.scale(pygame.image.load('assets/Smoke_cloud.png'), (500, 500)), "smoke", 2000)) self.kill() particule.py import pygame class Particule(pygame.sprite.Sprite): def __init__(self, pos, angle, speed, image, type, life): super().__init__() self.pos = pos self.angle = angle self.speed = speed self.velocity = pygame.math.Vector2(0, self.speed).rotate(-self.angle) self.origin_image = image self.image = pygame.transform.rotozoom(self.origin_image, self.angle, 1) self.type = type self.lifetime = life self.rect = self.image.get_rect(center=self.pos) def update(self): self.pos += self.velocity self.rect = self.image.get_rect(center=self.pos) self.lifetime -= 1 if self.lifetime == 0: self.kill() Continue reading...