AttributeError: 'Player' object has no attribute 'sprites' [closed] - python

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 6 years ago.
Improve this question
I'm building a game using PyGame and Python 3.4. I am having an issue with what appears to be the module itself and not the actual code I have because the full error is:
Traceback (most recent call last):
File "C:\Users\----\Desktop\Python\Game.py", line 115, in <module>
playerhit = pygame.sprite.spritecollide(ebullet, psprite, True)
File "C:\Python34\lib\site-packages\pygame\sprite.py", line 1514, in spritecollide
for s in group.sprites():
AttributeError: 'Player' object has no attribute 'sprites'
I dashed out my name but kept the length, though I don't think it matters.
I've looked around the web for different parts of the error and nothing has come up, so I came here. Here's the full code (it's kinda messy and long):
import pygame, time, sys, random, Sprites, os
from pygame.locals import *
BLACK = (0, 0, 0)
MAPX = 10
MAPY = 20
TXY = 32
gameover = False
score = 0
lives = 2
playerXY = [MAPX*TXY//2, MAPY*TXY-TXY-TXY-5]
spritesheet01 = Sprites.Sheet(32, 32, 128, 32, 'spritesheet03.png')
sprites = spritesheet01.clipSheet()
psprite = Sprites.Player(sprites[0])
clock = pygame.time.Clock()
counter = int(clock.get_fps())
ebullet = Sprites.eBullet(sprites[3])
allspriteslist = pygame.sprite.Group()
enemylist = pygame.sprite.Group()
ebulletlist = pygame.sprite.Group()
pbulletlist = pygame.sprite.Group()
allspriteslist.add(psprite)
pygame.init()
enemynum = 5
enemies = []
enemytorf = [False, False, False, False, False, False, False, False, False, False]
def pause():
os.system("pause")
def enemyCreate():
print("enemycreate called")
while len(enemylist) < 5:
randomindex = random.randint(0, MAPX-1)
if enemytorf[randomindex] == False:
enemy = Sprites.Enemy(sprites[1])
enemytorf[randomindex] = True
enemy.rect.x = randomindex
enemy.rect.y = 0
ebullet.rect.x = randomindex
ebullet.rect.y = 0
enemylist.add(enemy)
allspriteslist.add(enemy)
ebulletlist.add(ebullet)
allspriteslist.add(ebullet)
print("enemycreate done")
def eBulletCreate():
print("bulletpassed")
for wi in range(len(ebull)):
ebullappend = ebull[wi]
ebullets.append(ebullappend)
print("Got through function defining")
display = pygame.display.set_mode((MAPX*TXY, MAPY*TXY))
pygame.display.set_caption("Star Smasher")
print("created screen")
pygame.key.set_repeat(10, 10)
endgame = False
create_enemy = pygame.USEREVENT + 1
shootbullet = pygame.USEREVENT + 2
print("created events")
enemyCreate()
pygame.time.set_timer(create_enemy, 7500)
pygame.time.set_timer(shootbullet, 2500)
print("Got to the while")
while endgame == False:
print("got into while")
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_SPACE:
pbullet = Sprites.pBullet(sprites[2])
pbullet.rect.x = playerXY[0]
pbullet.rect.y = playerXY[1]
allspriteslist.add(pbullet)
pbulletlist.add(pbullet)
elif event.key == K_a:
if playerXY[0] > 5:
playerXY[0] -= 5
elif event.key == K_d:
if playerXY[0] < MAPX*TXY-TXY-7:
playerXY[0] += 5
if event.type == create_enemy:
enemyCreate()
if event.type == shootbullet:
eBulletCreate()
print("got through event handling")
for bullet in pbulletlist:
enemyhitlist = pygame.sprite.spritecollide(pbullet, enemylist, True)
for enemy in enemyhitlist:
pbulletlist.remove(bullet)
allspriteslist.remove(bullet)
score += 100
print(score)
if pbullet.rect.y < 0:
pbulletlist.remove(bullet)
allspriteslist.remove(bullet)
for bullet in ebulletlist:
playerhit = pygame.sprite.spritecollide(ebullet, psprite, True)
for player in playerhit:
ebulletlist.remove(bullet)
allspriteslist.remove(bullet)
gameover = True
if ebullet.rect.y > MAPY*TXY:
ebulletlist.remove(bullet)
allspriteslist.remove(bullet)
print("got through bullet handling")
display.fill(BLACK)
allspriteslist.draw(display)
if gameover == True:
font = pygame.font.Font(freesansbold.ttf, 20)
font.render("Game Over, press any button to continue!", True, BLACK, background=None)
display.blit(font, (160, 320, 200, 360))
pause()
pygame.display.update()
clock.tick(60)
print("Got to the display update")
pygame.quit()
Thanks in advance for the help!

It is the wrong way around for a start. playerhit = pygame.sprite.spritecollide(ebullet, psprite, True) - the function definition is spritecollide(sprite, group, dokill, collided = None) so the player should be first, and then the bullet group.
Also please post the Sprite.py code.

Related

Pygame beginner, player animation not working despite doing it by the tutorial

First time ever working with Pygame for a school assignment and I'm following a tutorial for it with my project members (tutorial link https://youtu.be/AY9MnQ4x3zk).
Problem is that despite following the tutorial to the dot at the "animating the player", my character (named "Marko" in the game and code) doesn't have his animation playing. When I start the game the character is stuck on it's first frame of animation. I've created a 3-frame animation and have the frames as separate png-files. The game so far itself works (it's on very beginner level, just a couple spawning enemies, collision and intro screens done so far), but the animation has had me and my project group scratching our heads for days. So far haven't found a solution by Googling nor searching here.
Also at the "# Marko's animations" -part "marko" is darkened and when hovering mouse on it, it says ""(variable) marko: Surface - "marko" is not accessed Pylance""
Here's the entire code:
import sys
from pygame.locals import *
from random import randint
from pygame import mixer
pygame.init()
width = 1920
height = 1080
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("Putkimies Marko")
start_time = 0
score = 0
nopeus = [3,3]
clock = pygame.time.Clock()
game_active = False
marko_gravity = 0
# Score
def display_score():
current_time = int(pygame.time.get_ticks() / 1000) - start_time
score_surf = test_font.render(f'Score: {current_time}',False,(black))
score_rect = score_surf.get_rect(center = (900,50))
screen.blit(score_surf,score_rect)
return current_time
def obstacle_movement(obstacle_list):
if obstacle_list:
for obstacle_rect in obstacle_list:
obstacle_rect.x -= 5
if obstacle_rect.bottom == 955:
screen.blit(rat,obstacle_rect)
else:
screen.blit(fly,obstacle_rect)
return obstacle_list
else: return[]
def collisions(marko,obstacles):
if obstacles:
for obstacle_rect in obstacles:
if marko.colliderect(obstacle_rect): return False
return True
# Surfaces
background = pygame.image.load("marko_background.png").convert_alpha()
sewer = pygame.image.load("background_sewer.png").convert_alpha()
ground = pygame.image.load("ground.png").convert_alpha()
rat = pygame.image.load("rat.png").convert_alpha()
game_over = pygame.image.load("game_over.png").convert_alpha()
fly = pygame.image.load("fly.png").convert_alpha()
# Marko Surfaces
marko_run_1 = pygame.image.load("marko_run_1.png").convert_alpha()
marko_run_2 = pygame.image.load("marko_run_2.png").convert_alpha()
marko_run_3 = pygame.image.load("marko_run_3.png").convert_alpha()
marko_run = [marko_run_1,marko_run_2,marko_run_3]
marko_index = 0
marko_jump = pygame.image.load("marko_jump.png").convert_alpha()
marko = marko_run[marko_index]
# Fonts
test_font = pygame.font.Font("supermario.ttf", 50)
# Colors
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
light_blue = (94,129,162)
purple = (36,5,83)
# Rects
game_overSurface = game_over.get_rect(midtop = (970,-200))
platform = pygame.Surface((300,50))
groundSurface = ground.get_rect(midtop = (960,480))
markoSurface = marko.get_rect()
text_surface = test_font.render('Putkimies Marko', False, red)
markoSurface.left = 50
markoSurface.bottom = 714
# Obstacles
obstacle_rect_list = []
# Intro screen
player_stand = pygame.image.load("putkimies_marko_idle.png")
player_stand = pygame.transform.rotozoom(player_stand,0,2)
player_stand_rect = player_stand.get_rect(center = (950,500))
game_name = test_font.render("PUTKIMIES MARKO", False,"Black")
game_name_rect = game_name.get_rect(center = (950,350))
game_message = test_font.render('PRESS SPACE TO PLAY',False,"Black")
game_message_rect = game_message.get_rect(center = (950,650))
game_message_start_again = test_font.render('PRESS SPACE TO PLAY AGAIN',False,"Black")
game_message_start_again_rect = game_message.get_rect(center = (850,720))
# Marko's animations
def marko_animation():
global markoSurface, marko_index
if markoSurface.bottom < 955:
marko = marko_jump
else:
marko_index += 0.1
if marko_index >= len(marko_run):marko_index = 0
marko = marko_run[int(marko_index)]
# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer,1500)
# Background music
mixer.music.load('smb_stage_clear.wav')
mixer.music.play(0)
# -1 Makes the music loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if game_active:
if event.type == KEYDOWN:
if event.key == K_SPACE and markoSurface.bottom >= 955:
marko_gravity = -18
else:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
game_active = True
start_time = int(pygame.time.get_ticks() / 1000)
if event.type == obstacle_timer and game_active:
if randint (0,2):
obstacle_rect_list.append(rat.get_rect(midbottom = (randint(2000,2200),955)))
else:
obstacle_rect_list.append(fly.get_rect(midbottom = (randint(2000,2200),855)))
if game_active:
# Draw
screen.blit(sewer, (0,0))
screen.blit(ground, (0,955))
marko_animation()
screen.blit(marko,markoSurface)
score = display_score()
# Key uses
key_use = pygame.key.get_pressed()
if key_use[K_LEFT]:
markoSurface.move_ip((-7,0))
if key_use[K_RIGHT]:
markoSurface.move_ip((7,0))
# Marko
marko_gravity += 1
markoSurface.y += marko_gravity
if markoSurface.bottom >= 955: markoSurface.bottom = 955
if markoSurface.left <= 0: markoSurface.left = 0
if markoSurface.right >= 1920: markoSurface.right = 1920
# Obstacle movement
obstacle_rect_list = obstacle_movement(obstacle_rect_list)
# Collision
game_active = collisions(markoSurface,obstacle_rect_list)
else: # Intro screen
screen.fill ("Light blue")
screen.blit(player_stand,player_stand_rect)
obstacle_rect_list.clear()
markoSurface.left = 80 # returns marko to 80
# Draws score message if score > 0
score_message = test_font.render(f'Your score: {score}',False,(red))
score_message_rect = score_message.get_rect(center = (950,650))
screen.blit(game_name,game_name_rect)
if score == 0: screen.blit(game_message,game_message_rect)
else:
screen.blit(score_message,score_message_rect)
screen.blit(game_over,game_overSurface)
screen.blit(game_message_start_again,game_message_start_again_rect)
pygame.display.update()
clock.tick(60)```
marko is a variable in global namespace. You must use the global statement to change a variable in the global namespace within a function:
def marko_animation():
global marko # <---
global marko_index
if markoSurface.bottom < 955:
marko = marko_jump
else:
marko_index += 0.1
if marko_index >= len(marko_run):
marko_index = 0
marko = marko_run[int(marko_index)]

Using multiprocessing with pygame?

I'm trying to separate my input loop from my game logic in my simple snake game that I've made with pygame, but, I'm really struggling to figure out why nothing is happening when I run the program.
I've tried importing pygame in the subprocess, I checked for errors on the subprocess, and got nowhere. I looked on google, but I wasn't able to find any usable examples, or similar issues. Has anybody ever figured any of this stuff out?
Okay, here's the code:
import pygame
import time
import multiprocessing as mp
import random as rnd
pygame.init()
def event_to_dict(event: pygame.event) -> dict:
return {
'type': event.type,
'key': event.key if event.type == pygame.KEYDOWN else None,
}
class SnakeBoard:
def __init__(self, rows: int, columns: int):
self.rows = rows
self.columns = columns
self.vertices = []
self.odd_column = False
self.buff = []
for _ in range(self.rows):
self.buff.append([' ' for _ in range(self.columns)])
def initialize(self):
for r in range(self.rows):
for c in range(self.columns):
self.buff[r][c] = ' '
self.odd_column = (self.columns >> 1) % 2 == 1
self.buff[self.rows >> 1][self.columns >> 1] = '\u25cb'
self.vertices = [(self.rows >> 1, self.columns >> 1)]
def place_food(self):
while True:
r = rnd.randint(0, self.rows - 1)
c = rnd.randint(0, self.columns - 1)
codd = c % 2 == 1
if (codd and self.odd_column or not codd and not self.odd_column) and self.buff[r][c] != '\u25cb':
self.buff[r][c] = '\u25c9'
break
def tick(self, direction: int) -> bool:
nr, nc = self.vertices[-1]
if direction == 0:
nr -= 1
elif direction == 1:
nc += 1
elif direction == 2:
nr += 1
elif direction == 3:
nc -= 1
else:
print("Invalid direction for snake")
exit(1)
if nr >= self.rows or nc >= self.columns or nr < 0 or nc < 0 or self.buff[nr][nc] == '\u25cb':
return False
self.vertices.append((nr, nc))
self.vertices.pop(0)
return True
class SnakeGame(SnakeBoard):
def __init__(self, rows: int, columns: int):
super().__init__(rows, columns)
self.score = 0
self.direction = 0
self.initialize()
self.place_food()
def tick(self, direction: int = -1) -> bool:
v = super().tick(self.direction if direction < 0 else direction)
if self.buff[self.vertices[-1][0]][self.vertices[-1][1]] == '\u25c9':
self.score += 1
self.vertices.append(self.vertices[-1])
self.place_food()
for r in range(self.rows):
for c in range(self.columns):
if (r, c) in self.vertices:
self.buff[r][c] = '\u25cb'
elif self.buff[r][c] != '\u25c9' and self.buff[r][c] != ' ':
self.buff[r][c] = ' '
return v
class GameLoop(mp.Process):
def __init__(self, q: object, size: list):
super().__init__()
self.q = q
self.size = size
self.g = SnakeGame(size[1] // 10, size[0] // 10)
self.g.initialize()
self.g.place_food()
self.screen = None
self.game_surf = None
self.font = None
def run(self) -> None:
try:
import pygame
pygame.init()
self.screen = pygame.display.set_mode(self.size)
self.game_surf = pygame.Surface(self.size)
self.font = pygame.font.SysFont('roboto', 16)
is_running = True
while is_running:
if self.q.poll(0):
d = self.q.recv()
if d is not None:
if d['type'] == pygame.KEYDOWN:
if d['key'] == pygame.K_a:
self.g.direction = 3
elif d['key'] == pygame.K_s:
self.g.direction = 2
elif d['key'] == pygame.K_d:
self.g.direction = 1
elif d['key'] == pygame.K_w:
self.g.direction = 0
elif d['key'] == pygame.K_ESCAPE:
is_running = False
else:
is_running = False
self.game_surf.fill((255, 255, 255))
for ri, r in enumerate(self.g.buff):
for ci, c in enumerate(r):
if c == '\u25cb':
# print("Drawing a snake at {}, {}".format(ri * 10, ci * 10))
pygame.draw.circle(self.game_surf,
(0, 0, 255),
((ci * 10) + 5, (ri * 10) + 5),
5)
elif c == '\u25c9':
# wprint("Placing food at {}, {}".format(ci, ri))
pygame.draw.circle(self.game_surf,
(0, 127, 255),
((ci * 10) + 5, (ri * 10) + 5),
5)
timg = self.font.render("Score: {}, Level: {}".format(self.g.score, self.g.score // 10 + 1),
True,
(0, 0, 0))
self.screen.blit(self.game_surf, (0, 0))
self.screen.blit(timg, (0, 0))
pygame.display.flip()
if self.g.tick():
time.sleep(1 / ((int(self.g.score / 10 + 1)) * 10))
else:
timg = self.font.render("Game Over! Would you like to try again?", True, (0, 0, 0))
self.screen.blit(timg, ((self.size[0] >> 1) - 150, self.size[1] >> 1))
timg = self.font.render("Yes", True, (0, 0, 0))
btn_pos = ((self.size[0] >> 1) - 25, (self.size[1] >> 1) + 20)
self.screen.blit(timg, btn_pos)
pygame.display.flip()
while True:
event = pygame.event.wait()
if event.type == pygame.QUIT:
is_running = False
break
elif event.type == pygame.MOUSEBUTTONUP:
mx, my = pygame.mouse.get_pos()
if btn_pos[0] - 5 <= mx <= btn_pos[0] + 30 and btn_pos[1] - 5 <= my <= btn_pos[1] + 20:
self.g.initialize()
self.g.place_food()
self.g.score = 0
break
self.q.close()
except Exception as e:
print(e)
if __name__ == '__main__':
size = [800, 600]
parent, child = mp.Pipe()
p = GameLoop(child, size)
p.start()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
ed = event_to_dict(event)
parent.send(ed)
parent.close()
p.join()
pygame.quit()
Sorry, it's kinda strange, this was migrated from the console to pygame, so some of the logic is still using the unicode symbols.
Generally in GUI applications it's common to want to separate the GUI from the logic.
There are benefits to doing this as it means your GUI remains responsive even if your logic
is busy. However, in order to run things concurrently there are many drawbacks, including
overheads. It's also important to know that python is not 'thread safe', so you can break
things (see race conditions) if you're not careful.
Simplified example with no concurrency
Your example is quite complex so lets start with a simple example: A simple pygame setup with
a moving dot
import pygame
import numpy as np
# Initialise parameters
#######################
size = np.array([800, 600])
position = size / 2
direction = np.array([0, 1]) # [x, y] vector
speed = 2
running = True
pygame.init()
window = pygame.display.set_mode(size)
pygame.display.update()
# Game loop
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
direction = np.array([0, -1])
elif event.key == pygame.K_a:
direction = np.array([-1, 0])
elif event.key == pygame.K_s:
direction = np.array([0, 1])
elif event.key == pygame.K_d:
direction = np.array([1, 0])
position += direction * speed
if position[0] < 0 or position[0] > size[0] or position[1] < 0 or position[1] > size[1]:
running = False
pygame.time.wait(10) # Limit the speed of the loop
window.fill((0, 0, 0))
pygame.draw.circle(window, (0, 0, 255), position, 10)
pygame.display.update()
pygame.quit()
quit()
We're going to split off the game logic from the gui
Mutliprocessing and other options:
So multiprocessing in python allows you to utilise multiple cores at the same time, through multiple interpreters.
While this sounds good, as far as I/O goes: it comes with higher overheads and doesn't help at all (it will likely
hurt your performance). Threading and asyncio both run on a single core i.e. they aren't 'parrallel' computing. But
what they allow is to complete code while waiting for other code to finish. In other words you can input commands
while your logic is running happily elsewhere.
TLDR: as a general rule:
CPU Bound (100% of the core) program: use multiprocessing,
I/O bound program: use threading or asyncio
Threaded version
import pygame
import numpy as np
import threading
import time
class Logic:
# This will run in another thread
def __init__(self, size, speed=2):
# Private fields -> Only to be edited locally
self._size = size
self._direction = np.array([0, 1]) # [x, y] vector, underscored because we want this to be private
self._speed = speed
# Threaded fields -> Those accessible from other threads
self.position = np.array(size) / 2
self.input_list = [] # A list of commands to queue up for execution
# A lock ensures that nothing else can edit the variable while we're changing it
self.lock = threading.Lock()
def _loop(self):
time.sleep(0.5) # Wait a bit to let things load
# We're just going to kill this thread with the main one so it's fine to just loop forever
while True:
# Check for commands
time.sleep(0.01) # Limit the logic loop running to every 10ms
if len(self.input_list) > 0:
with self.lock: # The lock is released when we're done
# If there is a command we pop it off the list
key = self.input_list.pop(0).key
if key == pygame.K_w:
self._direction = np.array([0, -1])
elif key == pygame.K_a:
self._direction = np.array([-1, 0])
elif key == pygame.K_s:
self._direction = np.array([0, 1])
elif key == pygame.K_d:
self._direction = np.array([1, 0])
with self.lock: # Again we call the lock because we're editing
self.position += self._direction * self._speed
if self.position[0] < 0 \
or self.position[0] > self._size[0] \
or self.position[1] < 0 \
or self.position[1] > self._size[1]:
break # Stop updating
def start_loop(self):
# We spawn a new thread using our _loop method, the loop has no additional arguments,
# We call daemon=True so that the thread dies when main dies
threading.Thread(target=self._loop,
args=(),
daemon=True).start()
class Game:
# This will run in the main thread and read data from the Logic
def __init__(self, size, speed=2):
self.size = size
pygame.init()
self.window = pygame.display.set_mode(size)
self.logic = Logic(np.array(size), speed)
self.running = True
def start(self):
pygame.display.update()
self.logic.start_loop()
# any calls made to the other thread should be read only
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.KEYDOWN:
# Here we call the lock because we're updating the input list
with self.logic.lock:
self.logic.input_list.append(event)
# Another lock call to access the position
with self.logic.lock:
self.window.fill((0, 0, 0))
pygame.draw.circle(self.window, (0, 0, 255), self.logic.position, 10)
pygame.display.update()
pygame.time.wait(10)
pygame.quit()
quit()
if __name__ == '__main__':
game = Game([800, 600])
game.start()
So what was achieved?
Something light like this doesn't really need any performance upgrades. What this does allow though, is that
the pygame GUI will remain reactive, even if the logic behind it hangs. To see this in action we can put the logic
loop to sleep and see that we can still move the GUI around, click stuff, input commands etc.
change:
# Change this under _loop(self) [line 21]
time.sleep(0.01)
# to this
time.sleep(2)
# if we tried this in the original loop the program becomes glitchy

Referencing an event variable before assignment error and I dont know how to fix it

I keep getting this error whenever I try to open the help section:
Traceback (most recent call last):
File "C:/Users/Chris/Desktop/Paul's stuff/Paul/CpmpProject/Window.py", line 142, in <module>
game.help()
File "C:/Users/Chris/Desktop/Paul's stuff/Paul/CpmpProject/Window.py", line 76, in help
if event.type == MOUSEBUTTONDOWN:
UnboundLocalError: local variable 'event' referenced before assignment
I don't know how to fix this issue. I have a lot of code and I feel that it is a lot to go through to find an error. If you can help me to fix this issue, I will be very grateful and I know a few other people working on similar projects that will be grateful as well as they are having the same issue. My code is below. I don't expect anyone to go through it, but I would be grateful to anyone is willing to and find the error I am having. I have included all of it just in case it is something further up than I expected, but I think the issue is in the help function definition.
import pygame, sys
from pygame.locals import *
import random
from random import shuffle
back = True
backbutton = pygame.image.load("Back button.png")
helpsection = pygame.image.load("Hunt Help section.png")
class Game():
def question(self):
questions = ["What species of bird is also a nickname for New Zealand?",
"Which Twins can you play as in Assassin's Creed Syndicate?",
"Which year was 'Killing In The Name' Christmas Number one?"]
answers = [["kiwi", "Kiwi", "Falcon", "Sparrow", "Crow"], ["frye", "Frye", "Bank", "Green", "Bundy"],
["2009", "2009",
"1999", "1993",
"2004"]]
# I had to do it in two separate lists as it's easier to work with later on
# Also I made the correct answers non-case sensitive to make it easier to test.
Game_back = True
while Game_back == True:
r = len(questions)
score = 0
s = random.randrange(0, r, 1)
# This generates a random number within the range of how many questions there are
# and then prints out that question
print(questions[s])
list = answers[s]
output = []
for i in range(1, 5):
output.append(answers[s][i])
shuffle(output)
print(output[0] + " ", output[1] + " ", output[2] + " ", output[3])
# this takes the answers that correspond with the randomly generated question and shuffles the answers
# I did this as otherwise, the answer would always be the first answer to appear and the player could exploit this
player_answer = input()
if player_answer == answers[s][0] or player_answer == answers[s][1]:
score += 1
print(score)
else:
print("Wrong")
panswer = input("Would you like to play another round?: ")
quit = ["Yes", "yes", "Yeah", "yeah"]
if panswer in quit:
Game_back = False
else:
pygame.quit()
sys.exit()
# this is the basics of the algorithm that will determine if a player can move forward or not in the maze and the score
# they will have at the end
## it takes the input from the player and compares it to the first 2 answers in the corresponding answer set which is
## a separate list from the list that is printed out to the player
def help(self):
pygame.init()
self.FPS = 60
self.fps_clock = pygame.time.Clock()
self.surface = pygame.display.set_mode((640, 480))
# This class sets the basic attributes for the window.
# The clock is set to 60 and the name of the window
# is set to The Hunt which is a working title for my project
DISPLAY_SURF.blit(helpsection, (0, 0))
DISPLAY_SURF.blit(backbutton, ((640 - 124), (480 - 87)))
if event.type == MOUSEBUTTONDOWN:
if (640 -124) >= mouse[0] > 640 and (480 - 87) >= mouse[1] > 480:
back = False
while True:
pygame.display.update()
self.fps_clock.tick(self.FPS)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# This updates the window display to refresh every clock tick
# and to set the background colour as white
# using the RGB colours. I might use these to alter the window's look at a later date
#Initialize pygame and define colours
pygame.init()
white = 255, 255, 255
#Sets the resolution to 640 pixels by 720 pixels and caption for pygame window
DISPLAY_SURF = pygame.display.set_mode((640, 720))
pygame.display.set_caption("The Hunt!")
#Create a clock object
clock = pygame.time.Clock()
FPS = 60
#Define a variable to refer to image
background = pygame.image.load("Startermenu.png")
start = pygame.image.load("PlayGameButton.png")
help = pygame.image.load("HelpButton.png")
credits = pygame.image.load("ShowCreditsButton.png")
Hoveringhelp = pygame.image.load("HoveringHelpButton.png")
#Start main loop
while True:
for event in pygame.event.get():
mouse = pygame.mouse.get_pos()
DISPLAY_SURF.fill(white)
DISPLAY_SURF.blit(background, (0, 0))
DISPLAY_SURF.blit(start, (0, 140))
DISPLAY_SURF.blit(help, (0, 186))
DISPLAY_SURF.blit(credits, (0, 235))
pygame.display.update()
#if 0 <= mouse[0] < 260 and 180 <= mouse[1] < 230:
# DISPLAY_SURF.blit(Hoveringhelp, (0, 186))
# print("hovering over help")
#elif 0 <= mouse[0] < 260 and 235 <= mouse[1] < 270:
# print("hovering over credits")
#elif 0 <= mouse[0] < 260 and 0 <= mouse[1] < 180:
# print("hovering over play button")
if event.type == MOUSEBUTTONDOWN:
if 0 <= mouse[0] < 260 and 140 <= mouse[1] < 180:
game = Game()
game.question()
elif 0 <= mouse[0] < 260 and 180 <= mouse[1] < 230:
game = Game()
game.help()
elif 0 <= mouse[0] < 260 and 240 <= mouse[1] < 285:
game = Game()
game.credits()
elif event.type == QUIT:
pygame.quit()
sys.exit()
In the help() method:
def help(self):
...
if event.type == MOUSEBUTTONDOWN:
...
while True:
...
for event in pygame.event.get():
event is defined in the for loop, but you're referring to it before that.
One way to fix it is to move the if event.type == MOUSEBUTTONDOWN statement inside the for loop.
Or, since .help() is only called from the bottom event loop where the event is already known to be MOUSEBUTTONDOWN, perhaps you could remove the if statement altogether?
(BTW, I thought the error message was pretty clear; did you not understand it?)

Pygame - Mixer system not initialized

I have been working on making a Pygame for my Social Studies class and I want to add new elements to this existing game. The problem is, when I load the old game, without making any significant changes, I get an error. It seems to have a couple of warnings as well that I have looked up but most of the threads are from years ago. My error is as follows:
Jordans-MacBook-Air:SS-Game Jordanxxi$ python ocean_cleaner.py
2017-05-26 12:23:15.729 Python[61184:1392206] Warning once: This application, or a library it uses, is using NSQuickDrawView, which has been deprecated. Apps should cease use of QuickDraw and move to Quartz.
May 26 12:23:15 Python[61184] <Error>: The function ‘SLSFlushWindow’ is obsolete and will be removed in an upcoming update. Unfortunately, this application, or a library it uses, is using this obsolete function, and is thereby contributing to an overall degradation of system performance. Please use `SLSFlushWindowContentRegion' instead.
Traceback (most recent call last):
File "ocean_cleaner.py", line 30, in <module>
hit = pygame.mixer.Sound("resources/audio/pop.wav")
pygame.error: mixer system not initialized
My code, as of now, is as follows:
#Import statements
import pygame, sys
import pygame.mixer
import time
from pygame.locals import *
#Pygame function to load the game and screen size
pygame.init()
screen = pygame.display.set_mode((700,500))
#Images needed in game
background = pygame.image.load("resources/images/background.png")
slick = pygame.image.load("resources/images/slick.png")
slick_med = pygame.image.load("resources/images/slick_med.png")
slick_sml = pygame.image.load("resources/images/slick_sml.png")
diver = pygame.image.load("resources/images/diver_gun.png")
diver1 = pygame.image.load("resources/images/diver_gun1.png")
spray_right = pygame.image.load("resources/images/spray_right.png")
spray_left = pygame.image.load("resources/images/spray_left.png")
win_screen = pygame.image.load("resources/images/win_screen.png")
lose_screen = pygame.image.load("resources/images/lose_screen.png")
red_bar = pygame.image.load("resources/images/red_bar.png")
green_bar2 = pygame.image.load("resources/images/green_bar2.png")
green_bar4 = pygame.image.load("resources/images/green_bar4.png")
air_bar = pygame.image.load("resources/images/air_bar.png")
spray_bar = pygame.image.load("resources/images/spray_bar.png")
#Sounds
hit = pygame.mixer.Sound("resources/audio/pop.wav")
hit.set_volume(0.5)
wash = pygame.mixer.Sound("resources/audio/spray.wav")
wash.set_volume(0.4)
pygame.mixer.music.load('resources/audio/tune_1.wav')
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)
#The Variables
player = diver
spray = spray_right
spray_off_set = 0
pop=False
pop_index=0
player_x = 250
player_y = 100
background_x = 0
background_y = 0
move_x = 0
move_y = 0
keys=[False,False,False,False,False]
slick_large=[[slick,300,250],[slick,1000,650],[slick,1400,1050]]
slick_medium =[]
slick_small = []
clean_up = 12
life = True
sprays = 30
main_loop = 1
while main_loop:
pygame.display.set_caption('Greek Mythology Quiz')
#How the charater moves when certain keys are clicked
#---------------------------------------------------#
#Move Right
if keys[0]==True and move_x <5:
move_x+= 1
player = diver1
spray = spray_left
spray_off_set = -200
#Move Left
if keys[1]==True and move_x >-1310:
move_x-= 1
player = diver
spray = spray_right
spray_off_set = 0
#Move Up
if keys[2]==True and move_y <10:
move_y+= 1
#Move Down
if keys[3]==True and move_y >-1010:
move_y-= 1
#Check for collisions
spray_rect=pygame.Rect(spray.get_rect())
spray_rect.left=(350+spray_off_set)
spray_rect.top=100
player_rect=pygame.Rect(player.get_rect())
player_rect.left= player_x
player_rect.top= player_y
for i in range(len(slick_large)):
slick_rect=pygame.Rect(slick.get_rect())
slick_rect.left=((slick_large[i][1])+move_x)
slick_rect.top=(slick_large[i][2]+move_y)
if spray_rect.colliderect(slick_rect) and keys[4] == True:
pop=True
pop_index=i
if player_rect.colliderect(slick_rect):
life = False
#When pop sound is called, volume depends on object size
if pop==True:
hit.play()
slick_medium.append([slick_med,(slick_large[pop_index][1]+75),(slick_large[pop_index][2]-50)])
slick_medium.append([slick_med,(slick_large[pop_index][1]+150),(slick_large[pop_index][2]+50)])
slick_large.pop(pop_index)
pop=False
#Collision redirect physics
for i in range(len(slick_medium)):
slick_rect=pygame.Rect(slick_med.get_rect())
slick_rect.left=((slick_medium[i][1])+move_x)
slick_rect.top=(slick_medium[i][2]+move_y)
if spray_rect.colliderect(slick_rect) and keys[4] == True:
pop=True
pop_index=i
if player_rect.colliderect(slick_rect):
life = False
if pop==True:
hit.play()
slick_small.append([slick_sml,(slick_medium[pop_index][1]-75),(slick_medium[pop_index][2]-75)])
slick_small.append([slick_sml,(slick_medium[pop_index][1]-150),(slick_medium[pop_index][2]-50)])
slick_medium.pop(pop_index)
pop=False
for i in range(len(slick_small)):
slick_rect=pygame.Rect(slick_sml.get_rect())
slick_rect.left=((slick_small[i][1])+move_x)
slick_rect.top=(slick_small[i][2]+move_y)
if spray_rect.colliderect(slick_rect) and keys[4] == True:
pop=True
pop_index=i
if player_rect.colliderect(slick_rect):
life = False
if pop==True:
hit.play()
slick_small.pop(pop_index)
clean_up -=1
pop=False
#Background scrolling
screen.fill(0)
screen.blit(background,((background_x+move_x),(background_y+move_y)))
screen.blit(player,(player_x,player_y))
if keys[4]==True:
wash.play()
screen.blit(spray,((350+spray_off_set),100))
else:
wash.stop()
for i in range( len(slick_large)):
screen.blit(slick_large[i][0],((slick_large[i][1]+move_x),(slick_large[i][2]+move_y)))
for i in range( len(slick_medium)):
screen.blit(slick_medium[i][0],((slick_medium[i][1]+move_x),(slick_medium[i][2]+move_y)))
for i in range( len(slick_small)):
screen.blit(slick_small[i][0],((slick_small[i][1]+move_x),(slick_small[i][2]+move_y)))
time_remaining = int((60-(pygame.time.get_ticks()/1000)))
screen.blit(air_bar,(8,8))
screen.blit(red_bar,(10,10))
for i in range(time_remaining):
screen.blit(green_bar2,(10+(i*2),10))
screen.blit(spray_bar,(570,8))
screen.blit(red_bar,(572,10))
for i in range(sprays):
screen.blit(green_bar4,(572+(i*4),10))
if clean_up == 0:
screen.blit(win_screen,(0,0))
main_loop = 0
if life == False or sprays == 0 or time_remaining == 0:
screen.blit(lose_screen,(0,0))
main_loop = 0
pygame.display.flip()
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
#Event checkers - Check to see if certain keys are pressed
if event.type == pygame.KEYDOWN:
if event.key==K_LEFT:
keys[0]=True
elif event.key==K_RIGHT:
keys[1]=True
elif event.key==K_UP:
keys[2]=True
elif event.key==K_DOWN:
keys[3]=True
elif event.key==K_SPACE:
keys[4]=True
#Check to see when certain keys are released
if event.type == pygame.KEYUP:
if event.key==K_LEFT:
keys[0]=False
elif event.key==K_RIGHT:
keys[1]=False
elif event.key==K_UP:
keys[2]=False
elif event.key==K_DOWN:
keys[3]=False
elif event.key==K_SPACE:
keys[4]=False
sprays -= 1
end = 1
while end:
#Exit function
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
Any help? Thanks in advance.
Update - I was running the game through terminal instead of Idle. I still get an error but it is a little bit different. Anyone know how to fix this?
Traceback (most recent call last):
File "/Users/Jordanxxi/Desktop/Game/ocean_cleaner.py", line 29, in <module>
hit = pygame.mixer.Sound("resources/audio/pop.wav")
error: mixer system not initialized
I believe you have to do:
pygame.mixer.init()
Check the documentation for mixer (this is always a good idea to do first when you have a problem!): http://www.pygame.org/docs/ref/mixer.html

