Adding enemies to game based on value of score - python

I'm a beginner and have needed a lot of help to get this far. I'm trying to add more enemies when my score reaches certain values such as 10, 20, etc. Ive tried something along the lines of if score_value >= 10: num_of_enemies = num_of_enemies + 10 but have been failing to produce results. I feel like it should be simple but i am missing how to add values to this list.
import pygame
import random
import math
from pygame import mixer
# initialize game
pygame.init()
# create screen, set height and weight (())
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('background1.png')
pygame.display.set_icon(background)
# Background sound
mixer.music.load('troubador.wav')
mixer.music.play(-1)
# Title and Icon
pygame.display.set_caption("Beasts of Cthulu")
icon = pygame.image.load('knight.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('wizard.png')
playerX = 370
playerY = 500
playerX_change = 0
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 5
max_enemies = 100
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('cthulhu.png'))
enemyX.append(random.randint(0, 735))
enemyY.append(random.randint(10, 150))
enemyX_change.append(3)
enemyY_change.append(40)
# Fireball
# ready - you cannot see fireball on screen
# fire - fireball is currently moving
fireballImg = pygame.image.load('fireball.png')
fireballX = 0
fireballY = 370
fireballX_change = 0
fireballY_change = 8
fireball_state = "ready"
# Score
score_value = 0
previous_score = score_value
font = pygame.font.Font('Enchanted_Land.otf', 32)
textX = 10
textY = 10
# Game over text
over_font = pygame.font.Font('Enchanted_Land.otf', 64)
def show_score(x, y):
score = font.render("Score :" + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (250, 200))
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def fire_fireball(x, y):
global fireball_state
fireball_state = "fire"
screen.blit(fireballImg, (x + 16, y + 10))
def isCollision(enemyX, enemyY, fireballX, fireballY):
distance = math.sqrt(math.pow(enemyX - fireballX, 2) + (math.pow(enemyY - fireballY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Keyboard actions
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -4
if event.key == pygame.K_RIGHT:
playerX_change = 4
if event.key == pygame.K_SPACE:
if fireball_state == "ready":
fireball_Sound = mixer.Sound('fireball-1.wav')
fireball_Sound.play()
fireballX = playerX
fire_fireball(fireballX, fireballY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# checking for boundaries
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Fireball movement
if fireballY <= 0:
fireballY = 480
fireball_state = "ready"
if fireball_state == "fire":
fire_fireball(fireballX, fireballY)
fireballY -= fireballY_change
# Enemy movement
enemyX += enemyX_change
for i in range(num_of_enemies):
# Game Over
if enemyY[1] > 370:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 3
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -3
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], fireballX, fireballY)
if collision:
explosion_Sound = mixer.Sound('fireball-explosion.wav')
explosion_Sound.play()
fireballY = 480
fireball_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 735)
enemyY[i] = random.randint(10, 150)
enemy(enemyX[i], enemyY[i], i)
player(playerX, playerY)
show_score(textX, textY)
pygame.display.update()

That's a lot of code and we can't run it, because we don't have the assets. What you need is a threshold, which increases once it was reached.
You can implement it like this:
import random
threshold = 10
score = 0
while score < 1000:
score += random.randint(1,4) # wherever points come from
print (f"Score {score}")
if score > threshold:
print (f"You have more than {threshold}. Adding enemies ...")
threshold += 10
See how the score can increase but enemies will only be added every 10 points and it needn't hit the value exactly.

The idea of #ThomasWeller is nice (+1). However, you will have difficulty adding it to your code.
Write a function that adds an enemy and use the function in the loop that creates the initial enemies:
enemySurf = pygame.image.load('cthulhu.png')
def addNewEnemy():
enemyImg.append(enemySurf)
enemyX.append(random.randint(0, 735))
enemyY.append(random.randint(10, 150))
enemyX_change.append(3)
enemyY_change.append(40)
for i in range(num_of_enemies):
addNewEnemy()
Use the idea of #ThomasWeller and add a new enemy when the scooter reaches a certain threshold:
threshold = 10
running = True
while running:
if score_value >= threshold:
addNewEnemy()
num_of_enemies += 1
threshold += 10
print(len(enemyX))
# [...]

Related

Class 'int' does not define '__getitem__', so the '[]' operator cannot be used on its instances [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm currently learning Pygame and got stuck on this error:
Class 'int' does not define 'getitem', so the '[]' operator cannot
be used on its instances
It happens on lines 125, 128, 134 and 144.
import pygame
import random
import math
# Initialize pygame module
pygame.init()
# Create the screen
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('back.png')
# Caption and Icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('ufo (1).png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('spaceship.png')
playerX = 370
playerY = 480
playerX_change = 0
speed = 1
minPosition = 0
maxPosition = 736
# Enemy
# corrected a bug where line31 makes enem spawns after 736 pixels which is bigger
# than enemyMaxPosition, causing it to fall off screen.
enemyImg = [] # This means an empty list
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
enemySpeed = []
enemyMinPosition = []
enemyMaxPosition = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 735))
enemyY.append(random.randint(50, 150))
enemyX_change.append(0.5)
enemyY_change.append(40)
enemySpeed.append(0.5)
enemyMinPosition.append(0)
enemyMaxPosition.append(736)
# Bullet
# bullet_isFiring = False // Can't see bullet on screen
# bullet_isFiring = True // Can see bullet on screen
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletY_change = 10
bullet_isFiring = False
# Score
score = 0
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
# global keyword access generic variable bullet_isFiring
def fire_bullet(x, y):
global bullet_isFiring
bullet_isFiring = True
screen.blit(bulletImg, (x + 16, y + 10))
# Define whether a collision between two objects has ocurred or not
# object1 // enemy
# object2 // bullet
def isCollision(object1_X, object1_Y, object2_X, object2_Y):
distance = math.sqrt(math.pow((object2_X - object1_X), 2) + math.pow((object2_Y - object1_Y), 2))
if distance < 27:
return True
# Game Loop
running = True
while running:
screen.fill((0, 0, 0))
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# If keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -speed
if event.key == pygame.K_RIGHT:
playerX_change = speed
if event.key == pygame.K_SPACE:
if bullet_isFiring is False:
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
playerX += playerX_change
enemyX += enemyX_change
# Player Movement
if playerX <= minPosition:
playerX = minPosition
elif playerX >= maxPosition:
playerX = maxPosition
# Enemy Movement
for i in range(num_of_enemies):
if enemyX[i] <= enemyMinPosition[i]:
enemyX_change[i] = enemySpeed[i]
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= enemyMaxPosition[i]:
enemyX_change[i] = -enemySpeed[i]
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
bulletY = 480
bullet_isFiring = False
score += 50
print(score)
enemyX = random.randint(0, 735)
enemyY = random.randint(0, 150)
# Enemy Spawn
enemy(enemyX[i], enemyY[i], i)
# Bullet Movement
if bulletY <= 0:
bullet_isFiring = False
bulletY = 480
if bullet_isFiring is True:
bulletY -= bulletY_change
fire_bullet(bulletX, bulletY)
player(playerX, playerY)
pygame.display.update()
enemyX and enemyY are lists of coordinates. Why you generate a new random position for an enemy you need to set the corresponding coordinate in the list:
for i in range(num_of_enemies):
# [...]
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
# [...]
# REMOVE
# enemyX = random.randint(0, 735)
# enemyY = random.randint(0, 150)
# ADD
enemyX[i] = random.randint(0, 735)
enemyY[i] = random.randint(0, 150)

