I'm trying to write my first game in pygame and successfully made a title screen, but can't find a way to make the 'play' button take the user to the actual gameplay. I have a function dedicated to the title screen, and when the user clicks the play button it stops the title screen loop and starts the gameplay loop, although the gameplay loop code doesn't work. The title screen just freezes and the game doesn't start. I also have never used Stack overflow so I'll just paste my code here I guess:
import sys
import random
pygame.init()
# title
game_title = 'GAME-TITLE'
# set display
win = pygame.display.set_mode((750, 500))
pygame.display.set_caption(game_title)
# load images
cloud = pygame.image.load('999-cloud-clipart-free-download-transparent-png-cloud-clipart-cloud-clipart-transparent-1044_592.png')
cloud = pygame.transform.scale(cloud, (128, 72))
# clock
clock = pygame.time.Clock()
# font
pygame.font.init()
font = pygame.font.SysFont('verdanaboldttf', 60)
font_2 = pygame.font.SysFont('timesnewromanttf', 30)
# colors
red = (255, 0, 0)
blue = (0, 0, 255)
green = (0, 255, 0)
white = (255, 255, 255)
light_blue = (173, 216, 230)
blue = (48, 131, 159)
navy = (0, 0, 200)
black = (0, 0, 0)
# clouds
cloud_values = []
i = 0
while i < 10:
cloud_values.append([random.randint(-750, -80), random.randint(-50, 550)])
i += 1
def title_screen():
run_title = True
run = True
show_help = False
play_game = False
while run_title:
clock.tick(10)
pygame.draw.rect(win, light_blue, pygame.Rect(-100, -100, 1000, 1000))
play_button = pygame.draw.rect(win, blue, pygame.Rect(150, 175, 450, 75))
help_button = pygame.draw.rect(win, blue, pygame.Rect(150, 275, 450, 75))
quit_button = pygame.draw.rect(win, blue, pygame.Rect(150, 375, 450, 75))
text = font_2.render('PLAY', True, white)
text_2 = font_2.render('HELP', True, white)
text_3 = font_2.render('QUIT', True, white)
title = font.render(game_title, True, navy)
win.blit(text, (340, 197))
win.blit(text_2, (340, 297))
win.blit(text_3, (340, 397))
win.blit(title, (165, 60))
for i in range(len(cloud_values)):
win.blit(cloud, (cloud_values[i][0], cloud_values[i][1]))
cloud_values[i][0] += 10
if cloud_values[i][0] > 760:
cloud_values[i][0] = random.randint(-750, -80)
keys = pygame.key.get_pressed()
if keys[pygame.K_ESCAPE]:
run = False
pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONUP:
pos = pygame.mouse.get_pos()
if pos[0] > 150 and pos[0] < 600 and pos[1] > 175 and pos[1] < 250:
play_game = True
elif pos[0] > 150 and pos[0] < 600 and pos[1] > 275 and pos[1] < 375:
show_help = True
elif pos[0] > 150 and pos[0] < 600 and pos[1] > 375 and pos[1] < 450:
run = False
if pos[0] > 150 and pos[0] < 600 and pos[1] > 175 and pos[1] < 250:
pygame.draw.rect(win, blue, pygame.Rect(145, 170, 460, 85))
win.blit(text, (340, 197))
elif pos[0] > 150 and pos[0] < 600 and pos[1] > 275 and pos[1] < 375:
pygame.draw.rect(win, blue, pygame.Rect(145, 270, 460, 85))
win.blit(text_2, (340, 297))
elif pos[0] > 150 and pos[0] < 600 and pos[1] > 375 and pos[1] < 450:
pygame.draw.rect(win, blue, pygame.Rect(145, 370, 460, 85))
win.blit(text_3, (340, 397))
if play_game or show_help or not run:
run_title = False
pygame.display.flip()
return run_title, play_game, run, show_help
def game_play():
run_game = True
run = True
x = 10
while run_game:
# set new background
pygame.draw.rect(win, light_blue, pygame.Rect(-100, -100, 1000, 1000))
# run gameplay here
return run
def show_help_screen():
show_help = True
while show_help:
pygame.draw.rect(win, light_blue, pygame.Rect(-100, -100, 1000, 1000))
# show help_screen
def show_results_screen():
run = False
show_results = True
while show_results:
pygame.draw.rect(win, light_blue, pygame.Rect(-100, -100, 1000, 1000))
# show results
return run
def run_game(run_title, play_game, run, show_help):
run = True
while run:
if play_game:
game_play()
show_results = True
elif show_help:
show_help_screen()
run_title = True
elif show_results:
run = show_results_screen()
pygame.quit()
sys.exit()
run_title, play_game, run, show_help = title_screen()
run_game(run_title, play_game, run, show_help)```
I went through your code, and I haven't seen an update once.
So since it's your first here's a quick lesson:
when there is any movement, any changes, anything that is changing on your window it won't show up unless you update it, using:
pygame.display.update()
or
pygame.display.flip()
When outputting things, think of them as layers, if you output one image, and then a second image. The first image won't show.
(That's if they are the same size but you know what I mean.)
Related
Game Target is for android device.
When i add the buttons, they seem only to work one at a time, how can i make it so more button could work?
Here's the function:
def button_move(player_car):
pressed = pygame.mouse.get_pressed()
pos = pygame.mouse.get_pos()
moved = False
if pressed[0] == 1:
if 300 < pos[0] < 400 and 800 < pos[1] < 900:
player_car.move_forward()
moved = True
if 300 < pos[0] < 400 and 1100 < pos[1] < 1200:
player_car.move_backward()
moved = True
if 100 < pos[0] < 200 and 950 < pos[1] < 1050:
player_car.rotate(left=True)
if 500 < pos[0] < 600 and 950 < pos[1] < 1050:
player_car.rotate(right=True)
if not moved:
player_car.reduce_speed()
[...] they seem only to work one at a time [...]"
You only have one mouse. You have to use the "touch" events. Use the FINGERDOWN and FINGERUP event. Store the position of the finger into a dictionary when a FINGERDOWN event occurs and remove it on FINGERUP:
fingers = {}
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.FINGERDOWN:
x = event.x * window.get_height()
y = event.y * window.get_width()
fingers[event.finger_id] = x, y
if event.type == pygame.FINGERUP:
fingers.pop(event.finger_id, None)
# [...]
Use the positions to detect if a button is touched. Use pygame.Rect and pygame.Rect.collidepoint for the "touch" detection. e.g.:
rect = pygame.Rect(300, 800, 100, 100)
touched = False
for finger, pos in fingers.items():
if rect.collidepoint(pos):
touched = True
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
buttons = [
pygame.Rect(25, 25, 100, 100),
pygame.Rect(175, 25, 100, 100),
pygame.Rect(25, 175, 100, 100),
pygame.Rect(175, 175, 100, 100)]
colors = [(64, 0, 0), (64, 64, 0), (0, 64, 0), (0, 0, 64)]
colorsH = [(255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 0, 255)]
fingers = {}
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.FINGERDOWN:
x = event.x * window.get_height()
y = event.y * window.get_width()
fingers[event.finger_id] = x, y
if event.type == pygame.FINGERUP:
fingers.pop(event.finger_id, None)
highlight = []
for i, rect in enumerate(buttons):
touched = False
for finger, pos in fingers.items():
if rect.collidepoint(pos):
touched = True
highlight.append(touched)
# the same with list comprehensions
#highlight = [any(r.collidepoint(p) for _, p in fingers.items()) for _, r in enumerate(buttons)]
window.fill(0)
for rect, color, colorH, h in zip(buttons, colors, colorsH, highlight):
c = colorH if h else color
pygame.draw.rect(window, c, rect)
pygame.display.flip()
pygame.quit()
exit()
This question already has an answer here:
How can I add an image or icon to a button rectangle in Pygame?
(1 answer)
Closed 1 year ago.
How can I stick an image to a rectangle? I think it has something to do with the blit function. I want to blit the image onto the rectangle on line 50.
import pygame
import sys
pygame.init()
FPS = 60
start_smallfont = pygame.font.SysFont('Corbel', 45)
start_text = start_smallfont.render('Start', True, (255, 255, 255))
rect_smallfont = pygame.font.SysFont('Corbel', 33)
rect_text = rect_smallfont.render('You', True, (255, 255, 255))
x = 375
y = 335
vel = 0.1
startWIDTH, startHEIGHT = 170, 80
screenWIDTH, screenHEIGHT = 800, 720
WIN = pygame.display.set_mode((screenWIDTH, screenHEIGHT))
pygame.display.set_caption(":D")
def main():
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
clock.tick(FPS)
run = False
while True:
global x, y
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
WIN.fill((0, 0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < screenWIDTH - 50 - vel:
x += vel
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN] and y < screenHEIGHT - 50 - vel:
y += vel
pygame.draw.rect(WIN, (255, 0, 0), (x, y, 50, 50))
pygame.display.update()
mouse = pygame.mouse.get_pos()
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
pygame.draw.rect(WIN, (255, 91, 91), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
else:
pygame.draw.rect(WIN, (255, 0, 0), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
WIN.blit(start_text, (800/2-85+42,720/2-40+20))
pygame.display.update()
if __name__ == "__main__":
main()
Any basic tutorial like this one shows how to do it, so it's not clear what you're having trouble with, since you didn't specify what issues you're having. This should work in your code though:
# goes at the top of the script:
image_to_draw = pygame.image.load('something.png')
# to draw the image:
WIN.blit(image_to_draw, (x, y, 50, 50))
I'm trying to fix my game. When the game is over, it calls a crash() function. It gives the user the option to play again or quit. When calling my game_loop function in the "Play Again" button inside the crash() function, the game will not restart. Any suggestions? Thanks in advance.......................
import math
import random
import time
import pygame
from pygame import mixer
# Intialize the pygame
pygame.init()
# next setup the display
display_width = 800
display_height = 600
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('waterbackground.jpg')
# game clock to time frames per second
clock = pygame.time.Clock()
# Sound
mixer.music.load("ocean.wav")
mixer.music.play(-1)
# setup colors needed in the game
black = (0,0,0)
white = (255, 255, 255)
red = (200, 0, 0)
bright_red = (255,0,0)
block_color = (53,115,255)
green = (0,200,0)
bright_green = (0,255,0)
# Caption and Icon
pygame.display.set_caption("Pirate War")
icon = pygame.image.load('pirateship.png')
pygame.display.set_icon(icon)
# cannon
cannonImg = pygame.image.load('cannonball.png')
cannonX = 0
cannonY = 480
cannonX_change = 0
cannonY_change = 10
cannon_state = "ready"
# Player
playerImg = pygame.image.load('cannon.png')
playerX = 370
playerY = 480
playerX_change = 0
# Score
score_value = 0
# add explosion sound
crash_sound = pygame.mixer.Sound("explosion.wav")
# ship
shipImg = []
shipX = []
shipY = []
shipX_change = []
shipY_change = []
num_of_ships = 6
for i in range(num_of_ships):
shipImg.append(pygame.image.load('pirateship.png'))
shipX.append(random.randint(0, 736))
shipY.append(random.randint(50, 150))
shipX_change.append(4)
shipY_change.append(40)
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
credits_font = pygame.font.Font('freesansbold.ttf', 24)
# text object function called by message display function
def text_objects(text, font):
textSurface = font.render(text, True, white)
return textSurface, textSurface.get_rect()
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER!", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
crash()
def game_credits_text(text):
over_text = over_font.render(text, True, (255, 255, 255))
screen.blit(over_text, (200, 150))
def game_credits_text_small(text):
credits_text = credits_font.render(text, True, (255, 255, 255))
screen.blit(credits_text, (20, 350))
def game_intro_text_small(text):
credits_text = credits_font.render(text, True, (255, 255, 255))
screen.blit(credits_text, (125, 375))
def player(x, y):
screen.blit(playerImg, (x, y))
def ship(x, y, i):
screen.blit(shipImg[i], (x, y))
def fire_cannon(x, y):
global cannon_state
cannon_state = "fire"
screen.blit(cannonImg, (x + 16, y + 10))
def isCollision(shipX, shipY, cannonX, cannonY):
distance = math.sqrt(math.pow(shipX - cannonX, 2) + (math.pow(shipY - cannonY, 2)))
if distance < 27:
return True
else:
return False
# function to setup message display
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 70)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2), (display_height/2))
screen.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def crash():
#add crash sound
pygame.mixer.music.stop()
pygame.mixer.Sound.play(crash_sound)
game_credits_text("Game Over!")
game_credits_text_small("Created by: Dominique Kellam, Hayley Cull and Dewayne Bowen")
while True:
# check for quit
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill((0, 0, 0))
#add buttons to start screen
button("Play Again",150, 450, 100, 50, green, bright_green, game_loop)
button("Quit",550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos() # returns a list of [x,y]
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y: #check is mouse over button
# redraw the rectange with active color when mouseover
pygame.draw.rect(screen, ac, (x, y, w, h))
#check for a click
if click[0] == 1 and action!=None:
action()
else:
pygame.draw.rect(screen, ic, (x, y, w, h))
# now display text on top of button that was just redrawn
smallText = pygame.font.Font('freesansbold.ttf', 20)
TextSurf, TextRect = text_objects(msg, smallText)
TextRect.center = ((x+(w/2)), (y+(h/2)))
screen.blit(TextSurf, TextRect)
def quitgame():
pygame.quit()
quit()
# start screen code
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects("Pirate War", largeText)
game_intro_text_small("[space bar] - fire cannon, [<] [>] arrows to move")
TextRect.center = ((display_width/2), (display_height/2))
screen.blit(TextSurf, TextRect)
#add buttons to start screen
button("Go!",150, 450, 100, 50, green, bright_green, game_loop)
button("Quit",550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def game_loop():
global playerX
global playerX_change
global cannonX
global cannonY
global cannon_state
global score_value
# Game Loop
running = True
while running:
# RGB = Red, Green, Blue
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.key == pygame.K_SPACE:
if cannon_state == "ready":
cannonSound = mixer.Sound("cannon_x.wav")
cannonSound.play()
# Get the current x cordinate of the spaceship
cannonX = playerX
fire_cannon(cannonX, cannonY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# ship Movement
for i in range(num_of_ships):
# Game Over
if shipY[i] > 440:
for j in range(num_of_ships):
shipY[j] = 2000
game_over_text()
break
shipX[i] += shipX_change[i]
if shipX[i] <= 0:
shipX_change[i] = 1 #######SHIP MOVEMENT
shipY[i] += shipY_change[i]
elif shipX[i] >= 736:
shipX_change[i] = -1 ######SHIP MOVEMENT
shipY[i] += shipY_change[i]
# Collision
collision = isCollision(shipX[i], shipY[i], cannonX, cannonY)
if collision:
explosionSound = mixer.Sound("explosion.wav")
explosionSound.play()
cannonY = 480
cannon_state = "ready"
score_value += 1
shipX[i] = random.randint(0, 736)
shipY[i] = random.randint(50, 150)
ship(shipX[i], shipY[i], i)
# cannon Movement
if cannonY <= 0:
cannonY = 480
cannon_state = "ready"
if cannon_state == "fire":
fire_cannon(cannonX, cannonY)
cannonY -= cannonY_change
player(playerX, playerY)
show_score(textX, testY)
pygame.display.update()
game_intro()
You are setting the ship y to 2000 which is > 400 so it just goes back to crash. Change this to zero and it will work.
I am new to pygame I am making a simple game. In this code, I am trying to draw a rectangle when the mouse is at a certain position but it is not drawing it works when I print anything
import pygame
pygame.init()
res = (600,600)
screen = pygame.display.set_mode(res)
pygame.display.set_caption("Tic Tac Toe")
background = (255,150,150)
color_light = (170,170,170)
color_dark = (100,100,100)
hover_color = (255, 204, 203)
width = screen.get_width()
height = screen.get_height()
def draw_line():
pygame.draw.rect(screen, line_color, (190,10,10,580))
pygame.draw.rect(screen, line_color, (390, 10, 10, 580))
pygame.draw.rect(screen, line_color, (10, 200, 580, 10))
pygame.draw.rect(screen, line_color, (10, 390, 580, 10))
def highlight():
if 10 <= mouse[0] <= 10+180 and 10 <= mouse[1] <= 10+190:
pygame.draw.rect(screen, hover_color, (10, 10, 180, 190)) # X,Y,WIDTH,HEIGHT
if 205 <= mouse[0] <= 205+180 and 10 <= mouse[1] <= 10+190:
pygame.draw.rect(screen, hover_color, (200, 10, 190, 190)) # X,Y,WIDTH,HEIGHT
if 400 <= mouse[0] <= 400+190 and 10 <= mouse[1] <= 10+190:
pygame.draw.rect(screen, hover_color, (400, 10, 190, 190)) # X,Y,WIDTH,HEIGHT
if 10 <= mouse[0] <= 10+180 and 210 <= mouse[1] <= 210+180:
pygame.draw.rect(screen, hover_color, (10, 210, 180, 180)) # X,Y,WIDTH,HEIGHT
if 200 <= mouse[0] <= 200+180 and 210 <= mouse[1] <= 210+180:
pygame.draw.rect(screen, hover_color, (200, 210, 200, 180)) # X,Y,WIDTH,HEIGHT
if 400 <= mouse[0] <= 400+190 and 210 <= mouse[1] <= 210+180:
pygame.draw.rect(screen, hover_color, (400, 210, 190, 180)) # X,Y,WIDTH,HEIGHT
if 10 <= mouse[0] <= 10+180 and 400 <= mouse[1] <= 400+200:
pygame.draw.rect(screen, hover_color, (10, 400, 180, 190)) # X,Y,WIDTH,HEIGHT
if 200 <= mouse[0] <= 200+190 and 400 <= mouse[1] <= 400+200:
pygame.draw.rect(screen, hover_color, (200, 400, 190, 190)) # X,Y,WIDTH,HEIGHT
if 400 <= mouse[0] <= 400+190 and 400 <= mouse[1] <= 400+190:
pygame.draw.rect(screen, hover_color, (400, 400, 190, 190)) # X,Y,WIDTH,HEIGHT
while True:
screen.fill(background)
mouse = pygame.mouse.get_pos()
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
if 10 <= mouse[0] <= 10 + 180 and 10 <= mouse[1] <= 10 + 190:
pygame.draw.rect(screen,background,(10,10,180,190))
pygame.display.update()
line_color = (212, 212, 255)
draw_line()
highlight()
pygame.display.update()
To make the rectangle permanent, you need to draw the rectangle in the application loop. The event occurs only once in a single frame. Add a variable clicked = False. Set the variable when the event occurs. And draw the rectangle dependent on the state of the variable:
clicked = False
while True:
screen.fill(background)
mouse = pygame.mouse.get_pos()
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
if 10 <= mouse[0] <= 10 + 180 and 10 <= mouse[1] <= 10 + 190:
clicked = True
line_color = (212, 212, 255)
draw_line()
highlight()
if clicked:
pygame.draw.rect(screen,background,(10,10,180,190))
pygame.display.update()
Simplify your code:
Create a list of pygame.Rect objects for the rectangles
rect_list = [pygame.Rect(10, 10, 180, 190), ...]
Create a list for the stated of the fields
clicked_list = [0 for _ in rect_list]
Use collideponit to test if the mouse is on a rectangle:
for rect in rect_list:
if rect.collidepoint(mouse):
pygame.draw.rect(screen, hover_color, rect)
Use collidepoint to evaluate whether a field is clicked and to change the state of the field
if ev.type == pygame.MOUSEBUTTONDOWN:
for i, rect in enumerate(rect_list):
if rect.collidepoint(ev.pos):
clicked_list[i] = 1
Draw the field in a loop depending on its state:
for i, rect in enumerate(rect_list):
if clicked_list[i]:
pygame.draw.rect(screen,background,rect)
Complete code:
import pygame
pygame.init()
res = (600,600)
screen = pygame.display.set_mode(res)
pygame.display.set_caption("Tic Tac Toe")
background = (255,150,150)
color_light = (170,170,170)
color_dark = (100,100,100)
hover_color = (255, 204, 203)
width = screen.get_width()
height = screen.get_height()
def draw_line():
pygame.draw.rect(screen, line_color, (190,10,10,580))
pygame.draw.rect(screen, line_color, (390, 10, 10, 580))
pygame.draw.rect(screen, line_color, (10, 200, 580, 10))
pygame.draw.rect(screen, line_color, (10, 390, 580, 10))
rect_list = [
pygame.Rect(10, 10, 180, 190),
pygame.Rect(200, 10, 180, 190),
pygame.Rect(400, 10, 180, 190),
pygame.Rect(10, 210, 180, 190),
pygame.Rect(200, 210, 180, 190),
pygame.Rect(400, 210, 180, 190),
pygame.Rect(10, 400, 180, 190),
pygame.Rect(200, 400, 180, 190),
pygame.Rect(400, 400, 180, 190)]
clicked_list = [0 for _ in rect_list]
def highlight():
for rect in rect_list:
if rect.collidepoint(mouse):
pygame.draw.rect(screen, hover_color, rect)
while True:
mouse = pygame.mouse.get_pos()
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
for i, rect in enumerate(rect_list):
if rect.collidepoint(ev.pos):
clicked_list[i] = 1
line_color = (212, 212, 255)
screen.fill(background)
draw_line()
highlight()
for i, rect in enumerate(rect_list):
if clicked_list[i] == 1:
pygame.draw.rect(screen,background,rect)
pygame.display.update()
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.
Alright so I am trying to just code a simple pong game in python using pygame module and I keep running into an attribute error. I know similar questions have been asked before but I can't figure out the answer from those questions. I'd appreciate any help at all :).
so, the error i am getting in my code is
File "D:/Dev/Documents/Projects/Pong/pong.py", line 81, in <module>
ball.x += ball_speed_x
AttributeError: 'pygame.Surface' object has no attribute 'x'
my code is
import pygame, sys
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 960
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('game')
background = pygame.image.load('bg.png')
white = (255, 255, 255)
green = (51, 255, 51)
ball = pygame.image.load('ball.png')
paddle1 = pygame.Rect(screen_width - int(20), screen_height/int(2) - int(70), int(10), int(140))
paddle2 = pygame.Rect(int(10), screen_height/int(2) - int(70), int(10), int(140))
basicfont = pygame.font.SysFont(None, 48)
text = basicfont.render('Pong Game', True, green)
textrect = text.get_rect()
textrect.centerx = screen.get_rect().centerx
ball_speed_x = 7
ball_speed_y = 7
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(white)
screen.blit(background, (0, 0))
screen.blit(text, textrect)
pygame.draw.rect(screen, white, paddle1)
pygame.draw.rect(screen, white, paddle2)
pygame.draw.aaline(screen, green, (screen_width/2, 0), (screen_width/2, screen_height))
pygame.display.flip()
ball.x += ball_speed_x
ball.y += ball_speed_y
if ball.top <= 0 or ball.bottom >= screen_height:
ball_speed_y *= -1
if ball.left <= 0 or ball.right >= screen_width:
ball_speed_x *= -1
clock.tick(60)
Again, any help would be greatly appreciated and I am aware of other similar questions, I'm just new to this language and can't seem to figure this out. Thanks.
A pygame.Surface has no position. A Surface just contains the image.
If you want to draw the ball surface in the window, then you have to blit() the ball at a certain position.
You have to create a pygame.Surface and a pygame.Rect objecct:
ball = pygame.image.load('ball.png')
ball_rect = ball.get_rect(center = (screen_width // 2, screen_height // 2))
Then you can change the location of ball_rect and blit the ball to the screen Surface:
screen.blit(ball, ball_rect)
See the example:
import pygame, sys
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 960
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('game')
background = pygame.image.load('bg.png')
white = (255, 255, 255)
green = (51, 255, 51)
ball = pygame.image.load('ball.png')
ball_rect = ball.get_rect(center = (screen_width // 2, screen_height // 2))
paddle1 = pygame.Rect(screen_width - int(20), screen_height/int(2) - int(70), int(10), int(140))
paddle2 = pygame.Rect(int(10), screen_height/int(2) - int(70), int(10), int(140))
basicfont = pygame.font.SysFont(None, 48)
text = basicfont.render('Pong Game', True, green)
textrect = text.get_rect()
textrect.centerx = screen.get_rect().centerx
ball_speed_x = 7
ball_speed_y = 7
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(white)
screen.blit(background, (0, 0))
screen.blit(text, textrect)
pygame.draw.rect(screen, white, paddle1)
pygame.draw.rect(screen, white, paddle2)
pygame.draw.aaline(screen, green, (screen_width/2, 0), (screen_width/2, screen_height))
screen.blit(ball, ball_rect)
pygame.display.flip()
ball_rect.x += ball_speed_x
ball_rect.y += ball_speed_y
if ball_rect.top <= 0 or ball_rect.bottom >= screen_height:
ball_speed_y *= -1
if ball_rect.left <= 0 or ball_rect.right >= screen_width:
ball_speed_x *= -1
clock.tick(60)