highscore in pygame game - python

I've made a game in pygame and I want to make it possible to have a high score thaat will be displayed at the the top of the show_go_screen. I just need a simple solution - I don't need to write who has the highest score, just the number itself at the top of the show_go_screen. I know there are already questions about this on Stack Overflow but the solutions don't work for me.
code:
# Pygame template
# Attributions
# (Heart) Icons made by Freepik from www.flaticon.com
# (Play)Background vector created by freepik - www.freepik.com
# (GameOver)Background vector created by pikisuperstar - www.freepik.com
# (Backing)Frozen Jam by tgfcoder <https://twitter.com/tgfcoder> licensed under CC-BY-3 <http://creativecommons.org/licenses/by/3.0/>
# (Graphics)Art by Kenney.nl
# Imports
import pygame as pg
import random
from os import path
# images / sound
img_dir = path.join(path.dirname(__file__), 'img')
snd_dir = path.join(path.dirname(__file__), 'snd')
# Constants
WIDTH = 500
HEIGHT = 700
FPS = 60
POWERUP_TIME = 60000
ENCO_TIME = 40000
# Define Colors
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
MAGENTA = (255, 0, 255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)
GREENISH_BLUE = (0, 255, 180)
# Initialize pygame and create window
pg.init()
pg.mixer.init()
screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption("Galaxy Shooters")
clock = pg.time.Clock()
score = 0
# save score
# import shelve
# d = shelve.open('score.txt') # here you will save the score variable
# d['highscore'] = score # thats all, now it is saved on disk.
# d.close()
font_name = pg.font.match_font('arial')
def draw_text(surf, text, size, x, y):
font = pg.font.Font(font_name, size)
text_surface = font.render(text, True, CYAN)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
def spawnmob():
m = Mob()
all_sprites.add(m)
mobs.add(m)
def draw_shield_status_bar(surf, x, y, pct):
if pct < 0:
pct = 0
BAR_LENGTH = 100
BAR_HEIGHT = 10
fill = (pct / 100) * BAR_LENGTH
outline_rect = pg.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
fill_rect = pg.Rect(x, y, fill, BAR_HEIGHT)
pg.draw.rect(surf, GREENISH_BLUE, fill_rect)
pg.draw.rect(surf, WHITE, outline_rect, 2)
def draw_lives(surf, x, y, lives, img):
for i in range(lives):
img_rect = img.get_rect()
img_rect.x = x + 30 * i
img_rect.y = y
surf.blit(img, img_rect)
class Player(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.transform.scale(player_img, (50, 38))
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.radius = 20
# pg.draw.circle(self.image, RED, self.rect.center, self.radius)
self.rect.centerx = WIDTH / 2
self.rect.bottom = HEIGHT - 10
self.speedx = 0
self.shield = 100
self.shoot_delay = 370
self.last_shot = pg.time.get_ticks()
self.lives = 3
self.hidden = False
self.hide_timer = pg.time.get_ticks()
self.power = 1
self.power_time = pg.time.get_ticks()
def update(self):
# Timeout for powerups
if self.power >= 2 and pg.time.get_ticks() - self.hide_timer > POWERUP_TIME:
self.power -= 1
self.power_time = pg.time.get_ticks
# Unhide if necessary
if self.hidden and pg.time.get_ticks() - self.hide_timer > 1000:
self.hidden = False
self.rect.centerx = WIDTH / 2
self.rect.bottom = HEIGHT - 10
self.speedx = 0
keystate = pg.key.get_pressed()
if keystate[pg.K_LEFT]:
self.speedx = -5
if keystate[pg.K_RIGHT]:
self.speedx = 5
if keystate[pg.K_SPACE]:
self.shoot()
self.rect.x += self.speedx
if self.rect.right > WIDTH:
self.rect.right = WIDTH
if self.rect.left < 0:
self.rect.left = 0
def powerup(self):
self.power += 1
self.power_time = pg.time.get_ticks()
def shoot(self):
now = pg.time.get_ticks()
if now - self.last_shot > self.shoot_delay:
self.last_shot = now
if self.power == 1:
laser = Laser(self.rect.centerx, self.rect.top)
all_sprites.add(laser)
lasers.add(laser)
random.choice(shoot_sounds).play()
if self.power >= 2:
laser1 = Laser(self.rect.left, self.rect.centery)
laser2 = Laser(self.rect.right, self.rect.centery)
all_sprites.add(laser1)
all_sprites.add(laser2)
lasers.add(laser1)
lasers.add(laser2)
random.choice(shoot_sounds).play()
def hide(self):
self.hidden = True
self.hide_timer = pg.time.get_ticks()
self.rect.center = (WIDTH / 2, HEIGHT + 200)
class Mob(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image_orig = random.choice(meteor_images)
self.image_orig.set_colorkey(BLACK)
self.image = self.image_orig.copy()
self.rect = self.image.get_rect()
self.radius = int(self.rect.width * .85 / 2)
# pg.draw.circle(self.image, RED, self.rect.center, self.radius)
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-150, -40)
self.speedy = random.randrange(1, 8)
self.speedx = random.randrange(-3, 3)
self.rot = 0
self.rot_speed = random.randrange(-8, 8)
self.last_update = pg.time.get_ticks()
def rotate(self):
now = pg.time.get_ticks()
if now - self.last_update > 50:
self.last_update = now
self.rot = (self.rot + self.rot_speed) % 360
new_image = pg.transform.rotate(self.image_orig, self.rot)
old_center = self.rect.center
self.image = new_image
self.rect = self.image.get_rect()
self.rect.center = old_center
def update(self):
self.rotate()
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.top > HEIGHT + 10 or self.rect.right < -25 or self.rect.left > WIDTH + 20:
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
class Laser(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = laser_img
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speedy = -10
def update(self):
self.rect.y += self.speedy
# Kill it if moves off the top of the screen
if self.rect.bottom < 0:
self.kill()
class Explosion(pg.sprite.Sprite):
def __init__(self, center, size):
pg.sprite.Sprite.__init__(self)
self.size = size
self.image = explosion_anim[self.size][0]
self.rect = self.image.get_rect()
self.rect.center = center
self.frame = 0
self.last_update = pg.time.get_ticks()
self.frame_rate = 75
def update(self):
now = pg.time.get_ticks()
if now - self.last_update > self.frame_rate:
self.last_update = now
self.frame += 1
if self.frame == len(explosion_anim[self.size]):
self.kill()
else:
center = self.rect.center
self.image = explosion_anim[self.size][self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
class Pow(pg.sprite.Sprite):
def __init__(self, center):
pg.sprite.Sprite.__init__(self)
self.type = random.choice(['shield', 'laser', 'star'])
self.image = powerup_images[self.type]
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.center = center
self.speedy = 4
def update(self):
self.rect.y += self.speedy
# Kill it if moves off the bottom of the screen
if self.rect.top > HEIGHT:
self.kill()
class Enco(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = draw_text(screen, (random.choice(encos), 37, WIDTH / 2, HEIGHT/ 4))
self.rect = self.image.get_rect()
self.hidden = True
self.hide_timer = pg.time.get_ticks()
def hide(self):
self.rect.y = HEIGHT - 40
self.rect.x = WIDTH / 2
def show_go_screen():
screen.blit(background2, background_rect2)
draw_text(screen, str(score), 25, WIDTH / 2, 10)
draw_text(screen, " Guardians of the Galaxy ", 37, WIDTH / 2, HEIGHT / 4)
draw_text(screen, "Arrow Keys move, Spacebar to shoot", 29, WIDTH / 2, HEIGHT / 2)
draw_text(screen, "Press any key to BEGIN", 22, WIDTH / 2, HEIGHT * 3/ 4)
pg.display.flip()
print(d)
waiting = True
while waiting:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
if event.type == pg.KEYUP:
waiting = False
# Load all game graphics
background = pg.image.load(path.join(img_dir, "2397814.jpg")).convert()
background_rect = background.get_rect()
background2 = pg.image.load(path.join(img_dir, "2474216.jpg")).convert()
background_rect2 = background2.get_rect()
pg.transform.scale(background, (500, 700))
player_img = pg.image.load(path.join(img_dir, "playerShip3_blue.png")).convert()
heart_img = pg.image.load(path.join(img_dir, "heart.png")).convert()
mini_heart_img = pg.transform.scale(heart_img, (23, 23))
mini_heart_img.set_colorkey(BLACK)
laser_img = pg.image.load(path.join(img_dir, "laserBlue01.png")).convert()
meteor_images = []
meteor_list = ['meteorBrown_big1.png', 'meteorBrown_big2.png', 'meteorBrown_big3.png',
'meteorBrown_med1.png','meteorBrown_small1.png','meteorBrown_small2.png',
'meteorBrown_tiny2.png',]
for img in meteor_list:
meteor_images.append(pg.image.load(path.join(img_dir, img)).convert())
explosion_anim = {}
explosion_anim['lg'] = []
explosion_anim['sm'] = []
explosion_anim['player'] = []
for i in range(9):
filename = 'regularExplosion0{}.png'.format(i)
img = pg.image.load(path.join(img_dir, filename)).convert()
img.set_colorkey(BLACK)
img_lg = pg.transform.scale(img, (75, 75))
explosion_anim['lg'].append(img_lg)
img_sm = pg.transform.scale(img, (32, 32))
explosion_anim['sm'].append(img_sm)
filename = 'sonicExplosion0{}.png'.format(i)
img = pg.image.load(path.join(img_dir, filename)).convert()
img.set_colorkey(BLACK)
explosion_anim['player'].append(img)
powerup_images = {}
powerup_images['shield'] = pg.image.load(path.join(img_dir, 'shield_silver.png')).convert()
powerup_images['laser'] = pg.image.load(path.join(img_dir, 'bolt_gold.png')).convert()
powerup_images['star'] = pg.image.load(path.join(img_dir, 'star_silver.png')).convert()
encos = ("Nice Job!", "You're rocking it man!", " Great!", "What a blast!", "Good one!", "Those asteroids stand no chance against you!"
"You're the master!")
# Load all game sounds
laser_powerup = pg.mixer.Sound(path.join(snd_dir, 'Laser_Powerup.wav'))
shield_powerup = pg.mixer.Sound(path.join(snd_dir, 'Shield_Powerup.wav'))
shoot_sounds = []
for snd in ['Laser_Shoot.wav', 'Laser_Shoot2.wav']:
shoot_sounds.append(pg.mixer.Sound(path.join(snd_dir, snd)))
expl_sounds = []
for snd in ['Expl.wav', 'Expl2.wav']:
expl_sounds.append(pg.mixer.Sound(path.join(snd_dir, snd)))
player_die_sound = pg.mixer.Sound(path.join(snd_dir, 'rumble1.ogg'))
pg.mixer.music.load(path.join(snd_dir, 'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
pg.mixer.music.set_volume(0.7)
pg.mixer.music.play(loops = -1)
# Game loop
game_over = True
running = True
while running:
if game_over:
show_go_screen()
game_over = False
# Sprite groups
all_sprites = pg.sprite.Group()
mobs = pg.sprite.Group()
lasers = pg.sprite.Group()
powerups = pg.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):
spawnmob()
score = 0
# Keep loop running at the right speed
clock.tick(FPS)
# Events
for event in pg.event.get():
# Check for closing window
if event.type == pg.QUIT:
running = False
# Update
all_sprites.update()
# Check to see if a laser hit a mob
hits = pg.sprite.groupcollide(mobs, lasers, True, True)
for hit in hits:
score += 50 - hit.radius
random.choice(expl_sounds).play()
expl = Explosion(hit.rect.center, 'lg')
all_sprites.add(expl)
if random.random() > 0.93:
pow = Pow(hit.rect.center)
all_sprites.add(pow)
powerups.add(pow)
spawnmob()
# Check to see if a mob hit the player
hits = pg.sprite.spritecollide(player, mobs, True, pg.sprite.collide_circle)
for hit in hits:
player.shield -= hit.radius * 2
expl = Explosion(hit.rect.center, 'sm')
all_sprites.add(expl)
spawnmob()
if player.shield <= 0:
player_die_sound.play()
death_expl = Explosion(player.rect.center, 'player')
all_sprites.add(death_expl)
player.hide()
player.lives -= 1
player.shield = 100
# Check to see if player hit a powerup
hits = pg.sprite.spritecollide(player, powerups, True)
for hit in hits:
if hit.type == 'shield':
pow.kill()
player.shield += random.randrange(10, 30)
shield_powerup.play()
if player.shield >= 100:
player.shield = 100
if hit.type == 'laser':
player.powerup()
laser_powerup.play()
if hit.type == 'star':
player.lives += 1
if player.lives >= 3:
player.lives = 3
# If the player died and the explosion finished playing
if player.lives == 0 and not death_expl.alive():
game_over = True
# Render
screen.fill(BLACK)
screen.blit(background, background_rect)
all_sprites.draw(screen)
draw_text(screen, str(score), 25, WIDTH / 2, 10)
draw_shield_status_bar(screen, 5, 5, player.shield)
draw_lives(screen, WIDTH - 100, 5, player.lives, mini_heart_img)
if score == 500:
draw_text(screen, "Nice Job!", 37, WIDTH / 2, HEIGHT / 2)
now = pg.time.get_ticks()
last.enco = pg.time.get_ticks()
if now - last.enco == ENCO_TIME:
hide_enco
# *After* drawing everything, flip the display
pg.display.flip()
pg.quit()
thanks!

Create a variable called highscore then then when the player looses, check if the current score is higher than highscore and if it is, then assign the score to highscore. Then you can just easily add a label with the highscore variable as a text
score = 0
highscore = 0
# save score
# import shelve
# d = shelve.open('score.txt') # here you will save the score variable
# d['highscore'] = score # thats all, now it is saved on disk.
# d.close()
# A lot of your code
def show_go_screen():
screen.blit(background2, background_rect2)
draw_text(screen, str(highscore), 50, WIDTH / 2, 10) #change the x value accordingly
# more of your code
while running:
if game_over:
show_go_screen()
game_over = False
# Sprite groups
all_sprites = pg.sprite.Group()
mobs = pg.sprite.Group()
lasers = pg.sprite.Group()
powerups = pg.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):
spawnmob()
if score > highscore:
highscore = score
score = 0
# the rest of your code

Related

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()

Check for collision and stop velocity in pygame

I am trying to make a simple platformer in pygame, with simulated gravity and collision. I can't make the collision working. On collision with a sprite, the player slowly falls through the sprite and continues falling at normal speed when reached through.
Main.py:
class Game:
def __init__(self):
# initialize pygame library
pg.init()
pg.mixer.init()
# initialize screen
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
self.font = pg.font.match_font(FONT_NAME)
self.running = True
self.playing = True
def new(self):
# initzialize sprite groups
self.sprites = pg.sprite.Group()
self.objects = pg.sprite.Group()
self.p = Player(self)
self.sprites.add(self.p)
self.g = Ground()
self.sprites.add(self.g)
self.objects.add(self.g)
self.o = Object(100, 350, 100, 20)
self.sprites.add(self.o)
self.objects.add(self.o)
self.collide = False
self.run()
# constant running functions
def run(self):
while self.playing:
self.clock.tick(FPS)
self.events()
self.update()
self.draw()
self.running = False
def events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.playing = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
self.p.jump()
def update(self):
self.sprites.update()
hits = pg.sprite.spritecollide(self.p, self.objects, False)
if hits:
self.collide = True
if self.p.vel.y >= 0.0:
self.p.x = hits[0].rect.top
print("Collide bottom")
elif self.p.vel.y < 0: self.p.top = hits[0].rect.bottom
elif self.p.vel.x > 0: self.p.rect.right = hits[0].rect.left
elif self.p.vel.x < 0: self.p.rect.left = hits[0].rect.right
self.p.vel.y = 0
#self.p.acc.y = 0
#print(f"Collision with {hits[0].name}")
else:
self.collide = False
def draw(self):
self.screen.fill(BLACK)
self.sprites.draw(self.screen)
self.drawtext(f"X Pos: = {int(self.p.pos.x)}", 15, WHITE, WIDTH - 5, 20, 3)
self.drawtext(f"Y Pos: = {int(self.p.pos.y)}", 15, WHITE, WIDTH - 5, 40, 3)
self.drawtext(f"Y Velocity = {self.p.vel.y}", 15, WHITE, 5, 50, 0)
self.drawtext(f"Y Accelleration = {self.p.acc.y}", 15, WHITE, 5, 70, 0)
self.drawtext(f"Collision: = {self.collide}", 15, WHITE, 5, 200, 0)
#print(self.p.vel.y)
pg.display.flip()
# other functions
def drawtext(self, text, size, color, x, y, align):
font = pg.font.Font(self.font, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
if align == 0:
text_rect.midleft = (x, y)
elif align == 1:
text_rect.midtop = (x, y)
elif align == 2:
text_rect.midbottom = (x, y)
elif align == 3:
text_rect.midright = (x, y)
else:
text_rect.center = (x, y)
self.screen.blit(text_surface, text_rect)
# def checkCollisionY(self):
# hits = pg.sprite.spritecollide(self.p, self.objects, False)
# if hits:
# self.collide = True
# return True
# else:
# self.collide = False
# return False
g = Game()
while g.running:
g.new()
pg.quit()
Sprites.py:
from settings import *
import pygame as pg
vec = pg.math.Vector2
class Player(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.width = 30
self.height = 30
self.image = pg.Surface((self.width, self.height))
self.image.fill(YELLOW)
self.rect = self.image.get_rect()
self.rect.center = vec(150, 100)
self.pos = vec(150, 100)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
def update(self):
self.acc = vec(0, PLAYER_GRAV)
#input
keys = pg.key.get_pressed()
if keys[pg.K_LEFT]:
self.acc.x = -PLAYER_ACC
if keys[pg.K_RIGHT]:
self.acc.x = PLAYER_ACC
self.acc.x += self.vel.x * PLAYER_FRICTION
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
print(f"{self.vel.y} + 0.5 * {self.acc.y} = {self.vel.y + 0.5 * self.acc.y}")
self.rect.topleft = self.pos
def jump(self):
hits = pg.sprite.spritecollide(self, self.game.objects, False)
if hits:
self.vel.y = -20
class Object(pg.sprite.Sprite):
def __init__(self, x, y, w, h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w, h))
self.image.fill((255, 0, 144))
self.name = "Object"
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Ground(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.name = "Ground"
self.image = pg.image.load("ground.png")
self.rect = self.image.get_rect()
self.rect.x = -100
self.rect.y = 550
Settings.py:
# game settings
TITLE = "My Game"
WIDTH = 480
HEIGHT = 800
FPS = 60
FONT_NAME = 'impact'
#Player properties
PLAYER_ACC = 0.7
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.7
# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)
PURPLE = (255, 0, 255)
The important code here is the update() in main.py and update() in sprites.py. Help?
EDIT
hits = pg.sprite.spritecollide(self.p, self.objects, False)
for hit in hits:
self.collide = True
if self.p.vel.x > 0.0:
self.p.rect.right = hit.rect.left
self.p.pos.x = self.p.rect.centerx
self.p.vel.x = 0
elif self.p.vel.x < 0.0:
self.p.rect.left = hit.rect.right
self.p.pos.x = self.p.rect.centerx
self.p.vel.x = 0
self.p.pos.x = self.p.rect.x
else:
self.collide = False
hits = pg.sprite.spritecollide(self.p, self.objects, False)
for hit in hits:
self.collide = True
if self.p.vel.y >= 0.0:
self.p.rect.bottom = hit.rect.top
self.p.pos.y = self.p.rect.centery
self.p.vel.y = 0
elif self.p.vel.y < 0.0:
self.p.rect.top = hit.rect.bottom
self.p.pos.y = self.p.rect.centery
self.p.vel.y = 0
self.p.pos.y = self.p.rect.y
else:
self.collide = False
Your Player class doesn't have x and y attributes but a pos attribute which you need to change after a collision. The rect of the object needs to be updated as well and it's better to do that first and then set the pos.y coordinate to the rect.centery coordinate afterwards.
if self.p.vel.y >= 0.0:
self.p.rect.bottom = hits[0].rect.top
self.p.pos.y = self.p.rect.centery
self.p.vel.y = 0
Do the same for the other directions.
Also, the horizontal and vertical movement should be handled separately, otherwise you'll see odd jumps for example from the side to the top of a platform. Take a look at the first part of this platformer example.
And in the jump method you need to move the rect down by 1 pixel so that it's able to collide with the platform sprites.
def jump(self):
self.rect.y += 1
# ...
Here's a complete, runnable example:
import pygame as pg
# game settings
TITLE = "My Game"
WIDTH = 480
HEIGHT = 800
FPS = 60
FONT_NAME = 'impact'
#Player properties
PLAYER_ACC = 0.7
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.7
# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
vec = pg.math.Vector2
class Player(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.image = pg.Surface((30, 30))
self.image.fill(YELLOW)
self.rect = self.image.get_rect(center=(150, 100))
self.pos = vec(150, 100)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
self.objects = game.objects
def update(self):
self.acc = vec(0, PLAYER_GRAV)
#input
keys = pg.key.get_pressed()
if keys[pg.K_LEFT]:
self.acc.x = -PLAYER_ACC
if keys[pg.K_RIGHT]:
self.acc.x = PLAYER_ACC
self.acc.x += self.vel.x * PLAYER_FRICTION
self.vel += self.acc
# Move along the x-axis first.
self.pos.x += self.vel.x + 0.5 * self.acc.x
# print(f"{self.vel.y} + 0.5 * {self.acc.y} = {self.vel.y + 0.5 * self.acc.y}")
self.rect.centerx = self.pos.x
# Check if the sprite collides with a platform.
hits = pg.sprite.spritecollide(self, self.objects, False)
if hits:
# Reset the x position.
if self.vel.x > 0:
self.rect.right = hits[0].rect.left
self.pos.x = self.rect.centerx
self.vel.x = 0
elif self.vel.x < 0:
self.rect.left = hits[0].rect.right
self.pos.x = self.rect.centerx
self.vel.x = 0
# Move along the y-axis.
self.pos.y += self.vel.y + 0.5 * self.acc.y
self.rect.centery = self.pos.y
# Check if the sprite collides with a platform.
hits = pg.sprite.spritecollide(self, self.objects, False)
if hits:
# Reset the y position.
if self.vel.y >= 0.0:
self.rect.bottom = hits[0].rect.top
self.pos.y = self.rect.centery
self.vel.y = 0
elif self.vel.y < 0:
self.rect.top = hits[0].rect.bottom
self.pos.y = self.rect.centery
self.vel.y = 0
def jump(self):
self.rect.y += 1 # Move it down to check if it collides with a platform.
hits = pg.sprite.spritecollide(self, self.game.objects, False)
if hits:
self.vel.y = -20
self.rect.y -= 1 # Move it up again after the collision check.
class Object(pg.sprite.Sprite):
def __init__(self, x, y, w, h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w, h))
self.image.fill((255, 0, 144))
self.name = "Object"
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Ground(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.name = "Ground"
self.image = pg.Surface((500, 300))
self.image.fill((90, 30, 30))
self.rect = self.image.get_rect()
self.rect.x = -100
self.rect.y = 550
class Game:
def __init__(self):
pg.init()
pg.mixer.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
self.font = pg.font.match_font(FONT_NAME)
self.running = True
self.playing = True
def new(self):
self.sprites = pg.sprite.Group()
self.objects = pg.sprite.Group()
self.p = Player(self)
self.sprites.add(self.p)
self.g = Ground()
self.sprites.add(self.g)
self.objects.add(self.g)
rects = [(100, 350, 100, 20), (50, 380, 100, 20),
(200, 450, 100, 100)]
for x, y, w, h in rects:
obj = Object(x, y, w, h)
self.sprites.add(obj)
self.objects.add(obj)
self.collide = False
self.run()
def run(self):
while self.playing:
self.clock.tick(FPS)
self.events()
self.update()
self.draw()
self.running = False
def events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.playing = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
self.p.jump()
def update(self):
self.sprites.update()
def draw(self):
self.screen.fill(BLACK)
self.sprites.draw(self.screen)
pg.display.flip()
g = Game()
while g.running:
g.new()
pg.quit()

Pygame Game results in Segmentation Fault(pygame parachute)

If you play the game and win, clicking on the screen will cause the game to play again. On the second play, the game segmentation faults after a second or two.
This code is for an intro to coding class and many others have coded this game successfully. I don't understand what is the problem here.
Help!
import sys
import os
import pygame
import random
import math
#Force static position of screen
os.environ ['SDL_VIDEO_CENTERED'] = '1'
#constants
BLACK = (0,0,0)
WHITE = (255, 255, 255)
SHIP_WIDTH = 13
SHIP_HEIGHT = 13
SIZE = WIDTH, HEIGHT = 920, 570
TOP_BUFFER = 50
PILL_HEIGHT = 30
PILL_WIDTH = 10
YELLOW = (157, 185, 45)
RED = (185, 45, 45)
BLUE = (45, 115, 185)
GREEN = (5, 94, 16)
#Runs imported module
pygame.init()
class Text:
def __init__(self, size, text, color, xpos, ypos):
self.font = pygame.font.SysFont("Britannic Bold", size)
self.image = self.font.render(text, 1, color)
self.rect = self.image.get_rect()
self.rect = self.rect.move(xpos, ypos)
class Ship(pygame.sprite.Sprite):
def __init__ (self, x, y, side):
pygame.sprite.Sprite.__init__(self)
self.density = SHIP_HEIGHT * SHIP_WIDTH
self.speed = 10
self.image = pygame.Surface((math.sqrt(self.density), math.sqrt(self.density))).convert()
self.rect = self.image.get_rect()
self.rect = self.rect.move(x, y)
self.type = side
self.score = Text(30, str(self.density - 169), BLACK, WIDTH / 4 , HEIGHT/ 17)
self.score_2 = Text(30, str(self.density - 169), BLACK, WIDTH * .75, HEIGHT / 17)
def update(self, pill_group):
key = pygame.key.get_pressed()
if self.type == "left":
if key[pygame.K_w]:
self.rect.y -= self.speed
if key[pygame.K_s]:
self.rect.y += self.speed
if key[pygame.K_a]:
self.rect.x -= self.speed
if key[pygame.K_d]:
self.rect.x += self.speed
if self.type == "left":
#Boundary Conditions
if self.rect.right > WIDTH/2:
self.rect.right = WIDTH/2
if self.rect.left < 0:
self.rect.left = 0
if self.rect.top < 50:
self.rect.top = 50
if self.rect.bottom > 570:
self.rect.bottom = 570
elif self.type == "right":
if key[pygame.K_UP]:
self.rect.y -= self.speed
if key[pygame.K_DOWN]:
self.rect.y += self.speed
if key[pygame.K_LEFT]:
self.rect.x -= self.speed
if key[pygame.K_RIGHT]:
self.rect.x += self.speed
# Ship 2 boundary conditions
if self.rect.right > WIDTH:
self.rect.right = WIDTH
if self.rect.top < TOP_BUFFER:
self.rect.top = TOP_BUFFER
if self.rect.left < WIDTH/2:
self.rect.left = WIDTH/2
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
collisions = pygame.sprite.spritecollide(self, pill_group, True)
for p in collisions:
self.density += p.density * 50
print(self.density)
self.score.image = self.score.font.render(str(self.density - 169), 1, BLACK)
self.score_2.image = self.score.font.render(str(self.density), 1, BLACK)
##if self.density > 500:
##self.play == False
self.rect.width = self.rect.height = math.sqrt(self.density)
self.image = pygame.transform.scale(self.image, (self.rect.width, self.rect.height))
class Pill(pygame.sprite.Sprite):
def __init__(self, xpos, density):
pygame.sprite.Sprite.__init__(self)
self.density = density
self.speed = 3
self.image = pygame.Surface((PILL_WIDTH, PILL_HEIGHT)).convert()
self.image.fill(self.set_color())
self.rect = pygame.Rect(xpos, -PILL_HEIGHT, 10, 30)
self.rect = self.image.get_rect()
self.rect = self.rect.move(xpos, HEIGHT/15)
def set_color(self):
if self.density == 1:
return YELLOW
elif self.density == 2:
return RED
elif self.density == 3:
return BLUE
elif self.density == 4:
return GREEN
def update(self):
self.rect.y += self.speed
if self.rect.y > HEIGHT:
self.kill()
def main():
#Initialize Local Vars
size = width, height = 920, 570
fps = 30
LeftWins = Text(30, "Left Ship Wins!", BLACK, WIDTH / 2.5, HEIGHT / 2)
RightWins = Text(30, "Right Ship Wins!", BLACK, WIDTH / 2.5, HEIGHT / 2)
Winner = Text (30, "Click here to play again", BLACK, WIDTH / 2.6, HEIGHT * .75)
pygame.display.set_caption('Density')
screen = pygame.display.set_mode(SIZE, pygame.SRCALPHA)
clock = pygame.time.Clock()
play = True
loop_counter = 0
vertical = pygame.Surface((1, HEIGHT - TOP_BUFFER)).convert()
horizontal = pygame.Surface((WIDTH, 1)).convert()
#Create Game Objects
ship_left = Ship(WIDTH/4 - SHIP_WIDTH/2, HEIGHT - (4 * SHIP_HEIGHT), "left")
ship_right = Ship((WIDTH * 3) / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "right")
#Create Groups
ship_group = pygame.sprite.Group()
ship_group.add(ship_left, ship_right)
pill_group = pygame.sprite.Group()
#play = True
outro = True
while True:
#Gameplay
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if loop_counter % 10 == 0:
pill = Pill(random.randrange(0, (WIDTH/2) - PILL_WIDTH), int(random.choice('1111111111111111111122222334')))
pill2 = Pill(random.randrange((WIDTH/2) + PILL_WIDTH, WIDTH - PILL_WIDTH), int(random.choice('1111111111111111111122222334')))
pill_group.add(pill)
pill_group.add(pill2)
#Update Groups
ship_group.update(pill_group)
pill_group.update()
#Draw/Blit Groups
screen.fill(WHITE)
screen.blit(ship_left.score.image, ship_left.score.rect)
screen.blit(ship_right.score_2.image, ship_right.score_2.rect)
ship_group.draw(screen)
pill_group.draw(screen)
screen.blit(vertical, (WIDTH/2, TOP_BUFFER))
screen.blit(horizontal, (0, TOP_BUFFER))
#60 / second one pill / 10 iterations
loop_counter += 1
#Limits frames per iteration of while loop
clock.tick(60)
# Writes to main surface
pygame.display.flip()
if (ship_left.density >= 500 or ship_right.density >= 500):
play = False
while outro:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN or pygame.key.get_pressed()[pygame.K_RETURN != 0]:
outro = False
play = True
ship_left.density = 0
ship_right.density = 0
for p in pill_group:
p.kill()
ship_left = Ship(WIDTH / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "left")
ship_right = Ship((WIDTH * 3) / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "right")
screen.blit(ship_left.image, ship_left.rect)
screen.blit(ship_right.image, ship_right.rect)
#Draw/Blit Groups
screen.fill(WHITE)
if (ship_left.density >= 500):
screen.blit(LeftWins.image, LeftWins.rect)
screen.blit(Winner.image, Winner.rect)
if (ship_right.density >= 500):
screen.blit(RightWins.image, RightWins.rect)
screen.blit(Winner.image, Winner.rect)
#Limits frames per iteration of while loop
clock.tick(60)
# Writes to main surface
pygame.display.flip()
if __name__ == "__main__":
main()
One way to solve this (but arguably not the best one) is to move the setup code inside the while True loop and ditch the reset code in while outro:
def main():
# The setup code from here ...
while True:
# Goes here
#Gameplay
while play:
# The Gameplay code
while outro:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN or pygame.key.get_pressed()[pygame.K_RETURN != 0]:
outro = False
#Draw/Blit Groups
screen.fill(WHITE)
# The reset of outro

pygame sprite.spritecollide() doesn't work with moving sprite Group

When my player sprite collides with the coin group the coins disappear as wanted, but when it collides with the enemys group nothing happens. The code is the same. I don't know what I did wrong because I did the same thing twice but it only works once. Does it have anything to do with the enemys moving? Here is the the code:
import pygame as pg
import random
a_white = (245, 245, 245)
a_red = (10, 0, 0)
black = (0, 0, 0)
white = (255, 255, 255)
blue_grey = (51, 93, 127)
dark_red = (85, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
yellow = (255, 255, 0)
bg_color = dark_red
width = 600
height = 500
FPS = 60
p_width = 70
p_height = 70
c_width = 35
c_height = 35
score = 0
level = 0
lives = 3
title = 'This Is My Game!'
pg.init()
pg.mixer.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((width, height))
pg.display.set_caption(title)
font_name = pg.font.match_font("arial")
coin_img = pg.image.load('coin3.png').convert()
player_img = pg.image.load('smiley.png').convert_alpha()
gegner_1 = pg.image.load('gegner_black.png').convert_alpha()
coin_snd = pg.mixer.Sound('coin_snd_2.ogg')
def new_coin():
x = random.randrange(c_width, width - c_width)
y = random.randrange(c_height, height - c_height)
coins = Coin(x, y)
all_sprites.add(player, coins)
coin_group.add(coins)
def draw_text(screen, text, t_color, size, t_x, t_y):
font = pg.font.Font(font_name, size)
text_surface = font.render(text, True, t_color)
text_rect = text_surface.get_rect()
text_rect.midtop = (t_x, t_y)
screen.blit(text_surface, text_rect)
def start_screen():
screen.fill(bg_color)
draw_text(screen, 'Welcome... !', white, 75, width / 2, height / 4 - 100)
draw_text(screen, 'ready to play my game*?', white, 24, width - 150, height / 4 - 20)
draw_text(screen, "Press any key to begin", white, 20, width / 2 + 60, height / 4 + 10)
draw_text(screen, "*The name of the game is \'MY GAME\' but that ",
white, 16, width / 2, height - 150)
draw_text(screen, " has nothing to do with the fact, that the game is", white, 16, width / 2, height - 130)
draw_text(screen, " my game. Yes, the game is actually my game, ", white, 16, width / 2, height - 110)
draw_text(screen, " but that\'s not the reason I named it my game. ", white, 16, width / 2, height - 90)
draw_text(screen, "...or is it?", white, 13, width - 28, height - 20)
pg.display.update()
waiting = True
while waiting:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
if event.type == pg.KEYUP:
waiting = False
class Player(pg.sprite.Sprite):
def __init__(self):
super().__init__()
self.image_orig = pg.transform.scale(player_img, (p_width, p_height))
self.image = self.image_orig.copy()
self.rect = self.image.get_rect()
self.rect.center = (width / 2), (height / 2)
self.radius = 35
def update(self):
keys = pg.key.get_pressed()
if keys[pg.K_RIGHT]:
self.rect.x += 5
if keys[pg.K_LEFT]:
self.rect.x -= 5
if keys[pg.K_UP]:
self.rect.y -= 5
if keys[pg.K_DOWN]:
self.rect.y += 5
if self.rect.right > width:
self.rect.right = width
if self.rect.left < 0:
self.rect.left = 0
if self.rect.top < 0:
self.rect.top = 0
if self.rect.bottom > height:
self.rect.bottom = height
class Coin(pg.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pg.transform.scale(coin_img, (c_width, c_height))
self.image.set_colorkey(white)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.radius = 18
class Gegner_1(pg.sprite.Sprite):
def __init__(self, x, y, yon):
super().__init__()
self.image_orig = pg.transform.scale(gegner_1, (p_width, p_height))
self.image_orig.set_colorkey(white)
self.image = self.image_orig.copy()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.radius = 35
self.yon = yon
if yon == 'yes':
self.speedx = 5
self.speed = self.speedx
elif yon == 'no':
self.speedy = 5
self.speed = self.speedy
def update(self):
if self.yon == 'yes':
self.rect.x += self.speed
if self.yon == 'no':
self.rect.y += self.speed
if self.rect.right > width:
self.speed = -5
if self.rect.left == 0:
self.speed = 5
if self.rect.bottom > height:
self.speed = -5
if self.rect.top < 0:
self.speed = 5
all_sprites = pg.sprite.Group()
coin_group = pg.sprite.Group()
enemys_group = pg.sprite.Group()
player = Player()
gegner1 = Gegner_1(0, 60, 'yes')
gegner2 = Gegner_1(width, 350, 'yes')
gegner3 = Gegner_1(50, p_height, 'no')
gegner4 = Gegner_1(width - p_width - 20, p_height, 'no')
enemys_group.add(gegner1, gegner2, gegner3, gegner4)
all_sprites.add(player)
for c in range(3):
new_coin()
start_game = True
game_over = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if start_game:
start_screen()
start_game = False
screen.fill(bg_color)
if score >= 5:
all_sprites.add(gegner1)
if score >= 10:
all_sprites.add(gegner2)
if score >= 15:
all_sprites.add(gegner3)
if score >= 20:
all_sprites.add(gegner4)
all_sprites.draw(screen)
all_sprites.update()
draw_text(screen, 'SCORE: ' + str(score), white, 20, 55, 10)
hits = pg.sprite.spritecollide(player, coin_group, True, pg.sprite.collide_circle)
for hit in hits:
score += 1
coin_snd.play()
new_coin()
hits = pg.sprite.spritecollide(player, enemys_group, True, pg.sprite.collide_circle)
for hit in hits:
lives -= 1
pg.display.update()
clock.tick(FPS)
pg.quit()
I also don't get any errors because of this.
The way you add and remove the gegner instances causes this problem. The enemys_group contains the gegners in the beginning and is used for the collision detection. That means you can already collide with them before they are visible (print the groups and hit in the for hit in hits: loop to check this). If you hit an instance, it is removed from the enemys_group correctly.
Then if you reach a score of 5 or higher you keep adding the instances, that are still bound to the gegner1, etc. variables, to the all_sprites group each frame, so the sprites become visible, but if they're not in the enemys_group they can't collide anymore.
You need to restructure the code. I'd leave the enemys_group empty at the beginning and then add the gegner instances in the coin collision loop:
hits = pg.sprite.spritecollide(player, coin_group, True, pg.sprite.collide_circle)
for hit in hits:
score += 1
new_coin()
if score == 5:
gegner = Gegner_1(0, 60, 'yes')
all_sprites.add(gegner)
enemys_group.add(gegner)
elif score == 10:
gegner = Gegner_1(width, 350, 'yes')
all_sprites.add(gegner)
enemys_group.add(gegner)
elif score == 15:
gegner = Gegner_1(50, p_height, 'no')
all_sprites.add(gegner)
enemys_group.add(gegner)
elif score == 20:
gegner = Gegner_1(width - p_width - 20, p_height, 'no')
all_sprites.add(gegner)
enemys_group.add(gegner)

Text not bliting to the screen on my pygame script with python

I wanted to add a sorta ammo clip thing in my shooter game, its very simple all I do is blit I * the ammount of ammo, but I wanted there to be three lines to show the clip like so:
IIIIIIIIIIIIIIIIIIIIII
IIIIIIIIIIIIIIIIIIIIII
IIIIIIIIIIIIIIIIIIIIII
Each line has 35 ammo symbols but if the player has more than 95 ammo I wanted it to blit that anount as a number next to the ammo clip, but no matter how much ammo I have it never blits the number and no matter how much ammo I have at the start it never blits more than this at the start until I collect a ammo box:
IIIIIIIIII
I really cant find out why it is doing this, I've tryed changing the amount it blits and many other things but nothing seems to work, so hear is my code:
#wave font
font = pygame.font.SysFont("", 34)
self.text_pause = font.render("WAVE " + str(self.wave) * self.blitwave, -1, RED)
self.text_pause_rect = self.text_pause.get_rect(center=self.screen.get_rect().center) # center text
texthealth = int(self.health / 10)
#health font
self.text_health = font.render("o" * texthealth, -1, RED)
#score font
self.text_score = font.render("SCORE " + str(self.score), -1, BLACK)
#cash font
self.text_cash = font.render(str(self.cash), -1, GREEN)
#ammo font
self.text_ammoS = font.render("I" * 35, -1, RED)
self.text_ammo = font.render("I" * self.ammo_amount, -1, RED)
self.text_ammoW = font.render("I" * (self.ammo_amount - 35), -1, RED)
self.text_ammoE = font.render("I" * (self.ammo_amount - 70), -1, RED)
self.text_ammoN = font.render(str(self.ammo_amount), -1, RED)
# send event to player
self.player.event_handler(event)
if not PAUSED:
self.all_sprites_list.update()
self.bullets_update()
player_rect = pygame.Rect(self.player.rect.x, self.player.rect.y, 20, 20)
block_rect = pygame.Rect(block.rect.x, block.rect.y, 20, 20)
I thought i could make a rect that follows the blocks and if that rect collides witht he player they die, pretty much using the same system as the ammo, coz that works instantly
if pygame.sprite.collide_rect(self.player, block):
self.player.health =- 00.0000000003
print('hit')
if self.ammo and player_rect.colliderect(self.ammo.rect):
self.ammo_amount += 70
self.all_sprites_list.remove(self.ammo)
self.ammo = None
#if self.Bomb and player_rect.colliderect(self.ammo.rect):
#print('nuke')
#self.all_sprites_list.remove(self.ammo)
#self.Bomb = None
self.crosshair.update()
# --- draws ---
self.background.draw(self.screen)
self.all_sprites_list.draw(self.screen)
#must be last
self.screen.blit(self.text_pause, (10, 610))
self.screen.blit(self.text_score, (700, 10))
self.screen.blit(self.text_cash, (740, 500))
#self.screen.blit(self.text_ammo, (450, 610))
if self.ammo_amount > 0 and self.ammo_amount < 36:
self.screen.blit(self.text_ammo, (600, 540))
if self.ammo_amount > 35 and self.ammo_amount < 71:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoW, (600, 560))
if self.ammo_amount > 70 and self.ammo_amount < 96:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoS, (600, 560))
self.screen.blit(self.text_ammoE, (600, 580))
if self.ammo_amount > 95:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoS, (600, 560))
self.screen.blit(self.text_ammoS, (600, 580))
self.screen.blit(self.text_ammoN, (550, 580))
self.screen.blit(self.text_health, (5, 5))
self.crosshair.draw(self.screen)
pygame.display.update() # use flip() OR update()
# --- FPS ---
clock.tick(70)
# --- quit ---
pygame.quit()
#----------------------------------------------------------------------
Game().run()
That is the important part but if you would like to see the whole code here it is:
import pygame
from pygame import *
import sys
import math
import random
import cmath
#----------------------------------------------------------------------
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
GREEN = (154 ,205, 50)
#images
IMAGE_GRASS = "grass_shit.png"
IMAGE_PLAYER = "shithead.png"
IMAGE_ALI = "shit_head2.png"
IMAGE_DEAD_SCREEN = "dead_shit.png"
IMAGE_CROSSHAIR = "crosshair.png"
IMAGE_PLAYBUTTON = "playbutton.png"
IMAGE_AMMO = "ammoshit.png"
#----------------------------------------------------------------------
class Block(pygame.sprite.Sprite):
def __init__(self, color, x, y, player = None):
pygame.sprite.Sprite.__init__(self)
self.player = player
self.image = pygame.Surface([20, 20])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.move_x = self.move_y = 0
def update(self):
if self.player:
player_x, player_y = self.player.rect.center
if self.rect.x < player_x:
self.rect.x += 1
elif self.rect.x > player_x:
self.rect.x -= 1
if self.rect.y < player_y:
self.rect.y += 1
elif self.rect.y > player_y:
self.rect.y -= 1
#----------------------------------------------------------------------
class Player(pygame.sprite.Sprite):
def __init__(self, screen_rect, x=0, y=0):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20,20])
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.min_x = screen_rect.left
self.min_y = screen_rect.top
self.max_x = screen_rect.right
self.max_y = screen_rect.bottom
self.move_x = self.move_y = 0
self.health = 138
def update(self):
pos = pygame.mouse.get_pos()
self.rect.x += self.move_x
self.rect.y += self.move_y
if self.rect.top < self.min_x:
self.rect.top = self.min_x
elif self.rect.bottom > self.max_y:
self.rect.bottom = self.max_y
if self.rect.left < self.min_x:
self.rect.left = self.min_x
elif self.rect.right > self.max_x:
self.rect.right = self.max_x
def event_handler(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
self.move_x = -8
elif event.key == pygame.K_d:
self.move_x = +8
elif event.key == pygame.K_w:
self.move_y = -8
elif event.key == pygame.K_s:
self.move_y = +8
if event.type == pygame.KEYUP:
if event.key in (pygame.K_a, pygame.K_d):
self.move_x = 0
elif event.key in (pygame.K_w, pygame.K_s):
self.move_y = 0
#----------------------------------------------------------------------
class Bullet(pygame.sprite.Sprite):
def __init__(self, start_pos, mouse_pos):
pygame.sprite.Sprite.__init__(self)
self.start_rect = start_pos.rect.copy()
self.mouse_x, self.mouse_y = mouse_pos # mouse[0], mouse[1]
self.image = pygame.Surface([5, 5])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.centerx = self.start_rect.centerx
self.rect.centery = self.start_rect.centery
self.speed = 20
self.max_range = 100
self.current_range = 0
distance_x = self.mouse_x - self.start_rect.centerx
distance_y = self.mouse_y - self.start_rect.centery
norm = math.sqrt(distance_x ** 2 + distance_y ** 2)
direction_x = distance_x / norm
direction_y = distance_y / norm
self.bullet_vector_x = direction_x * self.speed
self.bullet_vector_y = direction_y * self.speed
def update(self):
self.current_range += 1
if self.current_range < self.max_range:
#print self.start_rect.centerx + (self.bullet_vector_x*self.current_range),
#print self.rect.centerx + self.bullet_vector_x,
#self.rect.centerx += self.bullet_vector_x
self.rect.centerx = self.start_rect.centerx + (self.bullet_vector_x*self.current_range)
#print self.rect.centerx
#self.rect.centery += self.bullet_vector_y
self.rect.centery = self.start_rect.centery + (self.bullet_vector_y*self.current_range)
else:
self.kill()
#----------------------------------------------------------------------
class Crosshair(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(IMAGE_CROSSHAIR).convert_alpha()
self.rect = self.image.get_rect()
def update(self):
mouse_x, mouse_y = pygame.mouse.get_pos()
self.rect.centerx = mouse_x
self.rect.centery = mouse_y
def draw(self, screen):
screen.blit(self.image,self.rect.topleft)
#----------------------------------------------------------------------
class Background(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(IMAGE_GRASS).convert_alpha()
self.rect = self.image.get_rect()
def draw(self, screen):
screen.fill((128,128,128))
screen.blit(self.image,(0,0))
#----------------------------------------------------------------------
class Ammo(pygame.sprite.Sprite):
def __init__(self, color, x, y, player = None):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20, 20])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
pass
class Bomb(pygame.sprite.Sprite):
def __init__(self, color, x, y, player = None):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20, 20])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
pass
class Game():
def __init__(self):
pygame.init()
screen_width = 850
screen_height = 640
place_ammo = False
self.screen = pygame.display.set_mode( (screen_width,screen_height) )
pygame.mouse.set_visible(False)
#-----
self.all_sprites_list = pygame.sprite.Group()
self.block_list = pygame.sprite.Group()
self.bullet_list = pygame.sprite.Group()
self.blitwave = 1
# --- create sprites ---
self.background = Background()
self.player = Player(self.screen.get_rect(), 0, 370)
self.all_sprites_list.add(self.player)
self.ammo = Ammo(self.screen.get_rect(),random.randrange(10, 750),random.randint(10,600 - 10))
self.all_sprites_list.add(self.ammo)
self.ammo_amount = 100
self.on_screen = 1
self.score = 0
self.crosshair = Crosshair()
def bullet_create(self, start_pos, mouse_pos):
bullet = Bullet(start_pos, mouse_pos)
self.all_sprites_list.add(bullet)
self.bullet_list.add(bullet)
def bullets_update(self):
for bullet in self.bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, self.block_list, True)
screen_width = 850
screen_height = 640
for block in block_hit_list:
self.bullet_list.remove(bullet)
self.all_sprites_list.remove(bullet)
self.score += 1
self.on_screen -= 1
self.ammo_chance = self.ammo_amount * 5
if self.ammo_chance > 0:
self.drop = random.randint(1, self.ammo_chance)
print(self.drop)
if self.drop > 0 and self.drop < 2:
print('ammo drop')
self.ammo = Ammo(self.screen.get_rect(),random.randrange(10,screen_width),random.randint(10,screen_height - 10))
self.all_sprites_list.add(self.ammo)
if bullet.rect.y < -10:
self.bullet_list.remove(bullet)
self.all_sprites_list.remove(bullet)
# -------- Main Program Loop -----------
def run(self):
screen_width = 850
screen_height = 640
#wave
self.wave = 1
self.wave_no = 2
self.wave_running = True
block = Block(BLUE, random.randrange(100, screen_width), random.randrange(10, screen_height-10), self.player)
self.block_list.add(block)
self.all_sprites_list.add(block)
clock = pygame.time.Clock()
self.cash = 1
self.health = 100
self.ammo_amount = 10
RUNNING = True
PAUSED = False
while RUNNING:
# --- events ---
if self.player.health <= 0:
RUNNING = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = PAUSED
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
PAUSED = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
PAUSED = not PAUSED
elif event.type == pygame.MOUSEBUTTONDOWN and self.ammo_amount > 0:
self.bullet_create(self.player, event.pos)
self.ammo_amount -= 1
self.cash = self.score * 5
if self.on_screen == 0:
for i in range(self.wave_no):
block = Block(BLUE, random.randrange(100, screen_width), random.randrange(10, screen_height-10), self.player)
self.block_list.add(block)
self.all_sprites_list.add(block)
self.on_screen += 1
self.wave_div = int(self.wave_no / 2)
self.wave_no += self.wave_div
self.wave += 1
#wave font
font = pygame.font.SysFont("", 34)
self.text_pause = font.render("WAVE " + str(self.wave) * self.blitwave, -1, RED)
self.text_pause_rect = self.text_pause.get_rect(center=self.screen.get_rect().center) # center text
texthealth = int(self.health / 10)
#health font
self.text_health = font.render("o" * texthealth, -1, RED)
#score font
self.text_score = font.render("SCORE " + str(self.score), -1, BLACK)
#cash font
self.text_cash = font.render(str(self.cash), -1, GREEN)
#ammo font
self.text_ammoS = font.render("I" * 35, -1, RED)
self.text_ammo = font.render("I" * self.ammo_amount, -1, RED)
self.text_ammoW = font.render("I" * (self.ammo_amount - 35), -1, RED)
self.text_ammoE = font.render("I" * (self.ammo_amount - 70), -1, RED)
self.text_ammoN = font.render(str(self.ammo_amount), -1, RED)
# send event to player
self.player.event_handler(event)
if not PAUSED:
self.all_sprites_list.update()
self.bullets_update()
player_rect = pygame.Rect(self.player.rect.x, self.player.rect.y, 20, 20)
block_rect = pygame.Rect(block.rect.x, block.rect.y, 20, 20)
#I thought i could make a rect that follows the blocks and if that rect collides witht he player they die, pretty much using the same system as the ammo, coz that works instantly
if pygame.sprite.collide_rect(self.player, block):
self.player.health =- 00.0000000003
print('hit')
if self.ammo and player_rect.colliderect(self.ammo.rect):
self.ammo_amount += 70
self.all_sprites_list.remove(self.ammo)
self.ammo = None
#if self.Bomb and player_rect.colliderect(self.ammo.rect):
#print('nuke')
#self.all_sprites_list.remove(self.ammo)
#self.Bomb = None
self.crosshair.update()
# --- draws ---
self.background.draw(self.screen)
self.all_sprites_list.draw(self.screen)
#must be last
self.screen.blit(self.text_pause, (10, 610))
self.screen.blit(self.text_score, (700, 10))
self.screen.blit(self.text_cash, (740, 500))
#self.screen.blit(self.text_ammo, (450, 610))
if self.ammo_amount > 0 and self.ammo_amount < 36:
self.screen.blit(self.text_ammo, (600, 540))
if self.ammo_amount > 35 and self.ammo_amount < 71:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoW, (600, 560))
if self.ammo_amount > 70 and self.ammo_amount < 96:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoS, (600, 560))
self.screen.blit(self.text_ammoE, (600, 580))
if self.ammo_amount > 95:
self.screen.blit(self.text_ammoS, (600, 540))
self.screen.blit(self.text_ammoS, (600, 560))
self.screen.blit(self.text_ammoS, (600, 580))
self.screen.blit(self.text_ammoN, (550, 580))
self.screen.blit(self.text_health, (5, 5))
self.crosshair.draw(self.screen)
pygame.display.update() # use flip() OR update()
# --- FPS ---
clock.tick(70)
# --- quit ---
pygame.quit()
#----------------------------------------------------------------------
Game().run()
Thank you so much for your time and help.
You don't blit ammo number - see # in line:
#self.screen.blit(self.text_ammo, (450, 610))
And it has to be text_ammoN not text_ammo
By the way:
You have to much code in main loop - put some code in functions like update_wave_text() , update_ammo_text(), etc. , blit_wave_text(), blit_ammo_tex(), etc.
Use self.: in __init__ set
self.screen_width = 850
self.screen_height = 640
and than use self.screen_width, self.screen_height and you will not have to repeat
screen_width = 850
screen_height = 640

Categories