This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 2 years ago.
I'm starting a grid based game in Pygame, and I've gotten to the point where I have a grid on the screen, and I'm trying to let the user use the arrow keys to move the grid around. I tried to do it by adding a method to my Grid Object, but it doesn't seem to be doing anything. Help would be appreciated
#IMPORTING MODULES
import pygame
from pygame.locals import *
import random
import sys
white = (250,250,250)
black = (0,0,0)
#SETTING UP STUFF
pygame.init()
#ADDING FONTS AND TEXT
myfont = pygame.font.SysFont("monospace", 25)
title = myfont.render("X-COM: UFO DEFENSE", 1, (black))
#MORE SETTING UP
display_width = 800
display_height = 600
SIZE = 25
keys = [False,False,False,False]
scene = "start"
screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('X-COM UFO DEFENSE')
#SETTING UP BUTTON CLASS
class Button(object):
def __init__(self, x, y, width, height,text,touching,clicked):
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
self.rect = pygame.Rect([int(self.x),int(self.y),int(self.width),int(self.height)])
self.touching = touching
self.clicked = clicked
def draw(self):
#DRAW FUNCTION(MAY NEED WORK ON THE TEXT FORMULA)
text1 = myfont.render(str(self.text), 1, (black))
pygame.draw.rect(screen,[255,255,255],self.rect,0)
screen.blit(text1, (self.x + self.width/3,self.y + self.height/3))
def click(self):
#EASY CLICK DETECTION
if self.rect.collidepoint(pygame.mouse.get_pos()):
self.touching = True
else:
self.touching = False
#Creating GRID class
class GridSquare(object):
def __init__(self, internal_row, internal_column, touching,clicked):
self.internal_row = internal_row
self.internal_column = internal_column
self.touching = touching
self.clicked = clicked
self.right = 0
self.up = 0
self.rect = pygame.Rect([int(self.internal_row),int(self.internal_column),25,25])
def draw(self):
pygame.draw.rect(screen,[255,0,255],self.rect,0)
def camera(self):
self.internal_row = self.right+self.internal_row
self.internal_column = self.up+self.internal_column
if keys[0] == True:
self.up += 1
elif keys[1] == True:
self.right -= 1
elif keys[2] == True:
self.up -= 1
elif keys[3] == True:
self.right += 1
#BUTTONS
grid = []
for i in range(100,200,26):
for k in range(100,200,26):
grid.append(GridSquare(i,k,False,False))
titlescreen = Button(300,300,200,100,"Start",False,False)
#MAIN LOOP STARTS HERE
while True:
if scene == "start":
screen.fill(white)
screen.blit(title, (300,50))
titlescreen.draw()
titlescreen.click()
#EVENTS
for event in pygame.event.get():
if titlescreen.touching == True and event.type == pygame.MOUSEBUTTONDOWN:
titlescreen.clicked = True
else:
titlescreen.clicked = False
if event.type == KEYDOWN:
if event.key == pygame.K_w:
keys[0] = True
elif event.key == pygame.K_a:
keys[1] = True
elif event.key == pygame.K_s:
keys[2] = True
elif event.key == pygame.K_d:
keys[3] = True
if titlescreen.clicked == True:
scene = "game"
if scene == "game":
screen.fill(black)
for grids in grid:
grids.draw()
for grids in grid:
grids.camera()
pygame.display.flip()
Related
So, I was watching a video from youtube on making the game Snake on Python with the pygame module.. and it was quite confusing.. and now I'm having an issue.. The pygame window opened and closed suddenly and there was no errors in the output.
I ran this pile of code :
import os
os.environ['DISPLAY'] = ': 0.0'
import pygame
pygame.init()
import random
from enum import Enum
from collections import namedtuple
font = pygame.font.Font('PermanentMarker-Regular.ttf', 25)
#font = pygame.font.SysFont('arial', 25)
class Direction(Enum):
RIGHT = 1
LEFT = 2
UP = 3
DOWN = 4
Point = namedtuple('Point', ('x','y'))
WHITE = (255, 255, 255)
RED = (247,33,25)
BLUE = (0,0,255)
CYAN = (255, 255, 1)
BLACK = [0,0,0]
BLOCK_SIZE = 20
SPEED = 40
class SnakeGame:
def __init__(self, w=640, h=480):
self.w = w
self.h = h
# init display
self.display = pygame.display.set_mode((self.w, self.h))
pygame.display.set_caption("Snake")
self.clock = pygame.time.Clock()
# init game state
self.direction = Direction.RIGHT
self.head = Point(self.w/2, self.h/2)
self.snake = [self.head, Point(self.head.x-BLOCK_SIZE, self.head.y), Point(self.head.x-(2*BLOCK_SIZE), self.head.y)]
self.score = 0
self.food = None
self._place_food()
def _place_food(self):
x = random.randint(0, (self.w-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE
y = random.randint(0, (self.h-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE
self.food = Point(x, y)
if self.food in self.snake:
self._place_food()
self.head = Point(x,y)
def _move(self, direction):
x = self.head.x
y = self.head.y
if direction == Direction.RIGHT:
x += BLOCK_SIZE
elif direction == Direction.LEFT:
x -= BLOCK_SIZE
elif direction == Direction.UP:
y -= BLOCK_SIZE
elif direction == Direction.DOWN:
y += BLOCK_SIZE
def _is_collision(self):
# hits boundary
if self.head.x > self.w - BLOCK_SIZE or self.head.x < 0 or self.head.y > self.h - BLOCK_SIZE or self.head.y < 0:
return True
# hits itself
if self.head in self.snake[1:]:
return True
return False
pygame.display.flip()
def play_step(self):
# collect user input
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.direction = Direction.LEFT
elif event.key == pygame.K_RIGHT:
self.direction = Direction.RIGHT
elif event.key == pygame.K_UP:
self.direction = Direction.UP
elif event.key == pygame.K_DOWN:
self.direction = Direction.DOWN
#2. move
self._move(self.direction)
self.snake.insert(0, self.head)
#3. check if game over
game_over = False
if self._is_collision():
game_over = True
#4. place new food or move snake
if self.head == self.food:
self.score += 1
self._place_food()
else:
self.snake.pop()
#5. update ui and clock
self._update_ui()
self.clock.tick(SPEED)
#6. return game over and score
return game_over, self.score
def _update_ui(self):
self.display.fill(BLACK)
for pt in self.snake:
pygame.draw.rect(self.display, CYAN, pygame.Rect(pt.x, pt.y, BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(self.display, BLUE, pygame.Rect(pt.x+4, pt.y+4, 12, 12))
pygame.draw.rect(self.display, RED, pygame.Rect(self.food.x, self.food.y, BLOCK_SIZE, BLOCK_SIZE))
text = font.render("Score:", str(self.score), True, WHITE)
self.display.blit(text, [0,0])
if __name__ == '__main__':
game = SnakeGame()
# game loop
while True:
game_over, score = game.play_step()
if game_over == True:
break
print("Final score {}".format(score))
# break if game over
pygame.quit()
The issue is probably because I misplaced a method or did something in the script..
There are 4 issues:
Update the head attribute after in the move() method:
class SnakeGame:
# [...]
def _move(self, direction):
x = self.head.x
y = self.head.y
if direction == Direction.RIGHT:
x += BLOCK_SIZE
elif direction == Direction.LEFT:
x -= BLOCK_SIZE
elif direction == Direction.UP:
y -= BLOCK_SIZE
elif direction == Direction.DOWN:
y += BLOCK_SIZE
self.head = Point(x, y) # <--- this is missing
You have to concatenate the strings for the score text (see TypeError: Invalid foreground RGBA argument):
text = font.render("Score:", str(self.score), True, WHITE)
text = font.render("Score:" + str(self.score), True, WHITE)
Update the display after drawing the scene:
def _update_ui(self):
self.display.fill(BLACK)
for pt in self.snake:
pygame.draw.rect(self.display, CYAN, pygame.Rect(pt.x, pt.y, BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(self.display, BLUE, pygame.Rect(pt.x+4, pt.y+4, 12, 12))
pygame.draw.rect(self.display, RED, pygame.Rect(self.food.x, self.food.y, BLOCK_SIZE, BLOCK_SIZE))
text = font.render("Score:" + str(self.score), True, WHITE)
self.display.blit(text, [0,0])
pygame.display.flip() # <--- this is missing
Use pygame.time.Clock to control the frames per second and thus the game speed.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():
This method should be called once per frame.
if __name__ == '__main__':
game = SnakeGame()
# game loop
clock = pygame.time.Clock()
while True:
clock.tick(10)
game_over, score = game.play_step()
if game_over == True:
break
print("Final score {}".format(score))
I am currently making a top down racing game and need a way to detect when a vehicle has completed a full lap. I have chosen to do this by adding images around the circuit, acting as checkpoints, which match with the track surface. When driven over, they output true, all must have output true in order for a lap to count. However, I cannot find a way to detect a collision between my vehicles and an image.
I have tried adding rects to the vehicles and checking if an output can be produced when the two vehicles collide but I just get this error:
AttributeError: 'pygame.Surface' object has no attribute 'rect'
Is there any way I can do this? My code can be seen below.
import pygame
from pygame.locals import *
import math
import time
pygame.init()
F1image = pygame.image.load("F1image.png")
sportsimage = pygame.image.load("sportsimage.png")
bikeimage = pygame.image.load("bikeimage.png")
muscleimage = pygame.image.load("muscleimage.png")
truckimage = pygame.image.load("truckimage.png")
screen = pygame.display.set_mode((1280,720))
xpos = 280
xpos_2 = 280
ypos = 50
ypos_2 = 85
keys = [False, False, False, False]
keys_2 = [False, False, False, False]
direction = 0
direction_2 = 0
forward = 0
forward_2 = 0
class Background(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
BackGround = Background('track.png', [0,0])
class Vehicle:
'Base class for all vehicles (Cars and Motorbikes) in the game'
vehicleCount = 0
def __init__(self, max_speed, acceleration, turning_radius, image):
pygame.sprite.Sprite.__init__(self)
self.max_speed = max_speed
self.acceleration = acceleration
self.turning_radius = turning_radius
self.image = image
self.rect = self.image.get_rect()
Vehicle.vehicleCount = Vehicle.vehicleCount + 1
def displayAmount():
print ("Total number of Vehicle enteries: ", Vehicle.vehicleCount)
def displayVehicle(self):
print ("max speed: ", self.max_speed, "acceleration: ", self.acceleration, "turning radius: ", self.turning_radius)
def checkCollision(self, sprite1, sprite2):
col = pygame.sprite.collide_rect(sprite1, sprite2)
if col == True:
print ("True")
F1 = Vehicle(5.0, 0.1, 2.84, F1image)
sportscar = Vehicle(4.5, 0.2, 2.01, sportsimage)
bike = Vehicle(4.0, 0.15, 2.64, bikeimage)
musclecar = Vehicle(3.5, 0.25, 1.76, muscleimage)
truck = Vehicle(3.0, 0.3, 1.20, truckimage)
print (F1.max_speed)
player1choice = input("Input player 1 choice").lower()
player2choice = input("Input player 2 choice").lower()
if player1choice == ("f1"):
choice1 = F1
elif player1choice == ("sports"):
choice1 = sportscar
elif player1choice == ("muscle"):
choice1 = musclecar
elif player1choice == ("truck"):
choice1 = truck
else:
choice1 = bike
if player2choice == ("f1"):
choice2 = F1
elif player2choice == ("sports"):
choice2 = sportscar
elif player2choice == ("muscle"):
choice2 = musclecar
elif player2choice == ("truck"):
choice2 = truck
else:
choice2 = bike
running = True
while running:
pygame.display.set_caption("Speed Wars")
WHITE = (255, 255, 255)
screen.fill(WHITE)
screen.blit(BackGround.image, BackGround.rect)
#Vehicle 1
if keys[0] == True:
direction += (choice1).turning_radius
if keys[1] == True:
direction -= (choice1).turning_radius
if keys[2] == True and forward <= (choice1).max_speed:
forward += (choice1).acceleration
if keys[3] == True and forward >= 0:
forward -= (choice1).acceleration
#Vehicle 2
if keys_2[0] == True:
direction_2 += (choice2).turning_radius
if keys_2[1] == True:
direction_2 -= (choice2).turning_radius
if keys_2[2] == True and forward_2 <= (choice2).max_speed:
forward_2 += (choice2).acceleration
if keys_2[3] == True and forward_2 >= 0:
forward_2 -= (choice2).acceleration
movex = math.cos(direction / 57.29) * forward
movey = math.sin(direction / 57.29) * forward
xpos += movex
ypos -= movey
movex_2 = math.cos(direction_2 / 57.29) * forward_2
movey_2 = math.sin(direction_2 / 57.29) * forward_2
xpos_2 += movex_2
ypos_2 -= movey_2
rotation = pygame.transform.rotate((choice1).image, direction)
rotation_2 = pygame.transform.rotate((choice2).image, direction_2)
screen.blit(rotation, (xpos, ypos))
screen.blit(rotation_2, (xpos_2, ypos_2))
pygame.display.flip()
time.sleep(0.01)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
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
if event.key == K_a:
keys_2[0] = True
elif event.key == K_d:
keys_2[1] = True
elif event.key == K_w:
keys_2[2] = True
elif event.key == K_s:
keys_2[3] = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
keys[0] = False
elif event.key == pygame.K_RIGHT:
keys[1] = False
elif event.key == pygame.K_UP:
keys[2] = False
elif event.key == pygame.K_DOWN:
keys[3] = False
if event.key == pygame.K_a:
keys_2[0] = False
elif event.key == pygame.K_d:
keys_2[1] = False
elif event.key == pygame.K_w:
keys_2[2] = False
elif event.key == pygame.K_s:
keys_2[3] = False
#Collision detection
(choice1).checkCollision((choice2).image, (choice1).image)
The issue is that your code passes in two images into the checkCollision method in your Vehicle class. Then you are passing these two images into the collide_rect function which expects two Sprites.
As a result, you get an error telling you that the two objects passed in(Surfaces in this case), do not contain rects.
To fix this problem:
Use the superclass Sprite for your Vehicle class.
Simply pass in the other sprite into the checkCollision method.
As a result, your checkCollision function should look something like this:
def checkCollision(self, sprite2):
col = pygame.sprite.collide_rect(self, sprite2)
if col == True:
print ("True")
And the call to it should look something like this:
choice1.checkCollision(choice2)
Also, your Vehicle class header should look like this:
class Vehicle(pygame.sprite.Sprite)
Some other issues in your code that should be fixed:
You are receiving input from the keyboard. This is very weird in a game. Instead, you should look at handling this through keyboard input.
You use brackets around choice1 and choice2. This is not needed.
There is code in your main game loop that doesn't need to be ran every frame such as pygame.display.set_caption(). This again is not needed and code like this should go before the main game loop.
The order of you main game loop is different to how it is normally done. First, you should do event handling. Second, do your logic and lastly, do your rendering.
Also, you are making 5 objects and loading many images where only two will be used. Instead, create and load the objects that will be used in the game after the user has decided which car they will play as.
Never use time.sleep() inside a pygame script. This function is evil when used with pygame and causes many errors and bugs. If you would like to use a framerate cap then use a Clock.
I highly recommend you follow these items.
I hope this answer helped you and if you have any further questions please feel free to post a comment below!
To implement checkpoints in a game I would use a solution similar to this: Define a list, group, etc. which contains your checkpoints and set the start point and the active point to the first checkpoint in the list. You can use an itertools.cycle iterator to easily cycle through the points. When the player touches a checkpoint, you set the active_checkpoint to the next point in the iterator and check if it was the start point, if yes, increment your laps counter.
If you want pixel-perfect collision detection, you can give the sprites a self.mask attribute and use pygame.sprite.collide_mask.
Here's a simplified example. I just swap out the images of the sprites here to show which one is active.
import itertools
import pygame as pg
CHECKPOINT_IMG = pg.Surface((120, 20), pg.SRCALPHA)
CHECKPOINT_IMG.fill((120, 60, 0))
CHECKPOINT2_IMG = pg.Surface((120, 20), pg.SRCALPHA)
CHECKPOINT2_IMG.fill((220, 110, 0))
class Player(pg.sprite.Sprite):
def __init__(self, pos, checkpoints):
super().__init__()
self.image = pg.Surface((60, 60), pg.SRCALPHA)
pg.draw.polygon(self.image, (0, 100, 240), [(30, 0), (60, 60), (0, 60)])
self.rect = self.image.get_rect(center=pos)
self.mask = pg.mask.from_surface(self.image)
self.checkpoints = itertools.cycle(checkpoints)
self.active_checkpoint = next(self.checkpoints)
self.start_point = self.active_checkpoint
self.active_checkpoint.image = self.active_checkpoint.image_active
self.laps = -1 # I start at -1 because the start is the first checkpoint.
def handle_event(self, event):
if event.type == pg.MOUSEMOTION:
self.rect.center = event.pos
if pg.sprite.collide_mask(self, self.active_checkpoint):
if self.active_checkpoint == self.start_point: # Completed a round.
self.laps += 1
pg.display.set_caption('Laps: {}'.format(self.laps))
# I change the images of the previous and next checkpoint
# to show which one is active.
self.active_checkpoint.image = self.active_checkpoint.image_inactive
# Switch to the next checkpoint.
self.active_checkpoint = next(self.checkpoints)
self.active_checkpoint.image = self.active_checkpoint.image_active
class Checkpoint(pg.sprite.Sprite):
def __init__(self, pos, angle=0):
super().__init__()
self.image_inactive = pg.transform.rotate(CHECKPOINT_IMG, angle)
self.image_active = pg.transform.rotate(CHECKPOINT2_IMG, angle)
self.image = self.image_inactive
self.rect = self.image.get_rect(center=pos)
self.mask = pg.mask.from_surface(self.image)
class Game:
def __init__(self):
self.screen = pg.display.set_mode((640, 480))
self.done = False
self.clock = pg.time.Clock()
self.checkpoints = (
Checkpoint((100, 200), 0),
Checkpoint((300, 100), 60),
Checkpoint((500, 300), 10),
Checkpoint((200, 300), 30),
)
self.player = Player((20, 20), self.checkpoints)
self.all_sprites = pg.sprite.Group(self.player)
self.all_sprites.add(self.checkpoints)
def run(self):
while not self.done:
self.event_loop()
self.update()
self.draw()
pg.display.flip()
self.clock.tick(60)
def event_loop(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.done = True
self.player.handle_event(event)
def update(self):
pass
def draw(self):
self.screen.fill((30, 30, 30))
self.all_sprites.draw(self.screen)
if __name__ == '__main__':
pg.init()
game = Game()
game.run()
pg.quit()
This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why is nothing drawn in PyGame at all?
(2 answers)
How to run multiple while loops at a time in Pygame
(1 answer)
Pygame window freezes when it opens
(1 answer)
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 2 years ago.
so my issue is with my player class, I'm still trying to understand classes.
So, basically, I'm using this player movement code from one of Pyganim's examples but I can't seem to implement it into this player class of mine, probably because I don't really understand classes.
For starters. My player never gets displayed now, every thing worked before I tried to add classes. I've probably just over complicated things trying to use this movement. My code is:
import pygame, sys, random, pyganim
from pygame.locals import *
class Scene(object):
screen = pygame.display.set_mode((800, 600))
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
def draw(self):
Scene.screen.fill((0,0,0))
bg = pygame.image.load('C:\\Users\\PAx\\Desktop\\stuff\\fort.png')
Scene.screen.blit(pygame.transform.scale(bg,(400,300)),(0,0))
def update(self):
pass
def handle(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
return meun()
class Player(pygame.sprite.Sprite):
def __init__(self):
self.UP = 'up'
self.DOWN = 'down'
self.LEFT = 'left'
self.RIGHT = 'right'
self.direction = DOWN # player starts off facing down (front)
# load the "standing" sprites (these are single images, not animations)
self.playerWidth, playerHeight = front_standing.get_size()
# creating the PygAnimation objects for walking/running in all directions
self.animTypes = 'back_run back_walk front_run front_walk left_run left_walk'.split()
self.animObjs = {}
for animType in animTypes:
self.imagesAndDurations = [('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_%s.%s.gif' % (animType, str(num).rjust(3, '0')), 1) for num in range(6)]
self.animObjs[animType] = pyganim.PygAnimation(imagesAndDurations)
# create the right-facing sprites by copying and flipping the left-facing sprites
self.animObjs['right_walk'] = animObjs['left_walk'].getCopy()
self.animObjs['right_walk'].flip(True, False)
self.animObjs['right_walk'].makeTransformsPermanent()
self.animObjs['right_run'] = animObjs['left_run'].getCopy()
self.animObjs['right_run'].flip(True, False)
self.animObjs['right_run'].makeTransformsPermanent()
# have the animation objects managed by a conductor.
# With the conductor, we can call play() and stop() on all the animtion
# objects at the same time, so that way they'll always be in sync with each
# other.
self.moveConductor = pyganim.PygConductor(animObjs)
self.x = 100
self.y = 100
self.WALKRATE = 10
self.RUNRATE = 18
self.pygame.sprite.Sprite.__init__(self) #init the Pygame sprite
#load all images
#load the player image
self.front_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_front.gif')
self.back_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_back.gif')
self.left_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_left.gif')
self.right_standing = pygame.transform.flip(left_standing, True, False)
self.running = moveUp = moveDown = moveLeft = moveRight = False
def update(self):
for event in pygame.event.get():
if event.key == KEYDOWN:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has started running
running = True
if event.key == K_UP:
moveUp = True
moveDown = False
if not moveLeft and not moveRight:
# only change the direction to up if the player wasn't moving left/right
direction = UP
elif event.key == K_DOWN:
moveDown = True
moveUp = False
if not moveLeft and not moveRight:
direction = DOWN
elif event.key == K_LEFT:
moveLeft = True
moveRight = False
if not moveUp and not moveDown:
direction = LEFT
elif event.key == K_RIGHT:
moveRight = True
moveLeft = False
if not moveUp and not moveDown:
direction = RIGHT
elif event.type == KEYUP:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has stopped running
running = False
if event.key == K_UP:
moveUp = False
# if the player was moving in a sideways direction before, change the direction the player is facing.
if moveLeft:
direction = LEFT
if moveRight:
direction = RIGHT
elif event.key == K_DOWN:
moveDown = False
if moveLeft:
direction = LEFT
if moveRight:
direction = RIGHT
elif event.key == K_LEFT:
moveLeft = False
if moveUp:
direction = UP
if moveDown:
direction = DOWN
elif event.key == K_RIGHT:
moveRight = False
if moveUp:
direction = UP
if moveDown:
direction = DOWN
if moveUp or moveDown or moveLeft or moveRight:
# draw the correct walking/running sprite from the animation object
moveConductor.play() # calling play() while the animation objects are already playing is okay; in that case play() is a no-op
if running:
if direction == UP:
animObjs['back_run'].blit(screen, (x, y))
elif direction == DOWN:
animObjs['front_run'].blit(screen, (x, y))
elif direction == LEFT:
animObjs['left_run'].blit(screen, (x, y))
elif direction == RIGHT:
animObjs['right_run'].blit(screen, (x, y))
else:
# walking
if direction == UP:
animObjs['back_walk'].blit(screen, (x, y))
elif direction == DOWN:
animObjs['front_walk'].blit(screen, (x, y))
elif direction == LEFT:
animObjs['left_walk'].blit(screen, (x, y))
elif direction == RIGHT:
animObjs['right_walk'].blit(screen, (x, y))
# actually move the position of the player
if running:
rate = RUNRATE
else:
rate = WALKRATE
if moveUp:
y -= rate
if moveDown:
y += rate
if moveLeft:
x -= rate
if moveRight:
x += rate
else:
# standing still
moveConductor.stop() # calling stop() while the animation objects are already stopped is okay; in that case stop() is a no-op
if direction == UP:
Scene.screen.blit(back_standing, ((x, y)))
elif direction == DOWN:
Scene.screen.blit(front_standing, ((x, y)))
elif direction == LEFT:
screen.blit(left_standing, ((x, y)))
elif direction == RIGHT:
screen.blit(right_standing, (x, y))
# make sure the player does move off the screen
if x < 0:
x = 0
if x > WINDOWWIDTH - playerWidth:
x = WINDOWWIDTH - playerWidth
if y < 0:
y = 0
if y > WINDOWHEIGHT - playerHeight:
y = WINDOWHEIGHT - playerHeight
pygame.init()
clock = pygame.time.Clock()
Scene.screen = pygame.display.set_mode((800, 600))
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
scene = scene.update() or scene
scene.draw()
Player.update(scene)
pygame.display.flip()
clock.tick(20)
This is the new and working code.
I changed handle and update and added a lot of self where needed. Wasn't sure how to add in draw() this could probably be cleaned up and written better but at least it works.
import pygame, sys, random, pyganim
from pygame.locals import *
class Scene(object):
screen = pygame.display.set_mode((800, 600))
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
def draw(self):
Scene.screen.fill((0,0,0))
bg = pygame.image.load('C:\\Users\\PAx\\Desktop\\stuff\\fort.png')
Scene.screen.blit(pygame.transform.scale(bg,(400,300)),(0,0))
def update(self):
pass
def handle(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
return Menu()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.UP = 'up'
self.DOWN = 'down'
self.LEFT = 'left'
self.RIGHT = 'right'
self.front_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_front.gif')
self.back_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_back.gif')
self.left_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_left.gif')
self.right_standing = pygame.transform.flip(self.left_standing, True, False)
self.running = self.moveUp = self.moveDown = self.moveLeft = self.moveRight = False
self.direction = self.DOWN # player starts off facing down (front)
# load the "standing" sprites (these are single images, not animations)
self.playerWidth, self.playerHeight = self.front_standing.get_size()
# creating the PygAnimation objects for walking/running in all directions
self.animTypes = 'back_run back_walk front_run front_walk left_run left_walk'.split()
self.animObjs = {}
for self.animType in self.animTypes:
self.imagesAndDurations = [('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_%s.%s.gif' % (self.animType, str(num).rjust(3, '0')), 1) for num in range(6)]
self.animObjs[self.animType] = pyganim.PygAnimation(self.imagesAndDurations)
# create the right-facing sprites by copying and flipping the left-facing sprites
self.animObjs['right_walk'] = self.animObjs['left_walk'].getCopy()
self.animObjs['right_walk'].flip(True, False)
self.animObjs['right_walk'].makeTransformsPermanent()
self.animObjs['right_run'] = self.animObjs['left_run'].getCopy()
self.animObjs['right_run'].flip(True, False)
self.animObjs['right_run'].makeTransformsPermanent()
# have the animation objects managed by a conductor.
# With the conductor, we can call play() and stop() on all the animtion
# objects at the same time, so that way they'll always be in sync with each
# other.
self.moveConductor = pyganim.PygConductor(self.animObjs)
self.x = 100
self.y = 100
self.WALKRATE = 10
self.RUNRATE = 18
self.WINDOWWIDTH = 640
self.WINDOWHEIGHT = 480
#load all images
#load the player image
def update(self, scene):
if self.moveUp or self.moveDown or self.moveLeft or self.moveRight:
# draw the correct walking/running sprite from the animation object
self.moveConductor.play() # calling play() while the animation objects are already playing is okay; in that case play() is a no-op
if self.running:
if self.direction == self.UP:
self.animObjs['back_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.DOWN:
self.animObjs['front_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.LEFT:
self.animObjs['left_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.RIGHT:
self.animObjs['right_run'].blit(Scene.screen, (self.x, self.y))
else:
# walking
if self.direction == self.UP:
self.animObjs['back_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.DOWN:
self.animObjs['front_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.LEFT:
self.animObjs['left_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.RIGHT:
self.animObjs['right_walk'].blit(Scene.screen, (self.x, self.y))
# actually move the position of the player
if self.running:
rate = self.RUNRATE
else:
rate = self.WALKRATE
if self.moveUp:
self.y -= rate
if self.moveDown:
self.y += rate
if self.moveLeft:
self.x -= rate
if self.moveRight:
self.x += rate
else:
# standing still
self.moveConductor.stop() # calling stop() while the animation objects are already stopped is okay; in that case stop() is a no-op
if self.direction == self.UP:
Scene.screen.blit(self.back_standing, ((self.x, self.y)))
elif self.direction == self.DOWN:
Scene.screen.blit(self.front_standing, ((self.x, self.y)))
elif self.direction == self.LEFT:
Scene.screen.blit(self.left_standing, ((self.x, self.y)))
elif self.direction == self.RIGHT:
Scene.screen.blit(self.right_standing, (self.x, self.y))
# make sure the player does move off the screen
if self.x < 0:
self.x = 0
if self.x > self.WINDOWWIDTH - self.playerWidth:
self.x = self.WINDOWWIDTH - self.playerWidth
if self.y < 0:
self.y = 0
if self.y > self.WINDOWHEIGHT - self.playerHeight:
self.y = self.WINDOWHEIGHT - self.playerHeight
def handle(self, event):
if event.type == KEYDOWN:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has started running
running = True
if event.key == K_UP:
self.moveUp = True
self.moveDown = False
if not self.moveLeft and not self.moveRight:
# only change the direction to up if the player wasn't moving left/right
self.direction = self.UP
elif event.key == K_DOWN:
self.moveDown = True
self.moveUp = False
if not self.moveLeft and not self.moveRight:
self.direction = self.DOWN
elif event.key == K_LEFT:
self.moveLeft = True
self.moveRight = False
if not self.moveUp and not self.moveDown:
self.direction = self.LEFT
elif event.key == K_RIGHT:
self.moveRight = True
self.moveLeft = False
if not self.moveUp and not self.moveDown:
self.direction = self.RIGHT
elif event.type == KEYUP:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has stopped running
self.running = False
if event.key == K_UP:
self.moveUp = False
# if the player was moving in a sideways direction before, change the direction the player is facing.
if self.moveLeft:
self.direction = self.LEFT
if self.moveRight:
self.direction = self.RIGHT
elif event.key == K_DOWN:
self.moveDown = False
if self.moveLeft:
self.direction = self.LEFT
if self.moveRight:
self.direction = self.RIGHT
elif event.key == K_LEFT:
self.moveLeft = False
if self.moveUp:
self.direction = self.UP
if self.moveDown:
self.direction = self.DOWN
elif event.key == K_RIGHT:
self.moveRight = False
if self.moveUp:
self.direction = self.UP
if self.moveDown:
self.direction = self.DOWN
pygame.init()
clock = pygame.time.Clock()
Scene.screen = pygame.display.set_mode((800, 600))
player = Player()
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
player.handle(e) or scene
scene = scene.update() or scene
scene.draw()
player.update(scene)
pygame.display.flip()
clock.tick(20)
This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why do group lists in pygame have to have "update" functions, and not any other?
(1 answer)
Closed 2 years ago.
I am trying to create a game similar to "Bubble Trouble" in which the player detects eggs that are falling from the top of the screen. I have several problems with this.
The eggs will not appear on the screen no matter how much I attempt at drawing them and having them appear at some point on the y axis
I have no idea if the collision detection will work because
the program wont open and there is no error message.
Please help me figure out a solutions to this problem. I was so excited to work on this when I started but after days of trying I am being disheartened. Thank you in advance.
Code:
import pygame, random
import Tkinter
from pygame.locals import *
# CONSTANTS
WWD = 1280 # Window width
WHT = 720 # Window height
BLACK = (0,0,0) # Colors
WHITE = (255,255,255)
BACK = BLACK # Background Color
FORE = WHITE # Foreground Color
INT = 40 # Time interval for game and key repeat
BG = pygame.image.load("barn.png")
BG = pygame.transform.scale(BG, (1280, 720))
pygame.init()
pygame.key.set_repeat(INT,INT) # pygame.init disables keyboard repetition. This reenables it with a delay and rep interval
class Label:
def __init__(self,surf,cx,cy,fsize,strng,fcolor,bcolor):
self.screen = surf
self.fc = fcolor
self.bc = bcolor
self.font = pygame.font.SysFont(None,fsize)
self.cx = cx
self.cy = cy
self.str = strng
self.vis = False # tells if the label is visible
def draw(self):
self.text = self.font.render(self.str,True,self.fc,self.bc)
self.rect = self.text.get_rect()
self.rect.centerx = self.cx
self.rect.centery = self.cy
self.screen.blit(self.text,self.rect)
pygame.display.update([self.rect])
self.vis = True
def undraw(self):
self.text.fill(self.bc)
self.screen.blit(self.text,self.rect)
pygame.display.update([self.rect])
self.vis = False
def OpeningScreen(Scr):
Scr.blit(BG, (0, 0))
pygame.display.update()
L1 = Label(Display,WWD//2,WHT*3//8,WHT*3//50,"Use Arrow Keys to Begin",WHITE,BLACK) #Creating the menus
L1.draw()
L2 = Label(Display,WWD//2,WHT*4//8,WHT*3//50,"Hit Q to Quit Anytime",WHITE,BLACK) #Second menu option
L2.draw()
class Player:
def __init__(self,Scr,cx,cy,speed,bcolor):
self.screen = Scr
self.surf = pygame.image.load('player.png').convert_alpha()
self.surf = pygame.transform.scale(self.surf, (160, 200)).convert_alpha()
self.rect = self.surf.get_rect()
self.rect.centerx = cx
self.rect.y = 510
self.speed = 30
self.bc = bcolor
def draw(self):
self.screen.blit(self.surf,self.rect).convert_alpha()
pygame.display.update([self.rect])
def undraw(self):
surf = self.surf.copy()
surf.fill(self.bc)
self.screen.blit(surf,self.rect)
pygame.display.update([self.rect])
def move(self,mv):
self.undraw()
if mv == 'd' and self.rect.bottom < WHT:
self.rect.top += self.speed
if mv == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if mv == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if mv == 'r' and self.rect.right < WWD:
self.rect.right += self.speed
self.draw()
pygame.display.update()
def jump(self,top,left):
self.undraw()
self.rect.top = top
self.rect.left = left
self.draw()
pygame.display.update()
class EggDrop:
def __init__(self,Scr):
pygame.display.update()
pygame.mixer.music.load('background.mid')
pygame.mixer.music.play(-1,0.0)
self.Mplay = True
self.Player = Player(Scr,WWD//2,WHT//2,6,BLACK)
Scr.blit(BG, (0, 0))
self.Scr = Scr
def toggleMusic(self):
self.Mplay = not self.Mplay
if self.Mplay:
pygame.mixer.music.play(-1,0.0)
else:
pygame.mixer.music.stop()
def togglePlayer(self):
if self.Pvis:
self.Player.undraw()
else:
self.Player.draw()
self.Pvis = not self.Pvis
def hatchGif(self):
#files in order animated
files = ["pics\hatch1.gif", "pics\hatch2.gif", "pics\hatch2.gif", "pics\hatch3.gif", "pics\hatch4.gif", "pics\hatch5.gif", "pics\hatch6.gif", "pics\hatch7.gif", "pics\hatch8.gif", "pics\hatch9.gif", "pics\hatch10.gif", "pics\hatch11.gif", "pics\hatch12.gif", "pics\hatch13.gif"]
photos = [Tkinter.PhotoImage(file=x) for x in files]
label = Tkinter.Label()
label.photos = photos
label.counter = 0
def next_pic():
label['image'] = label.photos[label.counter%len(label.photos)]
label.after(25, next_pic) #25 = speed of animation
label.counter += 1
label.pack()
next_pic()
def splatGif(self):
files = ["pics\splat1.gif", "pics\splat2.gif", "pics\splat2.gif", "pics\splat3.gif", "pics\splat4.gif", "pics\splat5.gif", "pics\splat6.gif", "pics\splat7.gif", "pics\splat8.gif"]
photos = [Tkinter.PhotoImage(file=x) for x in files]
label = Tkinter.Label()
label.photos = photos
label.counter = 0
def next_pic():
label['image'] = label.photos[label.counter%len(label.photos)]
label.after(40, next_pic) #25 = speed of animation
label.counter += 1
label.pack()
next_pic()
def eggs(self):
while self.Player.draw():
self.eggsImage = pygame.image.load('hatch1.gif')
self.eggsImage = pygame.transform.scale(self.eggsImage, (30, 40))
self.screen.blit(self.eggsImage)
pygame.display.update([self.eggsImage])
self.eggsImage.centerx = cx
self.eggsImage.y = 300
self.speed = 30
def detectCollisions(x1,y1,w1,h1,x2,y2,w2,h2):
if (x2+w2>=x1>=x2 and y2+h2>=y1>=y2):
return True
elif (x2+w2>=x1+w1>=x2 and y2+h2>=y1>=y2):
return True
elif (x2+w2>=x1>=x2 and y2+h2>=y1+h1>=y2):
return True
elif (x2+w2>=x1+w1>=x2 and y2+h2>=y1+h1>=y2):
return True
else:
return False
class Sprite:
def __init__(self,x,y,width,height):
self.x=x
self.y=y
self.width=width
self.height=height
def render(self,collision):
if (collision==True):
hatchGif()
else:
pass
Sprite1=Player
Sprite2=eggs
moveX,moveY=0,0
gameLoop=True
while gameLoop:
STOP = False
while not STOP:
for event in pygame.event.get():
if event.type==pygame.QUIT:
gameLoop=False
STOP = True
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_LEFT or event.key == ord('a'):
moveX = -4
if event.key==pygame.K_RIGHT or event.key == ord('d'):
moveX = 4
if event.key== K_SPACE:
detectCollisions()
if event.type==pygame.KEYUP:
if event.key == ord('q'):
STOP = True
if event.key == K_ESCAPE:
STOP = True
if event.key == ord('x'):
top = random.randint(0, WHT - self.Player.rect.height)
left = random.randint(0, WWD - self.Player.rect.width)
self.Player.jump(top,left)
if event.key == ord('m'):
self.toggleMusic()
pygame.mixer.music.stop()
Sprite1.x+=moveX
Sprite1.y+=moveY
collisions=detectCollisions(Sprite1.x,Sprite1.y,Sprite1.width,Sprite1.height,Sprite2.x,Sprite2.y,Sprite2.width,Sprite2.height)
Sprite1.render(collisions)
Sprite2.render(False)
pygame.display.flip()
Display = pygame.display.set_mode((WWD,WHT),0,0)
pygame.display.set_caption('Incubator 3000 V.1')
OpeningScreen(Display)
g = EggDrop(Display)
g.run()
pygame.quit()
So I'm just learning how to work with classes and getting them to work between each different class. I'm trying to design a game where the user moves around and picks up food and each time the user picks up a piece of food the size of the character increases. I've done something similar before but now that there are classes involved I seem to have a hard time finding which class this should be part of. I added within the sprite update method that if it collides with a cherry then the size of the player should increase by 5 pixels each time. using the code :
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
Each time the game runs the player size doesn't change and for some reason the game no longer ends after the player has eaten a certain amount of cherries so I was just wondering if I was using a wrong method of changing the size of the player perhaps there may be an easier way to do so? Heres the rest of the code incase it helps at all.
import pygame, glob, random, time
from pygame.locals import *
from LabelClass import *
# CONSTANTS
WIDTH = 400 # Window width
HEIGHT = 400 # Window height
BLACK = (0,0,0) # Colors
WHITE = (255,255,255)
BACKGR = BLACK # Background Color
FOREGR = WHITE # Foreground Color
FPS = 40 # Frames per second
pwidth = 40
pheight = 40
class Food:
def __init__(self,screen,centerx,centery):
self.screen = screen
self.surface = pygame.image.load('cherry.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
class Player:
def __init__(self, screen, centerx,
centery, speed, backcolor):
self.surface = pygame.image.load('player.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
self.speed = speed
self.screen = screen
self.backcolor = backcolor
self.dir = ''
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
def move(self):
if self.dir != '':
if self.dir == 'd' and self.rect.bottom < HEIGHT:
self.rect.top += self.speed
if self.dir == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if self.dir == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if self.dir == 'r' and self.rect.right < WIDTH:
self.rect.right += self.speed
def jump(self,top,left):
self.rect.top = top
self.rect.left = left
class SpritesGame:
def __init__(self,screen):
self.screen = screen
screen.fill(BLACK)
pygame.display.update()
music_file = getRandomMusic()
pygame.mixer.music.load(music_file)
pygame.mixer.music.play(-1,0.0)
self.music = True
self.Foods = [ ]
self.Eaten = 0
for i in range(20):
self.Foods.append(
Food(self.screen,
WIDTH*random.randint(1,9)//10,
HEIGHT*random.randint(1,9)//10))
for f in self.Foods:
f.draw()
self.Player = Player(screen,WIDTH//2,HEIGHT//2,6,BLACK)
self.PickUpSound = pygame.mixer.Sound('pickup.wav')
self.PlaySound = True
self.startTime = time.clock()
self.endTime = -1
self.Won = False
def update(self):
self.screen.fill(BLACK)
pickedUp = False
for f in self.Foods[:]:
if self.Player.rect.colliderect(f.rect):
self.Foods.remove(f)
self.Foods.append(Food(self.screen,WIDTH*random.randint(1,9)//10,HEIGHT*random.randint(1,9)//10))
pickedUp = True
self.Eaten += 1
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
#self.rect.center = center
print self.Eaten
if pickedUp and self.PlaySound:
self.PickUpSound.play()
for f in self.Foods:
f.draw()
if self.Eaten == 40:
self.Won = True
self.endTime = time.clock()
self.Player.move()
self.Player.draw()
pygame.display.update()
def toggleMusic(self):
self.music = not self.music
if self.music:
pygame.mixer.music.play(-1,0.0)
else:
pygame.mixer.music.stop()
def run(self):
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYDOWN: # Keeps moving as long as key down
if event.key == K_LEFT or event.key == ord('a'):
self.Player.dir = 'l'
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = 'r'
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = 'u'
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = 'd'
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
if event.key == K_ESCAPE:
stop = True
if event.key == K_LEFT or event.key == ord('a'): # End repetition.
self.Player.dir = ''
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = ''
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = ''
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = ''
if event.key == ord('x'):
top = random.randint(0,
HEIGHT - self.Player.rect.height)
left = random.randint(0,
WIDTH - self.Player.rect.width)
self.Player.jump(top,left)
if event.key == ord('m'):
self.toggleMusic()
if event.key == ord('p'):
self.PlaySound = not self.PlaySound
mainClock.tick(FPS)
self.update()
if self.Won:
stop = True # END OF WHILE
if self.Won:
self.screen.fill(BLACK)
pygame.display.update()
msg = (str((int(self.endTime)
-int(self.startTime)))
+" seconds to finish. Hit Q.")
L2 = Label(display,WIDTH//2,HEIGHT*7//8,26,msg,WHITE,BLACK)
L2.draw()
stop = False
while not stop:
for event in pygame.event.get():
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
pygame.event.get()
pygame.mixer.music.stop()
def getRandomMusic():
mfiles = glob.glob("*.wav")
mfiles.append(glob.glob("*.mid"))
r = random.randint(0,len(mfiles)-1)
return mfiles[r]
def OpeningScreen(screen):
screen.fill(BLACK)
pygame.display.update()
L1 = Label(display,WIDTH//2,HEIGHT*7//8,26,"Hit Q to Quit, P to Play.",WHITE, BLACK)
L1.draw()
# Properly initiate pygame
pygame.init()
# pygame.key.set_repeat(INT,INT)
# Set the clock up
mainClock = pygame.time.Clock()
# Initialize Display
display = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Sprites and Sounds V06')
OpeningScreen(display)
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYUP:
if event.key == ord('p'):
game = SpritesGame(display)
game.run()
OpeningScreen(display)
if event.key == ord('q'):
stop = True
pygame.quit()
Surface.get_rect() will always return a rect starting at (0,0), and you also are modifying SpritesGame.rect. I think you should change
self.rect = self.Player.surface.get_rect()
to
self.Player.rect.inflate_ip(5, 5)