I made a game where blocks fall and you have to dodge it but can't get the hitboxes right - python-3.x

The hitbox seems to be on the left side of the cube, so it feels like the game is ending without me even hitting anything. I want to make it that the hitbox is exactly on the red rectangle, so that it's obvious that the black rectangle had hit you.
the up and down controls are just for future movement option if needed.
here's the code
import pygame as pg,pygame
import random
import sys
pygame.init()
WIDTH = 1000
HEIGHT = 800
# Positions, sizes
SPEED = 10
MIDDLE = [500, 400]
score = 0
player_size = 90
player_pos = [WIDTH/2, HEIGHT-2*player_size]
playerX_move = 0
playerY_move = 0
enemy_size = 50
enemy_pos = [random.randint(0,WIDTH - enemy_size), 30]
enemy_list = [enemy_pos]
# Colors
WHITE = [255, 255, 255]
GREY = [25, 25, 25]
BLUE = [65,105,225]
BLACK = [0,0,0]
GREEN = [65,255,105]
RED = [255,0,0]
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
screen = pygame.display.set_mode((WIDTH,HEIGHT))
game_over = False
clock = pygame.time.Clock()
def drop_enemies(enemy_list):
delay = random.random()
if len(enemy_list) < 10 and delay < 0.1:
x_pos = random.randint(0,WIDTH-enemy_size)
y_pos = 30
enemy_list.append([x_pos, y_pos])
def draw_enemies(enemy_list):
for enemy_pos in enemy_list:
pygame.draw.rect(screen,BLACK, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size))
def update_enemy_positions(enemy_list, score):
for idx, enemy_pos in enumerate(enemy_list):
if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT:
enemy_pos[1] += SPEED
else:
enemy_list.pop(idx)
score += 1
return score
def collision_check(enemy_list, player_pos):
for enemy_pos in enemy_list:
if detect_collision(enemy_pos, player_pos):
return True
return False
def detect_collision(player_pos, enemy_pos):
p_x = player_pos[0]
p_y = player_pos[1]
e_x = enemy_pos[0]
e_y = enemy_pos[1]
if (e_x >= p_x and e_x < (p_x + player_size)) or (p_x >= e_x and p_x < (e_x+enemy_size)):
if (e_y >= p_y and e_y < (p_y + player_size)) or (p_y >= e_y and p_y < (e_y+enemy_size)):
return True
return False
while not game_over:
player_pos[0] += playerX_move
player_pos[1] += playerY_move
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_move = -5
if event.key == pygame.K_RIGHT:
playerX_move = 5
# if event.key == pygame.K_UP:
# playerY_move = -5
# if event.key == pygame.K_DOWN:
# playerY_move = 5
if event.key == pygame.K_a:
playerX_move = -15
if event.key == pygame.K_d:
playerX_move = 15
# if event.key == pygame.K_w:
# playerY_move = -15
# if event.key == pygame.K_s:
# playerY_move = 15
if event.key == pg.K_SPACE:
print("SPACE")
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d or event.key == pygame.K_s or event.key == pygame.K_w:
playerX_move = 0
playerY_move = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame.K_UP:
playerX_move = 0
playerY_move = 0
screen.fill(BLACK)
drop_enemies(enemy_list)
score = update_enemy_positions(enemy_list,score)
if collision_check(enemy_list, player_pos):
game_over = True
draw_enemies(enemy_list)
pygame.draw.rect(screen, RED, (player_pos[0], player_pos[1], 90, 90))
clock.tick(30)
pygame.display.update()

I would recommend using a list of pygame.Rects instead of a List with the positions of your enemies. This would also allow you to use pygame.Rect.colliderect() instead of your detect_collision function.
I've also linked the Pygame Docs.

Related

in my incomplete version of space invaders, the 1 bullet is not being fired.. but no error message is shown. can somebody review it suggest a solution [duplicate]