Trying to add a restart keystroke to my problem but facing encounters

So I was trying to build this game using a free course on Youtube by Freecodeacademy(feel free to check them out) and after I finished I tried to add my own restart key log to the game. In the sense that I wanted that if people press R the game restarts.
I have tried the following methods
Put the game loop in a separate function and try to use recursion to replay the function over and over again but while the game does work, the images such as the bullet image or background does not load and hence it does not work properly
I have also tried creating a new python file in the same project and tried to import the main file over and over again using importlib.reload(main) but I can't seem to do that either.
I was wondering what else could the solution be and if there is a more efficient solution. I will leave my code down below and would appreciate any help.
Ps: I am only a armature in coding right now so I understand this problem might be small and stupid but I do want to learn from my failures and mistakes. Also I apologize if there is something wrong with anything in my question. This is my first question on stack overflow.
import pygame
import random
import math
from pygame import mixer
pygame.init() # This is to Initialise the game
screen = pygame.display.set_mode((800, 600)) # create screen and set height
# Background
background = pygame.image.load('background.png')
# Background sound
mixer.music.load("background.wav")
mixer.music.play(-1)
# Title and Icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load("space-invaders.png")
playerX = 370
playerY = 480
playerX_change = 0
def player(x, y): # This function is used to display the value on the screen
screen.blit(playerImg, (x, y)) # Blit is used to display stuff on the screen
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load("invader.png"))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)
def enemy(x, y, i): # This function is used to display the value on the screen
screen.blit(enemyImg[i], (x, y)) # Blit is used to display stuff on the screen
# Bullet
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready" # Ready state means bullet has not yet been fired, we use this as a bool
# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 16)
textX = 10
textY = 10
# Game Over Text
over_font = pygame.font.Font("freesansbold.ttf", 64)
def show_score(x, y):
over_text = font.render("Score: " + str(score_value), True, (255, 255, 255))
screen.blit(over_text, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER ", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
# Background color
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get(): # pygame.event.get() function is used to create a container of every action done
if event.type == pygame.QUIT: # Close game when cross is clicked
running = False
# Recording Keystrokes
if event.type == pygame.KEYDOWN: # KEYDOWN is used to check if key is pressed
if event.key == pygame.K_LEFT:
playerX_change -= 5
if event.key == pygame.K_RIGHT:
playerX_change += 5
if event.key == pygame.K_SPACE: # Bullet Shot
if bullet_state == "ready":
bullet_sound = mixer.Sound("laser.wav")
bullet_sound.play()
bulletX = playerX
fire_bullet(bulletX, playerY)
if event.key == pygame.K_r:
restart = True
if event.type == pygame.KEYUP: # KEYUP is used to know if the key is released
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Player Call
playerX += playerX_change
# Setting Boundaries
if playerX <= 0:
playerX = 0
if playerX >= 736:
playerX = 736
for i in range(num_of_enemies):
# Game Over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY += enemyY_change
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosion_sound = mixer.Sound("explosion.wav")
explosion_sound.play()
bulletY = 480
score_value += 1
bullet_state = "ready"
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet Movement
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state == "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textX, textY)
# Constantly updates the changes
pygame.display.update()
Write a function that will reset any variables that change when the game is running:
enemy_image = pygame.image.load("invader.png")
def resetGame():
global playerX, playerY, playerX_change
global enemyImg, enemyX, enemyY, enemyX_change, enemyY_change
global score_value
global bulletX, bulletY, bulletX_change, bulletY_change, bullet_state
playerX = 370
playerY = 480
playerX_change = 0
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(enemy_image)
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"
score_value = 0
Call the function once if the game needs to be restarted. You can even call the function before the application loop instead of setting all the variables.

How do i add lives into this python 3.0 game

I am quite new to python just trying to learn it. I've followed a tutorial on how to make this game and added my own stuff but I cant seem to add lives. I've tried all I know (not a lot). Anyway, all the tutorials I have watched have not worked either and I have been pulling my hair out over it for like 2 days now, so if anyone can help it would be very appreciated.
import math
import random
import pygame
from pygame import mixer
# Intialize the pygame
pygame.init( )
# create the screen
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('editor.jpg')
opensound = mixer.Sound("ftw.wav")
opensound.play( )
# Sound
mixer.music.load("bg noise.wav")
mixer.music.play(-1)
# Caption and Icon
pygame.display.set_caption("Virus Invader")
icon = pygame.image.load('virus.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('people.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('virus.png'))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(1)
enemyY_change.append(40)
# Bullet
# Ready - You can't see the bullet on the screen
# Fire - The bullet is currently moving
bulletImg = pygame.image.load('ligature.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 2
bullet_state = "ready"
# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
def Game_start_text():
over_text = over_font.render("Let the games begin!", True, (64, 64, 64))
screen.blit(over_text, (200, 250))
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX - bulletX, 2) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
# RGB = Red, Green, Blue
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get( ):
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check if its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -2
if event.key == pygame.K_RIGHT:
playerX_change = 2
if event.key == pygame.K_SPACE:
if bullet_state is "ready":
bulletSound = mixer.Sound("stab.wav")
bulletSound.play( )
# Get the current x cordinate of the charctar
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Enemy Movement
for i in range(num_of_enemies):
# Game Over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text( )
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 1
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -1
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosionSound = mixer.Sound("street fighter die.wav")
explosionSound.play( )
bulletY = 480
bullet_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet Movement
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textX, testY)
pygame.display.update( )
The reason adding this to your code is so difficult is because there's a whole bunch of extra code that's in the way.
When this happens, take a step back, and try to write a skeleton to do just what you need. When working on a huge system, say tracking down a complex bug, normally you would comment out sections of the code to pair the problem-space back to something manageable. Your code is pretty small, so maybe you can just ignore a lot of it.
In any event, take a backup of your code, then start adding the changes bit by bit, testing as you go.
First add a life-counter:
# Player
playerLives = 3 # <<-- HERE
playerImg = pygame.image.load('people.png')
playerX = 370
playerY = 480
playerX_change = 0
Then some way to test life-loss:
# if keystroke is pressed check if its right or left
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -2
elif event.key == pygame.K_RIGHT:
playerX_change = 2
elif event.key == pygame.K_d: # TEST CODE - Die on 'd' <<-- HERE
print( "Player Dies" )
playerLives -= 1
Now test this? Did it print "Player Dies" when you press d?
So... what should happen when the lives is zero? Maybe the player can't move any more:
# Has the player run out of lives?
if ( playerLives <= 0 ):
game_over_text()
else:
# Player still alive, allow controls, draw player
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
player(playerX, playerY)
Add these next changes in, test them. Does pressing d three times print "Player Dies" every time, and result in the game_over_text() function being called?
Then change the show_score() function to also draw the lives left:
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
# Write the Lives-left to the right of the score
lives = font.render("Lives : " + str(playerLives), True, (255, 255, 255))
screen.blit(lives, (x+200, y))
Test that. Does the on-screen score work? No? Make some small changes, test again, keep tweaking, keep fixing. If it all goes to hell-in-a-handcart you only need small changes to undo it.
Now that the losing-lives mechanism is working, find where it should actually take away lives, and add the changes in:
# Game Over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
playerLives -= 1 # <<-- lose a life
#game_over_text( )
reset_enemy_positions() # <<-- move enemies back to top, TODO!
break
Of course if you leave your enemies below line 440, the lose-a-life condition is still true. Thus the player will continue to lose many lives per second, every frame update. The enemies need to move back to start-position (or some suchlike).
Anyway I hope this gives you a nudge in the right direction. Maybe it would help you to try to write something yourself from scratch. Even just opening a window. Then adding key handling. Then drawing something... Incrementally add to your knowledge, I think you'll learn much faster this way. There's a reason every programming book starts with "Hello World".

