My collision detection isn't working and way to laggy - python

So here's just the base function:
def xCollision(self):
for tile in tiles:
if tile.colliderect(self.rect):
if self.x_vel >= 1:
self.rect.right = tile.left
elif self.x_vel <= -1:
self.rect.left = tile.right
def yCollision(self):
for tile in tiles:
if tile.colliderect(self.rect):
if self.y_vel >= 1:
self.rect.bottom = tile.top
elif self.y_vel <= -1:
self.rect.top = tile.bottom
This is inside the Player class.
Now, when i try this my frames go down to around 4 fps and it also isn't working.
About it not working it has to do something with the self.rect.something = tile.something because when i replace it with print() it prints whatever.
Here is the entire code for reference, And yes i just started out so don't think its gonna be any good ok?
import pygame
import random
import math
import time
# Initialize Pygame
pygame.init()
pygame.mixer.init()
# Set the size of the window
size = (900, 600)
screen = pygame.display.set_mode(size)
# Set the title of the window
pygame.display.set_caption("Classes testing")
clock = pygame.time.Clock()
fps = 60
pygame.mixer.music.load('PewPewProject/Retro Platform.wav')
pygame.mixer.music.set_volume(0.1)
pygame.mixer.music.play(-1)
pop_sound = pygame.mixer.Sound("PewPewProject/vine-boom.wav")
pop_sound.set_volume(0.5)
level = [
['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
['1','E','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','E','0','0','0','1'],
['1','0','0','0','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','1','0','1','0','0','0','0','0','0','0','0','E','0','0','0','0','1'],
['1','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','E','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','E','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','1','1','0','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','1','1','1','0','E','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','1','S','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
['1','0','0','E','0','0','0','0','0','1','1','1','1','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
]
tilex, tiley = [0, 0]
tilex_offset, tiley_offset = [0, 0]
tile_size = 50
tilemap = pygame.image.load('PewPewProject/tilemap.png')
tiles = []
collision_tiles = []
enemy_spawns = []
def Build_Level():
global tiley,tilex
tiley = -1
for rows in level:
tilex = -1
tiley += 1
for tile in rows:
tilex += 1
if tile == '1':
tile_rect = pygame.draw.rect(screen, (100, 100, 100), (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))
tiles.append(tile_rect)
elif tile == '0':
pass
elif tile == 'E':
enemy_spawns.append([tilex, tiley])
elif tile == 'S':
pygame.draw.rect(screen, (50, 255, 100), (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))
elif tile == 'R':
pygame.draw.rect(screen, (255, 50, 50), (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))
else:
print("Wrong Map Input")
def random_except(start, end, exception_start, exception_end):
num = random.randint(start, end)
while num >= exception_start and num <= exception_end:
num = random.randint(start, end)
return num
class Player:
def __init__(self, health, speed, x, y, size, healthboost, collision_tiles):
self.speed = speed
self.x = x
self.y = y
self.y_vel = 0
self.x_vel = 0
self.size = size
self.hitbox = pygame.draw.rect(screen, (230, 100, 100), (self.x, self.y, self.size, self.size))
self.gunsurface = pygame.Surface((90, 25), pygame.SRCALPHA)
self.healthboost = healthboost
self.health = health * healthboost
self.rotated_gunsurface = self.gunsurface
self.gunsurface.fill((150, 150, 150))
self.gunrect = self.gunsurface.get_rect()
self.rect = self.hitbox
self.projectiles = [Projectile(-100, 0, 0)]
self.last_shot_time = 0
self.cooldown = 0.5
self.is_slowed = False
self.alive = True
def xCollision(self):
for tile in tiles:
if tile.colliderect(self.rect):
if self.x_vel >= 1:
self.rect.right = tile.left
elif self.x_vel <= -1:
self.rect.left = tile.right
def yCollision(self):
for tile in tiles:
if tile.colliderect(self.rect):
if self.y_vel >= 1:
self.rect.bottom = tile.top
elif self.y_vel <= -1:
self.rect.top = tile.bottom
def Render(self):
self.rect = pygame.draw.rect(screen, (230, 100, 100), (self.x, self.y, self.size, self.size))
self.Gun()
def Alive(self):
if self.health <= 0:
self.alive = False
def GUI(self):
self.empty_health_bar = pygame.draw.rect(screen, (200, 20, 20), (screen.get_width()/4, 10,466, 25))
self.health_bar = pygame.draw.rect(screen, (20, 200, 20), (screen.get_width()/4, 10, self.health*4.66/self.healthboost, 25))
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10),(screen.get_width()/4+466, 10), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 35),(screen.get_width()/4+466, 35), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10), (screen.get_width()/4, 35), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4+466, 10), (screen.get_width()/4+466, 35), 2)
def Gun(self):
cursor_x, cursor_y = pygame.mouse.get_pos()
dx = cursor_x - (self.x + self.size)
dy = cursor_y - (self.y + self.size)
angle = math.atan2(dy, dx)
self.rotated_gunsurface = pygame.transform.rotate(self.gunsurface, math.degrees(angle * -1))
self.gunrect = self.rotated_gunsurface.get_rect(center = (self.x+self.size/2, self.y+self.size/2))
screen.blit(self.rotated_gunsurface, (self.gunrect.x, self.gunrect.y))
def Shoot(self):
if pygame.key.get_pressed()[pygame.K_e]:
current_time = time.time()
if current_time - self.last_shot_time > self.cooldown:
pop_sound.play()
cursor_x, cursor_y = pygame.mouse.get_pos()
dx = cursor_x - (self.x + self.size/2)
dy = cursor_y - (self.y + self.size/2)
angle = math.atan2(dy, dx)
self.projectiles.append(Projectile(self.x+self.size/2, self.y+self.size/2, angle))
self.last_shot_time = current_time
self.cooldown = 0.1
def Movement(self):
global tiley_offset, tilex_offset
keys = pygame.key.get_pressed()
if self.x >= screen.get_width()-100-self.size: # Move to the RIGHT
if keys[pygame.K_d]:
tilex_offset -= self.speed
if keys[pygame.K_a]:
self.x_vel = -self.speed
if not self.y <= 100:
if keys[pygame.K_w]:
self.y_vel = -self.speed
else:
if keys[pygame.K_w]:
tiley_offset += self.speed
if not self.y >= screen.get_height()-100-self.size:
if keys[pygame.K_s]:
self.y_vel = self.speed
else:
if keys[pygame.K_s]:
tiley_offset -= self.speed
elif self.x <= 100: # Move to the LEFT
if keys[pygame.K_a]:
tilex_offset += self.speed
if keys[pygame.K_d]:
self.x_vel = self.speed
if not self.y <= 100:
if keys[pygame.K_w]:
self.y_vel = -self.speed
else:
if keys[pygame.K_w]:
tiley_offset += self.speed
if not self.y >= screen.get_height()-100-self.size:
if keys[pygame.K_s]:
self.y_vel = self.speed
else:
if keys[pygame.K_s]:
tiley_offset -= self.speed
elif self.y >= screen.get_height()-100-self.size: # Move DOWN
if keys[pygame.K_s]:
tiley_offset -= self.speed
if keys[pygame.K_w]:
self.y_vel = -self.speed
if keys[pygame.K_a]:
self.x_vel =- self.speed
if keys[pygame.K_d]:
self.x_vel = self.speed
elif self.y <= 100: # Move UP
if keys[pygame.K_w]:
tiley_offset += self.speed
if keys[pygame.K_s]:
self.y_vel = self.speed
if keys[pygame.K_a]:
self.x_vel = -self.speed
if keys[pygame.K_d]:
self.x_vel = self.speed
else: # Default Movement
if keys[pygame.K_w]:
self.y_vel = -self.speed
if keys[pygame.K_s]:
self.y_vel = self.speed
if keys[pygame.K_a]:
self.x_vel = -self.speed
if keys[pygame.K_d]:
self.x_vel = self.speed
self.x += self.x_vel
self.xCollision()
self.y += self.y_vel
self.yCollision()
self.y_vel = 0
self.x_vel = 0
class Projectile:
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.angle = angle
self.speed = 8
self.hitbox = pygame.Rect(self.x, self.y, 5,5)
def Move(self):
self.x += math.cos(self.angle) * self.speed
self.y += math.sin(self.angle) * self.speed
def Render(self):
self.hitbox = pygame.draw.circle(screen, (255, 255, 0), (int(self.x), int(self.y)), 7)
class Enemy:
def __init__(self, health, main_speed, tag, size, player, x, y):
self.health = health
self.main_speed = 3
self.tag = tag
self.size = size
self.player = player
self.speed = 3
self.x = x
self.y = y
self.alive = True
def Destroy(self):
self.alive = False
def Spawning(self):
self.hitbox = pygame.draw.rect(screen, (100, 240, 100), (self.x + tilex_offset, self.y + tiley_offset, self.size, self.size))
def Movement(self):
dx = self.player.x - self.x
dy = self.player.y - self.y
angle = math.atan2(dy - tiley_offset, dx - tilex_offset)
self.x += self.speed * math.cos(angle)
self.y += self.speed * math.sin(angle)
def main():
player = Player(100, 3, screen.get_width()/2-50, screen.get_height()/2-50, 50, 1, tiles)
enemies = []
def Spawn_enemies(num_enemies, player):
for i in range(num_enemies):
x, y = random.choice(enemy_spawns)
enemy = Enemy(1, 1, i, 25, player, x*tile_size, y*tile_size)
enemies.append(enemy)
print(x, y)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Main Loop
screen.fill((100, 100, 200))
# usage
spawn_enemies_chance = random.randint(0, 200)
number_of_enemies = len(enemies)
if spawn_enemies_chance == 1 and number_of_enemies <= 4:
Spawn_enemies(1,player)
Build_Level()
# enemy
for enemy in enemies:
if enemy.alive:
enemy.Movement()
enemy.Spawning()
for projectile in player.projectiles:
if enemy.hitbox.colliderect(projectile.hitbox):
enemy.health -= 1
pop_sound.play()
if enemy.health <= 0:
enemy.alive = False
enemies.remove(enemy)
player.projectiles.remove(projectile)
keys = pygame.key.get_pressed()
if keys[pygame.K_LSHIFT]: # Slow things down by 3 times
player.is_slowed = True
for enemy in enemies:
enemy.speed = enemy.main_speed / 3
for projectile in player.projectiles:
projectile.speed = 2.6
player.speed = 1
player.cooldown = 1.5
spawn_enemies_chance = random.randint(0, 1500)
else:
player.is_slowed = False
for enemy in enemies:
enemy.speed = enemy.main_speed
for projectile in player.projectiles:
projectile.speed = 8
player.speed = 3
player.cooldown = 0.5
spawn_enemies_chance = random.randint(0, 500)
# Get Hurt
for enemy in enemies:
if enemy.hitbox.colliderect(player):
player.health -= 10
enemies.remove(enemy)
# Projectiles
for i, projectile in enumerate(player.projectiles):
projectile.Move()
projectile.Render()
if projectile.x < 0 or projectile.x > screen.get_width() or projectile.y < 0 or projectile.y > screen.get_height():
player.projectiles.pop(i)
# player
player.Alive()
player.Movement()
player.Shoot()
player.Render()
# Renders the UI ontop of everything
player.GUI()
pygame.display.update()
clock.tick(fps)
pygame.quit()
# DO NOT DISTURB!
if __name__ == "__main__":
main()
I honestly don't know why its not working but i think i know why its lagging.
It has to check for collision with every tile every single frame which causes some lag if you have a big map i belive, that's just my thought tho.