This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I stop more than 1 bullet firing at once?
(1 answer)
Closed 6 days ago.
import pygame
import random
# get the window
pygame.init
# window var declarataion and parameters
window = pygame.display.set_mode((800, 600))
background = pygame.image.load("space bg.png")
# characters
# spaceship
playerImg = pygame.image.load("spaceship-2.png")
playerX = 360
playerY = 535
playerX_change = 0
#enemy
enemyImg = pygame.image.load("space-invaders.png")
enemyX = random.randint(0, 536)
enemyY = random.randint(0, 120)
enemyX_change = 1
enemyY_change = 30
#bullet
bulletImg = pygame.image.load("space-invaders.png")
bulletX = playerX
bulletY = 535
bulletX_change = 0
bulletY_change = -100
bullet_state = "ready"
# character functions
#spaceship
def player(x, y):
window.blit(playerImg, (playerX, playerY))
def enemy(x, y):
window.blit(enemyImg, (enemyX, enemyY))
def fire_bullet(x, y):
global bullet_state
if bullet_state == "fire":
window.blit(bulletImg, (playerX + 16, playerY + 10))
# full loop
running = True
while running:
# to change the color of window
window.fill((255, 255, 255))
window.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# check if key pressed is right or left and executes events accordingly
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -1
if event.key == pygame.K_RIGHT:
playerX_change = 1
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# enemy movement
# loops the enemy movement
enemyX += enemyX_change
# to change the enemy direction when border of window hit
if enemyX <= 0:
enemyY += enemyY_change
enemyX_change = 1
elif enemyX >= 736:
enemyY += enemyY_change
enemyX_change = -1
# calling function
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
i tried to make the bullet move along the y axis of the spaceship by adding the code shown below into the keystroke code section:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -1
if event.key == pygame.K_RIGHT:
playerX_change = 1
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
but no error message is shown, the bullet is not being shown, but everything else works perfectly.. like the invader moving along the x axis infinitely, and the spaceship can still be controlled by my arrow key.. only thing that doesn't work is the bullet not firing from the spaceship.. and I can't seem to make it work with this code.. if someone could tell me where I went wrong, it would be of tons of help, and I've been on this problem for days now.. so
it would save me a lot of time in the future. thanks

Powerbar decrease script, pygame

I'm trying to create a "powerbar."
In the following code I can press left & right key to increase the bar, and the prg terminates when the bar_start_width > 400 px.
I would like the "powerbar" to decrease while bar_start_width > 0. So, if you stop to press the buttons, the bar will slowly decrease until bar_start_width > 0.
With my code it is slowly decreasing bar_start_width, but not updating the display. The while loop also continues running.
Here is full code:
import time
import random
import pygame
import time
import pygame
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
def powerbar(thingx, thingy, thingw, thingh, color):
pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh])
def game_quit():
pygame.quit()
quit()
def game_loop():
decrease_speed = -1
bar_start_width = 0
bar_x = 100
bar_y = 100
bar_height = 50
bar_color = black
x_change = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white) # the background color before img
# Should change so you can ONLY press right after left (or opposite)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = 5
if event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
bar_start_width += x_change
# Draw powerbar
powerbar(bar_x, bar_y, bar_start_width, bar_height, bar_color)
if bar_start_width > 10:
while True:
bar_start_width += decrease_speed
time.sleep(0.5)
print(bar_start_width) #See output in terminal
if bar_start_width == 0:
break
if bar_start_width > 400:
game_quit()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
I have tried also to think in terms of a for loop to solve my problems but after long time of trying out different things this is the best I can come up with.
Can anyone help, or link me to a similar discussion?
Thanks!
I'm not sure why you have a nested while loop in the main while loop. If I understand you correctly, you want to decrease the width every frame if (not while) the width is greater than 0. Just remove the while loop and the time.sleep call and decrease the width if bar_start_width > 0:.
import pygame
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
def game_loop():
decrease_speed = -1
bar_start_width = 0
bar_x = 100
bar_y = 100
bar_height = 50
x_change = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = 5
elif event.key == pygame.K_RIGHT:
x_change = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
bar_start_width += x_change
if bar_start_width > 0:
bar_start_width += decrease_speed
if bar_start_width <= 0: # Set it to the minimum width of 1.
bar_start_width = 1
if bar_start_width > 400:
print('> 400')
gameDisplay.fill(white)
# Draw powerbar
pygame.draw.rect(gameDisplay, black, (bar_x, bar_y, bar_start_width, bar_height))
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
I've rearranged a few things, because the game logic and the event loop were mixed. You should generally try to separate the event handling, game logic and the rendering.

