Pygame Sprite doesn't reset - python

I am making a platformer type game but I have run into two problems.
My Sprite is confined to a small box in the centered in the window. How do I make it so he can cover the entire window?
When I move the old sprite is not removed. It make it appear that there is a tail following the sprite.
Help for either would be appreciated!
import random, sys, copy, os, pygame, time, math
from pygame.locals import *
TILESIZE = 20
WINDOWWIDTH = 1280
WINDOWHEIGHT = 720
FPS = 30
floorx = (WINDOWHEIGHT - (TILESIZE))
floory = (WINDOWWIDTH / TILESIZE)
TileOffset = 20
tilesNeeded = (WINDOWWIDTH / TILESIZE)
floorSize = TILESIZE * 2
OUTSIDE_DECORATION_PCT = 20
HALF_WINDOWHEIGHT = (WINDOWHEIGHT / 2)
HALF_WINDOWWIDTH = (WINDOWWIDTH / 2)
CAMERASLACK = 25
MOVERATE = 9
BOUNCERATE = 6
BOUNCEHEIGHT = 30
INVULTIME = 2
GAMEOVERTIME = 4
MAXHEALTH = 3
STARTSIZE = 30
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
LIGHTGRAY = (174, 174, 174)
DARKGRAY = ( 41, 41, 41)
MEDGRAY = (101, 101, 101)
SKYBLUE = (200, 210, 255)
DARKTURQUOISE = ( 3, 54, 73)
GREEN = ( 0, 92, 7)
LIGHTGREEN = ( 0, 135, 15)
BGCOLOR = LIGHTGRAY
TEXTCOLOR = BLACK
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, TILESIZE, floorx, floory, floorCovered, tilesNeeded, OUTSIDEDECOMAPPING, L_Monster, R_Monster, BGIMAGE
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
FPSCLOCK = pygame.time.Clock()
pygame.display.set_caption('Alpha One')
# Set up the background image.
boardImage = pygame.image.load('bg.png')
# Use smoothscale() to stretch the board image to fit the entire board:
boardImageRect = boardImage.get_rect()
boardImageRect.topleft = (0, 0)
BGIMAGE = pygame.image.load('bg.png')
# Use smoothscale() to stretch the background image to fit the entire window:
BGIMAGE = pygame.transform.smoothscale(BGIMAGE, (WINDOWWIDTH, WINDOWHEIGHT))
BGIMAGE.blit(boardImage, boardImageRect)
#Draw the background
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
#Draw the Floor
drawFloor()
L_Monster = pygame.image.load('monster.png')
L_Monster = pygame.transform.scale(L_Monster, (1000, 600))
R_Monster = pygame.transform.flip(L_Monster, True, False)
pygame.display.flip()
#Main Game Loop
while True:
runGame()
#pygame.display.update()
def runGame():
invulnerableMode = False
invulnerableStartTime = 0
gameOverMode = False
gameOverStartTime = 0
winMode = False
camerax = 0
cameray = 0
playerObj = {'surface': pygame.transform.scale(L_Monster,(STARTSIZE, STARTSIZE)),
'facing': LEFT,
'size': STARTSIZE,
'x': HALF_WINDOWWIDTH,
'y': HALF_WINDOWHEIGHT,
'bounce':0,
'health': MAXHEALTH}
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
while True:
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
drawFloor()
#DISPLAYSURF.fill(WHITE)
if invulnerableMode and time.time() - invulnerableStartTime > INVULNTIME:
invulnerableMode = False
playerCenterx = playerObj['x'] + int(playerObj['size'] / 2)
playerCentery = playerObj['y'] + int(playerObj['size'] / 2)
if (camerax + HALF_WINDOWWIDTH) - playerCenterx > CAMERASLACK:
camerax = playerCenterx + CAMERASLACK - HALF_WINDOWWIDTH
elif playerCenterx - (camerax +HALF_WINDOWWIDTH) > CAMERASLACK:
camerax = playerCenterx - CAMERASLACK - HALF_WINDOWWIDTH
if (cameray + HALF_WINDOWHEIGHT) - playerCentery > CAMERASLACK:
cameray = playerCentery + CAMERASLACK - HALF_WINDOWHEIGHT
elif playerCentery - (cameray +HALF_WINDOWHEIGHT) > CAMERASLACK:
cameray = playerCentery - CAMERASLACK - HALF_WINDOWHEIGHT
flashIsOn = round(time.time(), 1) * 10 % 2 == 1
if not gameOverMode and not (invulnerableMode and flashIsOn):
playerObj['rect'] = pygame.Rect((playerObj['x'] - camerax,
playerObj['y'] - cameray - getBounceAmount(playerObj['bounce'], BOUNCERATE, BOUNCEHEIGHT),
playerObj['size'],
playerObj['size']))
DISPLAYSURF.blit(playerObj['surface'], playerObj['rect'])
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if event.key in (K_UP, K_w):
moveDown = False
moveUp = True
elif event.key in (K_DOWN, K_s):
moveUp = False
moveDown = True
elif event.key in (K_LEFT, K_a):
moveRight = False
moveLeft = True
if playerObj['facing'] == RIGHT:
playerObj['surface'] = pygame.transform.scale(L_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] == LEFT
elif event.key in (K_RIGHT, K_d):
moveLeft = False
moveRight = True
if playerObj['facing'] == LEFT:
playerObj['surface'] = pygame.transform.scale(R_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] = RIGHT
elif winMode and event.key == K_r:
return
elif event.type == KEYUP:
if event.key in (K_LEFT, K_a):
moveLeft = False
elif event.key in (K_RIGHT, K_d):
moveRight = False
elif event.key in (K_UP, K_w):
moveUp = False
elif event.key in (K_DOWN, K_s):
moveDown = False
elif event.key == K_ESCAPE:
terminate()
if not gameOverMode:
if moveLeft:
playerObj['x'] -= MOVERATE
if moveRight:
playerObj['x'] += MOVERATE
if moveUp:
playerObj['y'] -= MOVERATE
if moveDown:
playerObj['y'] += MOVERATE
if (moveLeft or moveRight or moveUp or moveDown) or playerObj['bounce'] != 0:
playerObj['bounce'] += 1
if playerObj['bounce'] > BOUNCERATE:
playerObj['bounce'] = 0
else:
# game is over, show "game over" text
DISPLAYSURF.blit(gameOverSurf, gameOverRect)
if time.time() - gameOverStartTime > GAMEOVERTIME:
return
if winMode:
DISPLAYSURF.blit(winSurf, winRect)
DISPLAYSURF.blit(winSurf2, winRect2)
pygame.display.update()
FPSCLOCK.tick(FPS)
def getBounceAmount(currentBounce, bounceRate, bounceHeight):
return int(math.sin( (math.pi / float(bounceRate)) * currentBounce ) * bounceHeight)
def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
# create a Rect of the camera view
cameraRect = pygame.Rect(camerax, cameray, WINDOWWIDTH, WINDOWHEIGHT)
while True:
x = random.randint(camerax - WINDOWWIDTH, camerax + (2 * WINDOWWIDTH))
y = random.randint(cameray - WINDOWHEIGHT, cameray + (2 * WINDOWHEIGHT))
# create a Rect object with the random coordinates and use colliderect()
# to make sure the right edge isn't in the camera view.
objRect = pygame.Rect(x, y, objWidth, objHeight)
if not objRect.colliderect(cameraRect):
return x, y
def isOutsideActiveArea(camerax, cameray, obj):
boundsLeftEdge = camerax - WINDOWWIDTH
boundsTopEdge = cameray - WINDOWHEIGHT
boundsRect = pygame.Rect(boundsLeftEdge, boundsTopEdge, WINDOWWIDTH * 3, WINDOWHEIGHT * 3)
objRect = pygame.Rect(obj['x'], obj['y'], obj['width'], obj['height'])
return not boundsRect.colliderect(objRect)
def checkForQuit():
for event in pygame.event.get(QUIT): # get all the QUIT events
terminate() # terminate if any QUIT events are present
for event in pygame.event.get(KEYUP): # get all the KEYUP events
if event.key == K_ESCAPE:
terminate() # terminate if the KEYUP event was for the Esc key
pygame.event.post(event)
def drawFloor():
#Open the image used for tiles and initialize N
floorTile = pygame.image.load('tile.png')
N = 0
while (N < tilesNeeded):
DISPLAYSURF.blit(floorTile,((20 * N, (floorx + (TILESIZE/4)) - TILESIZE)), )
DISPLAYSURF.blit(floorTile,(20 * N, (floorx + (TILESIZE/4))))
N = N + 1
#Updates the display
pygame.display.flip()
def checkCollide():
FLOOR_SURF = pygame.Rect( 0, (WINDOWHEIGHT - (TILESIZE * 2)), WINDOWWIDTH, WINDOWHEIGHT)
def terminate():
pygame.quit()
sys.exit()
if __name__ == '__main__':
main()