Pygame game loop trouble

I am a novice programming a game in the Python language using Pygame. I'm having a problem with my game loop. I can only run my game once then I can't make my game loop again. I will post my code below here:
This is my mouse based menu (Menu.py)
import pygame, os, sys
from pygame.locals import *
pygame.init()
def play_music(name, volume=0.7, loop=-1):
fullname = os.path.join('data', name)
try:
pygame.mixer.music.load(fullname)
pygame.mixer.music.set_volume(volume)
pygame.mixer.music.play(loop)
except:
raise SystemExit, "Can't load: " + fullname
def load_sound(name, volume=0.05):
fullname = os.path.join('data', name)
try:
sound = pygame.mixer.Sound(fullname)
sound.set_volume(volume)
except:
raise SystemExit, "Can't load: " + fullname
return sound
def run_game():
import Grab
def reset_highscore():
open("data/highscore.sav", "w").write(str(0))
print "Grab High score reset to 0"
class GrabMenu():
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.mouse.set_visible(0) #make the mouse cursor invisible
pygame.display.set_caption("Grab") #name the game
pygame.display.set_icon(pygame.image.load("data/Icon.png")) #set an icon for the game
screen = pygame.display.set_mode((800, 800)) #screen resolution width and height
background = pygame.Surface(screen.get_size()) #make the background
background = pygame.image.load("data/BG.png").convert() #convert background
background = pygame.transform.scale(background,(800, 800)) #scale the background down to the screen resulution
cursor = pygame.image.load("data/Hand1.png") #make a new cursor inside the game
WHITE = (255, 255, 255) # colors
YELLOW = (255, 216, 0)
running = True # value for main loop
clock = pygame.time.Clock()
font = pygame.font.SysFont("times new roman", 28, bold=True) # menu font and text.
fontcolor = WHITE
fontcolor2 = WHITE
fontcolor3 = WHITE
fontcolor4 = WHITE
mousetrigger = False
mouseclick = load_sound("Click.wav", 3.5) # mouse click
Menu1 = True
Menu2 = False #options menu
Menu3 = False #reset score menu
#JOYSTICK
try:
j = pygame.joystick.Joystick(0) # create a joystick instance
j.init() # init instance
print 'Enabled joystick: ' + j.get_name()
except:
pass
#main_loop
while running == True:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False, sys.exit()
if event.type == MOUSEBUTTONDOWN and event.button == 1: # if mouse button is pressed, (left mouse key only)
if Menu1:
if ren_r.collidepoint(pygame.mouse.get_pos()): # play the game
if Menu1 == False:
pass
else:
mouseclick.play()
run_game()
elif ren2_r.collidepoint(pygame.mouse.get_pos()): #options
if Menu1 == False:
pass
else:
mouseclick.play()
Menu1 = False
Menu2 = True
elif ren3_r.collidepoint(pygame.mouse.get_pos()): #how to play
if Menu1 == False:
pass
else:
mouseclick.play()
elif ren4_r.collidepoint(pygame.mouse.get_pos()): #quit the game
if Menu1 == False:
pass
else:
mouseclick.play()
running = False, pygame.quit(), sys.exit()
elif Menu2:
if ren5_r.collidepoint(pygame.mouse.get_pos()): #reset high score
mouseclick.play()
reset_highscore()
elif ren6_r.collidepoint(pygame.mouse.get_pos()): #go back
mouseclick.play()
Menu1 = True
Menu2 = False
screen.blit(background, (0, 0)) #draw the background
screen.blit(cursor, pygame.mouse.get_pos()) #set the cursor image as the new mouse cursor
if Menu1:
ren = font.render("Play", True, (fontcolor))
ren_r = ren.get_rect()
ren_r.x, ren_r.y = 340, 530
ren2 = font.render("Options", True, (fontcolor2))
ren2_r = ren2.get_rect()
ren2_r.x, ren2_r.y = 340, 590
ren3 = font.render("How to Play", True, (fontcolor3))
ren3_r = ren3.get_rect()
ren3_r.x, ren3_r.y = 340, 650
ren4 = font.render("Quit Game", True, (fontcolor4))
ren4_r = ren4.get_rect()
ren4_r.x, ren4_r.y = 340, 710
screen.blit(ren, (340, 530))
screen.blit(ren2, (340, 590))
screen.blit(ren3, (340, 650))
screen.blit(ren4, (340, 710))
if ren_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor = YELLOW
else:
fontcolor = WHITE
if ren2_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor2 = YELLOW
else:
fontcolor2 = WHITE
if ren3_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor3 = YELLOW
else:
fontcolor3 = WHITE
if ren4_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor4 = YELLOW
else:
fontcolor4 = WHITE
elif Menu2:
options = font.render("Options", 1, (WHITE))
ren5 = font.render("Reset High Score", True, (fontcolor))
ren5_r = ren5.get_rect()
ren5_r.x, ren5_r.y = 350, 650
ren6 = font.render("Go back", True, (fontcolor2))
ren6_r = ren6.get_rect()
ren6_r.x, ren6_r.y = 350, 700
screen.blit(options, (350, 600))
screen.blit(ren5, (350, 650))
screen.blit(ren6, (350, 700))
if ren5_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor = YELLOW
else:
fontcolor = WHITE
if ren6_r.collidepoint(pygame.mouse.get_pos()):
mousetrigger = True
fontcolor2 = YELLOW
else:
fontcolor2 = WHITE
pygame.display.update()
furthermore I use this when I press on "Play" text on my menu:
def run_game():
import Grab
to start my main program "Grab.py":
import pygame, time, math, sys, random, os
from pygame.locals import *
pygame.init() #make pygame ready
pygame.joystick.init
#my game code
done = False
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.key == K_ESCAPE:
if highscore == 0:
pass
if highscore < get_highscore():
pass
else:
save_highscore(highscore)
if score == 0:
pass
else:
save_score(score)
save_level(level)
save_world(world)
done = True
pygame.mixer.music.stop()
Main game loop ends here and sends me back to my menu just like I want. However, when I try to import grab again from my menu then nothing happens. I went and searched for "Python import cycle" from Google and I discovered a few things but i'm still stuck. There must be an easier way to make Grab.py loop from this:
def run_game():
import Grab
Any help is very much appreciated.
Regards HJ.
Generally speaking, use import to load the definition of constants, functions or classes. Do not use it to run a bunch of statements. Call a function to run a bunch of statements.
For efficiency, Python only imports modules once. After it is loaded the first time, the module is cached in sys.modules. Every time Python encounters an import statement it check if the module is in sys.modules and uses the cached module if it exists. Only if the module is not in sys.modules does Python execute the code in the module. Thus the code in the module is never executed more than once. That is why import Grab does not execute the code in Grab.py the second time the import statement is reached.
So, instead, refactor Grab.py to put all the code you wish to run multiple times inside a function:
import pygame, time, math, sys, random, os
from pygame.locals import *
pygame.init() #make pygame ready
pygame.joystick.init() # <-- Note you need parentheses to *call* the init function
def main():
done = False
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.key == K_ESCAPE:
if highscore == 0:
pass
if highscore < get_highscore():
pass
else:
save_highscore(highscore)
if score == 0:
pass
else:
save_score(score)
save_level(level)
save_world(world)
done = True
pygame.mixer.music.stop()
and then change
import Grab
to
import Grab
Grab.main()
You could move import Grab to the top of Menu.py; generally speaking it is recommended to put all the import statements at the top of any Python script or module.

Categories