New to Pygame, trying to rotate a png image but it it freezing the window

This is my program ive been working on with pygame, its a snake-like game where you collect apples to extend your snake and gain score, simple. But my problem atm is i am trying rotate my .png file snake head so it rotates with the snake as it moves, but whenever i try to the window freezes. The code that is freezing the window is just one extra line of code on (python) line 112, the line of code is simply:
return direction
This is the working code below:
import pygame
import time
import random
pygame.init()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Snake')
img_snake_head = pygame.image.load('C:/Users/Pc/Desktop/School Stuff/Programs/Python Programs/Large Projects & Home Projects/Snake Pygame/snake_head.png')
clock = pygame.time.Clock()
direction = "right"
font = pygame.font.SysFont(None, 45)
def snake(block_size, snakelist):
if direction == "right":
head = pygame.transform.rotate(img_snake_head, 270)
if direction == "left":
head = pygame.transform.rotate(img_snake_head, 90)
if direction == "up":
head = img_snake_head
if direction == "down":
head = pygame.transform.rotate(img_snake_head, 180)
gameDisplay.blit(img_snake_head, (snakelist[-1][0],snakelist[-1][1]))
for XnY in snakelist[:-1]:
pygame.draw.rect(gameDisplay, green, [XnY[0], XnY[1], block_size, block_size])
def message_to_screen(msg,colour):
screen_text = font.render(msg, True, colour)
gameDisplay.blit(screen_text, [display_width/2 - screen_text.get_width()/2, display_height/2 - screen_text.get_height()/2])
def gameLoop():
global direction
PlayerScore = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = "left"
lead_x_change = -block_size
lead_y_change = 0
elif event.key == pygame.K_RIGHT:
direction = "right"
lead_x_change = block_size
lead_y_change = 0
elif event.key == pygame.K_UP:
direction = "up"
lead_y_change = -block_size
lead_x_change = 0
elif event.key == pygame.K_DOWN:
direction = "down"
lead_y_change = block_size
lead_x_change = 0
#This is where the 'return direction' goes, as i mentioned which was the code freezing the window...
if lead_x >= display_width or lead_x <= 0 or lead_y >= display_height or lead_y <= 0:
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
gameDisplay.fill(blue)
pygame.draw.rect(gameDisplay, red, [randAppleX,randAppleY,AppleThickness,AppleThickness])
snakehead = []
snakehead.append(lead_x)
snakehead.append(lead_y)
snakelist.append(snakehead)
snake(block_size, snakelist)
if len(snakelist) > snakelength:
del snakelist[0]
if snakeMoving == True:
if snakehead in snakelist[:-1]:
gameOver = True
snake(block_size, snakelist)
scoretext = font.render("Score: "+str(PlayerScore), 0, (10,10,10))
gameDisplay.blit(scoretext, (5, 10))
pygame.display.update()
if lead_x >= randAppleX and lead_x < randAppleX + AppleThickness or lead_x + block_size > randAppleX and lead_x + block_size < randAppleX + AppleThickness:
if lead_y >= randAppleY and lead_y < randAppleY + AppleThickness or lead_y + block_size > randAppleY and lead_y + block_size < randAppleY + AppleThickness:
randAppleX = round(random.randrange(10, display_width-AppleThickness)/10.0)*10.0
randAppleY = round(random.randrange(10, display_height-AppleThickness)/10.0)*10.0
snakelength += 1
PlayerScore += 10
clock.tick(FPS)
pygame.quit()
quit()
gameLoop()
I hope someone can tell me why this is freezing as soon as possible! Thanks in advance!
The problem was that you assigned the rotated image to a variable head but blitted img_snake_head. In your snake function change:
gameDisplay.blit(img_snake_head, (snakelist[-1][0],snakelist[-1][1]))
to
gameDisplay.blit(head, (snakelist[-1][0],snakelist[-1][1]))
and it should fix the problem.