The actual problem is not the collision detection, but that Build_Level is called in the application loop. Therefore the tiles and enemy_spawns list contain more and more elements over time and your code gets slower and slower. To solve your problem, separate the function into two functions, build_level and draw_level. Call build_level before the application loop, but draw_level in the application loop:
def build_level():
for tiley, rows in enumerate(level):
for tilex, tile in enumerate(rows):
if tile == '1':
tile_rect = pygame.Rect(tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size)
tiles.append(tile_rect)
elif tile == '0':
pass
elif tile == 'E':
enemy_spawns.append([tilex, tiley])
elif tile == 'S':
pass
elif tile == 'R':
pass
else:
print("Wrong Map Input")
def draw_level():
for tiley, rows in enumerate(level):
for tilex, tile in enumerate(rows):
color = None
if tile == '1':
color = (100, 100, 100)
elif tile == 'S':
color = (50, 255, 100)
elif tile == 'R':
color = (255, 50, 50)
if color:
pygame.draw.rect(screen, color, (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))
def main():
# [...]
build_level()
running = True
while running:
# [...]
draw_level()

Related

i have a problem: my enemies are stacked vertically, on top of my player which is weird, and they don't move to their predefined positions [duplicate]

This question already exists:
in my shooting game, my players are positioned on top of my head (player) which is very abnormal and also once the game starts, they start shooting [closed]
Closed 6 months ago.
i have earlier tried to format my question properly but i hope this one is better. am creating a shooter game from https://github.com/russs123/Shooter. however my problem is that my enemies are stacked vertically upwards in a straight line when i run my game and the enemies don't start off at their predefined location. below is the full code i wrote. perhaps if you can run it, it will be better understood.
import pygame, sys
from player import Player
import os
import random
import csv
pygame.init()
screen_width = 600
scroll_thresh = 200
screen_scroll = 0
bg_scroll = 0
screen_height = int(screen_width * 0.8)
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Shooter Game")
clock = pygame.time.Clock()
fps = 60
# define game variables
GRAVITY = 0.75
level = 1
ROWS = 16
COLS = 150
TILE_SIZE = screen_height // ROWS
TILE_TYPES = 21
img_list = []
for x in range(TILE_TYPES):
img = pygame.image.load(f"img/tile/{x}.png")
img = pygame.transform.scale(img, (TILE_SIZE, TILE_SIZE))
img_list.append(img)
# color variables
bg = (144, 201, 120)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
# define player action variables
moving_left = False
moving_right = False
shoot = False
grenade = False
grenade_thrown = False
# load up images
pine1_img = pygame.image.load("img/Background/pine1.png").convert_alpha()
pine2_img = pygame.image.load("img/Background/pine2.png").convert_alpha()
mountain_img = pygame.image.load("img/Background/mountain.png").convert_alpha()
sky_cloud_img = pygame.image.load("img/Background/sky_cloud.png").convert_alpha()
bullet_img = pygame.image.load("img/icons/bullet.png").convert_alpha()
grenade_img = pygame.image.load("img/icons/grenade.png").convert_alpha()
# pick up boxes
health_box_img = pygame.image.load("img/icons/health_box.png").convert_alpha()
ammo_box_img = pygame.image.load("img/icons/ammo_box.png").convert_alpha()
grenade_box_img = pygame.image.load("img/icons/grenade_box.png").convert_alpha()
# name_dt = type(name)
item_boxes = {
"Health": health_box_img,
"Ammo": ammo_box_img,
"Grenade": grenade_img,
}
# define fonts
font = pygame.font.SysFont("Futura", 30)
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_bg():
screen.fill(bg)
screen.blit(sky_cloud_img, (0, 0))
screen.blit(mountain_img, (0, screen_height - mountain_img.get_height() - 300))
screen.blit(pine1_img, (0, screen_height - pine1_img.get_height() - 150))
screen.blit(pine2_img, (0, screen_height - pine2_img.get_height()))
class Soldier(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, ammo, grenades):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.ammo = ammo
self.start_ammo = ammo
self.shoot_cooldown = 0
self.grenades = grenades
self.health = 100
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.animation_list = []
self.frame_index = 0
self.action = 0
# ai specific variables
self.move_counter = 0
self.vision = pygame.Rect(0, 0, 150, 20)
self.idling = 0
self.idling_counter = 0
self.update_time = pygame.time.get_ticks()
# load all images for the players
animation_types = ["idle", "run", "jump", "death"]
for animation in animation_types:
temp_list = []
# reset temporary list of images
# count number of files in the folder
num_of_frames = len(os.listdir(f"img/{self.char_type}/{animation}"))
for i in range(num_of_frames):
img = pygame.image.load(f"img/{self.char_type}/{animation}/{i}.png").convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.width = self.image.get_width()
self.height = self.image.get_height()
def update(self):
self.update_animation()
self.check_alive()
# update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
def move(self, moving_left, moving_right):
screen_scroll = 0
dx = 0
dy = 0
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
# apply gravity
self.vel_y += GRAVITY
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
# check for collision
for tile in world.obstacle_list:
# check collision in the x direction
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
dx = 0
# check for collision in the y direction
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
# check if below the ground, i.e jumping
if self.vel_y < 0:
self.vel_y = 0
dy = tile[1].bottom - self.rect.top
# check if above the ground, ie falling
elif self.vel_y >= 0:
self.vel_y = 0
self.in_air = False
dy = tile[1].top - self.rect.bottom
self.rect.x += dx
self.rect.y += dy
# update scroll based on player position
if self.char_type == "player":
if self.rect.right > screen_width - scroll_thresh or self.rect.left < scroll_thresh:
self.rect.x = -dx
screen_scroll = -dx
return screen_scroll
def shoot(self):
if self.shoot_cooldown == 0 and self.ammo > 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.75 * self.rect.size[0] * self.direction), self.rect.centery,
self.direction)
bullet_group.add(bullet)
# reduce ammo after each shot
self.ammo -= 1
def ai(self):
if self.alive and player.alive:
if self.idling == False and random.randint(1, 200) == 1:
self.update_action(0)
self.idling = True
self.idling_counter = 50
# check if ai is near the player
if self.vision.colliderect(player.rect):
# stop running and face the player
self.update_action(0)
self.shoot()
else:
if self.idling == False:
if self.direction == 1:
ai_moving_right = True
else:
ai_moving_right = False
ai_moving_left = not ai_moving_right
self.move(ai_moving_left, ai_moving_right)
self.update_action(1)
self.move_counter += 1
# update ai vision as the enemy moves
self.vision.center = (self.rect.centerx + 75 * self.direction, self.rect.centery)
if self.move_counter > TILE_SIZE:
self.direction *= -1
self.move_counter *= -1
else:
self.idling_counter -= 1
if self.idling_counter <= 0:
self.idling = False
# scroll
self.rect.x = screen_scroll
def update_animation(self):
ANIMATION_COOLDOWN = 100
# update image depending on current index
self.image = self.animation_list[self.action][self.frame_index]
# check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
# if animation has run out then restart to the first
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 3:
self.frame_index = len(self.animation_list[self.action]) - 1
else:
self.frame_index = 0
def check_alive(self):
if self.health <= 0:
self.health = 0
self.speed = 0
self.alive = False
self.update_action(3)
def update_action(self, new_action):
# check if new action is different from the previous one
if new_action != self.action:
self.action = new_action
# update animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def draw(self):
screen.blit(pygame.transform.flip(self.image, self.flip, False), self.rect)
class HealthBar():
def __init__(self, health, x, y, max_health):
self.x = x
self.y = y
self.health = health
self.max_health = max_health
def draw(self, health):
self.health = health
pygame.draw.rect(screen, BLACK, (self.x - 2, self.y - 2, 154, 24))
pygame.draw.rect(screen, RED, (self.x, self.y, 150, 20))
ratio = self.health / self.max_health
pygame.draw.rect(screen, GREEN, (self.x, self.y, 150 * ratio, 20))
class World():
def __init__(self):
self.obstacle_list = []
def process_data(self, data):
for y, row in enumerate(data):
for x, tile in enumerate(row):
if tile >= 0:
img = img_list[tile]
img_rect = img.get_rect()
img_rect.x = x * TILE_SIZE
img_rect.y = y * TILE_SIZE
tile_data = (img, img_rect)
if 0 <= tile <= 8:
self.obstacle_list.append(tile_data)
elif 9 <= tile <= 10:
# water
water = Water(img, x * TILE_SIZE, y * TILE_SIZE, )
water_group.add(water)
pass
elif 11 <= tile <= 14:
# decoration
decoration = Decoration(img, x * TILE_SIZE, y * TILE_SIZE)
decoration_group.add(decoration)
elif tile == 15:
# create a player
player = Soldier("player", x * TILE_SIZE, y * TILE_SIZE, 1.65, 5, 20, 5)
health_bar = HealthBar(10, 10, player.health, player.health)
elif tile == 16:
# create enemy
enemy = Soldier("enemy", x * TILE_SIZE, y * TILE_SIZE, 1.65, 2, 20, 0)
enemy_group.add(enemy)
elif tile == 17:
# create ammo box
item_box = ItemBox("Ammo", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 18:
# create grenade box
item_box = ItemBox("Grenade", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 19:
# create health box
item_box = ItemBox("Health", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 20:
# create exit point
exit = Exit(img, x * TILE_SIZE, y * TILE_SIZE, )
exit_group.add(exit)
return player, health_bar
def draw(self):
for tile in self.obstacle_list:
tile[1][0] += screen_scroll
screen.blit(tile[0], tile[1])
class Decoration(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = img
self.rect = self.image.get_rect()
self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
def update(self):
self.rect.x += screen_scroll
class Water(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = img
self.rect = self.image.get_rect()
self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
def update(self):
self.rect.x += screen_scroll
class Exit(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = img
self.rect = self.image.get_rect()
self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
class ItemBox(pygame.sprite.Sprite):
def __init__(self, item_type, x, y):
pygame.sprite.Sprite.__init__(self)
self.item_type = item_type
self.image = item_boxes[self.item_type]
self.rect = self.image.get_rect()
self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
def update(self):
# scroll
self.rect.x += screen_scroll
# check if player has picked up the box
if pygame.sprite.collide_rect(self, player):
# check what kind of box it was
if self.item_type == "Health":
player.health += 25
if player.health > player.max_health:
player.health = player.max_health
elif self.item_type == "Ammo":
player.ammo += 15
elif self.item_type == "Grenade":
player.grenades += 3
# delete the item box
self.kill()
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 10
self.image = bullet_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
self.rect.x += self.direction * self.speed
# check if bullet has left the screen
if self.rect.right < 0 and self.rect.left > screen_width:
self.kill()
# check for collision with level
for tile in world.obstacle_list:
if tile[1].colliderect(self.rect):
self.kill()
# check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
for enemy in enemy_group:
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Grenade(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.timer = 100
self.vel_y = -11
self.speed = 7
self.image = grenade_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
self.width = self.image.get_width()
self.height = self.image.get_height()
def update(self):
self.vel_y += GRAVITY
dx = self.direction * self.speed
dy = self.vel_y
# check for collision with level
for tile in world.obstacle_list:
# check if grenade has hit a wall
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
self.direction *= -1
dx = self.direction * self.speed
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
self.speed = 0
# check if below the ground, i.e thrown
if self.vel_y < 0:
self.y = 0
dy = tile[1].bottom - self.rect.top
# check if above the ground, ie falling
elif self.vel_y >= 0:
self.vel_y = 0
dy = tile[1].top - self.rect.bottom
# update grenade position
self.rect.x += dx
self.rect.y += dy
# explosion countdown
self.timer -= 1
if self.timer <= 0:
self.kill()
explosion = Explosion(self.rect.x, self.rect.y, 0.5)
explosion_group.add(explosion)
# do damage to anyone nearby
if abs(self.rect.centerx - player.rect.centerx) < TILE_SIZE * 2 and \
abs(self.rect.centery - player.rect.centery) < TILE_SIZE * 2:
player.health -= 50
for enemy in enemy_group:
if abs(self.rect.centerx - enemy.rect.centerx) < TILE_SIZE * 2 and \
abs(self.rect.centery - enemy.rect.centery) < TILE_SIZE * 2:
enemy.health -= 50
class Explosion(pygame.sprite.Sprite):
def __init__(self, x, y, scale):
pygame.sprite.Sprite.__init__(self)
self.images = []
for num in range(1, 6):
img = pygame.image.load(f"img/explosion/exp{num}.png").convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), (int(img.get_height() * scale))))
self.images.append(img)
self.frame_index = 0
self.image = self.images[self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.counter = 0
def update(self):
EXPLOSION_SPEED = 4
# update explosion animation
self.counter += 1
if self.counter >= EXPLOSION_SPEED:
self.counter = 0
self.frame_index += 1
# if animation is complete, then delete the explosion
if self.frame_index >= len(self.images):
self.kill()
else:
self.image = self.images[self.frame_index]
# create sprite groups
enemy_group = pygame.sprite.Group()
bullet_group = pygame.sprite.Group()
grenade_group = pygame.sprite.Group()
explosion_group = pygame.sprite.Group()
item_box_group = pygame.sprite.Group()
decoration_group = pygame.sprite.Group()
water_group = pygame.sprite.Group()
exit_group = pygame.sprite.Group()
# create empty tile list
world_data = []
for row in range(ROWS):
r = [-1] * COLS
world_data.append(r)
# load in level data and create world
with open(f"level{level}_data.csv", newline="") as csvfile:
reader = csv.reader(csvfile, delimiter=",")
for x, row in enumerate(reader):
for y, tile in enumerate(row):
world_data[x][y] = int(tile)
print(world_data)
world = World()
player, health_bar = world.process_data(world_data)
run = True
while run:
clock.tick(fps)
draw_bg()
world.draw()
health_bar.draw(player.health)
# show ammo
draw_text("AMMO:", font, WHITE, 10, 35)
for x in range(player.ammo):
screen.blit(bullet_img, (90 + (x * 10), 40))
# show grenade
draw_text("GRENADES: ", font, WHITE, 10, 65)
for x in range(player.grenades):
screen.blit(grenade_img, (130 + (x * 15), 66))
player.update()
player.draw()
for enemy in enemy_group:
enemy.ai()
enemy.update()
enemy.draw()
# update and draw groups
bullet_group.update()
grenade_group.update()
explosion_group.update()
item_box_group.update()
decoration_group.update()
water_group.update()
exit_group.update()
bullet_group.draw(screen)
grenade_group.draw(screen)
explosion_group.draw(screen)
item_box_group.draw(screen)
decoration_group.draw(screen)
water_group.draw(screen)
exit_group.draw(screen)
# update player actions, 1 is run, 0 = idle, 2 = in air
if player.alive:
# shoot bullet
if shoot:
player.shoot()
elif grenade and grenade_thrown == False and player.grenades > 0:
grenade = Grenade(player.rect.centerx + (0.5 * player.rect.size[0] * player.direction),
player.rect.top, player.direction)
grenade_group.add(grenade)
# reduce grenades
player.grenades -= 1
grenade_thrown = True
if player.in_air:
player.update_action(2)
elif moving_left or moving_right:
player.update_action(1)
else:
player.update_action(0)
screen_scroll = player.move(moving_left, moving_right)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# keyboard presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_SPACE:
shoot = True
if event.key == pygame.K_q:
grenade = True
if event.key == pygame.K_w and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE:
run = False
# keyboard button released
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
if event.key == pygame.K_SPACE:
shoot = False
if event.key == pygame.K_q:
grenade = False
grenade_thrown = False
pygame.display.update()
pygame.quit()
i have looked at this code for days but cant seem to find out the problem exactly. so, the question once again is how to properly arrange the enemies on the screen at their various predefined positions and not directly on top of my player.

Bullets Are not Drawing on Simple Pygame

I am trying to create a simple bullet function in which am shooting bullets vertically. No bullets seem to be drawing in the program Help would be much appreciated.
class Bullet(pg.sprite.Sprite):
def __init__(self):
super().__init__()
pygame.sprite.Sprite.__init__(self)
self.image = pg.image.load(os.path.join(path, 'img', 'bullet.png'))
self.image = pygame.Surface([4, 10])
self.image.fill(RED)
self.rect = self.image.get_rect()
def update(self):
self.rect.y -= 5 enter code here
elif e.type == pg.KEYDOWN and e.key == pg.K_SPACE:
# Fire a bullet if the user clicks the space button
bullet = Bullet()
# Set the bullet so it is where the player is
bullet.rect.x = player.rect.x
bullet.rect.y = player.rect.y
# Add the bullet to the lists
cars_group.add(bullet)
bullet_list.add(bullet)
# Calculate mechanics for each bullet
for bullet in bullet_list:
# See if it hit a block
block_hit_list = pygame.sprite.spritecollide(bullet, cars_group, True)
# For each block hit, remove the bullet and add to the score
for block in block_hit_list:
bullet_list.remove(bullet)
cars_group.remove(bullet)
disclosure this isnt fully my code
Full code here:
import pygame as pg
import pygame.freetype
import random
import os
import math
os.environ['SDL_VIDEO_CENTERED'] = '1'
path = os.path.dirname(os.path.abspath(__file__))
record_file = os.path.join(path, 'Record', 'record.txt')
try:
with open(record_file, 'x') as f:
f.write(str(0))
except (BaseException, OSError):
pass
SIZE = WIDTH, HEIGHT = 800, 600
GREY = (128, 128, 128)
GREEN = (0, 128, 0)
WHITE = (200, 200, 200)
RED = (230, 0, 0)
rgb = [0, 250, 0]
block = False
pause = [False, True]
count = [0]
car_accident = 0
level = 40
start = 255
blink = 0
hit_old = None
play, out = None, None
def icon():
size, text = 32, '\u0056\u004F'
sur = pg.Surface((size, size), pg.SRCALPHA)
pg.draw.circle(
sur, '#44475a59', (size // 2, size // 2), size // 2)
font_text = pg.freetype.SysFont('Arial', 16, True)
rect = font_text.get_rect(text)
x, y = (size - rect.width) // 2, (size - rect.height) // 2
font_text.render_to(sur, (x, y), text, fgcolor='#ff0000')
pg.display.set_icon(sur)
pg.init()
icon()
pg.display.set_caption('Rally')
screen = pg.display.set_mode(SIZE)
FPS = 120
clock = pg.time.Clock()
font = pygame.freetype.Font(os.path.join(path, 'font', 'seguisym.ttf'), 30)
cars = [pg.image.load(os.path.join(path, 'img', 'car1.png')),
pg.image.load(os.path.join(path, 'img', 'car2.png')),
pg.image.load(os.path.join(path, 'img', 'car3.png'))]
alarm = [pg.image.load(os.path.join(path, 'alarm', '1.png')),
pg.image.load(os.path.join(path, 'alarm', '2.png'))]
sound_car_accident = pg.mixer.Sound(os.path.join(path, 'sound', 'udar.wav'))
sound_canister = pg.mixer.Sound(os.path.join(path, 'sound', 'canister.wav'))
sound_accident = pg.mixer.Sound(os.path.join(path, 'sound', 'accident.wav'))
button_start = pg.image.load(os.path.join(path, 'img', 'btn_play.png'))
button_start_rect = button_start.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 100))
button_stop = pg.image.load(os.path.join(path, 'img', 'btn_exit.png'))
button_stop_rect = button_stop.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 100))
fuel_image = pg.image.load(os.path.join(path, 'img', 'fuel.png'))
canister_image = pg.image.load(os.path.join(path, 'img', 'canister.png'))
water_image = pg.image.load(os.path.join(path, 'img', 'water.png'))
bullet_image = pg.image.load(os.path.join(path, 'img', 'bullet.png'))
u1_event = pg.USEREVENT + 1
pg.time.set_timer(u1_event, random.randrange(6000, 26001, 4000))
u2_event = pg.USEREVENT + 2
pg.time.set_timer(u2_event, random.randrange(13000, 28001, 5000))
class Player(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load(os.path.join(path, 'img', 'car4.png'))
self.orig_image = self.image
self.angle = 0
self.speed = 2
self.acceleration = 0.02
self.rect = self.image.get_rect(center=(WIDTH - 20, HEIGHT - 70))
self.position = pg.math.Vector2()
self.velocity = pg.math.Vector2()
self.vx = 0 # velocity.x for speedometer
def update(self):
self.image = pg.transform.rotate(self.orig_image, self.angle)
self.position += self.velocity
self.rect = self.image.get_rect(center=self.position)
keys = pg.key.get_pressed()
if keys[pg.K_RIGHT]:
self.velocity.x = self.speed
self.angle -= 1
self.vx -= self.acceleration
if self.angle < -25:
self.angle = -25
elif keys[pg.K_LEFT]:
self.velocity.x = -self.speed
self.angle += 1
self.vx -= self.acceleration
if self.angle > 25:
self.angle = 25
else:
self.vx += self.acceleration if self.vx < 0 else 0
self.velocity.x = 0
if self.angle < 0:
self.angle += 1
elif self.angle > 0:
self.angle -= 1
if keys[pg.K_UP]:
self.velocity.y -= self.acceleration
if self.velocity.y < -self.speed:
self.velocity.y = -self.speed
elif keys[pg.K_DOWN]:
self.velocity.y += self.acceleration
if self.velocity.y > self.speed:
self.velocity.y = self.speed
else:
if self.velocity.y < 0:
self.velocity.y += self.acceleration
if self.velocity.y > 0:
self.velocity.y = 0
elif self.velocity.y > 0:
self.velocity.y -= self.acceleration
if self.velocity.y < 0:
self.velocity.y = 0
def for_speedometer(self):
if self.vx <= -0.4:
self.vx = -0.4 # left-right speedometer max
if self.velocity.y < self.vx or self.velocity.y > 0:
self.vx = self.velocity.y
if self.vx >= 1.04:
self.vx = 1.04 # speedometer min for speed=2
return self.vx
class Alarm(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.images = alarm
self.index = 0
self.range = len(self.images)
self.image = self.images[self.index]
self.rect = self.image.get_rect()
self.speed = 1
def update(self):
self.index += 0.02
self.image = self.images[int(self.index % self.range)]
self.rect.y += self.speed
if self.rect.top > HEIGHT:
self.kill()
class Car(pg.sprite.Sprite):
def __init__(self, x, y, img):
pg.sprite.Sprite.__init__(self)
if img == fuel_image:
self.image = img
self.speed = 0
elif img == canister_image or img == water_image:
self.image = img
self.speed = 1
else:
self.image = pg.transform.flip(img, False, True)
self.speed = random.randint(2, 3)
self.rect = self.image.get_rect(center=(x, y))
def update(self):
self.rect.y += self.speed
if self.rect.top >= HEIGHT:
if self is canister or self is water:
self.kill()
else:
if 40 < player.rect.centerx < WIDTH - 40 \
and player.rect.top < HEIGHT and player.rect.bottom > 0:
count[0] += 1
list_x.remove(self.rect.centerx)
while True:
self.rect.centerx = random.randrange(80, WIDTH, 80)
if self.rect.centerx in list_x:
continue
else:
list_x.append(self.rect.centerx)
self.speed = random.randint(2, 3)
self.rect.bottom = 0
break
class Road(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface(screen.get_size())
self.image.fill(GREY)
pg.draw.line(self.image, GREEN, (20, 0), (20, 600), 40)
pg.draw.line(self.image, GREEN, (780, 0), (780, 600), 40)
for xx in range(10):
for yy in range(10):
pg.draw.line(
self.image, WHITE,
(40 + xx * 80, 0 if xx == 0 or xx == 9 else 10 + yy * 60),
(40 + xx * 80, 600 if xx == 0 or xx == 9 else 50 + yy * 60), 5)
self.rect = self.image.get_rect(topleft=(x, y))
self.speed = 1
def update(self):
self.rect.y += self.speed
if self.rect.top >= HEIGHT:
self.rect.bottom = 0
class Volume(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((20, 140), pg.SRCALPHA)
self.rect = self.image.get_rect(center=(x, y))
self.radius = 10
self.x = self.y = self.radius
self.color_circle = (0, 255, 0, 128)
self.color_rect = (0, 180, 0, 128)
self.color_text = (255, 255, 255)
self.alpha = 255
self.volume = 1
def update(self):
self.image.set_alpha(self.alpha)
pg.draw.rect(
self.image, self.color_rect, [0, 0, *self.rect[2:]],
border_radius=self.radius)
pg.draw.circle(self.image, self.color_circle, (self.x, self.y), self.radius)
text = str(round(self.volume * 100))
text_rect = font.get_rect(text, size=11)
font.render_to(
self.image, (self.x - text_rect[2] / 2., self.y - text_rect[3] / 2.), text,
self.color_text, rotation=0, size=11)
sp = "\U0001F507" if self.volume == 0 else "\U0001F508" if self.volume < 0.2 \
else "\U0001F509" if self.volume < 0.7 else "\U0001F50A"
font.render_to(
screen, (self.rect.x, self.rect.y - font.size), sp, [*WHITE, self.alpha])
def render(self, e_buttons, e_pos):
if self.rect.left < e_pos[0] < self.rect.right and \
self.rect.top < e_pos[1] < self.rect.bottom and \
e_buttons:
self.y = abs(self.rect.top - e_pos[1])
if self.y > self.rect.h - self.radius:
self.y = self.rect.h - self.radius
elif self.y < self.radius:
self.y = self.radius
self.volume = (100 - (self.y - self.radius) / 1.2) / 100.
sound_car_accident.set_volume(self.volume)
sound_canister.set_volume(self.volume)
sound_accident.set_volume(self.volume)
class Speedometer(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
w, h = 150, 150
self.radius = 140
self.image = pg.Surface((w, h), pg.SRCALPHA)
self.rect = self.image.get_rect(bottomright=(WIDTH, HEIGHT))
font.render_to(self.image, (w - 50, h - 50), 'km/h', WHITE, size=20)
for deg in range(5, 84, 6):
length = 18 if deg == 5 or deg == 23 or deg == 41 or deg == 59 or deg == 77 else 10
cos = math.cos(math.radians(deg))
sin = math.sin(math.radians(deg))
pg.draw.line(
self.image, WHITE,
(w - self.radius * cos, h - self.radius * sin),
(w - (self.radius - length) * cos, h - (self.radius - length) * sin), 2)
for value, deg in enumerate(range(9, 78, 17)):
cos = math.cos(math.radians(deg))
sin = math.sin(math.radians(deg))
font.render_to(self.image, (
round(w - (self.radius - 30) * cos), round(h - (self.radius - 30) * sin)),
str(value * 100), WHITE, size=15)
def render(self):
s = 30 - player.for_speedometer() * 25 # from 4 to 80
pg.draw.line(
screen, RED, self.rect.bottomright,
(self.rect.right - (self.radius - 10) * math.cos(math.radians(s)),
self.rect.bottom - (self.radius - 10) * math.sin(math.radians(s))), 4)
pg.draw.circle(screen, WHITE, self.rect.bottomright, 25)
vol.update()
class Bullet(pg.sprite.Sprite):
def __init__(self):
super().__init__()
pygame.sprite.Sprite.__init__(self)
self.image = pg.image.load(os.path.join(path, 'img', 'bullet.png'))
self.image = pygame.Surface([4, 10])
self.image.fill(RED)
self.rect = self.image.get_rect()
def update(self):
self.rect.y -= 5
all_sprite = pg.sprite.LayeredUpdates()
cars_group = pg.sprite.Group()
canister_group = pg.sprite.Group()
bullet_list = pg.sprite.Group()
for r in range(2):
bg = Road(x=0, y=0)
all_sprite.add(Road(0, 0 if r == 0 else -HEIGHT), layer=0)
speedometer = Speedometer()
all_sprite.add(speedometer, layer=0)
player = Player()
list_x = []
n = 0
while n < 6:
car_x = random.randrange(80, WIDTH, 80)
if car_x in list_x:
continue
else:
list_x.append(car_x)
cars_group.add(Car(car_x, random.randint(
-cars[0].get_height() * 3, -cars[0].get_height()),
cars[n] if n < 3 else random.choice(cars)))
n += 1
fuel = Car(WIDTH - 80, 40, fuel_image)
canister = Car(0, 0, canister_image)
water = Car(0, 0, water_image)
vol = Volume(20, HEIGHT - 80)
all_sprite.add(*cars_group, layer=1)
all_sprite.add(player, layer=3)
all_sprite.add(fuel, layer=4)
all_sprite.add(vol, layer=4)
def my_record():
with open(record_file, 'r+') as d:
record = d.read()
if count[0] > int(record):
record = str(count[0])
d.seek(0)
d.truncate()
d.write(record)
return record
def home_screen(b):
screen.blit(all_sprite.get_sprite(0).image, (0, 0))
screen.blit(speedometer.image, speedometer.rect)
button_start.set_alpha(start)
button_stop.set_alpha(start)
screen.blit(button_start, button_start_rect)
screen.blit(button_stop, button_stop_rect)
font.render_to(screen, (48, 10), f'Record: {rec}', [
*RED, 255 if count[0] <= record_old else 255 if int(b) % 2 else 0], size=24)
font.render_to(screen, (48, 40), f'Points: {count[0]}', RED, size=24)
font.render_to(screen, (48, 70), f'Accidents: {car_accident}', RED, size=24)
vol.update()
screen.blit(vol.image, vol.rect)
rec = my_record()
record_old = int(rec)
game = True
while game:
for e in pg.event.get():
if e.type == pg.QUIT or e.type == pg.KEYDOWN and e.key == pg.K_ESCAPE:
game = False
elif e.type == pg.KEYDOWN and e.key == pg.K_p and start == 0:
pause.reverse()
if pause[0]:
pg.mouse.set_visible(True)
vol.alpha = 255
else:
pg.mouse.set_visible(False)
vol.alpha = 0
elif e.type == pg.MOUSEMOTION and (start == 255 or pause[0]):
vol.render(e.buttons[0], e.pos)
elif e.type == pg.KEYDOWN and e.key == pg.K_SPACE:
# Fire a bullet if the user clicks the space button
bullet = Bullet()
# Set the bullet so it is where the player is
bullet.rect.x = player.rect.x
bullet.rect.y = player.rect.y
# Add the bullet to the lists
cars_group.add(bullet)
bullet_list.add(bullet)
elif e.type == pg.MOUSEBUTTONDOWN and start == 255:
if e.button == 1:
if button_start_rect.collidepoint(e.pos):
player.angle = 0
player.velocity.x, player.velocity.y = 0, 0
player.position.x, player.position.y = WIDTH - 400, HEIGHT - 70
player.update()
all_sprite.remove_sprites_of_layer(2)
water.kill()
canister.kill()
for cr in cars_group:
cr.speed = random.randint(2, 3)
cr.rect.bottom = 0
level = 40
car_accident = 0
count[0] = 0
start -= 1
record_old = int(rec)
pg.mouse.set_visible(False)
elif button_stop_rect.collidepoint(e.pos):
game = False
elif e.type == u1_event and not pause[0] and not all_sprite.has(water): # water.alive():
all_sprite.add(water, layer=0)
water.rect.center = \
random.randrange(80, WIDTH, 80), -water.rect.h
timer1 = random.randrange(6000, 26001, 4000)
pg.time.set_timer(u1_event, timer1)
elif e.type == u2_event and not pause[0] and not canister_group.has(canister):
canister_group.add(canister)
all_sprite.add(canister, layer=0)
canister.rect.center = \
random.randrange(80, WIDTH, 80), -canister.rect.h
timer2 = random.randrange(13000, 28001, 5000)
pg.time.set_timer(u2_event, timer2)
# Calculate mechanics for each bullet
for bullet in bullet_list:
# See if it hit a block
block_hit_list = pygame.sprite.spritecollide(bullet, cars_group, True)
# For each block hit, remove the bullet and add to the score
for block in block_hit_list:
bullet_list.remove(bullet)
cars_group.remove(bullet)
hit = pg.sprite.spritecollideany(player, cars_group) # hit -> sprite car
if hit and hit.speed != 1:
player.position.x += 50 * random.randrange(-1, 2, 2)
player.angle = 50 * random.randrange(-1, 2, 2)
hit.speed = 1
car_alarm = Alarm()
all_sprite.add(car_alarm, layer=2)
car_alarm.rect.center = hit.rect.center
car_accident += 1
if car_accident > 10:
car_accident = 10
sound_car_accident.play()
if pg.sprite.spritecollide(player, canister_group, True):
level = 40
sound_canister.play()
if pg.sprite.collide_rect(player, water):
if not block:
player.angle = random.randint(60, 90) * random.randrange(-1, 2, 2)
sound_accident.play()
block = True
else:
block = False
if start > 0:
home_screen(blink)
blink = 0 if blink > 99 else blink + .02
if start != 255:
start -= 1
vol.alpha = start
else:
if not pause[0]:
level -= .01
if level < 0 or car_accident > 9:
rec = my_record()
pg.mouse.set_visible(True)
vol.alpha = start
elif level < 10:
rgb[:2] = 250, 0
elif level < 20:
rgb[0] = 250
else:
rgb[:2] = 0, 250
all_sprite.update()
else:
vol.update()
all_sprite.draw(screen)
pg.draw.rect(
screen, rgb,
(fuel.rect.left + 10, fuel.rect.bottom - level - 8, 21, level))
font.render_to(screen, (48, 10), f'accidents: {car_accident}', GREEN, size=24)
font.render_to(screen, (48, HEIGHT - 30), f'{count[0]}', GREEN, size=24)
speedometer.render() # speedometer
pg.display.update()
clock.tick(FPS)
pg.display.set_caption(f'Rally FPS: {int(clock.get_fps())}')
pygame.quit()
# pg.image.save(screen, 'road.jpg')
aos;dfihj ;aslkdjfh ;salkj
askl;fjas;lkfjd
a sdlfkj as;ldkfj as
asld;kj f;laskjd
asl;kjdf;lasjk f
sdla ;fjkas;ldkf j
asdlf jkasl;dkf j
asld flasdkjf ;
You are drawing all the Sprites in the all_sprites Group:
all_sprite.draw(screen)
However, t he bullets are not in this Group Either add the bullets to the all_sprites Group or draw the Sprites contained in the bullet_list Group.
Either
elif e.type == pg.KEYDOWN and e.key == pg.K_SPACE:
# [...]
bullet_list.add(bullet)
bullet_list.draw(screen)
or
bullet_list.draw(screen)
Remove the bullets form all Groups using kill():
for bullet in bullet_list:
# See if it hit a block
block_hit_list = pygame.sprite.spritecollide(bullet, cars_group, True)
# For each block hit, remove the bullet and add to the score
for block in block_hit_list:
bullet.kill()

What should I do in order to create multiple instances of enemies?

As a beginner, I am struggling to create multiple enemies in pygame. What could I possibly add or implement to my code in order to do so?
Code:
# WORK IN PROGRESS!
# I followed techwithtim's tutorial
# I do not own the images and sounds used in game
# TODO Create multiple Enemies
import pygame
import random
# Screen parameters
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("SPPACCE")
bg = pygame.image.load("bg.png")
font = pygame.font.SysFont('comicsans', 30, True)
clock = pygame.time.Clock()
score = 0
# Music & Sound effects
bulletsound = pygame.mixer.Sound('sounds/bullet_soundeffect.wav')
explosion = pygame.mixer.Sound('sounds/explosion_effect.wav')
explosion2 = pygame.mixer.Sound('sounds/torpedo_explosion.wav')
# Player parameters
class Player(object):
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.player_vel = 5
def draw(self, screen):
screen.blit(player_char, (self.x, self.y))
# Enemy parameters
class Enemy(object):
def __init__(self, x, y, height, width, end):
self.x = x
self.y = y
self.height = height
self.width = width
self.enemy_vel = 1.5
self.end = end
self.path = [self.x, self.end]
self.hitbox = (self.x + 17, self.y + 2, 65, 65)
self.health = 5
self.visible = True
def draw(self, screen):
self.move()
if self.visible:
self.hitbox = (self.x + 0, self.y, 65, 65)
pygame.draw.rect(screen, (255, 0, 0), self.hitbox, 2)
screen.blit(enemy_char, (self.x, self.y))
# Health bars
pygame.draw.rect(screen, (0, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65, 7))
pygame.draw.rect(screen, (255, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65 - (12 * (5 - self.health)), 7))
def move(self):
if self.enemy_vel > 0:
if self.x < self.path[1] + self.enemy_vel:
self.x += self.enemy_vel
else:
self.enemy_vel = self.enemy_vel * -1
self.x += self.enemy_vel
else:
if self.x > self.path[0] - self.enemy_vel:
self.x += self.enemy_vel
else:
self.enemy_vel = self.enemy_vel * -1
self.x += self.enemy_vel
def hit(self):
if self.health > 0:
self.health -= 1
else:
self.visible = False
explosion.play()
global score
score += 1
# Player Projectile parameters
class Projectile(object):
def __init__(self, x, y, color, radius):
self.x = x
self.y = y
self.color = color
self.radius = radius
self.vel = 12.5
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
# Images
player_char = pygame.image.load('sprites/hotdog.png')
enemy_char = pygame.image.load('sprites/hamburger.png')
def blit(): # This draws the sprites
player.draw(screen)
enemy.draw(screen)
for projectile in projectiles:
projectile.draw(screen)
score_text = font.render("Score: " + str(score), 1, (0, 109, 255))
version = font.render("Version 01 ", 1, (51, 153, 255))
screen.blit(score_text, (0, 0))
screen.blit(version, (520, 0))
shootloop = 0
if shootloop > 0:
shootloop += 1
if shootloop > 2:
shootloop = 0
player = Player(300, 400, 64, 64)
enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
enemy_count = random.randint(1, 10)
projectiles = []
run = True
while run:
clock.tick(60)
screen.fill((0, 0, 0))
screen.blit(bg, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Movement keys with playeborders
keys = pygame.key.get_pressed()
if keys[pygame.K_s] and player.y < 480 - player.height - player.player_vel:
player.y += player.player_vel
if keys[pygame.K_w] and player.y > 280:
player.y -= player.player_vel
if keys[pygame.K_d] and player.x < 640 - player.width - player.player_vel:
player.x += player.player_vel
if keys[pygame.K_a] and player.x > player.player_vel:
player.x -= player.player_vel
for projectile in projectiles:
if projectile.y - projectile.radius < enemy.hitbox[1] + enemy.hitbox[3] and projectile.y + projectile.radius > enemy.hitbox[1]:
if enemy.visible == True:
if projectile.x + projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0] + enemy.hitbox[2]:
enemy.hit()
explosion2.play()
projectiles.pop(projectiles.index(projectile))
if projectile.y < 640 and projectile.y > 0:
projectile.y -= projectile.vel
else:
projectiles.pop(projectiles.index(projectile))
# Player shooting
if keys[pygame.K_SPACE] and shootloop == 0:
if len(projectiles) < 1:
projectiles.append(Projectile(round(player.x + player.width //2),
round(player.y + player.height //2), [255, 150, 0], 7))
blit()
pygame.display.update()
I tried to recycle code from my last game project, but it doesn't work because the code structures are way too different from each other. This project is OOP meanwhile the last one has scattered variables.
Similar to your projectiles make a list of Enemy objects:
enemies = []
enemy_count = random.randint(3, 10)
for i in range( enemy_count ):
new_enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
enemies.append( new_enemy )
projectiles = []
Update your blit() to draw a list of enemies:
def blit(): # This draws the sprites
player.draw(screen)
for enemy in enemies:
enemy.draw(screen)
for projectile in projectiles:
projectile.draw(screen)
score_text = font.render("Score: " + str(score), 1, (0, 109, 255))
version = font.render("Version 01 ", 1, (51, 153, 255))
screen.blit(score_text, (0, 0))
screen.blit(version, (520, 0))
And check them all for collisions:
for enemy in enemies:
for projectile in projectiles:
if projectile.y - projectile.radius < enemy.hitbox[1] + enemy.hitbox[3] and projectile.y + projectile.radius > enemy.hitbox[1]:
if enemy.visible == True:
if projectile.x + projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0] + enemy.hitbox[2]:
enemy.hit()
explosion2.play()
projectiles.pop(projectiles.index(projectile))
That should get you started.
The changes are relatively simple because you already have the data compartmentalised in objects. Good job.
EDIT: Re-spawning an enemy is simply a matter of adding another Enemy object to the enemies list:
new_enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
enemies.append( new_enemy )

Object to shoot a projectile

I'm trying to make my tanks shoot, and I did all the code I think I should have done but I don't know why the tanks aren't shooting anything.
import pygame, assetloader
from pygame.locals import *
import random, time, math
import pygame
GRAD = math.pi/180
blue = (0, 0, 255)
wallRects = []
bullets = []
maze = [[] for i in range(25)]
assetloader.set_asset_path("assets/")
I defined the Bullet Class here:
def calculate_dir_with_angle(angle):
direction = [0, 0]
if (angle > 0 and angle < 180) or (angle > -360 and angle < -180):
direction[0] = -1
elif (angle > -180 and angle < 0) or (angle > 180 and angle < 360):
direction[0] = 1
elif (angle > -90 and angle < 90) or (angle > 270 and anlge < 360):
direction[1] = -1
elif (angle > 90 and angle < 270) or (angle > -270 and angle < -90):
direction[1] = 1
return direction
class Bullet:
def __init__(self, pos, r, angle):
self.x = pos[0]
self.y = pos[1]
self.r = r
self.counter = 50
direction = calculate_dir_with_angle(angle)
self.vel = [direction[0] * 2, direction[1] * 2]
def draw(self, screen):
self.x = int(self.x)
self.y = int(self.y)
pygame.draw.circle(screen, (25, 25, 25), (self.x, self.y), (self.r))
def move(self):
self.x += self.vel[0]
self.y += self.vel[1]
self.rect = pygame.Rect(self.x-self.r, self.y - self.r, 2 * self.r, 2 * self.r)
for wr in wallRects:
if self.rect.centery >= wr.top and self.rect.centery <= wr.bottom:
if self.rect.left <= wr.right and self.rect.left > wr.left:
self.vel[0] = -self.vel[0]
self.x = wr.right + self.r + 1
self.rect.x = wr.right + 1
elif self.rect.right >= wr.left and self.rect.right < wr.right:
self.vel[0] = -self.vel[0]
self.x = wr.left + self.r - 1
self.rect.x = wr.left - 2 * self.r - 1
if self.rect.centerx >= wr.left and self.rect.centerx <= wr.right:
if self.rect.top <= wr.bottom and self.rect.top > wr.top:
self.vel[1] = -self.vel[1]
self.y = wr.bottom + self.r + 1
self.rect.y = wr.bottom + 1
elif self.rect.bottom >= wr.top and self.rect.bottom < wr.bottom:
self.vel[1] = -self.vel[1]
self.y = wr.top - self.r - 1
self.rect.y = wr.top - 2 * self.r - 1
if self.counter > 0:
self.counter -= 1
def generateRandomPosition():
row = random.randint(1, 23)
col = random.randint(1, 23)
while maze[row][col-1] != 0 or maze[row][col] != 0 or maze[row][col+1] != 0:
row = random.randint(1, 23)
col = random.randint(1, 23)
return row, col
Player 1:
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, pos):
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = assetloader.load_image("Tank.png", -1)
self.rect.x = x
self.rect.y = y
self.rect.clamp_ip(screen.get_rect())
self.rows = pos[0]
self.cols = pos[1]
self.x = self.cols * gsize
self.y = self.rows * gsize
self.orig_image, self.orig_rect = assetloader.load_image("Tank.png", -1)
self.orig_rect.x = self.x
self.orig_rect.y = self.y
self.orig_gun_pos = self.orig_rect.midtop
self.ammo = 5
def checkCollisions(self):
for b in bullets:
if b.counter <= 0:
if b.rect.colliderect(self.orig_rect):
self.dead = True
def calculate_gun_pos(self):
self.orig_gun_pos = self.orig_rect.midtop
new_y = self.orig_gun_pos[1] - self.orig_rect.centery
new_x = self.orig_gun_pos[0] - self.orig_rect.centerx
rads = self.dir * GRAD
gun_x = (new_y * math.sin(rads)) + (new_x * math.cos(rads)) + (self.orig_rect.centerx)
gun_y = (new_y * math.cos(rads)) - (new_x * math.sin(rads)) + (self.orig_rect.centery)
self.gun_pos = (gun_x, gun_y)
def shoot(self):
if self.ammo > 0:
self.calculate_gun_pos()
b = Bullet(self.gun_pos, 3, self.dir)
bullets.append(b)
self.ammo -= 1
def draw(self, screen):
image = pygame.transform.rotate(self.image, self.dir)
screen.blit(image, self.rect)
def update(self):
oldCenter = self.rect.center
self.rect = self.image.get_rect()
self.rect.center = oldCenter
screen_rect = screen.get_rect()
keys = pygame.key.get_pressed()
if keys[K_m]:
p.shoot()
if not screen_rect.contains(self.rect):
self.rect.clamp_ip(screen_rect)
Calling the functions:
size = width, height = 500, 400
gsize = 25
start_x, start_y = 0, 0
bgColor = 255, 255, 255
pygame.init()
screen = pygame.display.set_mode(size)#, pygame.FULLSCREEN)
pygame.display.set_caption("Sample Sprite")
clock = pygame.time.Clock()
p = Player(width/2, height/4, (3,4))
coll_font = pygame.font.Font(None, 30)
going = True
while going:
clock.tick(60)
for event in pygame.event.get():
if event.type == QUIT:
going = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
going = False
elif event.type == KEYDOWN:
if event.key == K_m:
p.shoot()
for b in bullets:
b.move()
p.update()
screen.fill(bgColor)
p.draw(screen)
pygame.display.flip()
pygame.quit()
How would I call the bullet to actually appear and fire because I have the Bullet class which gets called within the Player class in def shoot(self) so does anyone have an idea why the bullets aren't appearing?
I usually add bullets in this way: I pass the group that contains all sprites and the bullet group to the player instance and add new bullets to these group in the player's handle_event method.
import pygame as pg
from pygame.math import Vector2
pg.init()
screen = pg.display.set_mode((640, 480))
screen_rect = screen.get_rect()
FONT = pg.font.Font(None, 24)
BG_COLOR = pg.Color('gray12')
BULLET_IMAGE = pg.Surface((20, 11), pg.SRCALPHA)
pg.draw.polygon(
BULLET_IMAGE, pg.Color('aquamarine1'), [(0, 0), (20, 5), (0, 11)])
PLAYER_IMAGE = pg.Surface((50, 30), pg.SRCALPHA)
pg.draw.polygon(
PLAYER_IMAGE, pg.Color('dodgerblue1'), [(0, 0), (50, 15), (0, 30)])
class Player(pg.sprite.Sprite):
def __init__(self, pos, all_sprites, bullet_group):
super().__init__()
self.image = PLAYER_IMAGE
self.orig_image = self.image # Needed to preserve image quality.
self.rect = self.image.get_rect(center=(pos))
self.pos = Vector2(pos)
self.vel = Vector2(1, 0)
self.angle = 0
self.angle_speed = 0
self.all_sprites = all_sprites
self.bullet_group = bullet_group
def handle_event(self, event):
if event.type == pg.MOUSEBUTTONDOWN:
# Left button fires a bullet from cannon center with
# current angle. Add the bullet to the bullet_group.
if event.button == 1:
bullet = Bullet(self.pos, self.angle)
self.bullet_group.add(bullet)
self.all_sprites.add(bullet)
elif event.type == pg.KEYDOWN:
# Rotate self by setting the .angle_speed.
if event.key in (pg.K_a, pg.K_LEFT):
self.angle_speed = -3
elif event.key in (pg.K_d, pg.K_RIGHT):
self.angle_speed = 3
elif event.type == pg.KEYUP:
if event.key in (pg.K_a, pg.K_LEFT):
self.angle_speed = 0
elif event.key in (pg.K_d, pg.K_RIGHT):
self.angle_speed = 0
def update(self):
self.pos += self.vel
self.rect.center = self.pos
if self.angle_speed != 0:
self.rotate()
def rotate(self):
# Update the angle and the velocity vector.
self.angle += self.angle_speed
self.vel.rotate_ip(self.angle_speed)
# Rotate the image and get a new rect with the previous center.
self.image = pg.transform.rotozoom(self.orig_image, -self.angle, 1)
self.rect = self.image.get_rect(center=self.rect.center)
class Bullet(pg.sprite.Sprite):
def __init__(self, pos, angle):
super().__init__()
self.image = pg.transform.rotate(BULLET_IMAGE, -angle)
self.rect = self.image.get_rect(center=pos)
# To apply an offset (40 pixels) to the start position,
# create another vector and rotate it as well.
offset = Vector2(40, 0).rotate(angle)
# Add the offset vector to the position vector (the center).
self.pos = Vector2(pos) + offset
# Rotate the start velocity vector (9, 0) by the angle.
self.vel = Vector2(9, 0).rotate(angle)
def update(self):
# Add the velocity to the pos to move the sprite.
self.pos += self.vel
self.rect.center = self.pos # Update the rect as well.
# Remove bullets outside of the screen area.
if not screen_rect.contains(self.rect):
self.kill()
def main():
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
# Bullets will be added to this group.
bullet_group = pg.sprite.Group()
# Pass the bullet group to the player.
player = Player((300, 200), all_sprites, bullet_group)
all_sprites.add(player)
playing = True
while playing:
for event in pg.event.get():
if event.type == pg.QUIT:
playing = False
# Pass events to the player instance.
player.handle_event(event)
all_sprites.update()
screen.fill(BG_COLOR)
all_sprites.draw(screen)
pg.display.update()
clock.tick(30)
if __name__ == '__main__':
main()
pg.quit()

adding a def main to the end of my pong game code

I'm trying to add a def main to the end of my pong game to make it easier to read, but i've ran into problems trying to do that. When I add the def main, I just get a black screen, but without it I get the whole game.
import pygame
SCR_WID, SCR_HEI = 640, 480
class Player():
def __init__(self):
self.x, self.y = 16, SCR_HEI/2
self.speed = 3
self.padWid, self.padHei = 8, 64
self.score = 0
self.scoreFont = pygame.font.Font("imagine_font.ttf", 64)
def scoring(self):
scoreBlit = self.scoreFont.render(str(self.score), 1, (255, 255, 255))
screen.blit(scoreBlit, (32, 16))
if self.score == 10:
print ("player 1 wins!")
exit()
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.y -= self.speed
elif keys[pygame.K_s]:
self.y += self.speed
if self.y <= 0:
self.y = 0
elif self.y >= SCR_HEI-64:
self.y = SCR_HEI-64
def draw(self):
pygame.draw.rect(screen, (255, 255, 255), (self.x, self.y, self.padWid, self.padHei))
class Enemy(Player):
def __init__(self):
self.x, self.y = SCR_WID-16, SCR_HEI/2
self.speed = 3
self.padWid, self.padHei = 8, 64
self.score = 0
self.scoreFont = pygame.font.Font("imagine_font.ttf", 64)
def scoring(self):
scoreBlit = self.scoreFont.render(str(self.score), 1, (255, 255, 255))
screen.blit(scoreBlit, (SCR_HEI+92, 16))
if self.score == 10:
print ("Player 2 wins!")
exit()
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
self.y -= self.speed
elif keys[pygame.K_DOWN]:
self.y += self.speed
if self.y <= 0:
self.y = 0
elif self.y >= SCR_HEI-64:
self.y = SCR_HEI-64
def draw(self):
pygame.draw.rect(screen, (255, 255, 255), (self.x, self.y, self.padWid, self.padHei))
class Ball():
def __init__(self):
self.x, self.y = SCR_WID/2, SCR_HEI/2
self.speed_x = -3
self.speed_y = 3
self.size = 8
def movement(self):
self.x += self.speed_x
self.y += self.speed_y
#wall col
if self.y <= 0:
self.speed_y *= -1
elif self.y >= SCR_HEI-self.size:
self.speed_y *= -1
if self.x <= 0:
self.__init__()
enemy.score += 1
elif self.x >= SCR_WID-self.size:
self.__init__()
self.speed_x = 3
player.score += 1
##wall col
#paddle col
#player
for n in range(-self.size, player.padHei):
if self.y == player.y + n:
if self.x <= player.x + player.padWid:
self.speed_x *= -1
break
n += 1
#enemy
for n in range(-self.size, enemy.padHei):
if self.y == enemy.y + n:
if self.x >= enemy.x - enemy.padWid:
self.speed_x *= -1
break
n += 1
##paddle col
def draw(self):
pygame.draw.rect(screen, (255, 255, 255), (self.x, self.y, 8, 8))
SCR_WID, SCR_HEI = 640, 480
screen = pygame.display.set_mode((SCR_WID, SCR_HEI))
pygame.display.set_caption("Pong")
pygame.font.init()
clock = pygame.time.Clock()
FPS = 60
def main():
ball = Ball()
player = Player()
enemy = Enemy()
while True:
#process
for event in pygame.event.get():
if event.type == pygame.QUIT:
print ("Game exited by user")
exit()
##process
#logic
ball.movement()
player.movement()
enemy.movement()
##logic
#draw
screen.fill((0, 0, 0))
ball.draw()
player.draw()
player.scoring()
enemy.draw()
enemy.scoring()
##draw
#_______
pygame.display.flip()
clock.tick(FPS)
main()
The call for main() on the end should be
if __name__ == "__main__":
main()
So that you can run your code and get the function to run. Also your indentation seems a little off. Is your code structured correctly with regard to spaces?
As already answered, you should insert the following statement at the end of the script:
if __name__ == "__main__":
main()
This answer will give you more info about the meaning of that statement.
What does if __name__ == "__main__": do?
In short, it tells the interpreter what it has to do with the function main():
1) Run it automatically if the file has been executed as stand alone script.
2) Don't run if the file has been imported as module from another script.
In your case, the wanted behaviour is the number one.

Categories