Why are the trees not displaying? - python

I want to add the tree sprite to the sprite group named tree_group
I expect the distance of the trees spawning is calculated like this: if 800 - (tree.x + TREE_HEIGHT) > Tree.get_distance(score): tree_group.draw(tree)
For some reason, the trees are not appearing and I believe that this is because the tree sprite is not in the group yet, that is why I want to use the add() function.
I want the draw_display function to iterate over all the trees currently on the screen and move them using the get_speed equation.
My code is this:
import pygame
import sys
import random
import os
import time
from pygame.event import post
# initializes pygame libraries
pygame.init()
pygame.font.init()
pygame.mixer.init()
score = 0
FPS = 60
VEL = 5
# region | main window attributes and background
WIDTH, HEIGHT = 800, 800
display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Ski Game")
BACKGROUND = pygame.transform.scale(pygame.image.load(os.path.join("background.jpg")), (WIDTH, HEIGHT))
# endregion
# region | fonts and colors
SCORE_FONT = pygame.font.SysFont('comicsans', 40)
GAME_OVER_FONT = pygame.font.SysFont('comicsans', 100)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# endregion
# region | linking sprites and resizing then
SKIER_WIDTH = 65
SKIER_HEIGHT = 105
SKIER = pygame.transform.scale(pygame.image.load(
os.path.join("skier.png")), (SKIER_WIDTH, SKIER_HEIGHT))
# endregion
clock = pygame.time.Clock()
done = False
# create a custom event
CRASH_TREE = pygame.USEREVENT + 1
def draw_display(score, skier):
# blits the background
display.blit(BACKGROUND, (0, 0))
score_text = SCORE_FONT.render("Score: " + str(score), 1, BLACK)
display.blit(score_text, (WIDTH / 2 - score_text.get_width()/2, 10))
# blit skier
display.blit(SKIER, (skier.x, skier.y))
# blit trees
tree = Tree(score)
tree_group = pygame.sprite.Group()
tree_group.draw(display)
if score == 0:
tree_group.add(tree)
score += 1
elif 800 - (tree.rect.x + 150) > tree.get_distance(score):
tree_group.add(tree)
score += 1
pygame.display.update()
class Tree(pygame.sprite.Sprite):
def __init__(self, score):
super().__init__()
self.TREE_WIDTH = 80
self.TREE_HEIGHT = 150
self.image = pygame.transform.scale(pygame.image.load(os.path.join("tree.png")), (self.TREE_WIDTH, self.TREE_HEIGHT))
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0, WIDTH)
self.rect.y = 700
print("init")
def get_speed(self, score, base=2, interval=10, multiplier=0.05):
return base + ((score//interval) * multiplier)
def get_distance(self, score, base=100, interval=10, multiplier=5):
return base + ((score//interval) * multiplier)
def update(self):
self.rect.y -= self.get_speed(score)
print("update")
def handle_skier_movement(keys_pressed, skier):
if keys_pressed[pygame.K_LEFT] and skier.x - VEL > 0: # LEFT
skier.x -= VEL
if keys_pressed[pygame.K_RIGHT] and skier.x + VEL + skier.width < WIDTH: # RIGHT
skier.x += VEL
if keys_pressed[pygame.K_UP] and skier.y - VEL > 0: # UP
skier.y -= VEL
if keys_pressed[pygame.K_DOWN] and skier.y + VEL + skier.width < WIDTH: # DOWN
skier.y += VEL
def game_over():
game_over_text = GAME_OVER_FONT.render("GAME OVER", 1, BLACK)
display.blit(game_over_text, (WIDTH/2 - game_over_text.get_width() /
2, HEIGHT/2 - game_over_text.get_height()/2))
pygame.display.update()
pygame.time.delay(5000)
def main():
skier = pygame.Rect(700, 300, SKIER_WIDTH, SKIER_HEIGHT)
score = 0
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
keys_pressed = pygame.key.get_pressed()
handle_skier_movement(keys_pressed, skier)
draw_display(score, skier)
tree = Tree(score)
tree.update()
if event.type == CRASH_TREE:
game_over()
score = 0
break
if __name__ == "__main__":
main()

In your draw_display function, you are first drawing the group and then adding the elements. That way, you are only drawing an empty group, and thus nothing happens. You should therefore place the tree_group.draw(display) line after the elif statement, right before pygame.display.update() line.

Related

Why does the text not render on canvas Pygame

So I'm working on a pong copy using pygame. So far everything was working fine with pygame and everything was rendering. I wanted to add the player score to the screen, and I can't get it up. I'm not actually familiar with pygame that much so I pretty muched copied the text code from the docs and other sources. However they would not render, but when I opened a standalone, python file, it worked fine. Here is my main.py file where I render text and a link to the demo using replit: https://replit.com/#Glitchez/Pong-demo?v=1
import pygame
from paddles import *
from controls import *
from ball import *
pygame.font.init()
# SCREEN INIT
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pong")
# VARIABLES
ball_radius = 7
paddle_speed = 5
paddle_length = 100
FPS = 60
# DEFINE OBJECTS
paddle1 = Paddle(paddle_length, 15, 100, paddle_speed, True, WHITE)
paddle2 = Paddle(paddle_length, 970, 100, paddle_speed, False, WHITE)
ball = Ball(WIDTH // 2, HEIGHT // 2, ball_radius)
font = pygame.font.SysFont(None, 24)
# COLLISION MANAGEMENT
def handle_collision(ball, paddle1, paddle2):
if ball.y + ball.radius >= HEIGHT:
ball.y_vel *= -1
elif ball.y - ball.radius <= 0:
ball.y_vel *= -1
if ball.x_vel < 0:
if paddle1.y <= ball.y <= paddle1.y + paddle1.height:
if ball.x - ball.radius <= paddle1.x + paddle1.width:
ball.x_vel *= -1
middle_y = paddle1.y + paddle1.height / 2
difference_in_y = middle_y - ball.y
reduction_factor = (paddle1.height / 2) / ball.MAX_VEL
y_vel = difference_in_y / reduction_factor
ball.y_vel = -1 * y_vel
else:
if paddle2.y <= ball.y <= paddle2.y + paddle2.height:
if ball.x + ball.radius >= paddle2.x:
ball.x_vel *= -1
middle_y = paddle2.y + paddle2.height / 2
difference_in_y = middle_y - ball.y
reduction_factor = (paddle2.height / 2) / ball.MAX_VEL
y_vel = difference_in_y / reduction_factor
ball.y_vel = -1 * y_vel
# HANDLE ALL GRAPHICS
def graphics(screen):
screen.fill(BLACK)
paddle1.draw(screen)
paddle2.draw(screen)
ball.draw(screen)
# DRAWS DOTTED LINE
for i in range(10, HEIGHT, HEIGHT // 20):
if i % 2 == 1:
continue
pygame.draw.rect(screen, WHITE, (WIDTH // 2 - 5, i, 8, HEIGHT // 40))
# GAME LOOP
def main():
run = True
clock = pygame.time.Clock()
P1_SCORE, P2_SCORE = 0, 0
#ISSUE HERE!!!
my_font = pygame.font.SysFont('Comic Sans MS', 30)
text_surface = my_font.render(str(P1_SCORE), False, (255, 255, 255))
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win.blit(text_surface, (250,250))
paddle1.move()
paddle2.move()
ball.move()
handle_collision(ball, paddle1, paddle2)
P1_SCORE, P2_SCORE = ball.check_win(P1_SCORE, P2_SCORE)
graphics(win)
pygame.display.update()
print(f"player 1: {P1_SCORE}, player 2: {P2_SCORE}")
pygame.quit()
if __name__ == '__main__':
main()
The code is rendering the score correctly, blit()ing it to the window perfectly... but then erasing everything when the screen is painted in graphics().
So, you have a function graphics(), move the score-drawing into there.
# HANDLE ALL GRAPHICS
def graphics(screen, font, p1_score, p2_score):
screen.fill(BLACK)
paddle1.draw(screen)
paddle2.draw(screen)
ball.draw(screen)
# DRAWS DOTTED LINE
for i in range(10, HEIGHT, HEIGHT // 20):
if i % 2 == 1:
continue
pygame.draw.rect(screen, WHITE, (WIDTH // 2 - 5, i, 8, HEIGHT // 40))
# DRAWS THE SCORE
# PLAYER 1 (LEFT)
text_surface = my_font.render(str(p1_score), False, (255, 255, 255))
screen.blit(text_surface, (250,250))
# PLAYER 2 (RIGHT)
text_surface = my_font.render(str(p2_score), False, (255, 255, 255))
screen.blit(text_surface, (WIDTH-WIDTH//4,250)) # 25% from the right-side
# GAME LOOP
def main():
run = True
clock = pygame.time.Clock()
P1_SCORE, P2_SCORE = 0, 0
my_font = pygame.font.SysFont('Comic Sans MS', 30)
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
paddle1.move()
paddle2.move()
ball.move()
handle_collision(ball, paddle1, paddle2)
P1_SCORE, P2_SCORE = ball.check_win(P1_SCORE, P2_SCORE)
graphics(win, my_font, P1_SCORE, P2_SCORE)
pygame.display.update()
print(f"player 1: {P1_SCORE}, player 2: {P2_SCORE}")
pygame.quit()
NOTE: This is not tested code, errors and omissions should be expected.
If the text-rendering becomes slow, you could also pre-render all the scores to an array of surfaces on start-up. Then just blit the one that matches the score.

Pygame, restarting game results in program closing

I know this question has been asked before but I'v tried different approaches and I can't seem to be able to fix it.
I know I have to reset my important global variables in order to correctly restart the game.
The reset of those variables is done when lives == 0 -> I reset the global variables, main menu becomes True and Game False which should put me back in the main menu.
However when I run my game, as soon as the lives reach 0 the code finishes and exits -> Process finished with exit code 0.
The issue must be in my while game loop but I'm unsure what I'm doing wrong.
I'v also tried wrapping my game logic in a function, this seems to mess with my game since I only get the frozen state screen, no enemy spawning and not able to move.
Any ideas what might cause this issue?
Full code:
import pygame
import pygame_gui
import random
# Initialize game window here
pygame.init()
# Variables for the game window
window = pygame.display.set_mode((800, 800))
manager = pygame_gui.UIManager((800, 800))
pygame.display.set_caption('Sea Invaders')
clock = pygame.time.Clock() # Adds the clock for spawn timers
score_font = pygame.font.SysFont('Calibri', 36)
multiplier_font = pygame.font.SysFont('Calibri', 18)
# Sprites, background, UI and music
background = pygame.image.load('Background.jpg')
whale_sprite = pygame.image.load('Whale.png')
speedboat_sprite = pygame.image.load('Speedboat.png')
beam_sprite = pygame.image.load('Beam.png')
life_sprite = pygame.image.load('Life.png')
pirate_boss_sprite_right = pygame.image.load('Pirateboss_right.png')
game_title = pygame_gui.elements.UILabel(relative_rect=pygame.Rect((200, 100), (400, 100)), text='SEA INVADERS',
manager=manager)
description_box = pygame_gui.elements.UILabel(relative_rect=pygame.Rect((150, 250), (500, 100)),
text='Protect the ocean as long as possible by destroying ships',
manager=manager)
start_button = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((350, 400), (100, 50)), text='Start',
manager=manager)
quit_button = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((350, 450), (100, 50)), text='Quit',
manager=manager)
# Classes
class Player():
def __init__(self, x, y, width, height):
# Variables for the Whale go here
self.x = x
self.y = y
self.width = width
self.height = height
self.mov_speed = 5
self.hitbox = (self.x, self.y, self.width, self.height)
def draw(self, window):
# This function draws the whale using the sprite and the defined location in the class parameters
window.blit(whale_sprite, (self.x, self.y))
self.hitbox = (self.x, self.y, self.width, self.height)
# Whale hitbox check
# pygame.draw.rect(window, (255, 0, 0), self.hitbox, 2)
class Enemy(pygame.sprite.Sprite):
def __init__(self, width, height, mov_speed):
# Variables for the various enemies
pygame.sprite.Sprite.__init__(self)
self.width = width
self.height = height
self.mov_speed = mov_speed
self.image = speedboat_sprite
self.rect = self.image.get_rect()
self.rect.x = random.randint(64, 734)
self.rect.y = random.randrange(-150, -100)
self.hitbox = (self.rect.x + 22, self.rect.y + 15, 19, 45)
self.alive = True
def update(self):
# This function lets the enemy go forward until the end of the screen
max_distance = 800 - self.height
if self.rect.y < max_distance:
self.rect.y += self.mov_speed
def hit(self):
# This function deletes the sprite from the sprite group when hit by an attack from a player
self.kill()
self.alive = False
class Boss():
def __init__(self, x, y, width, height, mov_speed, hitpoints):
# Variables for the boss objects
self.x = x
self.y = y
self.width = width
self.height = height
self.mov_speed = mov_speed
self.hitpoints = hitpoints
self.hitbox = (self.x + 30, self.y + 50, 225, 160) # Dimensions of the hitbox to make it close to the model
self.alive = False
self.killed = False
self.end_reached = False
def draw(self, window):
if self.alive and not self.killed:
window.blit(pirate_boss_sprite_right, (self.x, self.y))
self.hitbox = (self.x + 30, self.y + 50, 225, 160)
pygame.draw.rect(window, (255, 0, 0),
(self.x + ((self.width / 2) - (self.hitpoints / 2)), self.y + 220, 50, 10))
pygame.draw.rect(window, (0, 255, 0),
(self.x + ((self.width / 2) - (self.hitpoints / 2)), self.y + 220, self.hitpoints, 10))
# Pirate Boss hitbox check
# pygame.draw.rect(window, (255, 0, 0), self.hitbox, 2)
def move(self):
# This function moves the boss forward. As soon as the boss reaches the end it spawns lower on the screen.
# If the end is reached the model is deleted and the end_reached parameter is set tot True.
max_distance = 800 - self.height
if self.x < (800 + self.width):
self.x += self.mov_speed
else:
self.y += 100
self.x = -51
if self.y >= max_distance:
self.alive = False
self.end_reached = True
def hit(self):
# As soon as the Whale hitpoints reaches 0, the model is overwritten on screen.
if self.hitpoints <= 0:
self.killed = True
return True
class Projectile():
def __init__(self, x, y, width, height, speed, damage, image):
# Variables for the player attacks (ranged)
self.x = x
self.y = y
self.width = width
self.height = height
self.speed = speed
self.damage = damage
self.image = image
self.rect = self.image.get_rect()
def draw(self, window):
window.blit(self.image, (self.x, self.y))
def checkCollision(self, enemy):
# This function checks collision with enemies that belong to a Sprite Group.
self.rect.x = int(self.x)
self.rect.y = int(self.y)
# noinspection PyTypeChecker
return any(pygame.sprite.spritecollide(self, enemy, True))
class Hud():
# class to place the HUDS on the screen (lives, score)
def __init__(self, x, y, sprite):
self.x = x
self.y = y
self.sprite = sprite
def draw(self, window):
window.blit(self.sprite, (self.x, self.y))
# Methods
def redrawUI():
window.blit(background, (0, 0)) # Loads in the background
whale.draw(window) # Draws the Whale in the game
window.blit(speedboat_sprite, (100, 100))
window.blit(speedboat_sprite, (620, 100))
manager.draw_ui(window)
if lives == 0:
text = f'Game over! Your score: {score}.'
game_over = score_font.render(text, True, (0, 0, 0))
window.blit(game_over, (200, 200))
pygame.display.update()
def redrawGameWindow():
window.blit(background, (0, 0)) # Loads in the background
whale.draw(window) # Draws the Whale in the game
scoreboard = score_font.render(str(score), True, (255, 255, 255))
multiplier_message = multiplier_font.render(f'multiplier: {multiplier}', True, (255, 255, 255))
window.blit(scoreboard, (700, 760))
window.blit(multiplier_message, (85, 766))
x_life = 0
# This for loop places the lives next to eachother on the HUD
for life in range(lives):
life = Hud(x_life, 760, life_sprite)
x_life += 25
life.draw(window)
for b in bosses:
b.alive = True
b.draw(window)
b.move()
speedboats.draw(window)
speedboats.update()
for fired_beam in beams:
fired_beam.draw(window)
pygame.display.update() # This updates the above changes to the game window
# Game logic here
main_menu = True
game = False
FPS = 100
whale = Player(334, 650, 128, 128) # Spawns the Player at the start of the game in the middle of the screen
speedboat_locations = (125, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800)
speedboats = pygame.sprite.Group()
bosses = []
beams = []
cooldown = 0
lives = 3
score = 0
speedboat_hits = 0
multiplier = 1
start = pygame.time.get_ticks()
while main_menu:
time_delta = clock.tick(60) / 1000.0
for event in pygame.event.get(): # this for-loop makes sure the game exits when clicking x
if event.type == pygame.QUIT:
main_menu = False
if event.type == pygame.USEREVENT:
if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
if event.ui_element == start_button:
game = True
main_menu = False
if event.ui_element == quit_button:
main_menu = False
manager.process_events(event)
manager.update(time_delta)
redrawUI()
while game:
for event in pygame.event.get(): # this for-loop makes sure the game exits when clicking x
if event.type == pygame.QUIT:
game = False
# Life check
for speedboat in speedboats:
if speedboat.rect.y >= 734:
speedboat.kill()
lives -= 1
if not speedboat.alive:
speedboats.remove(speedboat)
for pirate_boss in bosses:
if pirate_boss.end_reached and not pirate_boss.killed:
lives = 0
if lives == 0:
whale = Player(334, 650, 128, 128) # Spawns the Player at the start of the game in the middle of the screen
speedboat_locations = (125, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800)
speedboats = pygame.sprite.Group()
bosses = []
beams = []
cooldown = 0
lives = 3
score = 0
speedboat_hits = 0
multiplier = 1
main_menu = True
game = False
# Basic cooldown for the projectiles of the player
if cooldown > 0:
cooldown += 1
if cooldown > 50:
cooldown = 0
# Collision of attacks
for beam in beams:
if beam.checkCollision(speedboats):
speedboat_hits += 1
score += (25 * multiplier)
beams.pop(beams.index(beam))
for pirate_boss in bosses:
if pirate_boss.alive and not pirate_boss.killed:
if beam.y - beam.width < pirate_boss.hitbox[1] + pirate_boss.hitbox[3] and beam.y + beam.width > \
pirate_boss.hitbox[1]:
if beam.x + beam.height > pirate_boss.hitbox[0] and beam.x - beam.height < pirate_boss.hitbox[0] + \
pirate_boss.hitbox[2]:
pirate_boss.hitpoints -= beam.damage
beams.pop(beams.index(beam))
alive_check = pirate_boss.hit()
if alive_check:
multiplier += 1
bosses.remove(pirate_boss)
if beam.y > 0:
beam.y -= beam.speed # This makes sure the bullet moves forward as long as it is not of the screen
beam.rect.center = (beam.x, beam.y)
else:
beams.pop(beams.index(beam)) # If the bullet goes of the screen it gets removed from the list
# --- PLAYER CONTROLS ---
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and whale.x > whale.mov_speed:
# Makes sure the whale can move left
# and prevents the whale from exiting the screen
whale.x = whale.x - whale.mov_speed
if keys[pygame.K_RIGHT] and whale.x < 800 - whale.mov_speed - whale.width:
# Makes sure the whale can move right
# and prevents the whale from exiting the screen
whale.x = whale.x + whale.mov_speed
if keys[pygame.K_SPACE] and cooldown == 0:
# This block of code takes care of the beam-projectile the player can shoot
if len(beams) < 3:
beams.append(
Projectile(round(whale.x + (whale.width // 2) - (32 // 2)), round(whale.y - (32 // 2)), 32, 32, 2,
10, beam_sprite))
# The beam gets spawned at the whale X/Y Coordinate. To make the beam appear in the middle and at the
# nose we add half the sprites width - half the width of the projectile to the for the x coordinate
# and we use the y coordinate - half the length of the projectile to make the attack spawn at the top
cooldown = 1
# --- ENEMY SPAWNING ---
now = pygame.time.get_ticks()
spawn_time = 3000
speedboat = Enemy(64, 64, 1)
boss = Boss(1, 1, 256, 256, 1, 50)
# Game loop to increase difficulty
if score > 500:
spawn_time = 2000
if score > 1000:
spawn_time = 1500
if score > 5000:
speedboat = Enemy(64, 64, 2)
spawn_time = 2000
if score > 10000:
speedboat = Enemy(64, 64, 2)
spawn_time = 1500
if now - start > spawn_time:
start = now
speedboats.add(speedboat)
if speedboat_hits >= 10:
bosses.append(boss)
speedboat_hits = 0
redrawGameWindow()
clock.tick(FPS)
You are setting game = False, but using that in the while loop. As soon as game is set to False the while loop exits and the game ends. If you want to do it this way, use another variable in the while loop:
running = True
while running:
if game:
game_loop()
elif menu:
menu_loop()
Then use game and menu as switches to decide which thing to show.

How do I make my pygame levels more efficient? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I've been redoing a lot of my game in order to make it more efficient, before I had functions for each level and it had about 300+ repeated lines of code for each level, I've taken it out however I'm trying to get level one to function properly now. Below is my code, any help as to how to get my code to play level1 when I run the game as right now it only displays the background screen and none of the enemies, platforms or the character.
import pygame
import time
import random
from pygame.math import Vector2 as vec
pygame.init()
# Set the screen size
screen = pygame.display.set_mode([700, 500])
# Define the colours for text
black = (0,0,0)
white = (255,255,255)
green = (0,51,0)
light_green = (51,102,0)
PLAYER_FRICTION = 0.0
PLAYER_ACC = 3
HEIGHT = 500
WIDTH = 700
FPS = 60
# Set Display
pygame.display.set_caption('Jungle Blast')
clock = pygame.time.Clock()
class Character(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("TheoHills.png")
self.rect = self.image.get_rect(topleft=(50, 300))
self.x = 50
self.y = 300
self.pos = vec(50, 300)
self.vel = vec(0,0)
self.acc = vec(0,0)
def characterJump(self,platforms):
self.rect.y += 1
hits = pygame.sprite.spritecollide(self, platforms, False)
self.rect.y -= 1
if hits:
self.vel.y = -18
def update(self):
self.acc = vec(0, 0.5)
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
self.acc.x = -PLAYER_ACC
if keys[pygame.K_d]:
self.acc.x = PLAYER_ACC
# apply friction
self.vel.x *= PLAYER_FRICTION
self.vel += self.acc
self.pos += self.vel
self.rect.midbottom = self.pos
if self.pos.y == 500:
background_image = pygame.image.load("Lose Screen.png")
if self.pos.x > 699:
level2()
class Bullet(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("Bullet.png").convert()
self.image.set_colorkey(black)
self.rect = self.image.get_rect()
def update(self):
self.rect.x += 10
class levelInd(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("1 out of 5.png")
self.rect = self.image.get_rect(topleft=(20, 20))
self.pos = vec(20, 20)
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 88))
self.image.fill(black)
self.image = pygame.image.load("Platform1.png")
self.rect = self.image.get_rect(topleft=(x, y))
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 50))
self.image = pygame.image.load("RobberStanding.png")
self.rect = self.image.get_rect(topleft=(x,y))
def draw_text(surface, text, size, x, y,font_name):
font = pygame.font.SysFont(str(font_name), size)
text_surface = font.render(text, True, black)
text_rect = text_surface.get_rect()
text_rect.topleft = (x, y)
surface.blit(text_surface, text_rect)
class levels():
levelind = levelInd()
character = Character()
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
background_image = pygame.image.load("JungleBackground.png")
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
character.characterJump(platforms)
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
bullet = Bullet()
bullet.rect.x = character.rect.x + 10
bullet.rect.y = character.rect.y + 50
bullet_list.add(bullet)
all_sprites.add(bullet)
for bullet in bullet_list:
# See if the enemy is hit
enemyHit = pygame.sprite.spritecollide(bullet,enemies,True)
if enemyHit:
enemies.remove(Enemy)
score1 += 10
if bullet.rect.x > 700:
bullet_list.remove(bullet)
if character.rect.y >= 500:
background_image = pygame.image.load("Lose Screen.png")
pygame.display.update()
all_sprites.empty()
death = pygame.sprite.spritecollide(character, enemies, True)
if len(death) > 0:
background_image = pygame.image.load("Lose Screen.png")
all_sprites.empty()
all_sprites.update()
hits = pygame.sprite.spritecollide(character, platforms, False)
for platform in hits:
if character.vel.y > 0:
character.rect.bottom = character.rect.bottom
character.vel.y = 0
elif character.vel.y < 0:
character.rect.top = character.rect.top
character.vel.y = 3
character.pos.y = character.rect.bottom
screen.blit(background_image,[0,0])
all_sprites.draw(screen)
pygame.display.flip()
def level1():
done = False
clock = pygame.time.Clock()
font_name = pygame.font.match_font("Arial")
black = ( 0, 0, 0)
white = ( 255, 255, 255)
x = 300
y = 88
e1 = Enemy(250, 125)
enemies.add(e1)
all_sprites.add(character)
all_sprites.add(levelind)
all_sprites.add(e1)
p1 = Platform(-80, 400, WIDTH - 400, HEIGHT - 10)
p2 = Platform(175, 210, WIDTH - 400, HEIGHT - 10)
p3 = Platform(500, 400, WIDTH - 400, HEIGHT - 10)
all_sprites.add(p1, p2, p3)
platforms.add(p1, p2, p3)
score1 = 0
level1()
This is the image that shows up whenever the game is run.
I Think you should take a look at your "levels" Class.
Give it a proper init method, for example.
I got the game running by modifing the class as follows:
class levels():
def __init__(self):
self.levelind = levelInd()
self.character = Character()
self.all_sprites = pygame.sprite.Group()
self.platforms = pygame.sprite.Group()
self.enemies = pygame.sprite.Group()
self.bullet_list = pygame.sprite.Group()
self.background_image = pygame.image.load("1LPqX.png")
self.score1 = 0
self.running = True
def run(self):
while self.running:
self.level1()
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
pygame.display.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
self.haracter.characterJump(self.platforms)
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
bullet = Bullet()
bullet.rect.x = self.character.rect.x + 10
bullet.rect.y = self.character.rect.y + 50
self.bullet_list.add(bullet)
self.all_sprites.add(bullet)
for bullet in self.bullet_list:
# See if the enemy is hit
enemyHit = pygame.sprite.spritecollide(bullet, self.enemies, True)
if enemyHit:
self.enemies.remove(Enemy)
self.score1 += 10
if bullet.rect.x > 700:
self.bullet_list.remove(bullet)
if self.character.rect.y >= 500:
self.background_image = pygame.image.load("1LPqX.png")
pygame.display.update()
self.all_sprites.empty()
death = pygame.sprite.spritecollide(self.character, self.enemies, True)
if len(death) > 0:
self.background_image = pygame.image.load("1LPqX.png")
self.all_sprites.empty()
self.all_sprites.update()
hits = pygame.sprite.spritecollide(self.character, self.platforms, False)
for platform in hits:
if self.character.vel.y > 0:
self.character.rect.bottom = self.character.rect.bottom
self.character.vel.y = 0
elif self.character.vel.y < 0:
self.character.rect.top = self.character.rect.top
self.character.vel.y = 3
self.character.pos.y = self.character.rect.bottom
screen.blit(self.background_image, [0, 0])
self.all_sprites.draw(screen)
pygame.display.flip()
def level1(self):
done = False
clock = pygame.time.Clock()
font_name = pygame.font.match_font("Arial")
black = (0, 0, 0)
white = (255, 255, 255)
x = 300
y = 88
e1 = Enemy(250, 125)
self.enemies.add(e1)
self.all_sprites.add(self.character)
self.all_sprites.add(self.levelind)
self.all_sprites.add(e1)
p1 = Platform(-80, 400, WIDTH - 400, HEIGHT - 10)
p2 = Platform(175, 210, WIDTH - 400, HEIGHT - 10)
p3 = Platform(500, 400, WIDTH - 400, HEIGHT - 10)
self.all_sprites.add(p1, p2, p3)
self.platforms.add(p1, p2, p3)
self.score1 = 0
# level1()
(seems like the indentation was not copied properly, everything below "class levels()" has to be indented 4 more spaces)
and adding
if __name__ == '__main__':
game = levels()
game.run()
at the bottom of the file.

Pygame logo changes back after some time

I am a noob in pygame and i have a problem. Pygame logo changes after a while. I have two images. Pls help! First image is how the window should look like and the second image is my window after 20 sec. What schould i do? I never had this problem and i tried so many things but i can't do it.
import pygame
import random
# initialize idk pygame.init()
# size Width = 800 Height = 600 white = (255, 255, 255) icon = pygame.image.load('sunflower.png') player_img =
pygame.image.load('cat.png') enemy1_img = pygame.image.load('dog.png')
FPS = 120 Vel = 5
# enemy random coordinates enemy1_X = random.randint(64, 736) enemy1_Y = random.randint(50, 150)
# screen def screen_f(p_rect, e_rect):
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('dog destroyer')
icon = pygame.image.load('sunflower.png')
pygame.display.set_icon(icon)
backgroud = pygame.image.load('backg.png')
screen.blit(backgroud, (0, 0))
screen.blit(player_img, (p_rect))
screen.blit(enemy1_img, (e_rect))
# player def player_movement(key_pressed, p_rect):
if key_pressed[pygame.K_RIGHT]:
p_rect.x += Vel
if key_pressed[pygame.K_LEFT]:
p_rect.x -= Vel
if key_pressed[pygame.K_UP]:
p_rect.y -= Vel
if key_pressed[pygame.K_DOWN]:
p_rect.y += Vel
def borders(p_rect):
if p_rect.x < 0:
p_rect.x = 0
elif p_rect.x > 735:
p_rect.x = 735
elif p_rect.y < 0:
p_rect.y = 0
elif p_rect.y > 535:
p_rect.y = 535
# main def main():
Vel_e = 4 # enemy velocity
player_rect = pygame.Rect(368, 500, 64, 64)
enemy_rect = pygame.Rect(enemy1_X, enemy1_Y, 64, 64)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
key_pressed = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
enemy_rect.x += Vel_e
if enemy_rect.x >= 736:
Vel_e = -4
enemy_rect.y += 50
if enemy_rect.x < 0:
Vel_e = 4
enemy_rect.y += 50
borders(player_rect)
player_movement(key_pressed, player_rect)
screen_f(player_rect, enemy_rect)
pygame.display.update()
if __name__ == "__main__":
main()
Before
After 20 seconds
your code is not clearly visible but i think i know how to fix it.
you usually want to set your screen and other important stuf right at the beginning of your file, not in a def that has to be called.
try it like this:
import pygame
pygame.init()
width = ...
height = ...
fps = ...
#set any colors
#load all you pictures
screen = pygame.display.set_mode((width, height))
# you would also want to set your caption and icon here so:
pygame.display.set_caption('your caption')
pygame.display.set_icon(icon)
#all your defs
#and when its all set you go to a main loop.
#(at the bottom of your file)
main()
# and quit for if the user quits and run gets set to False
pygame.quit()
quit()

I am trying to make a platform around the bottom of the screen but it keeps giving me an error

I have a problem when I made my code and This is the error it shows
platforms_list.append[pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)]
TypeError: 'builtin_function_or_method' object is not subscriptable
I don't get what it means by subscriptable. I have a circle player that can jump move and can go around but falls off his platform because there is no bottom platform and I don't no how to make it
import math
import os
import sys
# It is importing everything
import pygame
from pygame.locals import *
class Platform:
def __init__(self, size, x, y, color):
#size is a list, this means it has width and height
self.size = size
self.x = x
self.y = y
self.color = color
# This is what the platform class has and what it does
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(display, self.color, (int(self.x), int(self.y), self.size[0], self.size[1]))
# This is def draw function is showing that how I want my Platform to look like
def do(self):
self.draw()
# The def do function is running def draw function
class Player:
def __init__(self, velocity, maxJumpRange, x, y, size):
self.falling = True
self.jumpCounter = 0
self.xVelocity = 0
self.y = y
self.x = x
self.jumping = False
self.velocity = velocity
self.maxJumpRange = maxJumpRange
self.jump_offset = 0
self.size = size
self.TouchedGround = False
# The player class is making how the Player is going to look and what are his limits
def keys(self):
k = pygame.key.get_pressed()
# The def keys(self): is creating a variable for pygame.key.get_pressed() and underneath is a function to make the player move around
if k[K_LEFT]:
self.xVelocity = -self.velocity
elif k[K_RIGHT]:
self.xVelocity = self.velocity
else:
self.xVelocity = 0
if (k[K_SPACE] or k[K_UP]) and not self.jumping and self.TouchedGround:
self.jumping = True
self.jumpCounter = 0
self.TouchedGround = False
# The if k[K_Space] or k[K_UP] is making sure the player has a jump limit and can't continue jumping forever.
def move(self):
self.x += self.xVelocity
# if the player is jumping, change y value
if self.jumping:
self.y -= self.velocity
self.jumpCounter += 1
if self.jumpCounter == self.maxJumpRange:
self.jumping = False
self.falling = True
elif self.falling:
self.y += self.velocity
self.jumpCounter -= 1
def draw(self):
display = pygame.display.get_surface()
pygame.draw.circle(display, White, (int(self.x), int(self.y)), self.size)
def do(self):
self.keys()
self.move()
self.draw()
# This Function is doing all of the Functions self.keys(), self.move(), self.draw()
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
#window size
w = 576
h = 516
# The above is showing the width the height and Area
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
# the above is showing what the graphics are
#player
p = Player(1, 100, 290, 250, 30)
#start pygame
pygame.init()
Clock = pygame.time.Clock()
DS = pygame.display.set_mode((w, h)) # This is what the display size is
pygame.display.set_caption("Try to get point B")
#variables
FPS = 120
Black = (0, 0, 0, 255)
White = (255, 255, 255, 255)
Red = (255, 0, 0)
# Bkgd stands for background
bkgd = pygame.Surface((w,h)) # didnt have the image so i made it blue
bkgd.fill((0,0,255))
#platforms
pl = Platform([290,20], 250, 350, White)
#this is a list that holds all the platforms
platforms_list = [pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)]
platforms_list.append[pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)]
#this is how much to scroll the background by
background_scroll = 0
# What the while true loop is doing is to make sure that the background moves while the player moves
while True:
events()
#blit the background, since the image is same size as window blit twice so when scrolls, you dont have blackness
DS.blit(bkgd, (-background_scroll, 0))
DS.blit(bkgd, (w-background_scroll, 0))
#check for x button clicked
events()
#update the player
p.do()
#update platforms and check for collision with player
platform_color = Red
for platform in platforms_list:
platform.color = platform_color
if p.jumping == 0:
platform.color = White
platform.do()
#if bottom of player is in the platform, move the player on top of the platform
if p.y + p.size > platform.y and p.y + p.size < platform.y + platform.size[1]:
if p.x > platform.x and p.x < platform.x + platform.size[0]:
p.y = platform.y - p.size
p.TouchedGround = True
#if the player reaches the side of the screen, move the background and platforms to make it look like it is moving
if p.x + p.size >= w:
p.x = w - p.size
background_scroll += 1
for platform in platforms_list:
platform.x -= 1
if background_scroll == w:
background_scroll = 0
#same but for the left
if p.x - p.size <= 0:
p.x = 0 + p.size
background_scroll -= 1
for platform in platforms_list:
platform.x += 1
if background_scroll == 0:
background_scroll = w
#update screen
pygame.display.update()
Clock.tick(FPS)
DS.fill(Black)
platforms_list.append[pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)] this is the code that I added but it keeps giving me the code
I think append needs to be .append() not [].
Try this:
platforms_list.append(pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White))

Categories