make sprite crouch in current position python

Hi i'm making a fighting game to get some practice with pygame but I have run into a problem with crouching/ducking. When I press the down button it goes back to its original location then ducks. If you need more info to help i will provide.
import pygame
import random
display_height = 600
display_width = 1000
dis_screen = pygame.display.set_mode((display_width, display_height))
FPS = 30
clock = pygame.time.Clock()
img = pygame.image.load('foo.png')
crouchimg = pygame.image.load('crouchimg.png')
# Simple player object
class Player(object):
def __init__(self, x, y, image):
self.x = x
self.y = y
self.image = image
# Method to draw object
def draw(self):
dis_screen.blit(self.image, (self.x, self.y))
# Method to move object
def move(self, speedx, speedy):
self.x += speedx
self.y += speedy
class MainRun(object):
def __init__(self, displayw, displayh):
self.dw = displayw
self.dh = displayh
self.Main()
def Main(self):
# Put all variables up here
stopped = False
x_move = 0
y_move = 0
p1_y_loc = 200
p1_x_loc = 200
x = pygame.Rect().x
greg = Player(p1_x_loc, p1_y_loc, img)
# Main Loop
while not stopped:
print(x)
dis_screen.fill((255, 255, 255)) # Tuple for filling display... Current is white
# Event Tasking
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
y_move = 0
x_move = 5
elif event.key == pygame.K_LEFT:
y_move = 0
x_move = -5
elif event.key == pygame.K_UP:
y_move = -5
x_move = 0
elif event.key == pygame.K_DOWN:
p1_y_loc = 300
p1_x_loc = 0
greg = Player(p1_x_loc, p1_y_loc, crouchimg)
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
p1_y_loc = 200
greg = Player(p1_x_loc, p1_y_loc, img)
if event.key == pygame.K_UP:
y_move = 0
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
x_move = 0
greg.move(x_move, y_move)
greg.draw()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
run = MainRun(display_width, display_height)
run.Main()
That's because when you're pressing the down key you're creating a new player at the x-position p1_x_loc (which you've set to 0) and y-position p1_y_loc (which you've set to 300). So when the player crouches it also moves it to (0, 300) no matter the position the player currently is.
A way to solve this would be to just change the player's image, and not create a completely new player. You can do it this way, player.image = crouchimg instead of greg = Player(p1_x_loc, p1_y_loc, crouchimg). And when the player gets up you just change the image again: player.image = img
And if you have to change the players' y-position when crouching you could do it the same way: player.y = 200 and player.y = 300.

Why does the display of text decrease my pygame FPS?

I'm trying to write this simple game that replicates a few aspects of Asteroids and have had some problems with the FPS. I have not finished the game yet, but was concerned about the FPS drop as I have a lot more text that I wish to display, but am unable to display for fear the game will suffer so much frame drop. I have only noticed this frame drop with text being displayed on screen. My code can be found below.
import os
import pickle
import pygame
from pygame.locals import *
import random
import sys
import time
pygame.init()
pygame.display.init()
common_drops = ['Janus', 'Peace of Mind', 'Second Chance']
rare_drops = ['Invincibility', 'Shield', 'Bonus Credits', 'Weapon']
ultra_rare_drops = []
janus_count = 0
peace_of_mind_count = 0
bonus_lives_count = 0 #Second Chance
invincibility_count = 0
shield_count = 0
weapon_count = 0
credit_count = 30
high_score = 0
def save():
loot_out = open('./nec_files/user_data/player.pickle', 'wb')
pickle.dump(player_loot_data, loot_out)
loot_out.close()
if os.path.isfile('./nec_files/user_data/player.pickle') == True:
loot_in = open('./nec_files/user_data/player.pickle', 'rb')
loot_dict = pickle.load(loot_in)
player_loot_data = {
'janus_count' : loot_dict['janus_count'],
'peace_of_mind_count' : loot_dict['peace_of_mind_count'],
'bonus_lives_count' : loot_dict['bonus_lives_count'], #Second Chance
'invincibility_count' : loot_dict['invincibility_count'],
'shield_count' : loot_dict['shield_count'],
'weapon_count' : loot_dict['weapon_count'],
'credit_count' : loot_dict['credit_count'],
'high_score' : loot_dict['high_score']
}
loot_in.close()
save()
else:
player_loot_data = {
'janus_count' : janus_count,
'peace_of_mind_count' : peace_of_mind_count,
'bonus_lives_count' : bonus_lives_count, #Second Chance
'invincibility_count' : invincibility_count,
'shield_count' : shield_count,
'weapon_count' : weapon_count,
'credit_count' : credit_count,
'high_score' : high_score
}
save()
display_width = 1280
display_height = 720
black = (0,0,0)
white = (255,255,255)
blue = (0, 102, 204)
bright_blue = (102, 178, 255)
red = (204, 0, 0)
bright_red = (255, 51, 51)
yellow = (204, 204, 0)
bright_yellow = (255, 255, 102)
gray = (169, 169, 169)
game_title = 'Asteroids: Reimagined'
paused = False
alpha = True
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption(game_title)
print(pygame.display.get_driver())
clock = pygame.time.Clock()
playerImg = pygame.image.load('./nec_files/graphics/player_image.png')
asteroidImg = pygame.image.load('./nec_files/graphics/asteroid_image.png')
current_drops = []
def open_common_drop():
global current_drops
current_drops.clear()
if player_loot_data['credit_count'] >= 5:
player_loot_data['credit_count'] -= 5
for x in range(3):
rand_num = random.randint(0, 50)
if rand_num < 49:
drops = random.choice(common_drops)
elif rand_num >= 49:
drops = random.choice(rare_drops)
if drops == 'Janus':
player_loot_data['janus_count'] += 1
elif drops == 'Peace of Mind':
player_loot_data['peace_of_mind_count'] += 1
elif drops == 'Second Chance':
player_loot_data['bonus_lives_count'] += 1
elif drops == 'Bonus Credits':
bonus_credits = random.randint(1, 50)
player_loot_data['credit_count'] += bonus_credits
elif drops == 'Invincibility':
player_loot_data['invincibility_count'] += 1
elif drops == 'Shield':
player_loot_data['shield_count'] += 1
elif drops == 'Weapon':
player_loot_data['weapon_count'] += 1
current_drops.append(drops)
save()
def open_rare_drop():
global current_drops
current_drops.clear()
if player_loot_data['credit_count'] >= 10:
player_loot_data['credit_count'] -= 10
for x in range(3):
rand_num = random.randint(0, 50)
if rand_num < 36:
drops = random.choice(common_drops)
elif rand_num >= 36:
drops = random.choice(rare_drops)
if drops == 'Janus':
player_loot_data['janus_count'] += 1
elif drops == 'Peace of Mind':
player_loot_data['peace_of_mind_count'] += 1
elif drops == 'Second Chance':
player_loot_data['bonus_lives_count'] += 1
elif drops == 'Bonus Credits':
bonus_credits = random.randint(1, 50)
player_loot_data['credit_count'] += bonus_credits
elif drops == 'Invincibility':
player_loot_data['invincibility_count'] += 1
elif drops == 'Shield':
player_loot_data['shield_count'] += 1
elif drops == 'Weapon':
player_loot_data['weapon_count'] += 1
current_drops.append(drops)
save()
def player(player_x, player_y):
gameDisplay.blit(playerImg, (player_x, player_y))
def asteroid(thingx, thingy):
gameDisplay.blit(asteroidImg, (thingx, thingy))
def game_display_text(display_msg, display_x, display_y, text_size):
font = pygame.font.SysFont(None, text_size)
text = font.render(str(display_msg), True, black)
gameDisplay.blit(text, (display_x, display_y))
def title(msg):
largeText = pygame.font.SysFont(None, 75)
TextSurf, TextRect = text_objects(msg, largeText)
TextRect.center = ((display_width / 2), (display_height * 0.10))
gameDisplay.blit(TextSurf, TextRect)
def button(x, y, w, h, ic, ac, action = None):
global paused
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action == Game:
Game()
if click[0] == 1 and action == quitgame:
sys.exit()
if click[0] == 1 and action == None:
paused = False
if click[0] == 1 and action == StartScreen:
save()
StartScreen()
if click[0] == 1 and action == LootScreen:
LootScreen()
if click[0] == 1 and action == open_common_drop:
open_common_drop()
if click[0] == 1 and action == open_rare_drop:
open_rare_drop()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
def things(thingx, thingy, thingw, thingh, color):
pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh])
def things2(thingx, thingy, thingw, thingh, color):
pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh])
def text_box(box_x, box_y, box_w, box_h, color):
pygame.draw.rect(gameDisplay, color, [box_x, box_y, box_w, box_h])
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 50)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def reset():
message_display('Out of Bounds: Player Location Reset')
def quitgame():
pygame.quit()
sys.exit()
def StartScreen():
intro = True
settings_x = 1230
settings_y = 670
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
gameDisplay.fill(gray)
title(game_title)
button(420, 250, 125, 50, blue, bright_blue, Game)
button(720, 250, 125, 50, red, bright_red, quitgame)
button(570, 250, 125, 50, yellow, bright_yellow, LootScreen)
game_display_text('Start', 450, 260, 40)
game_display_text('Quit', 750, 260, 40)
game_display_text('Loot', 600, 260, 40)
game_display_text('Licensed by: #1024MBStudio', 925, 690, 35)
pygame.display.update()
clock.tick(30)
def LootScreen():
global current_drops
loot = True
while loot:
for event in pygame.event.get():
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_t:
open_common_drop()
elif event.key == pygame.K_y:
open_rare_drop()
if event.key == pygame.K_ESCAPE:
StartScreen()
gameDisplay.fill(gray)
title('Loot Chests!')
button(400, 150, 260, 50, blue, bright_blue, None)
button(695, 150, 260, 50, red, bright_red, None)
button(display_width * 0.42, display_height / 1.15, 255, 50, red, bright_red, StartScreen)
game_display_text('Open Common Chest (T)', 407, 165, 30)
game_display_text('Open Rare Chest (Y)', 725, 165, 30)
game_display_text('You Got: %s' % current_drops, 50, display_height / 2, 35)
game_display_text('Credits: %.2f' % player_loot_data['credit_count'], 15, 15, 35)
game_display_text('Main Menu', display_width * 0.47, display_height / 1.13, 35)
game_display_text('Janus\': %.2f' % player_loot_data['janus_count'] , 1025, 500, 35)
game_display_text('Peace of Minds: %.2f' % player_loot_data['peace_of_mind_count'], 1025, 535, 35)
pygame.display.update()
clock.tick(30)
def PauseScreen():
global paused
paused = True
pausebox_x = 0
pausebox_y = 625
pausebox_width = display_width
pausebox_height = display_height - 625
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
paused = False
gameDisplay.fill(gray)
title('Paused')
button(560, 130, 173, 50, blue, bright_blue, None)
button(560, 205, 173, 50, red, bright_red, StartScreen)
game_display_text('Resume', 590, 140, 40)
game_display_text('Quit', 615, 218, 40)
text_box(pausebox_x, pausebox_y, pausebox_width, pausebox_height, blue)
game_display_text('Janus\': %s' % player_loot_data['janus_count'] , 5, 630, 35)
game_display_text('Peace of Minds: %s' % player_loot_data['peace_of_mind_count'], 5, 665, 35)
game_display_text('Bonus Lives: %s' % player_loot_data['bonus_lives_count'], 250, 630, 35)
pygame.display.update()
clock.tick(30)
def DeadScreen():
current_score = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
gameDisplay.fill(gray)
title('You Died')
game_display_text('You earned %s' % credit_gain + ' credits that game!', display_width * 0.33, display_height * 0.40, 40)
button(520, 120, 250, 55, blue, bright_blue, Game)
button(520, 190, 250, 55, red, bright_red, StartScreen)
game_display_text('Play Again?', 560, 132, 40)
game_display_text('Main Menu', 569, 205, 40)
pygame.display.update()
clock.tick(30)
def Game():
global death_counter, attempt_counter, credit_gain
player_x = (display_width * 0.5)
player_y = (display_height * 0.5)
player_speed = 5.5
playerHeight = 50
x_change = 0
y_change = 0
enemyWidth = 165
thing_startx = 1500
thing2_startx = 1500
thing_speed = -6
thing2_speed = -5.5
thing_starty = random.randrange(75, display_height - enemyWidth)
thing2_starty = random.randrange(75, display_height - enemyWidth)
dead = False
janus = False
peace_of_mind = False
invincibility = False
full_screen = False
earnable_credits = 0.125
current_score = 0
credit_gain = 0
current_lives = 0
RESETEVENT = pygame.USEREVENT + 1
DISABLEJANUS = pygame.USEREVENT + 5
textbox_x = 0
textbox_y = 0
textbox_width = 1280
textbox_height = 60
while not dead:
if pygame.display.get_active() == True:
for event in pygame.event.get():
pygame.time.set_timer(RESETEVENT, 275)
if peace_of_mind == True:
thing_original_speed = thing_speed
thing2_original_speed = thing2_speed
if event.type == RESETEVENT:
current_score += 1
pygame.time.set_timer(RESETEVENT, 275)
if event.type == DISABLEJANUS:
janus = False
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if janus == True:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
x_change = -player_speed
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
x_change = player_speed
if event.key == pygame.K_UP or event.key == pygame.K_w:
y_change = -player_speed
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
y_change = player_speed
if event.key == pygame.K_u and player_loot_data['janus_count'] > 0 and janus == False:
pygame.time.set_timer(DISABLEJANUS, 15000)
player_loot_data['janus_count'] -= 1
janus = True
elif event.key == pygame.K_i and player_loot_data['peace_of_mind_count'] > 0 and peace_of_mind == False:
player_loot_data['peace_of_mind_count'] -= 1
peace_of_mind = True
elif event.key == pygame.K_o and player_loot_data['bonus_lives_count'] > 0:
player_loot_data['bonus_lives_count'] -= 1
current_lives += 1
if event.key == pygame.K_ESCAPE:
PauseScreen()
elif event.key == pygame.K_F4:
sys.exit()
elif event.key == pygame.K_F11:
if full_screen == False:
pygame.display.set_mode((display_width, display_height), pygame.FULLSCREEN)
full_screen = True
PauseScreen()
elif full_screen == True:
pygame.display.set_mode((display_width, display_height))
PauseScreen()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_a or event.key == pygame.K_d:
x_change = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_w or event.key == pygame.K_s:
y_change = 0
elif event.key == pygame.K_SPACE:
y_change = 0
if thing_startx < 0 - enemyWidth:
thing_startx = 1500
thing_starty = random.randrange(75, display_height - enemyWidth)
thing_speed += -0.05
player_loot_data['credit_count'] += earnable_credits
credit_gain += earnable_credits
if thing2_startx < 0 - enemyWidth:
thing2_startx = 1500
thing2_starty = random.randrange(75, display_height - enemyWidth)
thing2_speed += -0.1
player_loot_data['credit_count'] += earnable_credits
credit_gain += earnable_credits
player_x += x_change
player_y += y_change
thing_startx += thing_speed
thing2_startx += thing2_speed
if player_loot_data['high_score'] < current_score:
player_loot_data['high_score'] = current_score
if player_y > display_height:
player_y = textbox_height
if player_y < 10:
player_y = display_height - playerHeight
if player_x < 0 - playerHeight:
player_x = (display_width * 0.5)
if player_x > display_width:
player_x = (display_width * 0.5)
if player_y < thing_starty + enemyWidth and player_y + playerHeight > thing_starty:
if player_x > thing_startx and player_x < thing_startx + enemyWidth or player_x + playerHeight > thing_startx and player_x + playerHeight < thing_startx + enemyWidth:
if current_lives > 0:
current_lives -= 1
player_x = (display_width * 0.5)
player_y = (display_height * 0.5)
thing_startx = 1500
thing2_startx = 1500
else:
dead = True
if player_y < thing2_starty + enemyWidth and player_y + playerHeight > thing2_starty:
if player_x > thing2_startx and player_x < thing2_startx + enemyWidth or player_x + playerHeight > thing2_startx and player_x + playerHeight < thing2_startx + enemyWidth:
if current_lives > 0:
current_lives -= 1
player_x = (display_width * 0.5)
player_y = (display_height * 0.5)
thing_startx = 1500
thing2_startx = 1500
else:
dead = True
else:
crossover = 'null'
gameDisplay.fill(gray)
player(player_x, player_y)
asteroid(thing_startx, thing_starty)
asteroid(thing2_startx, thing2_starty)
text_box(textbox_x, textbox_y, textbox_width, textbox_height, blue)
game_display_text('High Score: %s' % player_loot_data['high_score'], 5, 5, 30)
game_display_text('Current Score: %s' % current_score, 5, 35, 30)
game_display_text('Current Chances: %s' % current_lives, 200, 5, 30)
if janus == True:
game_display_text('Janus Enabled', 850, 5, 30)
if peace_of_mind == True:
game_display_text('Peace of Mind Enabled', 850, 35, 30)
if invincibility == True:
game_display_text('Invincibility Enabled', 950, 5, 30)
if alpha == True:
game_display_text('FPS: %s' % clock.get_fps(), 5, 635, 30)
pygame.display.update()
clock.tick()
else:
PauseScreen()
DeadScreen()
if __name__ == '__main__':
StartScreen()
sys.exit()
You're doing two things wrong with your text rendering.
The first (and probably major) one is that you load the font again and again every time you want to display some text:
def game_display_text(display_msg, display_x, display_y, text_size):
font = pygame.font.SysFont(None, text_size)
...
You should create the font object once, so you don't load it every time from disk.
The second issue is that the rendering of the text to a Surface is a rather expensive operation:
def game_display_text(display_msg, display_x, display_y, text_size):
...
text = font.render(str(display_msg), True, black)
...
A better method is to cache the already created surfaces, and reuse them.
A very simple cache could look like this:
text_font = pygame.font.SysFont("whatever", 14)
cache={}
def get_msg(msg):
if not msg in cache:
cache[msg] = text_font.render(msg, 1 , text_color)
return cache[msg]
and then you would use the get_msg method to create your text surfaces. Or use something like e.g. the lru_cache decorator.

Resources