Why is my pygame window not opening after I close another window and producing an unexpected error?

so here is my code:
import math
import random
import time
import pygame
from pygame import mixer
import pygame_functions
from pygame_functions import *
# Initialises pygame
pygame.init()
pygame.display.init()
#Difficulty
num_of_enemies = 0
set_positive_enemyX_change = 0
set_negative_enemyX_change = 0
#Menu
def menu(num_of_enemies, set_positive_enemyX_change, set_negative_enemyX_change):
screenSize(1000, 1000)
# text, fontSize, xpos, ypos, fontColour='black', font='Arial', background='clear'
difficultyLabel = makeLabel("Which level of difficulty would you like to play on ?<br>The types are :<br>- easy<br>- medium<br>- hard<br>- insane", 40, 10, 10, "blue", "Agency FB", "yellow")
showLabel(difficultyLabel)
# x, y, width, case, text, max length, fontsize
inputBox = makeTextBox(10, 270, 300, 0, "Enter difficulty level here", 0, 24)
showTextBox(inputBox)
difficultyInput = textBoxInput(inputBox)
easyLabel = makeLabel("easy settings applied", 40, 20, 310, "white", "Agency FB", )
mediumLabel = makeLabel("medium settings applied", 40, 20, 310, "white", "Agency FB",)
hardLabel = makeLabel("hard settings applied", 40, 20, 310, "white", "Agency FB", )
insaneLabel = makeLabel("insane settings applied", 40, 20, 310, "white", "Agency FB")
startingLabel = makeLabel("Starting game", 40, 40, 310, "red", "Agency FB")
if difficultyInput == "easy":
showLabel(easyLabel)
num_of_enemies = 4
set_positive_enemyX_change = 1
set_negative_enemyX_change = -1
end()
if difficultyInput == "medium":
showLabel(mediumLabel)
num_of_enemies = 6
set_positive_enemyX_change = 1.5
set_negative_enemyX_change = -1.5
end()
showLabel(startingLabel)
if difficultyInput == "hard":
showLabel(hardLabel)
num_of_enemies = 7
set_positive_enemyX_change = 2
set_negative_enemyX_change = -2
end()
if difficultyInput == "insane":
showLabel(insaneLabel)
num_of_enemies = 8
set_positive_enemyX_change = 3.5
set_negative_enemyX_change = -3.5
end()
else:
menu(num_of_enemies, set_positive_enemyX_change, set_negative_enemyX_change)
menu(num_of_enemies, set_positive_enemyX_change, set_negative_enemyX_change)
# Creates the screen
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('hyperspace.png')
# Sound
mixer.music.load("background.wav")
mixer.music.play(-1)
global deathSound
global liveLossSound
liveLossSound = mixer.Sound("Death sound in Minecraft.wav")
deathSound = mixer.Sound("Pacman-death.wav")
liveLossSoundBoolean = True
deathSoundBoolean = True
# Caption and Icon
pygame.display.set_caption("Space Invader")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(2)
enemyY_change.append(20)
# Bullet
# Ready - You can't see the bullet on the screen
# Fire - The bullet is currently moving
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 5
bullet_state = "ready"
# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textSX = 10
textSY = 10
# Lives
lives_value = 3
textLX = 650
textLY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def show_lives(x, y):
lives = font.render("Lives : " + str(lives_value), True, (255, 255, 255))
screen.blit(lives, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def play_liveLossSound():
liveLossSound.play()
liveLossSoundBoolean = False
def play_deathSound(deathSound):
deathSound.play()
deathSoundBoolean = False
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX - bulletX, 2) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
# RGB = Red, Green, Blue
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -2 #5
if event.key == pygame.K_RIGHT:
playerX_change = 2 #5
if event.key == pygame.K_SPACE:
if bullet_state is "ready":
bulletSound = mixer.Sound("laser.wav")
bulletSound.play()
# Gets the current x co-ordinate of the spaceship
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Enemy Movement
for i in range(num_of_enemies):
if enemyY[i] > 200: # was 440
lives_value -= 1
show_lives(textLX, textLY)
pygame.display.update()
if lives_value < 1:
for j in range(num_of_enemies):
enemyY[j] = -2000
if deathSoundBoolean:
play_deathSound(deathSound)
game_over_text()
time.sleep(5)
running = False
elif lives_value >= 1:
if liveLossSoundBoolean:
play_liveLossSound()
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
# Bouncing enemies off of edge of window // enemy speed
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = set_positive_enemyX_change
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = set_negative_enemyX_change
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosionSound = mixer.Sound("explosion.wav")
explosionSound.play()
bulletY = 480
bullet_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet Movement
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textSX, textSY)
show_lives(textLX, textLY)
pygame.display.update()
I am using this library from github https://github.com/StevePaget/Pygame_Functions/wiki ( i only used methods from this library from lines 18-63 )
I am trying to load the pygame window for my actual game after ( lines 66+) after the menu() function has finished
The problem is that I am getting these errors for no apparent reason, I am most concerned with the video initialisation error as it seems irrelevant to my program, the other errors I just do not understand as my program should logically work, as far as I understand.
You get the error video system not initialized because you called pygame.quit() beforehand (it's called by the end() function).
It even says so in the wiki of the library you use:
end()
Note: Any graphical commands which appear after the window has closed will raise an error.
There's usually no reason to call pygame.quit() at all, so I suggest to just remove it.
If you really want to close a window and open a new one, you can initialze the pygame module again (pygame.init()) and create a new window (pygame.display.set_mode(...)). But usually you're better of to restructure your code.

Why does my game made with Pygame suddenly lag for a few seconds? [duplicate]

This question already has answers here:
Lag when win.blit() background pygame
(2 answers)
Closed 2 years ago.
I made a little space invaders game with pygame, I noticed that the game lags for a few seconds periodically. I do not know what the problem is. I am a beginner.
Can you tell me why this happens? Is there any fix to this?
Also, why does everything slow down once you add the background image in the main game loop?
import pygame
from pygame import mixer
import random
import math
# Starting pygame
pygame.init()
# window
screen = pygame.display.set_mode((800, 600))
background = pygame.image.load('background.png')
# title and icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
# background
mixer.music.load('galaxy.ogg')
mixer.music.play(-1)
# player
playerimg = pygame.image.load('rocket.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemy
enemy_img = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 1
for i in range(num_of_enemies):
enemy_img.append(pygame.image.load('Enemy.png'))
enemyX.append(random.randint(0, 735))
enemyY.append(random.randint(50, 300))
enemyX_change.append(4)
enemyY_change.append(40)
# Bullet
bulletimg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"
# ready = you can't see the bullet on the screen
# fire = the bullet is currently moving
# score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
textY = 10
# gameover text
over_font = pygame.font.Font('freesansbold.ttf', 70)
def show_score(x, y):
score = font.render("Score: " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER!", True, (255, 0, 0))
screen.blit(over_text, (200, 250))
def player(x, y):
screen.blit(playerimg, (x, y))
def enemy(x, y, i):
screen.blit(enemy_img[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletimg, (x + 25, y + 10))
def iscollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX - bulletX, 2) + math.pow(enemyY - bulletY, 2))
if distance < 30:
return True
else:
return False
# gameloop
running = True
while running:
# RGB screen
screen.fill((0, 0, 0))
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Check keystroke left or right
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -10
if event.key == pygame.K_RIGHT:
playerX_change = 10
if event.key == pygame.K_SPACE:
if bullet_state is "ready":
bullet_sound = mixer.Sound('shoot.wav')
bullet_sound.play()
# gets the current x cor of the player
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
playerX_change = 0
if event.key == pygame.K_RIGHT:
playerX_change = 0
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
for i in range(num_of_enemies):
# game over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] *= -1
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] *= -1
enemyY[i] += enemyY_change[i]
# collision
collision = iscollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosion_sound = mixer.Sound('explosion.wav')
explosion_sound.play()
bulletY = 480
bullet_state = "ready"
score_value += 1
# print(score)
enemyX[i] = random.randint(0, 735)
enemyY[i] = random.randint(50, 300)
enemy(enemyX[i], enemyY[i], i)
# if enemyY <= 50:
# enemyY_change *= -1
# elif enemyY >= 300:
# enemyY_change *= -1
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textX, textY)
pygame.display.update()
Call convert() on the background image. That ensures that the image has the same pixel format as the display Surface and will help blit to operate with optimal performance:
screen = pygame.display.set_mode((800, 600))
background = pygame.image.load('background.png').convert()
Note, if the surface has a different format than the display, then blit has to convert the format on the fly in every frame.

Categories