The reason you're getting the "tail" of your sprite is because you're not clearing the screen before you begin drawing a new frame. One way to handle this would be to enter something like the following at the beginning of runGame():
DISPLAYSURF.fill(white)
This will "clear" the surface by covering everything in white. When you begin drawing images for that frame, they will be drawn over a blank white surface. The caveat to this is that you will need to redraw every sprite on the screen, not just the ones that have moved in the last frame.
For the first question, if you're asking how to scale the size of the image, you would use the scale function from pygame.transform
L_monster = pygame.transform.scale(L_monster, (500, 500))
This creates a new surface by transforming the given surface to the new size given by the tuple.
http://www.pygame.org/docs/ref/transform.html#pygame.transform.scale

Related

Python Snake doesn't grow [duplicate]

This question already has an answer here:
How do I get the snake to grow and chain the movement of the snake's body?
(1 answer)
Closed 1 year ago.
I'm new to python and only now the basics, I'm trying to make a snake game but I can't seem to figure out how to make my snake grow 1 extra square each time it eats an apple. My reasoning is that I keep a list of all the old positions but only show the last one on the screen, and each time the snakes eats another apple it shows 1 extra old positions making the snake 1 square longer.
This is my code:
import pygame
from random import randint
WIDTH = 400
HEIGHT = 300
dis = pygame.display.set_mode((WIDTH,HEIGHT))
white = (255,255,255)
BACKGROUND = white
blue = [0,0,255]
red = [255,0,0]
class Snake:
def __init__(self):
self.image = pygame.image.load("snake.bmp")
self.rect = self.image.get_rect()
self.position = (10,10)
self.direction = [0,0]
self.positionslist = [self.position]
self.length = 1
pygame.display.set_caption('Snake ')
def draw_snake(self,screen):
screen.blit(self.image, self.position)
def update(self):
self.position = (self.position[0] + self.direction[0],self.position[1] + self.direction[1])
self.rect = (self.position[0],self.position[1],5, 5 )
self.positionslist.append(self.position)
if self.position[0]< 0 :
self.position = (WIDTH,self.position[1])
elif self.position[0] > WIDTH:
self.position = (0,self.position[1])
elif self.position[1] > HEIGHT:
self.position = (self.position[0],0)
elif self.position[1] < 0 :
self.position = (self.position[0],HEIGHT)
class Food:
def __init__(self):
self.image = pygame.image.load("appel.png")
self.rect = self.image.get_rect()
apple_width = -self.image.get_width()
apple_height = -self.image.get_height()
self.position = (randint(0,WIDTH+apple_width-50),randint(0,HEIGHT+apple_height-50))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
def draw_appel(self,screen):
screen.blit(self.image, self.position)
def eat_appel (self, snake):
if self.rect.colliderect(snake.rect) == True:
self.position = (randint(0,WIDTH),randint(0,HEIGHT))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
snake.length += 1
def main():
game_over = False
while not game_over:
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
snake = Snake()
food = Food()
while True:
screen.fill(BACKGROUND)
font = pygame.font.Font('freesansbold.ttf', 12)
text = font.render(str(snake.length), True, red, white)
textRect = text.get_rect()
textRect.center = (387, 292)
screen.blit(text,textRect)
snake.update()
#snake.update_list()
snake.draw_snake(screen)
food.draw_appel(screen)
food.eat_appel(snake)
pygame.display.flip()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
snake.direction = [0,1]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
snake.direction = [1,0]
if event.key == pygame.K_LEFT:
snake.direction = [-1,0]
if event.key == pygame.K_UP:
snake.direction = [0,-1]
if event.key == pygame.K_DOWN:
snake.direction = [0,1]
if __name__ == "__main__":
main()
This can have multiple reasons. Firstly, I saw you tried to increase the length of the snake by typing snake.length += 1, which may work (probably won't because the module pygame allows the snake to hover around, but not like the loop or conditional statements). One of my tips would be, to increase the length of the snake by using the idea of adding the score with your present snake.length every time (because once your score is 1 by eating an apple, your snake.length would be 2. And it increases with the score). This is my code (a few modifications might be needed):
import pygame
import time
import random
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
orange = (255, 165, 0)
width, height = 600, 400
game_display = pygame.display.set_mode((width, height))
pygame.display.set_caption("Snake Mania")
clock = pygame.time.Clock()
snake_size = 10
snake_speed = 15
message_font = pygame.font.SysFont('ubuntu', 30)
score_font = pygame.font.SysFont('ubuntu', 25)
def print_score(score):
text = score_font.render("Score: " + str(score), True, orange)
game_display.blit(text, [0,0])
def draw_snake(snake_size, snake_pixels):
for pixel in snake_pixels:
pygame.draw.rect(game_display, white, [pixel[0], pixel[1], snake_size, snake_size])
def run_game():
game_over = False
game_close = False
x = width / 2
y = height / 2
x_speed = 0
y_speed = 0
snake_pixels = []
snake_length = 1
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
while not game_over:
while game_close:
game_display.fill(black)
game_over_message = message_font.render("Game Over!", True, red)
game_display.blit(game_over_message, [width / 3, height / 3])
print_score(snake_length - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
game_over = True
game_close = False
if event.key == pygame.K_2:
run_game()
if event.type == pygame.QUIT:
game_over = True
game_close = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_speed = -snake_size
y_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = snake_size
y_speed = 0
if event.key == pygame.K_UP:
x_speed = 0
y_speed = -snake_size
if event.key == pygame.K_DOWN:
x_speed = 0
y_speed = snake_size
if x >= width or x < 0 or y >= height or y < 0:
game_close = True
x += x_speed
y += y_speed
game_display.fill(black)
pygame.draw.rect(game_display, orange, [target_x, target_y, snake_size, snake_size])
snake_pixels.append([x, y])
if len(snake_pixels) > snake_length:
del snake_pixels[0]
for pixel in snake_pixels[:-1]:
if pixel == [x, y]:
game_close = True
draw_snake(snake_size, snake_pixels)
print_score(snake_length - 1)
pygame.display.update()
if x == target_x and y == target_y:
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
snake_length += 1
clock.tick(snake_speed)
pygame.quit()
quit()
run_game()

PyGame detecting collisions even though they are not happening [duplicate]

This question already has an answer here:
Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
(1 answer)
Closed 2 years ago.
I want to make a Snake game in Python but when I want to detect collision with rects, it seems the game detects collisions even though they are not happening:
if snake_rect.colliderect(jablko_rect):
print("Mniam!")
This collision check prints out text infinitely. How can it print out text when obviously these 2 separate objects are not touching each other. It's not a while loop problem I think. The collision check is for the images which are 49 x 49 px
The whole code:
import random
import pygame
from time import sleep
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
plansza = pygame.display.set_mode((SZEROKOSC, WYSOKOSC)) # rozmiar okna gry
pygame.display.update()
pygame.display.set_caption("Snake") # tytuł okna gry
KROK = 25 # o ile "kroków" ma się przemieszczać snake
snake = pygame.image.load("snake_element.png").convert() # nasz snake
jablko = pygame.image.load("apple.png").convert() # nasze jabłko
snake_rect = snake.get_rect()
jablko_rect = jablko.get_rect()
clock = pygame.time.Clock()
czcionka = pygame.font.SysFont(None, 50)
def wiadomosc(msg, color):
wiad = czcionka.render(msg, True, color)
plansza.blit(wiad, [SZEROKOSC / 2 - 100, WYSOKOSC / 2 - 25])
def petla_gry():
przegrana = False
zamkniecie = False
x1 = SZEROKOSC / 2 # koordynaty
y1 = WYSOKOSC / 2 # koordynaty
x1_zmiana = 0
y1_zmiana = 0
jablko_x = round(random.randrange(0, SZEROKOSC - 25) / 25.0) * 25.0 # 25 to połowa rozmiaru naszych obrazków
jablko_y = round(random.randrange(0, WYSOKOSC - 25) / 25.0) * 25.0 # 25 to połowa rozmiaru naszych obrazków
print(jablko_x)
print(jablko_y)
while not przegrana:
while zamkniecie:
plansza.fill(white)
wiadomosc("Przegrałeś! Q - wyjście z gry, C - restart gry", (255, 0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
przegrana = True
zamkniecie = False
if event.key == pygame.K_c:
petla_gry()
for event in pygame.event.get():
if event.type == pygame.QUIT:
przegrana = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
x1_zmiana = -KROK
y1_zmiana = 0
elif event.key == pygame.K_d:
x1_zmiana = KROK
y1_zmiana = 0
elif event.key == pygame.K_w:
x1_zmiana = 0
y1_zmiana = -KROK
elif event.key == pygame.K_s:
x1_zmiana = 0
y1_zmiana = KROK
if x1 >= SZEROKOSC or x1 <= 0 or y1 >= WYSOKOSC or y1 <= 0:
przegrana = True
wiadomosc("Przegrałeś!", (255, 0, 0))
pygame.display.update()
sleep(2)
x1 += x1_zmiana
y1 += y1_zmiana
plansza.fill((255, 255, 255))
plansza.blit(snake, (x1 - 25, y1 - 25)) # 25 to połowa rozmiaru naszych obrazków
plansza.blit(jablko, (jablko_x, jablko_y))
pygame.display.update()
if snake_rect.colliderect(jablko_rect):
print("Mniam!")
'''if x1 == jablko_x and y1 == jablko_y:
print("Mniam!")'''
clock.tick(8) # czas odświeżania - ruch snake'a
pygame.quit()
quit()
petla_gry()
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.
The Surface is placed at a position on the display with the blit function.
You've to set the location of the rectangle,, e.g:
snake_rect.topleft = (x1 - 25, y1 - 25)
jablko_rect.topleft = (jablko_x, jablko_y)
if snake_rect.colliderect(jablko_rect):
print("Mniam!")

Pygame pygame.Rect how to add text into a rect and move it around the screen?

Trying to add text into a rectangle and move the rectangle around the screen using the arrow keys. I want to make it so the text doesn't go off the edge. So far I had it working without putting it into a Rect but I want to make the Rect function work. Right now the text just bounces back and I don't know how big to make the original rectangle that corresponds with the font size.
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((800,600),0)
pygame.display.set_caption("Basic Pygame Text With Rects")
width = screen.get_width()
height = screen.get_height()
x = int(width/2)
y = int(height/2)
dx = 0
dy = 0
speed = 10
oldx = x
oldy = y
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
colour = BLACK
textRect = pygame.Rect(x, y, 30, 10)
screen.fill(WHITE)
pygame.display.update()
# first set up your font (typeface and size)
# I have created two different ones here that can be used later in the program
fontTitle = pygame.font.SysFont("arial",10)
main = True
while main:
for event in pygame.event.get():
if event.type ==pygame.QUIT:
main = False
if event.type ==pygame.KEYDOWN:
if event.key == pygame.K_UP:
dx = 0
dy = -speed
colour = RED
elif event.key == pygame.K_DOWN:
dx = 0
dy = speed
colour = BLUE
elif event.key == pygame.K_LEFT: # note: this section of code
dx = -speed # doesn't have to change from
dy = 0
colour = GREEN
elif event.key == pygame.K_RIGHT:
dx = speed
dy = 0
colour = YELLOW
elif event.key == pygame.K_c:
x = screen.get_width() / 2
y = screen.get_height() / 2
colour = BLACK
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
dx = 0
dy = 0
elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dx = 0
dy = 0
screen.fill(WHITE)
oldx = x
oldy = y
textRect.move_ip(dx,dy)
if (textRect.y <= 0) or (textRect.y >= height):
dy = 0
textRect.y = int(oldy)
if (textRect.x <= 20) or (textRect.x >= width - 20):
dx = 0
textRect.x = int(oldx)
# render the text into an image of the text, colour is red
# create a rect with it's centre placed at centre of screen
# blit the image to memory, it will display upon next update
textTitle = fontTitle.render("Go Huskies", True, colour)
drawText = textTitle.get_rect(center=(textRect.x, textRect.y))
screen.blit(textTitle, textRect)
pygame.display.update()
pygame.quit()
sys.exit()
You could generate text at start to get its size
fontTitle = pygame.font.SysFont("arial", 10)
textTitle = fontTitle.render("Go Huskies", True, colour)
rectTitle = textTitle.get_rect(center=screen.get_rect().center)
and later use only this rectTitle to move it and check collision with borders - and don't create new textTitle.get_rect()
screen.blit(textTitle, rectTitle)
Rect has .top, .bottom, .left, .right, .centerx, .centery which you can use to check collision
oldx, oldy = rectTitle.center
rectTitle.move_ip(dx, dy)
if (rectTitle.top <= 0) or (rectTitle.bottom >= height):
dy = 0
rectTitle.centery = oldy
if (rectTitle.left <= 0) or (rectTitle.right >= width):
dx = 0
rectTitle.centerx = oldx
import pygame
import sys
# --- constants --- (UPPER_CASE_NAMES)
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
# --- classes --- (CamelCaseNames)
# empty
# --- functions --- (lower_case_names)
# empty
# --- main --- (lower_case_names)
pygame.init()
screen = pygame.display.set_mode((800,600),0)
screen_rect = screen.get_rect()
pygame.display.set_caption("Basic Pygame Text With Rects")
x, y = screen_rect.center
width, height = screen_rect.size
dx = 0
dy = 0
speed = 10
oldx = x
oldy = y
colour = BLACK
fontTitle = pygame.font.SysFont("arial", 10)
textTitle = fontTitle.render("Go Huskies", True, colour)
rectTitle = textTitle.get_rect(center=screen_rect.center)
# - mainloop -
clock = pygame.time.Clock()
main = True
while main:
# - events -
for event in pygame.event.get():
if event.type ==pygame.QUIT:
main = False
if event.type ==pygame.KEYDOWN:
if event.key == pygame.K_UP:
dx = 0
dy = -speed
colour = RED
elif event.key == pygame.K_DOWN:
dx = 0
dy = speed
colour = BLUE
elif event.key == pygame.K_LEFT: # note: this section of code
dx = -speed # doesn't have to change from
dy = 0
colour = GREEN
elif event.key == pygame.K_RIGHT:
dx = speed
dy = 0
colour = YELLOW
elif event.key == pygame.K_c:
x, y = screen_rect.center
colour = BLACK
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
dx = 0
dy = 0
elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dx = 0
dy = 0
# - moves/updates -
oldx, oldy = rectTitle.center
rectTitle.move_ip(dx,dy)
if (rectTitle.top <= 0) or (rectTitle.bottom >= height):
dy = 0
rectTitle.centery = oldy
if (rectTitle.left <= 0) or (rectTitle.right >= width):
dx = 0
rectTitle.centerx = oldx
textTitle = fontTitle.render("Go Huskies", True, colour)
# - draws -
screen.fill(WHITE)
screen.blit(textTitle, rectTitle)
pygame.display.update()
clock.tick(25) # slow down to 25 FPS (frames per seconds)
# - end -
pygame.quit()
sys.exit()
If you want to move text with background rectangle then you can create Surface(), fill it with some color and then blit text on it
at start:
rectRect = pygame.surface.Surface
fontTitle = pygame.font.SysFont("arial", 10)
textTitle = fontTitle.render("Go Huskies", True, colour)
rectTitle = textTitle.get_rect(center=screen_rect.center)
item_surface = pygame.surface.Surface(rectTitle.size)
item_surface.fill(RED)
item_surface.blit(textTitle, (0,0))
textTitle = item_surface
in loop:
textTitle = fontTitle.render("Go Huskies", True, colour)
item_surface = pygame.surface.Surface(rectTitle.size)
item_surface.fill(RED)
item_surface.blit(textTitle, (0,0))
textTitle = item_surface
Full code:
import pygame
import sys
# --- constants --- (UPPER_CASE_NAMES)
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
# --- classes --- (CamelCaseNames)
# empty
# --- functions --- (lower_case_names)
# empty
# --- main --- (lower_case_names)
pygame.init()
screen = pygame.display.set_mode((800,600),0)
screen_rect = screen.get_rect()
pygame.display.set_caption("Basic Pygame Text With Rects")
x, y = screen_rect.center
width, height = screen_rect.size
dx = 0
dy = 0
speed = 10
oldx = x
oldy = y
colour = BLACK
rectRect = pygame.surface.Surface
fontTitle = pygame.font.SysFont("arial", 10)
textTitle = fontTitle.render("Go Huskies", True, colour)
rectTitle = textTitle.get_rect(center=screen_rect.center)
item_surface = pygame.surface.Surface(rectTitle.size)
item_surface.fill(RED)
item_surface.blit(textTitle, (0,0))
textTitle = item_surface
# - mainloop -
clock = pygame.time.Clock()
main = True
while main:
# - events -
for event in pygame.event.get():
if event.type ==pygame.QUIT:
main = False
if event.type ==pygame.KEYDOWN:
if event.key == pygame.K_UP:
dx = 0
dy = -speed
colour = RED
elif event.key == pygame.K_DOWN:
dx = 0
dy = speed
colour = BLUE
elif event.key == pygame.K_LEFT: # note: this section of code
dx = -speed # doesn't have to change from
dy = 0
colour = GREEN
elif event.key == pygame.K_RIGHT:
dx = speed
dy = 0
colour = YELLOW
elif event.key == pygame.K_c:
x, y = screen_rect.center
colour = BLACK
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
dx = 0
dy = 0
elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dx = 0
dy = 0
# - moves -
oldx, oldy = rectTitle.center
rectTitle.move_ip(dx,dy)
if (rectTitle.top <= 0) or (rectTitle.bottom >= height):
dy = 0
rectTitle.centery = oldy
if (rectTitle.left <= 0) or (rectTitle.right >= width):
dx = 0
rectTitle.centerx = oldx
textTitle = fontTitle.render("Go Huskies", True, colour)
item_surface = pygame.surface.Surface(rectTitle.size)
item_surface.fill(RED)
item_surface.blit(textTitle, (0,0))
textTitle = item_surface
# - draws -
screen.fill(WHITE)
screen.blit(textTitle, rectTitle)
pygame.display.update()
clock.tick(25) # slow down to 25 FPS (frames per seconds)
# - end -
pygame.quit()
sys.exit()

How to make my pygade code run faster? It is only running at 4fps

I am trying to make a simple 2d game in pygame and for some reason it only runs at 4fps.h This causes it to be very laggy and choppy. I have looked at other questions which suggest convert() but I do not have any images. Any way to make it faster?? I want it to be running at least 40 fps. I am working on MacOs currently. Here's my code so far:
import math
import sys
import pygame
from pygame.locals import *
pygame.init()
BLACK = (0,0,0)
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE=(0,0,255)
PI = 3.141592653
font = pygame.font.SysFont('Times',12, True,False)
def write_text(text, pos,color):
hi = font.render(text, True,color)
screen.blit(hi, pos)
def draw_label_rect(text,color,object):
pygame.draw.rect(screen, object.color, object.Display_Rect)
hi =font.render( text, True, color)
center_x = object.pos[0]+ 1/2*object.width
center_y =object.pos[1] + 1/2 * object.length
text_width = hi.get_width()
text_height = hi.get_height()
screen.blit(hi, (math.floor(center_x-1/2*text_width),math.floor(center_y-1/2*text_height)))
def draw_image_label_rect_centered(image, color, pos,scale_factor):
pygame.draw.rect(screen, color,pos)
image = pygame.image.load(image).convert_alpha()
width = image.get_width()
height = image.get_height()
image2 = pygame.transform.smoothscale(image,(math.floor(width*scale_factor),math.floor(height*scale_factor)))
new_width = image2.get_width()
new_height = image2.get_height()
center_x = pos[0]+ 1/2*pos[2]
center_y =pos[1] + 1/2 * pos[3]
screen.blit(image2, (center_x-1/2*new_width, center_y-1/2*new_height))
def draw_image_label_rect_behind(image, color, pos,scale_factor):
pygame.draw.rect(screen, color,pos)
image = pygame.image.load(image).convert_alpha()
width = image.get_width()
height = image.get_height()
image2 = pygame.transform.smoothscale(image,(math.floor(width*scale_factor),math.floor(height*scale_factor)))
center_x = pos[0]+ 1/2*pos[2]
new_width = image2.get_width()
screen.blit(image2, (center_x-1/2*new_width, pos[3]+pos[1]+1))
size = (1500, 700)
background = pygame.display.set_mode(size)
screen = pygame.surface.Surface((10000, 10000))
pygame.display.set_caption("HI")
done = False
clock = pygame.time.Clock()
FPS = 120
scroll_y = 0
scroll_x = 0
originalmousex = None
originalmousey = None
Rects= []
Objects = []
class Camera():
def __init__(self):
self.x = 5000
self.y = 5000
self.distance_x = 750
self.distance_y = 350
def move(self,offset_x,offset_y):
self.x +=offset_x
self.y +=offset_y
for i in Objects:
i.screenpos=(i.pos[0]-self.x+750,i.pos[1]-self.y+350)
i.virtual_rect = pygame.Rect(i.screenpos[0],i.screenpos[1],i.width,i.length)
def zoom_in(self):
self.distance_x = math.floor(self.distance_x * 0.95)
self.distance_y = math.floor( self.distance_y * 0.95)
def zoom_out(self):
self.distance_x = math.floor(self.distance_x * 1.05)
self.distance_y = math.floor(self.distance_y * 1.05)
def subsurfacing(self):
self.camera_surface = screen.subsurface((self.x- self.distance_x,self.y - self.distance_y,2*self.distance_x,2*self.distance_y))
background.blit(pygame.transform.smoothscale(self.camera_surface,(1500,700)),(0,0))
main_camera = Camera()
class InfantryRect():
def __init__(self,number, color,formation,pos):
self.number = number
self.color = color
self.formation = formation
class_formation = self.formation
self.pos = pos
self.moving = False
self.movingto = None
self.startmovingframe = None
self.screenpos = (self.pos[0]-main_camera.x+750,self.pos[1]-main_camera.y+350)
if self.formation == 'line':
lengthy = 25
self.Display_Rect = pygame.Rect(self.pos[0],self.pos[1],lengthy*2,(self.number//lengthy)*2)
self.length = self.Display_Rect.height
self.width = self.Display_Rect.width
self.virtual_rect = pygame.Rect(self.screenpos[0],self.screenpos[1],self.width,self.length)
self.speed = 1
def display(self):
if self.formation== 'line':
pygame.draw.rect(screen,self.color,[self.pos[0],self.pos[1],self.width,self.length])
hi = font.render(str(self.number),True,(255,225,64))
center_x = self.pos[0]+ 1/2*self.width
center_y =self.pos[1] + 1/2 * self.length
text_width = hi.get_width()
text_height = hi.get_height()
screen.blit(hi, (math.floor(center_x-1/2*text_width),math.floor(center_y-1/2*text_height)))
def movingcreating(self,position):
self.distance = math.hypot(position[0]-self.virtual_rect.x,position[1]-self.virtual_rect.y)
if self.distance!=0:
self.dx = ((position[0]-self.virtual_rect.x)/self.distance)*self.speed
self.dy = ((position[1]-self.virtual_rect.y)/self.distance)*self.speed
def move(self,position):
if self.distance!=0:
self.pos = (self.pos[0]+self.dx,self.pos[1]+self.dy)
self.virtual_rect = pygame.Rect(int(self.pos[0]-main_camera.x+750),int(self.pos[1]-main_camera.y+350),self.width,self.length)
self.Display_Rect = pygame.Rect(int(self.pos[0]),int(self.pos[1]),self.width,self.length)
self.movingcreating(position)
TestInf = InfantryRect(100,RED,'line',[5000,5000])
Objects.append(TestInf)
count = 0
width = screen.get_width()
length = screen.get_height()
clock = pygame.time.Clock()
z_is_pressed = False
x_is_pressed = False
up_is_pressed = False
down_is_pressed = False
right_is_pressed = False
left_is_pressed = False
mouse_button_holding = False
frames = 0
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos
for i in Objects:
if i.virtual_rect.collidepoint(mouse_pos):
print('Hello')
mouse_button_holding = i
break
if mouse_button_holding==False:
mouse_button_holding = 'scrolling'
originalmousex = mouse_pos[0]
originalmousey = mouse_pos[1]
elif event.type == pygame.MOUSEBUTTONUP:
if mouse_button_holding!= False and mouse_button_holding!='scrolling':
mouse_button_holding.movingto = (event.pos[0] -0.5*mouse_button_holding.width-main_camera.x+5000 , event.pos[1]-0.5*mouse_button_holding.length-main_camera.y+5000)
mouse_button_holding.movingcreating(event.pos)
mouse_button_holding.moving = True
mouse_button_holding.startmovingframe = frames
mouse_button_holding = False
originalmousex = None
originalmousey = None
mouse_button_holding = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_z:
z_is_pressed = True
elif event.key ==pygame.K_x:
x_is_pressed = True
elif event.key == pygame.K_UP:
up_is_pressed = True
elif event.key == pygame.K_DOWN:
down_is_pressed = True
elif event.key == pygame.K_RIGHT:
right_is_pressed = True
elif event.key == pygame.K_LEFT:
left_is_pressed = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_z:
z_is_pressed = False
elif event.key ==pygame.K_x:
x_is_pressed = False
if mouse_button_holding=='scrolling':
main_camera.move(-(pygame.mouse.get_pos()[0]-originalmousex),-(pygame.mouse.get_pos()[1]-originalmousey))
originalmousex = pygame.mouse.get_pos()[0]
originalmousey = pygame.mouse.get_pos()[1]
if z_is_pressed:
main_camera.zoom_in()
if x_is_pressed:
main_camera.zoom_out()
background.fill(BLACK)
screen.fill(BLACK)
# pygame.draw.line(screen, GREEN, [0, 0], [100, 100], 5)
#for y_offset in range(0, 100, 10):
#pygame.draw.line(screen,RED,[0,10+y_offset],[100,110+y_offset],5)
#draw_label_rect('Hello',RED,[250,250,50,50],WHITE)
TestInf.display()
for i in Objects:
if i.moving:
i.move(i.movingto)
main_camera.subsurfacing()
print(clock.get_fps())
clock.tick(60)
pygame.display.update()
frames+=1
pygame.quit()
The major issue is that, screen is a pygame.Surface object with a size of 10000x10000. This surface is cleared in every frame and that's what causes the performance impact:
screen = pygame.surface.Surface((10000, 10000))
screen.fill(BLACK)
Since just a small area (subsurface) of the surface is blit to the screen,
def subsurfacing(self):
self.camera_surface = screen.subsurface((self.x- self.distance_x,self.y - self.distance_y,2*self.distance_x,2*self.distance_y))
background.blit(pygame.transform.smoothscale(self.camera_surface,(1500,700)),(0,0))
It is not necessary to clear the complete screen Surface in every frame. Just clear that area which is drawn into the window later, by pygame.draw.rect:
class Camera():
# [...]
def clearsubsurface(self, color):
px = self.x- self.distance_x,self.y - self.distance_y
py = 2*self.distance_x,2*self.distance_y
pygame.draw.rect(screen, color, (px, py))
while not done:
# [...]
#screen.fill(BLACK) <--- DELETE
main_camera.clearsubsurface(BLACK)
# [...]

Ping Pong Pygame collision with side of pad

I am trying to program a ping pong game in python, and I am able to make the ball bounce off the side of the pad. However, I am unable to make the ball bounce off the top and bottom of the pad. I am currently only doing the left pad (pad1). Here is my code:
import sys, pygame, random, math
pygame.init()
width, height = 1200, 675
screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
clock = pygame.time.Clock()
FPS = 120
xmb1 = False
xmf1 = False
ymb1 = False
ymf1 = False
xmb2 = False
xmf2 = False
ymb2 = False
ymf2 = False
squareh = 275
squarew = 35
squares = 3
x1 = 100
y1 = (height / 2) - (squareh / 2)
x2 = width - 100 - squarew
y2 = (height / 2) - (squareh / 2)
BLACK = (0,0,0)
WHITE = (255,255,255)
font = pygame.font.SysFont("arial", 30)
text = font.render("Press Space to start", True, WHITE)
text3 = font.render("3", True, WHITE)
text2 = font.render("2", True, WHITE)
text1 = font.render("1", True, WHITE)
startt = font.render("Start!", True, WHITE)
text3b = False
text2b = False
text1b = False
starttb = False
start = False
startballmove = False
bx = width / 2
by = height / 2
br = 40
bms = 6
bxm = random.randint(-bms, bms)
bym = random.randint(-bms, bms)
btc = by
blc = bx
bbc = by + br + br
brc = bx + br + br
circle=pygame.Surface((br * 2, br * 2))
circle.fill((0, 0, 0))
pygame.draw.circle(circle, WHITE , (br, br), br, 0)
circle.set_colorkey((0, 0, 0))
pad1 = pygame.Rect(x1, y1, squarew, squareh)
pad2 = pygame.Rect(x2, y2, squarew, squareh)
while 1:
if start and not text1b and not text2b and not text3b and not starttb and not startballmove:
text3b = True
pygame.time.set_timer(pygame.USEREVENT, 1000)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.display.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
# pad 2 check if key is down
if event.key == pygame.K_UP:
ymb2 = True
if event.key == pygame.K_DOWN:
ymf2 = True
# pad 1 check if key is down
if event.key == pygame.K_w:
ymb1 = True
if event.key == pygame.K_s:
ymf1 = True
if event.key == pygame.K_SPACE:
start = True
elif event.type == pygame.KEYUP:
#pad 2 check if key goes up
if event.key == pygame.K_UP:
ymb2 = False
if event.key == pygame.K_DOWN:
ymf2 = False
# pad 1 check if key goes up
if event.key == pygame.K_w:
ymb1 = False
if event.key == pygame.K_s:
ymf1 = False
# check if window has been resized
if event.type == pygame.VIDEORESIZE:
width = event.dict['size'][0]
height = event.dict['size'][1]
screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
if event.type == pygame.USEREVENT:
# check if start should be hidden
if starttb:
starttb = False
startballmove = True
# check if start should be showed
if text1b and not text2b and not text3b:
text1b = False
text2b = False
text3b = False
starttb = True
# check if 1 should be showed
if text2b and not text3b and not text1b:
text3b = False
text2b = False
text1b = True
# check if 2 should be showed
if text3b and not text2b and not text1b:
text3b = False
text2b = True
text1b = False
# check if pad 1 is out of bounds and move it
if ymb1 and not (y1 <= 0): y1 -= squares
if ymf1 and not (y1 + squareh >= height): y1 += squares
if y1 > (height - squareh) + 1: y1 -= squares
# check if pad 2 is out of bounds and move it
if ymb2 and not (y2 <= 0): y2 -= squares
if ymf2 and not (y2 + squareh >= height): y2 += squares
if y2 > (height - squareh) + 1: y2 -= squares
# put pads in center if game has not started
if not start:
# pad 1
x1 = 75
y1 = (height / 2) - (squareh / 2)
# pad 2
x2 = width - 75 - squarew
y2 = (height / 2) - (squareh / 2)
#ball
bx = width / 2 - br
by = height / 2 - br
# put pads in center in x if game has started
else:
# pad 1
x1 = 75
# pad 2
x2 = width - 75 - squarew
# if ball has not started moving center it
if not startballmove:
bx = width / 2 - br
by = height / 2 - br
# check if movement variables are 0
while bxm == 0 or bym == 0:
if bxm == 0:
bxm = random.randint(-6, 6)
if bym == 0:
bym = random.randint(-6, 6)
screen.fill(BLACK)
# draw starting text if game has not started
if not start:
screen.blit(text,((width / 2) - text.get_width() // 2, (height / 4) - text.get_height() // 2))
# put 3 on screen
if start and text3b:
screen.blit(text3,((width / 2) - 15, (height / 4) - (text.get_height() / 2)))
# put 2 on screen
if start and text2b:
screen.blit(text2,((width / 2) - 15, (height / 4) - (text.get_height() / 2)))
# put 1 on screen
if start and text1b:
screen.blit(text1,((width / 2) - 15, (height / 4) - (text.get_height() / 2)))
# put start on screen
if start and starttb:
screen.blit(startt,((width / 2) - (text.get_width() / 8), (height / 4) - (text.get_height() / 2)))
# check if ball is out of bounds
btc = by
blc = bx
bbc = by + br + br
brc = bx + br + br
if start and startballmove:
# screen
if btc <= 0:
bym = bym * -1
print("top side")
if bbc >= height:
bym = bym * -1
print("bottom side")
if blc <= 0:
bxm = bxm * -1
print("left side")
if brc >= width:
bxm = bxm * -1
print("right side")
# left pad
pad1 = pygame.Rect(x1, y1, squarew, squareh)
if pad1.collidepoint(int(bx), int(by)):
bxm = bxm * -1
bx += abs(bxm)
print("Collision")
# move ball
if start and startballmove:
bx += bxm
by += bym
# draw circle if game start
if start:
screen.blit(circle, (int(bx), int(by)))
# draw pad 1
pad1 = pygame.Rect(x1, y1, squarew, squareh)
pygame.draw.rect(screen, WHITE, pad1, 0)
# draw pad 2
pad2 = pygame.Rect(x2, y2, squarew, squareh)
pygame.draw.rect(screen, WHITE, pad2, 0)
pygame.display.flip()
clock.tick(FPS)
Does anyone know how to do this? I have only recently learned to program in python and pygame.
You have to split move and cheking collision on two steps. First move only in X and then you can recognize front collision. Later move in Y and you can recogize side collision.
Your code is big mess so it may need a lot changes. You should organize code and use better names for variables to make it more readable.
And you could use elif and nested if so it will be cleaner.
import sys
import pygame
import random
import math
# --- constants --- (UPPER_CASE_NAMES)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
FPS = 60
SQUARE_HEIGHT = 275
SQUARE_WIDTH = 35
SQUARE_SPEED = 3
BALL_R = 40
# --- main ---
window_width = 1200
window_height = 675
# - init -
pygame.init()
screen = pygame.display.set_mode((window_width, window_height), pygame.RESIZABLE)
screen_rect = screen.get_rect()
# - text -
font = pygame.font.SysFont("arial", 30)
# - text - press space -
text_press_space = font.render("Press Space to start", True, WHITE)
text_press_space_rect = text_press_space.get_rect()
text_press_space_rect.centerx = screen_rect.centerx
text_press_space_rect.centery = screen_rect.height // 4
# - text - count down -
text_1 = font.render("1", True, WHITE)
text_1_rect = text_1.get_rect()
text_1_rect.centerx = screen_rect.centerx
text_1_rect.centery = screen_rect.height // 4
text_2 = font.render("2", True, WHITE)
text_2_rect = text_2.get_rect()
text_2_rect.centerx = screen_rect.centerx
text_2_rect.centery = screen_rect.height // 4
text_3 = font.render("3", True, WHITE)
text_3_rect = text_3.get_rect()
text_3_rect.centerx = screen_rect.centerx
text_3_rect.centery = screen_rect.height // 4
text_start = font.render("Start!", True, WHITE)
text_start_rect = text_start.get_rect()
text_start_rect.centerx = screen_rect.centerx
text_start_rect.centery = screen_rect.height // 4
display_text_3 = False
display_text_2 = False
display_text_1 = False
display_text_start = False
# - ball -
ball = pygame.Surface((BALL_R * 2, BALL_R * 2))
# circle.fill(BLACK) # not need it because surface is black as default
ball.set_colorkey(BLACK)
pygame.draw.circle(ball, WHITE , (BALL_R, BALL_R), BALL_R, 0)
ball_rect = ball.get_rect()
ball_rect.center = screen_rect.center
ball_speed = 6
ball_speed_x = ball_speed * random.choice([1, -1])
ball_speed_y = ball_speed * random.choice([1, -1])
ball_move = False
# - pads -
pad1_rect = pygame.Rect(0, 0, SQUARE_WIDTH, SQUARE_HEIGHT)
pad1_rect.left = 100
pad1_rect.centery = screen_rect.centery
pad1_move_up = False
pad1_move_down = False
pad2_rect = pygame.Rect(0, 0, SQUARE_WIDTH, SQUARE_HEIGHT)
pad2_rect.right = screen_rect.right - 100
pad2_rect.centery = screen_rect.centery
pad2_move_up = False
pad2_move_down = False
# --- mainloop ---
play_start = False
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
# pad 2 check if key is down
if event.key == pygame.K_UP:
pad2_move_up = True
elif event.key == pygame.K_DOWN:
pad2_move_down = True
# pad 1 check if key is down
elif event.key == pygame.K_w:
pad1_move_up = True
elif event.key == pygame.K_s:
pad1_move_down = True
elif event.key == pygame.K_SPACE:
if not play_start:
play_start = True
pygame.time.set_timer(pygame.USEREVENT, 1000)
display_text_3 = True
elif event.type == pygame.KEYUP:
#pad 2 check if key goes up
if event.key == pygame.K_UP:
pad2_move_up = False
elif event.key == pygame.K_DOWN:
pad2_move_down = False
# pad 1 check if key goes up
elif event.key == pygame.K_w:
pad1_move_up = False
elif event.key == pygame.K_s:
pad1_move_down = False
# check if window has been resized
if event.type == pygame.VIDEORESIZE:
window_width = event.dict['size'][0]
window_height = event.dict['size'][1]
screen = pygame.display.set_mode((window_width, window_height), pygame.RESIZABLE)
screen_rect = screen.get_rect()
if event.type == pygame.USEREVENT:
if display_text_3:
display_text_3 = False
display_text_2 = True
elif display_text_2:
display_text_2 = False
display_text_1 = True
elif display_text_1:
display_text_1 = False
display_text_start = True
elif display_text_start:
display_text_start = False
ball_move = True
# - moves (without draws) -
# move paddle 1
if pad1_move_up and pad1_rect.top > 0: # > screen_rect.top:
pad1_rect.y -= SQUARE_SPEED
if pad1_rect.top < 0:
pad1_rect.top = 0
if pad1_move_down and pad1_rect.bottom < screen_rect.bottom:
pad1_rect.y += SQUARE_SPEED
if pad1_rect.bottom > screen_rect.bottom:
pad1_rect.bottom = screen_rect.bottom
# move paddle 2
if pad2_move_up and pad2_rect.top > 0: # > screen_rect.top:
pad2_rect.y -= SQUARE_SPEED
if pad2_rect.top < 0:
pad2_rect.top = 0
if pad2_move_down and pad2_rect.bottom < screen_rect.bottom:
pad2_rect.y += SQUARE_SPEED
if pad2_rect.bottom > screen_rect.bottom:
pad2_rect.bottom = screen_rect.bottom
# check if ball is out of bounds
if play_start:
# move ball
if ball_move:
ball_rect.x += ball_speed_x
# check FRONT collision with pads
if pad1_rect.colliderect(ball_rect):
#if
ball_rect.left = pad1_rect.right
ball_speed_x = -ball_speed_x
print("Front collision right pad")
if pad2_rect.colliderect(ball_rect):
ball_rect.right = pad2_rect.left
ball_speed_x = -ball_speed_x
print("Front collision left pad")
ball_rect.y += ball_speed_y
# check SIDE collision with pads
if pad1_rect.colliderect(ball_rect):
# move from top
if ball_speed_y > 0:
ball_rect.bottom = pad1_rect.top
print("Top collision right pad")
# move from bottom
else: # elif ball_speed_y < 0:
ball_rect.top = pad1_rect.bottom
print("Bottom collision right pad")
# change both or only Y (depends on what effect you need)
ball_speed_x = -ball_speed_x
ball_speed_y = -ball_speed_y
if pad2_rect.colliderect(ball_rect):
# move from top
if ball_speed_y > 0:
ball_rect.bottom = pad2_rect.top
print("Top collision left pad")
# move from bottom
else: # if ball_speed_y < 0:
ball_rect.top = pad2_rect.bottom
print("Bottom collision left pad")
# change both or only Y (depends on what effect you need)
ball_speed_x = -ball_speed_x
ball_speed_y = -ball_speed_y
# check collision with border
if ball_rect.left <= 0: # <= screen_rect.left:
ball_speed_x = -ball_speed_x
print("left side")
print("point for left player")
# move ball to center
ball_rect.center = screen_rect.center
ball_speed_x = ball_speed * random.choice([1, -1])
ball_speed_y = ball_speed * random.choice([1, -1])
if ball_rect.right >= screen_rect.right:
ball_speed_x = -ball_speed_x
print("right side")
print("point for right player")
# move ball to center
ball_rect.center = screen_rect.center
ball_speed_x = ball_speed * random.choice([1, -1])
ball_speed_y = ball_speed * random.choice([1, -1])
if ball_rect.top <= 0: # <= screen_rect.top:
ball_speed_y = -ball_speed_y
print("top side")
if ball_rect.bottom >= screen_rect.bottom:
ball_speed_y = -ball_speed_y
print("bottom side")
# - draws (without moves) -
screen.fill(BLACK)
if not play_start:
screen.blit(text_press_space, text_press_space_rect)
else: # if play_start:
if display_text_3:
screen.blit(text_3, text_3_rect)
if display_text_2:
screen.blit(text_2, text_2_rect)
if display_text_1:
screen.blit(text_1, text_1_rect)
if display_text_start:
screen.blit(text_start, text_start_rect)
screen.blit(ball, ball_rect)
# draw pads
pygame.draw.rect(screen, WHITE, pad1_rect, 0)
pygame.draw.rect(screen, WHITE, pad2_rect, 0)
pygame.display.flip()
clock.tick(FPS)
# --- end ---
pygame.quit()

Categories

Resources