I'm making a copy of Pac-Man with Python and Pygame, but I'm having a problem when trying to delete the dots a pills, I'm not sure of how to do it I tried to use "del" and didn't work, I also tried adding the dots to a list and then make a for loop that iterates in every dot and remove it if the player collide with one of them, but it makes the game to laggy, how can I remove the pills from the screen?
from pygame.locals import *
pygame.init()
#Variables del juego
windowWidth = 504
windowHeight = 648
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
mainClock = pygame.time.Clock()
FPS = 30
pygame.display.set_caption('Pac-Man')
#Colores
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
yellow = (255, 255, 0)
cyan = (0, 255, 255)
navyBlue = (0, 0, 53)
pink = (255, 192, 203)
#Tamaño del bloque
blockSize = 24
dotSize = 4
pillSize = 8
#Datos del jugador
playerSize = 24
player = pygame.Rect(240, 480, playerSize, playerSize)
speed = 5
#Variables de movimiento
moveLeft = moveRight = moveDown = moveUp = False
#Laberinto
maze = [
"xxxxxxxxxxxxxxxxxxxxx",
"x.........x.........x",
"x.xxx.xxx.x.xxx.xxx.x",
"x-xxx.xxx.x.xxx.xxx-x",
"x.xxx.xxx.x.xxx.xxx.x",
"x...................x",
"x.xxx.x.xxxxx.x.xxx.x",
"x.xxx.x.xxxxx.x.xxx.x",
"x.....x...x...x.....x",
"xxxxx.xxxoxoxxx.xxxxx",
"oooox.xooooooox.xoooo",
"oooox.xoxxoxxox.xoooo",
"xxxxx.xoxoooxox.xxxxx",
"ooooo.ooxoooxoo.ooooo",
"xxxxx.xoxxxxxox.xxxxx",
"oooox.xooooooox.xoooo",
"oooox.xoxxxxxox.xoooo",
"xxxxx.xoxxxxxox.xxxxx",
"x.........x.........x",
"x.xxx.xxx.x.xxx.xxx.x",
"x-..x.....o.....x..-x",
"xxx.x.x.xxxxx.x.x.xxx",
"xxx.x.x.xxxxx.x.x.xxx",
"x.....x...x...x.....x",
"x.xxxxxxx.x.xxxxxxx.x",
"x...................x",
"xxxxxxxxxxxxxxxxxxxxx"
]
def createMaze():
pointX = 0
pointY = 0
for i in maze:
for j in i:
if j == "x":
block = pygame.Rect(pointX, pointY, blockSize, blockSize)
pygame.draw.rect(windowSurface, navyBlue, block)
if block.colliderect(player):
if player.bottom - block.top < 10:
player.y = block.top - playerSize
if block.bottom - player.top < 10:
player.y = block.bottom
if block.right - player.left < 10:
player.x = block.right
if player.right - block.left < 10:
player.x = block.left - playerSize
if j == ".":
dot = pygame.Rect(pointX + (blockSize / 2) - (dotSize / 2), pointY + (blockSize / 2) - (dotSize / 2), dotSize, dotSize)
pygame.draw.rect(windowSurface, white, dot)
if j == "-":
pygame.draw.circle(windowSurface, white, (pointX + pillSize + (pillSize / 2), pointY + pillSize + (pillSize / 2)), pillSize)
if j == "o":
pass
pointX += blockSize
pointX = 0
pointY += blockSize
#Función para cerrar juego
def close():
pygame.quit()
sys.exit()
#Ciclo principal del juego
while True:
#Buscar evento QUIT
for event in pygame.event.get():
if event.type == QUIT:
close()
if event.type == KEYDOWN:
if event.key == K_w:
moveUp = True
moveDown = False
moveLeft = False
moveRight = False
if event.key == K_s:
moveUp = False
moveDown = True
moveLeft = False
moveRight = False
if event.key == K_a:
moveUp = False
moveDown = False
moveLeft = True
moveRight = False
if event.key == K_d:
moveUp = False
moveDown = False
moveLeft = False
moveRight = True
#Mover jugador
if moveLeft:
player.move_ip(-1 * speed, 0)
if moveRight:
player.move_ip(speed, 0)
if moveUp:
player.move_ip(0, -1 * speed)
if moveDown:
player.move_ip(0, speed)
#Portal
if player.left > windowWidth:
player.x = 0 - playerSize
if player.right < 0:
player.x = windowWidth
windowSurface.fill(black)
createMaze()
pygame.draw.rect(windowSurface, yellow, player)
pygame.display.update()
mainClock.tick(FPS)```
I changed the "." with and "o" (that represents a emty space) by creating a new string
if dot.colliderect(player):
maze[y] = maze[y][:x] + "o" + maze[y][x + 1:]
Related
I'm implementing and "IA" to my ghost in my copy of Pac-Man, the ghost when hit a block check for every way it can go, but one of that ways is the opposite direction he was taking and that makes that for example if hits a block while moving left, then move right, and then hit a block and move left again, how can I avoid that? I tried doing a "oppositeDirection" variable that changes depending where it the block but the ghost keep doig the same
import pygame, sys, random
from pygame.locals import *
pygame.init()
#Variables del juego
windowWidth = 504
windowHeight = 648
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
mainClock = pygame.time.Clock()
FPS = 30
pygame.display.set_caption('Pac-Man')
#Colores
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
yellow = (255, 255, 0)
cyan = (0, 255, 255)
navyBlue = (0, 0, 53)
pink = (255, 192, 203)
#Tamaño del bloque
blockSize = 24
dotSize = 4
pillSize = 10
#Datos del jugador
playerSize = 24
player = pygame.Rect(240, 480, playerSize, playerSize)
speed = 5
#Datos del fantasma
ghostSize = 24
player = pygame.Rect(240, 480, playerSize, playerSize)
ghostSpeed = 4
#Variables de movimiento del jugador
moveLeft = moveRight = moveDown = moveUp = False
#Variables del fantasma
ghost = pygame.Rect(240, 480, ghostSize, ghostSize)
ghostMoveLeft = 1
ghostMoveRight = 2
ghostMoveUp = 3
ghostMoveDown = 4
ghostCurrentDirection = None
ghostPossibleMove = []
ghostOpossiteDirection = None
#Laberinto
maze = [
"xxxxxxxxxxxxxxxxxxxxx",
"x.........x.........x",
"x.xxx.xxx.x.xxx.xxx.x",
"x-xxx.xxx.x.xxx.xxx-x",
"x.xxx.xxx.x.xxx.xxx.x",
"x...................x",
"x.xxx.x.xxxxx.x.xxx.x",
"x.xxx.x.xxxxx.x.xxx.x",
"x.....x...x...x.....x",
"xxxxx.xxxoxoxxx.xxxxx",
"oooox.xooooooox.xoooo",
"oooox.xoxxoxxox.xoooo",
"xxxxx.xoxoooxox.xxxxx",
"ooooo.ooxoooxoo.ooooo",
"xxxxx.xoxxxxxox.xxxxx",
"oooox.xooooooox.xoooo",
"oooox.xoxxxxxox.xoooo",
"xxxxx.xoxxxxxox.xxxxx",
"x.........x.........x",
"x.xxx.xxx.x.xxx.xxx.x",
"x-..x.....o.....x..-x",
"xxx.x.x.xxxxx.x.x.xxx",
"xxx.x.x.xxxxx.x.x.xxx",
"x.....x...x...x.....x",
"x.xxxxxxx.x.xxxxxxx.x",
"x...................x",
"xxxxxxxxxxxxxxxxxxxxx"
]
def createMaze():
pointX = 0
pointY = 0
y = 0
for i in maze:
x = 0
for j in i:
if j == "x":
block = pygame.Rect(pointX, pointY, blockSize, blockSize)
pygame.draw.rect(windowSurface, navyBlue, block)
global ghostCurrentDirection
if block.colliderect(player):
if player.bottom - block.top < 10:
player.y = block.top - playerSize
if block.bottom - player.top < 10:
player.y = block.bottom
if block.right - player.left < 10:
player.x = block.right
if player.right - block.left < 10:
player.x = block.left - playerSize
global ghostPossibleMove
global ghostOpossiteDirection
if ghost.right is not block.left:
ghostPossibleMove.append(ghostMoveRight)
if ghost.left is not block.right:
ghostPossibleMove.append(ghostMoveLeft)
if ghost.top is not block.bottom:
ghostPossibleMove.append(ghostMoveDown)
if ghost.bottom is not block.top:
ghostPossibleMove.append(ghostMoveUp)
if ghostCurrentDirection == None:
ghostCurrentDirection = random.choice(ghostPossibleMove)
ghostPossibleMove = []
if ghostCurrentDirection == ghostOpossiteDirection:
ghostCurrentDirection = None
else:
pass
if block.colliderect(ghost):
if ghost.bottom - block.top < 10:
ghost.y = block.top - playerSize
ghostCurrentDirection = None
ghostOpossiteDirection = ghostMoveUp
if block.bottom - ghost.top < 10:
ghost.y = block.bottom
ghostCurrentDirection = None
ghostOpossiteDirection = ghostMoveDown
if block.right - ghost.left < 10:
ghost.x = block.right
ghostCurrentDirection = None
ghostOpossiteDirection = ghostMoveRight
if ghost.right - block.left < 10:
ghost.x = block.left - playerSize
ghostCurrentDirection = None
ghostOpossiteDirection = ghostMoveLeft
if j == ".":
dot = pygame.Rect(pointX + (blockSize / 2) - (dotSize / 2), pointY + (blockSize / 2) - (dotSize / 2), dotSize, dotSize)
pygame.draw.rect(windowSurface, white, dot)
if dot.colliderect(player):
maze[y] = maze[y][:x] + "o" + maze[y][x + 1:]
if j == "-":
pill = pygame.Rect(pointX + (blockSize / 2) - (pillSize / 2), pointY + (blockSize / 2) - (pillSize / 2), pillSize, pillSize)
pygame.draw.rect(windowSurface, white, pill)
if pill.colliderect(player):
maze[y] = maze[y][:x] + "o" + maze[y][x + 1:]
if j == "o":
pass
pointX += blockSize
x += 1
pointX = 0
pointY += blockSize
y += 1
#Función para cerrar juego
def close():
pygame.quit()
sys.exit()
#Ciclo principal del juego
while True:
#Buscar evento QUIT
for event in pygame.event.get():
if event.type == QUIT:
close()
if event.type == KEYDOWN:
if event.key == K_w:
moveUp = True
moveDown = False
moveLeft = False
moveRight = False
if event.key == K_s:
moveUp = False
moveDown = True
moveLeft = False
moveRight = False
if event.key == K_a:
moveUp = False
moveDown = False
moveLeft = True
moveRight = False
if event.key == K_d:
moveUp = False
moveDown = False
moveLeft = False
moveRight = True
if event.key == K_c:
ghostCurrentDirection = random.choice(ghostPossibleMove)
#Mover jugador
if moveLeft:
player.move_ip(-1 * speed, 0)
if moveRight:
player.move_ip(speed, 0)
if moveUp:
player.move_ip(0, -1 * speed)
if moveDown:
player.move_ip(0, speed)
#Mover al fantasma
# if ghost.x % 24 == 0:
# ghostCurrentDirection = random.choice(ghostPossibleMove)
if ghostCurrentDirection == ghostMoveLeft:
ghost.move_ip(-1 * ghostSpeed, 0)
if ghostCurrentDirection == ghostMoveRight:
ghost.move_ip(ghostSpeed, 0)
if ghostCurrentDirection == ghostMoveUp:
ghost.move_ip(0, -1 * ghostSpeed)
if ghostCurrentDirection == ghostMoveDown:
ghost.move_ip(0, ghostSpeed)
#Portal
if player.left > windowWidth:
player.x = 0 - playerSize
if player.right < 0:
player.x = windowWidth
windowSurface.fill(black)
createMaze()
pygame.draw.rect(windowSurface, yellow, player)
pygame.draw.rect(windowSurface, cyan, ghost)
pygame.display.update()
mainClock.tick(FPS)
Keep track of the direction he was heading. Make the opposite of that direction be the last possible choice. If you want to do a little more work, keep track of each block visited (a simple Boolean map), and when there is a choice to make, then sort the directions of any visited blocks to the end of the choice list.
I want to make it so when my character touches the "v" block the game quits. What I tried was to find all blocks that are "v" and put them in the list. If player colliderect with any in list of "v" game will quit.
I think this should work although it does not seem to be working. Whenever I run it when I touch the "v" block nothing happens.
Here is my code
import pygame
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
WINDOW_SIZE = (600, 400)
pygame.display.set_caption("Game")
screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32)
display = pygame.Surface((300, 200))
player_image = pygame.image.load("Jacques clone-1.png (1).png").convert()
player_image.set_colorkey((255,255,255))
location = [50, 50]
#boolean for movement
moving_right = False
moving_left = False
scroll = [0, 0]
Stay_right = True
game_map1 = """
-----------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------
xx----------x----------------------------------------
----------vvvv---------------------xxx----------------
---------xooo----------------------------------------
xxxxxxxxxooooxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ooooooooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooooooooo
""".splitlines()
game_map = [list(lst) for lst in game_map1]
tl = {}
tl["v"] = spike_img = pygame.image.load('dirt.png')
tl["o"] = dirt_img = pygame.image.load('grass.png')
tl["x"] = grass_img = pygame.image.load('grass.png')
player_rect = pygame.Rect(50, 50, 25, 25)
momentum = 0
air_timer = 0
#adding tiles list that are hit for movement
def collision_test(rect, tiles):
hit_list = []
for tile in tiles:
if rect.colliderect(tile):
hit_list.append(tile)
#print(hit_list)
return hit_list
def move(rect, movement, tiles):
collision_types = {'top': False, 'bottom': False, 'right': False, 'left': False}
rect.x += movement[0]
hit_list = collision_test(rect, tiles)
for tile in hit_list:
if movement[0] > 0:
rect.right = tile.left
collision_types['right'] = True
elif movement[0] < 0:
rect.left = tile.right
collision_types['left'] = True
rect.y += movement[1]
hit_list = collision_test(rect, tiles)
for tile in hit_list:
if movement[1] > 0:
rect.bottom = tile.top
collision_types['bottom'] = True
elif movement[1] < 0:
rect.top = tile.bottom
collision_types['top'] = True
return rect, collision_types
run = True
while run:
display.fill((146, 244, 255))
scroll[0] += (player_rect.x - scroll[0] - 130)
tile_rects = []
y = 0
for line_of_symbols in game_map:
x = 0
for symbol in line_of_symbols:
if symbol in tl:
display.blit(tl[symbol], (x * 16 - scroll[0], y * 16 - scroll[1]))
if symbol != "-":
tile_rects.append(pygame.Rect(x * 16, y * 16, 16, 16))
x += 1
y += 1
list_ofspike = []
y2 = 0
for lineofsymbols in game_map:
x2 = 0
for symbols in lineofsymbols:
if symbols == "v":
list_ofspike.append(pygame.Rect(x2 * 16, y2 * 16, 16, 16))
x2 += 1
y2 += 1
for spike in list_ofspike:
if player_rect.colliderect(spike):
pygame.quit()
player_movement = [0, 0]
if moving_right:
player_movement[0] += 2
if moving_left:
player_movement[0] -= 2
player_movement[1] += momentum
momentum += 0.3
if momentum > 3:
momentum = 3
player_rect, collisions = move(player_rect, player_movement, tile_rects)
if collisions['bottom']:
air_timer = 0
momentum = 0
else:
air_timer += 1
if Stay_right:
display.blit(player_image, (player_rect.x - scroll[0], player_rect.y - scroll[1]))
else:
display.blit(pygame.transform.flip(player_image, 1, 0 ),(player_rect.x - scroll[0], player_rect.y - scroll[1]))
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == KEYDOWN:
if event.key == K_RIGHT:
moving_right = True
Stay_right = True
if event.key == K_LEFT:
moving_left = True
Stay_right = False
if event.key == K_SPACE:
if air_timer < 6:
momentum = -5
if event.type == KEYUP:
if event.key == K_RIGHT:
moving_right = False
if event.key == K_LEFT:
moving_left = False
screen.blit(pygame.transform.scale(display, (WINDOW_SIZE)), (0, 0))
pygame.display.update()
clock.tick(60)
pygame.quit()
You do not detect a collision with the spikes, because your collision detection works too perfectly.
When you move the player then you ensure, that the player does not intersect any object, thus the player does not intersect a spike, too.
You have to test if the player touches a spike. Increase the player rectangle by 1 in direction and use the increased rectangle to do the collision test with the spikes:
while run:
# [...]
test_rect = pygame.Rect(player_rect.left-1, player_rect.top-1,
player_rect.width+2, player_rect.height+2)
for spike in list_ofspike:
if test_rect.colliderect(spike):
pygame.quit()
# [...]
So I have this code that's my main game:
def game():
running = True
import pygame, sys
import random
import math as m
mainClock = pygame.time.Clock()
pygame.init()
pygame.font.init
pygame.display.set_caption('Ping Pong')
SCREEN = width, height = 900,600
white = (255, 255, 255)
green = (0, 255, 0)
blue = (0, 0, 128)
black = (0,0,0)
speed = [4,4]
font = pygame.font.Font('freesansbold.ttf', 32)
score = 0
score = str(score)
font.size(score)
font.set_bold(True)
text = font.render(score, True, white)
textRect = text.get_rect()
textRect.center = ((width/2 - width / 20), (height/60 + height/20))
screen = pygame.display.set_mode(SCREEN, 0,32)
height1 = height/4
score = int(score)
ball = pygame.Rect(width/2, height/2, 50,50)
player = pygame.Rect(0,(height/2),25,height1)
player_1 = pygame.Rect(width - 25,(height/2),25,height1)
font1 = pygame.font.Font('freesansbold.ttf', 32)
score1 = 0
score1 = str(score)
font1.size(score1)
font1.set_bold(True)
text1 = font1.render(score1, True, white)
score1 = int(score1)
textRect1 = text1.get_rect()
textRect1.center = ((width/2 + width / 15), (height/60 + height/20))
up = False
down = False
up_1 = False
down_1 = False
RED = (255,0,0)
particles = []
while running:
color = (192,192,192)
# clear display #
screen.fill((0,0,0))
screen.blit(text, textRect)
screen.blit(text1, textRect1)
bx = ball.centerx
by = ball.centery
particles.append([[bx, by],[random.randint(0,20) / 10 - 1, -1], random.randint(4,6)])
for particle in particles:
particle[0][0] += particle[1][0]
particle[0][1] += particle[1][1]
particle[2] -= 0.1
particle[1][1] += 0.1
pygame.draw.circle(screen, color, [int(particle[0][0]), int(particle[0][1])], int(particle[2]))
if particle[2] <= 0:
particles.remove(particle)
if up == True:
player.y -= 5
if down == True:
player.y += 5
if up_1 == True:
player_1.y -= 5
if down_1 == True:
player_1.y += 5
if player.top < 0 :
player.y = 0
if player.bottom > height:
player.bottom = height
if player_1.top < 0 :
player_1.y = 0
if player_1.bottom > height :
player_1.bottom = height
for i in range(-90,(height + 130), 120):
rectangle = pygame.Rect((width/2), i, 13, 60)
pygame.draw.rect(screen, (255,255,255), rectangle)
pygame.draw.rect(screen,(191, 224, 255),player)
pygame.draw.rect(screen,(191, 224, 255),player_1)
color = (192,192,192)
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
pygame.draw.rect(screen,color,ball, 3)
import time
ball.x += speed[0]
ball.y += speed[1]
if ball.top < 0 or ball.bottom > height:
speed[1] = -speed[1]
r = random.randint(0,255)
g = random.randint(0,255)
b = random.randint(0,255)
pygame.draw.rect(screen,(r,b,g),ball, 3)
pygame.draw.circle(screen, (r,b,g), [int(particle[0][0]), int(particle[0][1])], int(particle[2]))
dab = random.randint(0,1)
if ball.left < 0 :
font = pygame.font.Font('freesansbold.ttf', 32)
score1 = int(score1)
score1 += 1
score1 = str(score1)
font.set_bold(True)
text1 = font.render(score1, True, white)
textRect1 = text.get_rect()
textRect1.center = ((width/2 + width / 15), (height/60 + height/20))
screen.blit(text1, textRect1)
ball.x = width/2
ball.y = height/2
if dab == 1:
ball.x += -speed[0]
ball.y += -speed[1]
elif dab == 0:
ball.x += speed[0]
ball.y += speed[1]
if ball.right > width:
font = pygame.font.Font('freesansbold.ttf', 32)
score = int(score)
score += 1
score = str(score)
font.set_bold(True)
text = font.render(score, True, white)
textRect = text.get_rect()
textRect.center = ((width/2 - width / 20), (height/60 + height/20))
screen.blit(text, textRect)
ball.x = width/2
ball.y = height/2
if dab == 1:
ball.x += -speed[0]
ball.y += -speed[1]
elif dab == 0:
ball.x += speed[0]
ball.y += speed[1]
# event handling #
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_s:
down = True
if event.key == K_w:
up = True
if event.key == K_UP:
up_1 =True
if event.key == K_ESCAPE:
running = False
if event.key == K_DOWN:
down_1 = True
if event.type == KEYUP:
if event.key == K_s:
down = False
if event.key == K_w:
up = False
if event.key == K_UP:
up_1 = False
if event.key == K_DOWN:
down_1 = False
if ball.colliderect(player_1):
dab = random.randint(0,1)
if dab == 1:
speed[1] = -speed[1]
speed[0] = -speed[0]
r = random.randint(0,255)
g = random.randint(0,255)
b = random.randint(0,255)
pygame.draw.rect(screen,(r,b,g),ball, 3)
if ball.colliderect(player):
speed[0] = -speed[0]
speed[0] = random.randint(4,6)
r = random.randint(0,255)
g = random.randint(0,255)
b = random.randint(0,255)
pygame.draw.rect(screen,(r,b,g),ball, 3)
# update display #
pygame.display.update()
mainClock.tick(60)
and I have a menu screen that displays some options. Only button_1 works.:
def main_menu():
while True:
white = (255,255,255)
font = pygame.font.Font('freesansbold.ttf', 32)
font.set_bold(True)
screen.fill((0,0,0))
button_1 = pygame.Rect(width/2, (height/2), width/2, 50)
button_1.centerx = width/2
button_2 = pygame.Rect(width/2, height/1.5, width/2, 50)
button_2.centerx = width/2
pygame.draw.rect(screen, (255, 0, 0), button_1)
pygame.draw.rect(screen, (255, 0, 0), button_2)
#draw_text('Start!', font, (255, 255, 255), screen, button_1.centerx, button_1.centery)
font = pygame.font.Font('freesansbold.ttf', 32)
font.set_bold(True)
text1 = font.render('Start!', True, white)
textRect1 = text1.get_rect()
textRect1.center = (button_1.centerx, button_1.centery)
screen.blit(text1, textRect1)
mx, my = pygame.mouse.get_pos()
if button_1.collidepoint((mx, my)):
if click:
game()
if button_2.collidepoint((mx, my)):
if click:
options()
click = False
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
if event.button == 1:
click = True
pygame.display.update()
clock.tick(60)
How do I make it so that after button_1 is pressed, there's a 3,2,1 countdown on the screen, and then the game starts?
In order to do the countdown, you import the time module:
import time
...then you need a for loop, with a step -1, counting down from 3 to 1. Inside the for loop, print the numbers and sleep one second, using the time module:
for a in range(3,0,-1):
print(a)
time.sleep(1)
After this for loop, you put the rest of your code.
I am trying to make my game have special abilities for the player, but am having some issues. For some reason user_health_active and user_health_display_active do not update after reaching round 10. I can't figure out why this is and have been attempting to for about two hours. By the seems of it, not only does the surface not update, but the actual background function doesn't either. If anyone can provide me some insight on why this isn't working, please let me know. Here is my code.
"""
Game Developer: Austin H.
Game Owner: Austin H.
Licensed Through: theoiestinapps
Build: 2
Version: 1.0.1
"""
import os
import pygame as pygame
import random
import sys
import time
pygame.init()
left = False
right = False
playerDead = False
devMode = False
game_completed = False
game_level_score = (0)
game_display_score = (0)
enemy_speed = (5)
user_teleport_active = False
user_health_active = False
user_teleport_display_active = ("False")
user_health_display_active = ("False")
display_width = 800
display_height = 600
customBlue = (17, 126, 194)
black = (0, 0, 0)
blue = (0, 0, 255)
green = (0, 255, 0)
red = (255, 0, 0)
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Space Dodge")
clock = pygame.time.Clock()
backgroundMusic = pygame.mixer.music.load('C:/Program Files/Space Dodge/game_background_music.mp3')
enemyImg = pygame.image.load('C:/Program Files/Space Dodge/enemy_image.png')
backgroundImg = pygame.image.load('C:/Program Files/Space Dodge/background_image.png')
rocketImg = pygame.image.load('C:/Program Files/Space Dodge/player_image.png')
injuredSound = pygame.mixer.Sound('C:/Program Files/Space Dodge/player_hurt_sound.wav')
def teleport_powerup(user_teleport_display_active):
font = pygame.font.SysFont(None, 25)
text = font.render("Teleport Powerup: " + str(user_teleport_display_active), True, red)
gameDisplay.blit(text, (display_width - 205, 5))
def ehealth_powerup(user_health_display_active):
font = pygame.font.SysFont(None, 25)
text = font.render("Ehealth Powerup: " + str(user_health_display_active), True, red)
gameDisplay.blit(text, (display_width - 205, 25))
def enemies_dodged(enemy_objects_dodged):
font = pygame.font.SysFont(None, 25)
text = font.render("Dodge Asteroids: " + str(enemy_objects_dodged), True, green)
gameDisplay.blit(text, (5, 5))
def game_level(game_display_score):
font = pygame.font.SysFont(None, 25)
game_display_score = game_level_score + 1
text = font.render("Game Level: " + str(game_display_score), True, green)
gameDisplay.blit(text, (5, 25))
def enemies(enemyx, enemyy, enemyw, enemyh, color):
pygame.draw.rect(gameDisplay, color, [enemyx, enemyy, enemyw, enemyh])
def rocket(x, y):
gameDisplay.blit(rocketImg, (x, y))
def background(cen1, cen2):
gameDisplay.blit(backgroundImg, (cen1, cen2))
def text_objects(text, font):
textSurface = font.render(text, True, blue)
return textSurface, textSurface.get_rect()
def message_display(text):
global game_completed
largeText = pygame.font.Font('freesansbold.ttf', 70)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
if game_completed == True:
time.sleep(300)
else:
time.sleep(5)
if game_level_score > 0:
pass
else:
pygame.mixer.music.play()
game_loop()
def crash():
injuredSound.play()
message_display("You Died. Game Over!")
def game_loop():
global left
global right
global playerDead
global game_level_score
global enemy_speed
global game_completed
global user_teleport_active
global user_teleport_display_active
global user_health_active
global user_health_display_active
x = (display_width * 0.43)
y = (display_height * 0.74)
cen1 = (0)
cen2 = (0)
x_change = 0
rocket_width = (86)
game_score = (0)
enemy_objects_dodged = (0)
enemy_startx = random.randrange(0, display_width)
enemy_starty = -600
enemy_width = 100
enemy_height = 100
while not playerDead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.mixer.music.stop()
playerDead = True
if devMode == True:
print(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
left = True
if event.key == pygame.K_d:
right = True
if event.key == pygame.K_LEFT:
left = True
if event.key == pygame.K_RIGHT:
right = True
if event.key == pygame.K_KP4:
left = True
if event.key == pygame.K_KP6:
right = True
if event.key == pygame.K_ESCAPE:
playerDead = True
if event.key == pygame.K_SPACE:
game_level_score += 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or pygame.K_d:
left = False
if event.key == pygame.K_d:
right = False
if event.key == pygame.K_LEFT:
left = False
if event.key == pygame.K_RIGHT:
right = False
if event.key == pygame.K_KP4:
left = False
if event.key == pygame.K_KP6:
right = False
if event.key == pygame.K_SPACE:
pass
if left and right:
x_change *= 1
elif left and x > -86:
x_change = -5
elif right and x < (display_width - 89):
x_change = 5
else:
x_change = 0
if game_score == 10:
enemy_speed += 0.5
game_level_score += 1
if game_level_score == 49:
game_completed = True
message_display('Game Complete!')
else:
message_display('Levels Completed: %s' % game_level_score)
if game_level_score > 4:
user_teleport_active = True
user_teleport_display_active = ("True")
elif game_level_score > 9:
user_health_active = True
user_health_display_active = ("True")
if user_teleport_active == True:
if x < -0:
x = 850
if enemy_starty > display_height:
enemy_starty = 0 - enemy_height
enemy_startx = random.randrange(0, display_width)
game_score += 1
enemy_objects_dodged += 1
if y < enemy_starty + enemy_height:
if x > enemy_startx and x < enemy_startx + enemy_width or x + rocket_width > enemy_startx and x + rocket_width < enemy_startx + enemy_width:
pygame.mixer.music.stop()
game_level_score = (0)
user_teleport_active = False
user_teleport_display_active = ("False")
crash()
x += x_change
background(cen1, cen2)
enemies(enemy_startx, enemy_starty, enemy_width, enemy_height, customBlue)
enemy_starty += enemy_speed
rocket(x, y)
enemies_dodged(enemy_objects_dodged)
game_level(game_display_score)
teleport_powerup(user_teleport_display_active)
ehealth_powerup(user_health_display_active)
pygame.display.update()
clock.tick(90)
pygame.mixer.music.set_volume(0.20)
pygame.mixer.music.play(-1)
game_loop()
pygame.quit()
quit()
The code that modifies the variables you mention will never be run. Here's the relevant bit:
if game_level_score > 4:
user_teleport_active = True
user_teleport_display_active = ("True")
elif game_level_score > 9:
user_health_active = True
user_health_display_active = ("True")
Because you're using an if and an elif, the condition for the second block is only ever tested if the first block's condition was false. Since any value greater than 9 is also going to be greater than 4, the second block will never run.
If you want the two conditions to be tested independently, you need to just use plain if statements for both conditions. If you only want one block to run , you either need to extend the first condition to 4 < game_level_score <= 9 or you need to change the order so that the > 9 test comes before the > 4 test.
I am trying to write a rip off 'Brick Breaker' game in Pygame. But I am currently stuck and do not know what to do know.
(blah blah blah, explain scenario much more clearly, blah blah blah, clear, clear scenario)
(I need more random text so I can post all this code)
Here is all of the code, (yes all of it):
import pygame, sys, time, random
from pygame.locals import *
pygame.init()
fpsclock = pygame.time.Clock()
WINDOWWIDTH = 450
WINDOWHEIGHT = 650
mainwindow = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Luzion - Brick Breaker')
paddle = pygame.image.load('Brick Breaker - Paddle.png')
paddlerect = paddle.get_rect()
paddlerect.topleft = (190, 575)
ball = pygame.image.load ('ball.png')
ballrect = ball.get_rect()
ballrect.topleft = (195, 565)
cooltext = pygame.image.load('cooltext1.png')
cooltextrect = cooltext.get_rect()
cooltextrect.topleft = (0, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 128, 0)
BLUE = (0, 0, 255)
LIME = (0, 255, 0)
TEXTCOLOR = WHITE
font = pygame.font.SysFont(None, 48)
def displaytext(text, font, surface, x, y):
text = font.render(text, 1, TEXTCOLOR)
textrect = text.get_rect()
textrect.topleft = (x, y)
surface.blit(text, textrect)
def waitforplayer():
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
return
moveleft = False
moveright = False
SPEED = 7
bmoveup = bmovedown = bmoveleft = bmoveright = False
BALLSPEED = 8
mainwindow.blit(cooltext, cooltextrect)
pygame.display.update()
time.sleep(1)
displaytext('Level 1', font, mainwindow, 150, 100)
pygame.display.update()
time.sleep(1)
displaytext('Press any key to begin...', font, mainwindow, 22, 200)
pygame.display.update()
waitforplayer()
while True:
rb = pygame.image.load('redblock.png')
rbrect = rb.get_rect()
rbrect.topleft = (0, 0)
rb1 = rb
rb1rect = rb1.get_rect()
rb1rect.topleft = (40, 0)
level1blocks = [rb, rb1]
level1rects = [rbrect, rb1rect]
number = random.randint(0, 1)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == ord('a') or event.key == K_LEFT:
moveleft = True
moveright = False
if event.key == ord('d') or event.key == K_RIGHT:
moveleft = False
moveright = True
if event.key == ord('g'):
bmoveup = True
if number == 1:
bmoveleft = True
else:
bmoveright = True
if event.type == KEYUP:
if event.key == ord('a') or event.key == K_LEFT:
moveleft = False
if event.key == ord('d') or event.key == K_RIGHT:
moveright = False
if moveleft and paddlerect.left > 0:
paddlerect.left -= SPEED
if moveright and paddlerect.right < WINDOWWIDTH:
paddlerect.right += SPEED
if bmovedown and ballrect.bottom < WINDOWHEIGHT:
ballrect.top += BALLSPEED
if bmoveup and ballrect.top > 0:
ballrect.top -= BALLSPEED
if bmoveleft and ballrect.left > 0:
ballrect.left -= BALLSPEED
if bmoveright and ballrect.right < WINDOWWIDTH:
ballrect.right += BALLSPEED
if ballrect.top <= 0:
bmovedown = not bmovedown
bmoveup = not bmoveup
if ballrect.left <= 0:
bmoveleft = not bmoveleft
bmoveright = not bmoveright
if ballrect.right >= WINDOWWIDTH:
bmoveleft = not bmoveleft
bmoveright = not bmoveright
if ballrect.bottom >= WINDOWHEIGHT:
bmovedown = not bmovedown
bmoveup = not bmoveup
mainwindow.fill(WHITE)
mainwindow.blit(paddle, paddlerect)
mainwindow.blit(ball, ballrect)
for x in range(len(level1blocks)):
mainwindow.blit(level1blocks[x], level1rects[x])
for x in level1rects:
if ballrect.colliderect(x):
level1rects.remove([x])
level1blocks.remove([x])
if ballrect.colliderect(paddlerect):
bmovedown = not bmovedown
bmoveup = not bmoveup
bmoveleft = not bmoveleft
bmoveright = not bmoveright
pygame.display.update()
fpsclock.tick(35)
And here is my error:
Traceback (most recent call last):
File "C:/Python32/Luzion - Brick Breaker", line 144, in <module>
level1rects.remove([x])
ValueError: list.remove(x): x not in list
Please help.
As you mention in the comments, both for loops are inside a larger while loop. That means that when the line
level1rects.remove(x)
happens, it will decrease the size of level1rects and cause level1rects[x] (when x is 1) to raise an exception.
The best way to fix this is to change your for loops to the following:
for b in level1blocks:
mainwindow.blit(b, b.get_rect())
for x in level1blocks[:]:
if ballrect.colliderect(x.get_rect()):
level1blocks.remove(x)
This obliviates the need for level1rects- it caused too many problems, because you were removing items from the list of rectangles without removing the corresponding block from the list of blocks. Changing the first loop to for b in level1blocks: allows the code to work even as blocks disappear.
Do a print or pprint on the level1blocks and level1rects lists, one of them doesn't have enough members for the range(2) iterator, which will try accessing the first (index 0) and second (index 1) members of each list.