Related
I use a system like this which should theoretically work to close the window:
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Here is the code:
import pygame
import random
import sys
# Set width and height of window
(width, height) = (400, 600)
# Sets the colours
background_colour = (0, 2, 20)
white = (255, 255, 255)
# creates window
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Space Dodger")
screen.fill(background_colour)
def gameLoop():
# sets sprite starting coordinates
rocketX = 200
rocketY = 450
leftX = 0
leftY = -25
leftWidth = random.randint(0, 300)
# sets obstacle start speed
obstacleSpeed = 1
# sets starting score
score = 0
pygame.init()
font = pygame.font.Font("Pixeled.ttf", 32)
fontSmall = pygame.font.Font("Pixeled.ttf", 25)
scoreX = 10
scoreY = 10
# All images/sprites
# rocket
rocket = pygame.image.load("rocket.png")
rocket = pygame.transform.smoothscale(rocket, (50, 100))
# background image
backgroundSpace = pygame.image.load("spacesky.png")
backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
backgroundColour = (10, 32, 61)
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# sets rectangles for obstacles
leftObstacle = pygame.draw.rect(screen, white, pygame.Rect(leftX, leftY, leftWidth, 25))
rightObstacle = pygame.draw.rect(
screen, white, pygame.Rect(leftWidth + 100, leftY, width, 25)
)
rocketRec = pygame.draw.rect(
screen, backgroundColour, pygame.Rect(rocketX + 10, rocketY, 30, 75)
)
# sets score text
displayScore = font.render(str(score), True, (105, 105, 105))
# makes cursor invisible
pygame.mouse.set_visible(False)
# draws new layer over screen
screen.blit(backgroundSpace, (0, 0))
# tracks the mosue location
mouseX, mouseY = pygame.mouse.get_pos()
# draws rectangle behind rocket
pygame.draw.rect(screen, backgroundColour, rocketRec)
# displays the rocket
screen.blit(rocket, (rocketX, rocketY))
# sets rocket horizontal position
if mouseX > width - 50:
rocketX = width - 50
else:
rocketX = mouseX
# displays the score
screen.blit(displayScore, (scoreX, scoreY))
# creates the moving obstacles
pygame.draw.rect(screen, white, leftObstacle)
pygame.draw.rect(screen, white, rightObstacle)
leftY = leftY + obstacleSpeed
# brings obstacle back to top
if leftY > 600:
leftY = -25
leftWidth = random.randint(0, 300)
score = score + 1
if obstacleSpeed >= 6:
obstacleSpeed = 6
else:
obstacleSpeed = obstacleSpeed + 0.2
if rocketRec.colliderect(leftObstacle) or rocketRec.colliderect(rightObstacle):
collisionScreen()
def startScreen():
lightGrey = (200, 200, 200)
darkGrey = (165, 165, 165)
lightGrey2 = (200, 200, 200)
darkGrey2 = (165, 165, 165)
# background image
backgroundSpace = pygame.image.load("spacesky.png")
backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
backgroundColour = (10, 32, 61)
pygame.init()
fontSmall = pygame.font.Font("Pixeled.ttf", 25)
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# start screen
# makes cursor visible
pygame.mouse.set_visible(True)
# tracks the mosue location
mouseX, mouseY = pygame.mouse.get_pos()
# draws new layer over screen
screen.blit(backgroundSpace, (0, 0))
# Puts on logo
logo = pygame.image.load("name.png")
logo = pygame.transform.smoothscale(logo, (500, 300))
screen.blit(logo, (-40, 10))
# creates start button
startRecU = pygame.draw.rect(screen, darkGrey, pygame.Rect(120, 270, 160, 60))
startRec = pygame.draw.rect(screen, lightGrey, pygame.Rect(125, 275, 150, 50))
startText = fontSmall.render("START", True, (0, 0, 0))
# displays the start text
screen.blit(startText, (135, 262))
# detects if mouse is hovering over button
if 280 > mouseX > 120 and 330 > mouseY > 270:
darkGrey = (200, 200, 200)
lightGrey = (165, 165, 165)
else:
lightGrey = (200, 200, 200)
darkGrey = (165, 165, 165)
# detects if start button is clicked
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and 280 > mouseX > 120 and 330 > mouseY > 270:
gameLoop()
# creates quit button
quitRecU = pygame.draw.rect(screen, darkGrey2, pygame.Rect(120, 350, 160, 60))
quitRec = pygame.draw.rect(screen, lightGrey2, pygame.Rect(125, 355, 150, 50))
quitText = fontSmall.render("QUIT", True, (0, 0, 0))
# displays the start text
screen.blit(quitText, (156, 340))
# detects if mouse is hovering over button
if 280 > mouseX > 120 and 410 > mouseY > 350:
darkGrey2 = (200, 200, 200)
lightGrey2 = (165, 165, 165)
else:
lightGrey2 = (200, 200, 200)
darkGrey2 = (165, 165, 165)
# detects if quit button is clicked
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and 280 > mouseX > 120 and 410 > mouseY > 350:
running = False
def collisionScreen():
lightGrey = (200, 200, 200)
darkGrey = (165, 165, 165)
lightGrey2 = (200, 200, 200)
darkGrey2 = (165, 165, 165)
# background image
backgroundSpace = pygame.image.load("spacesky.png")
backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
backgroundColour = (10, 32, 61)
# explosion
explosion = pygame.image.load("explosion.png")
explosion = pygame.transform.smoothscale(explosion, (100, 100))
pygame.init()
fontSmall = pygame.font.Font("Pixeled.ttf", 25)
fontMini = pygame.font.Font("Pixeled.ttf", 15)
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# draws new layer over screen
screen.blit(backgroundSpace, (0, 0))
# makes cursor visible
pygame.mouse.set_visible(True)
# tracks the mosue location
mouseX, mouseY = pygame.mouse.get_pos()
# displays the explosion
screen.blit(explosion, (150, 400))
# creates play again button
playAgainRecU = pygame.draw.rect(screen, darkGrey, pygame.Rect(120, 270, 160, 60))
playAgainRec = pygame.draw.rect(screen, lightGrey, pygame.Rect(125, 275, 150, 50))
playAgainText = fontMini.render("PLAY AGAIN", True, (0, 0, 0))
# displays the start text
screen.blit(playAgainText, (135, 278))
# detects if mouse is hovering over button
if 280 > mouseX > 120 and 330 > mouseY > 270:
darkGrey = (200, 200, 200)
lightGrey = (165, 165, 165)
else:
lightGrey = (200, 200, 200)
darkGrey = (165, 165, 165)
# detects if play button is clicked
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and 280 > mouseX > 120 and 330 > mouseY > 270:
gameLoop()
# creates quit button
quit2RecU = pygame.draw.rect(screen, darkGrey2, pygame.Rect(120, 350, 160, 60))
quit2Rec = pygame.draw.rect(screen, lightGrey2, pygame.Rect(125, 355, 150, 50))
quit2Text = fontSmall.render("QUIT", True, (0, 0, 0))
# displays the start text
screen.blit(quit2Text, (156, 340))
# detects if mouse is hovering over button
if 280 > mouseX > 120 and 410 > mouseY > 350:
darkGrey2 = (200, 200, 200)
lightGrey2 = (165, 165, 165)
else:
lightGrey2 = (200, 200, 200)
darkGrey2 = (165, 165, 165)
# detects if quit button is clicked
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and 280 > mouseX > 120 and 410 > mouseY > 350:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
startScreen()
Your code is pretty messy, try to do all your code to only one main loop (you have three now). This is how I suggest how it should be done.
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
#Conststants, variables and images
startMenu = True
mainGame = False
collisionScreen = False
#Main loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
#All things that are supposed to happen can be pressed by the mouse (if statement)
if startMenu:
#Start Menu code
elif mainGame:
#Main game code
elif collisionScreen:
#Collision screen code
pygame.display.update()
clock.tick(60) #fps
I hope it helps you, Adam
import pygame
from pygame.constants import K_DOWN
import time
from time import sleep
pygame.init()
screen = pygame.display.set_mode((300, 300))
tickNumber = int(0)
done = False
boxOneSymbol = 0
boxTwoSymbol = 0
boxThreeSymbol = 0
boxFourSymbol = 0
boxFiveSymbol = 0
boxSixSymbol = 0
boxSevenSymbol = 0
boxNineSymbol = 0
smallBoxColor = (154, 154, 154)
playerTurn = 0
FPS_CLOCK = pygame.time.Clock()
#mouse_presses = pygame.mouse.get_pressed()
left, middle, right = pygame.mouse.get_pressed()
font = pygame.font.SysFont('Roboto', 13)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
is_blue = not is_blue
pressed = pygame.key.get_pressed()
pygame.draw.rect(screen, (0, 128, 255), pygame.Rect(10, 10, 280, 280))
#if is_blue: color = (0, 128, 255)
#else: color = (255, 100, 0)
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(30, 30, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(30, 120, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(30, 215, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(120, 215, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(120, 120, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(120, 30, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(215, 215, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(215, 120, 60, 60))
pygame.draw.rect(screen, smallBoxColor, pygame.Rect(215, 30, 60, 60))
textsurface = font.render('Au joueur 1!', False, (0, 0, 0))
#if event.type == pygame.MOUSEBUTTONDOWN:
#mouse_presses = pygame.mouse.get_pressed()
#if mouse_presses[0]:
#print("Left Mouse key was clicked")
left, middle, right = pygame.mouse.get_pressed()
if left:
print("Left Mouse Key is being pressed")
pygame.display.update()
FPS_CLOCK.tick(30)
tickNumber = (tickNumber) + (1)
#print(int(tickNumber), 'Ticks')
pygame.display.flip()
Im making a tic-tac-toe game with pygame, and i need to detect when player clicks somewhere, so i found this little piece of code on https://coderslegacy.com/ :
left, middle, right = pygame.mouse.get_pressed()
if left:
print("Left Mouse Key is being pressed")
to detect left click, but it always detect up to 4 clicks instead of only one, because my tick clock is refreshing 4 times while i click, how can i fix that?
One approach is to use flags and add a condition:
clicked = False
while not done:
left, middle, right = pygame.mouse.get_pressed()
if left and not clicked:
clicked = True
print('clicked')
if not left:
clicked = False
You can also use events since no more ...DOWN events will be generated while you hold the button:
for event in pygame.event.get():
if event.type = pygame.MOUSEBUTTONDOWN:
if event.button == 1:
print('clicked')
Hi so I wanna limit the texts inside a rectangle and if the text surpasses the rectangle's dimension then it reduces itself to fit in. I use class to make the code easier to read and easier to add more input boxes. When I run the code, there should be different input boxes in which I can edit the text in and if the text is too long, it reduces itself( lastest character) to fit in the box. But when I run the code, the text can go over the rectangle for 1 character and for any letter after that, it deletes a whole chunk of text. Here is the code.
''' python
import pygame
import datetime
pygame.init()
clock = pygame.time.Clock()
pygame.font.init()
# Note
finish = 0
leftover = 16
# Font
numb_font = pygame.font.Font('dogicapixelbold.ttf', 14)
text_font = pygame.font.Font('dogicapixelbold.ttf', 16)
color = (233, 248, 215)
active = False
# screen resolution
Width = 800
Height = 600
bg = pygame.image.load('opennote.png')
screen = pygame.display.set_mode((Width, Height))
# Time
time_box = pygame.Rect(250, 63, 50, 30)
date_box = pygame.Rect(221, 27, 50, 30)
# boxes numb
leftover_box = pygame.Rect(265, 105, 30, 30)
finish_box = pygame.Rect(325, 105, 30, 30)
class InputBox:
def __init__(self, x, y, w, h, text=''):
self.rect = pygame.Rect(x, y, w, h)
self.color = color
self.text = text
self.txt_surface = text_font.render(text, True, self.color)
self.active = False
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
# If the user clicked on the input_box rect.
if self.rect.collidepoint(event.pos):
# Toggle the active variable.
self.active = not self.active
else:
self.active = False
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
print(self.text)
self.text = ''
elif event.key == pygame.K_BACKSPACE:
self.text = self.text[:-1]
else:
self.text += event.unicode
# Re-render the text.
self.txt_surface = text_font.render(self.text, True, self.color)
def draw(self, screen):
# Blit the text.
screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
# Blit the rect.
pygame.draw.rect(screen, self.color, self.rect, 2)
def update(self):
# Limit character
if self.txt_surface.get_width() > self.rect.w:
self.text = self.text[:-1]
def main():
clock = pygame.time.Clock()
input_box1 = InputBox(115, 170, 250, 36)
input_box2 = InputBox(115, 224, 250, 36)
input_box3 = InputBox(115, 278, 250, 36)
input_box4 = InputBox(115, 333, 250, 36)
input_box5 = InputBox(115, 386, 250, 36)
input_box6 = InputBox(115, 440, 250, 36)
input_box7 = InputBox(115, 494, 250, 36)
input_boxes = [input_box1, input_box2, input_box3, input_box4, input_box5, input_box6, input_box7]
done = False
while not done:
# Background
screen.fill((0, 0, 0))
screen.blit(bg, (0, 0))
now = datetime.datetime.now()
date_now = now.strftime("%d/%m/%Y")
time_now = now.strftime("%H:%M:%S")
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for box in input_boxes:
box.handle_event(event)
for box in input_boxes:
box.update()
for box in input_boxes:
box.draw(screen)
# Real Time
# Date
pygame.draw.rect(screen, 'white', date_box, -1)
datebox_surface = numb_font.render(date_now, True, color)
screen.blit(datebox_surface, (date_box.x + 5, date_box.y + 5))
# Time
pygame.draw.rect(screen, 'white', time_box, -1)
timebox_surface = numb_font.render(time_now, True, color)
screen.blit(timebox_surface, (time_box.x + 5, time_box.y + 5))
# finish &Leftover
# finish box
pygame.draw.rect(screen, 'white', finish_box, -1)
finishbox_surface = numb_font.render(str(finish), True, color)
screen.blit(finishbox_surface, finish_box)
# Leftover box
pygame.draw.rect(screen, 'white', leftover_box, -1)
leftover_box_surface = numb_font.render(str(leftover), True, color)
screen.blit(leftover_box_surface, leftover_box)
pygame.display.update()
clock.tick(120)
if __name__ == '__main__':
main()
pygame.quit()
'''
But when the letter outside the rect's width, it deletes a whole bunch of text not just the letter that outside the width.
Switch your update and re-render contents.
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
print(self.text)
self.text = ''
elif event.key == pygame.K_BACKSPACE:
self.text = self.text[:-1]
else:
self.text += event.unicode
# Limit characters -20 for border width
if self.txt_surface.get_width() > self.rect.w -20:
self.text = self.text[:-1]
def draw(self, screen):
# Blit the text.
screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
# Blit the rect.
pygame.draw.rect(screen, self.color, self.rect, 2)
def update(self):
# Re-render the text.
self.txt_surface = text_font.render(self.text, True, self.color)
Edit: oh, it's 3am; I'm just about asleep by now, if I missed posting something that was edited I don't remember. Had to swap out the background for a plain black rectangle and blit that in just for testing, but I know for certain it runs OK here. Downloaded same font and everything. This is what it looks like.
#! /usr/bin/env python3
import pygame
import datetime
pygame.init()
clock = pygame.time.Clock()
pygame.font.init()
# Note
finish = 0
leftover = 16
# Font
numb_font = pygame.font.Font('dogicapixelbold.ttf', 14)
text_font = pygame.font.Font('dogicapixelbold.ttf', 16)
color = (233, 248, 215)
active = False
# screen resolution
Width = 800
Height = 600
bg = pygame .Surface( [Width, Height] )
pygame .draw .rect( bg, (0, 0, 0), [0, 0, Width, Height] )
## bg = pygame.image.load('opennote.png')
screen = pygame.display.set_mode((Width, Height))
# Time
time_box = pygame.Rect(250, 63, 50, 30)
date_box = pygame.Rect(221, 27, 50, 30)
# boxes numb
leftover_box = pygame.Rect(265, 105, 30, 30)
finish_box = pygame.Rect(325, 105, 30, 30)
class InputBox:
def __init__(self, x, y, w, h, text=''):
self.rect = pygame.Rect(x, y, w, h)
self.color = color
self.text = text
self.txt_surface = text_font.render(text, True, self.color)
self.active = False
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
# If the user clicked on the input_box rect.
if self.rect.collidepoint(event.pos):
# Toggle the active variable.
self.active = not self.active
else:
self.active = False
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
print(self.text)
self.text = ''
elif event.key == pygame.K_BACKSPACE:
self.text = self.text[:-1]
else:
self.text += event.unicode
# Limit characters -20 for border width
if self.txt_surface.get_width() > self.rect.w -20:
self.text = self.text[:-1]
def draw(self, screen):
# Blit the text.
screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
# Blit the rect.
pygame.draw.rect(screen, self.color, self.rect, 2)
def update(self):
# Re-render the text.
self.txt_surface = text_font.render(self.text, True, self.color)
def main():
clock = pygame.time.Clock()
input_box1 = InputBox(115, 170, 250, 36)
input_box2 = InputBox(115, 224, 250, 36)
input_box3 = InputBox(115, 278, 250, 36)
input_box4 = InputBox(115, 333, 250, 36)
input_box5 = InputBox(115, 386, 250, 36)
input_box6 = InputBox(115, 440, 250, 36)
input_box7 = InputBox(115, 494, 250, 36)
input_boxes = [input_box1, input_box2, input_box3, input_box4, input_box5, input_box6, input_box7]
done = False
while not done:
# Background
screen.fill((0, 0, 0))
screen.blit(bg, (0, 0))
now = datetime.datetime.now()
date_now = now.strftime("%d/%m/%Y")
time_now = now.strftime("%H:%M:%S")
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
for box in input_boxes:
box.handle_event(event)
for box in input_boxes:
box.update()
for box in input_boxes:
box.draw(screen)
# Real Time
# Date
pygame.draw.rect(screen, 'white', date_box, -1)
datebox_surface = numb_font.render(date_now, True, color)
screen.blit(datebox_surface, (date_box.x + 5, date_box.y + 5))
# Time
pygame.draw.rect(screen, 'white', time_box, -1)
timebox_surface = numb_font.render(time_now, True, color)
screen.blit(timebox_surface, (time_box.x + 5, time_box.y + 5))
# finish &Leftover
# finish box
pygame.draw.rect(screen, 'white', finish_box, -1)
finishbox_surface = numb_font.render(str(finish), True, color)
screen.blit(finishbox_surface, finish_box)
# Leftover box
pygame.draw.rect(screen, 'white', leftover_box, -1)
leftover_box_surface = numb_font.render(str(leftover), True, color)
screen.blit(leftover_box_surface, leftover_box)
pygame.display.update()
clock.tick(120)
if __name__ == '__main__':
main()
pygame.quit()
I'm trying to make a pause function I've tested this pause function separately and it seems to be working fine although there is nothing that it can do at the moment but it still shows. However, when I implement it in my game it doesn't work?
I've put it in different places before the while loop and in the while loop. When it's before the while loop the pause function will show first then mess up the game. When it's put in the while loop, it wont show at all even when 'p' is pressed.
What is the issue?
import pygame
import os
import sys
pygame.init()
pygame.font.init()
WHITE = (255, 255, 255)
BLACK = (0, 0, 0, 0)
clock = pygame.time.Clock()
FPS = 60
DS = pygame.display.set_mode((900, 600))
sprite_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(sprite_image, (90, 100, 200), [25, 25], 25)
W, H = DS.get_size()
pause = True
st = pygame.font.SysFont("comicsans ms", 20)
lf = pygame.font.SysFont("comicsans ms", 120)
def paused():
DS.fill((50, 50, 70)) # Fill the display surface.
text_surf, text_rect = text_objects('Paused', (W/2, H/2), lf)
DS.blit(text_surf, text_rect)
# The buttons are dictionaries now.
resume_button = button('Resume', 150, 450, 100, 50, WHITE, WHITE)
quit_button = button('Quit', 350, 450, 100, 50, WHITE, WHITE)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Should be pygame.quit not QUIT.
sys.exit() # Better use sys.exit() instead of quit().
elif event.type == pygame.MOUSEMOTION:
# Switch the active surface of the buttons
# if we're hovering over them.
for btn in (resume_button, quit_button):
if btn['rect'].collidepoint(event.pos):
btn['active_surface'] = btn['surface_hover']
else:
btn['active_surface'] = btn['surface']
elif event.type == pygame.MOUSEBUTTONDOWN:
# Check if the buttons were clicked.
if resume_button['rect'].collidepoint(event.pos):
return # Return to the main loop.
elif quit_button['rect'].collidepoint(event.pos):
pygame.quit()
sys.exit()
def text_objects(text, pos, font):
text_surface = font.render(text, True, BLACK)
return text_surface, text_surface.get_rect(center=pos)
def display_message(text):
lf = pygame.font.SysFont("comicsans", 120)
TextSurf, TextRect = text_objects(text, lf)
TextRect.center = ((W / 2)), ((H / 2))
DS.blit(TextSurf, TextRect)
pygame.display.update()
def button(msg, x, y, w, h, inactive_color, active_color):
"""Create a button dictionary with the images and a rect."""
text_surf, text_rect = text_objects(msg, (w/2, h/2), st)
# Create the normal and hover surfaces and blit the text onto them.
surface = pygame.Surface((w, h))
surface.fill(inactive_color)
surface.blit(text_surf, text_rect)
surface_hover = pygame.Surface((w, h))
surface_hover.fill(active_color)
surface_hover.blit(text_surf, text_rect)
return {'active_surface': surface,
'surface': surface,
'surface_hover': surface_hover,
'rect': pygame.Rect(x, y, w, h),
}
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
super(Platform, self).__init__()
self.image = pygame.Surface((w, h))
self.image.fill((90, 90, 120))
self.rect = self.image.get_rect(topleft=(x, y))
class Sprite(pygame.sprite.Sprite):
def __init__(self, pos):
super(Sprite, self).__init__()
self.image = sprite_image
self.rect = self.image.get_rect()
self.rect.center = pos
self._vx = 0
self._vy = 0
self._spritex = pos[0]
self._spritey = pos[1]
self.level = None
self._gravity = .9
def update(self):
# Adjust the x-position.
self._spritex += self._vx
self.rect.centerx = self._spritex # And update the rect.
block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
for block in block_hit_list:
if self._vx > 0:
self.rect.right = block.rect.left
elif self._vx < 0:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
self._spritex = self.rect.centerx # Update the position.
# Adjust the y-position.
self._vy += self._gravity # Accelerate downwards.
self._spritey += self._vy
self.rect.centery = self._spritey # And update the rect.
# Check and see if we hit anything
if block_hit_list == pygame.sprite.spritecollide(self, self.level, False):
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self._vy > 0:
self.rect.bottom = block.rect.top
elif self._vy < 0:
self.rect.top = block.rect.bottom
self._spritey = self.rect.centery # Update the position.
# Stop our vertical movement
self._vy = 0
def jump(self):
self.rect.y += 3
platform_hit_list = pygame.sprite.spritecollide(self, self.level, False)
self.rect.y -= 3
# If it is ok to jump, set our speed upwards
if len(platform_hit_list) > 0 or self.rect.bottom >= H:
self._vy = -17
def go_left(self):
# Called when the user hits the left arrow.
self._vx = -3
def go_right(self):
#Called when the user hits the right arrow.
self._vx = 3
def stop(self):
# Called when the user lets off the keyboard.
self._vx = 0
sprite = Sprite([60, 60])
active_sprite_list = pygame.sprite.Group(sprite)
sprite.level = pygame.sprite.Group()
# A list with rect style tuples (x, y, width, height).
rects = [
(20, 20, 150, 20), (120, 200, 200, 20), (400, 440, 300, 20),
(40, 100, 200, 20), (320, 300, 150, 20), (520, 550, 300, 20),
(600, 100, 150, 20), (300, 200, 200, 20), (290, 440, 300, 20),
(40, 100, 200, 20), (320, 300, 150, 20), (95, 550, 300, 20),
(250,300,150,20), (350,100,150,20), (450,50,270,20), (700,185,70,20),
(650,350,350,20)
]
# You can unpack the rect tuples directly in the head of the for loop.
for x, y, width, height in rects:
# Create a new platform instance and pass the coords, width and height.
platform = Platform(x, y, width, height)
# Add the new platform instance to the sprite groups.
sprite.level.add(platform)
active_sprite_list.add(platform)
active_sprite_list.add(sprite.level)
done = False
while not done:
def paused():
DS.fill((50, 50, 70)) # Fill the display surface.
text_surf, text_rect = text_objects('Paused', (W / 2, H / 2), lf)
DS.blit(text_surf, text_rect)
# The buttons are dictionaries now.
resume_button = button('Resume', 150, 450, 100, 50, WHITE, WHITE)
quit_button = button('Quit', 350, 450, 100, 50, WHITE, WHITE)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Should be pygame.quit not QUIT.
sys.exit() # Better use sys.exit() instead of quit().
elif event.type == pygame.MOUSEMOTION:
# Switch the active surface of the buttons
# if we're hovering over them.
for btn in (resume_button, quit_button):
if btn['rect'].collidepoint(event.pos):
btn['active_surface'] = btn['surface_hover']
else:
btn['active_surface'] = btn['surface']
elif event.type == pygame.MOUSEBUTTONDOWN:
# Check if the buttons were clicked.
if resume_button['rect'].collidepoint(event.pos):
return # Return to the main loop.
elif quit_button['rect'].collidepoint(event.pos):
pygame.quit()
sys.exit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
pause = True
paused()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
sprite.go_left()
pause = False
if event.key == pygame.K_RIGHT:
sprite.go_right()
pause = False
if event.key == pygame.K_UP:
sprite.jump()
pause = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and sprite._vx < 0:
sprite.stop()
pause = False
if event.key == pygame.K_RIGHT and sprite._vx > 0:
sprite.stop()
# If the player gets near the right side, shift the world left (-x)
if sprite.rect.right > W:
sprite.rect.right = W
# If the player gets near the left side, shift the world right (+x)
if sprite.rect.left < 0:
sprite.rect.left = 0
active_sprite_list.update()
DS.fill(WHITE)
# Blit the sprite's image at the sprite's rect.topleft position.
active_sprite_list.draw(DS)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
Take a look at this example. I use dictionaries for the buttons which consist of the images, the currently active image and a rect which is used for the collision detection and as the position. If the user clicks the resume button, I just return to the main game loop.
import sys
import pygame
pygame.init()
WHITE = (255, 255, 255)
GRAY = pygame.Color("gray30")
BLACK = (0, 0, 0, 0)
clock = pygame.time.Clock()
FPS = 60
DS = pygame.display.set_mode((900, 600))
W, H = DS.get_size()
# Define the fonts once when the program starts.
st = pygame.font.SysFont("comicsans ms", 20)
lf = pygame.font.SysFont("comicsans ms", 120)
def paused():
DS.fill((50, 50, 70)) # Fill the display surface.
text_surf, text_rect = text_objects('Paused', (W/2, H/2), lf)
DS.blit(text_surf, text_rect)
# The buttons are dictionaries now.
resume_button = button('Resume', 150, 450, 100, 50, WHITE, GRAY)
quit_button = button('Quit', 350, 450, 100, 50, WHITE, GRAY)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Should be pygame.quit not QUIT.
sys.exit() # Better use sys.exit() instead of quit().
elif event.type == pygame.MOUSEMOTION:
# Switch the active surface of the buttons
# if we're hovering over them.
for btn in (resume_button, quit_button):
if btn['rect'].collidepoint(event.pos):
btn['active_surface'] = btn['surface_hover']
else:
btn['active_surface'] = btn['surface']
elif event.type == pygame.MOUSEBUTTONDOWN:
# Check if the buttons were clicked.
if resume_button['rect'].collidepoint(event.pos):
return # Return to the main loop.
elif quit_button['rect'].collidepoint(event.pos):
pygame.quit()
sys.exit()
# Draw the active surfaces at the rects of the buttons.
DS.blit(resume_button['active_surface'], resume_button['rect'])
DS.blit(quit_button['active_surface'], quit_button['rect'])
pygame.display.update()
clock.tick(15)
def text_objects(text, pos, font):
text_surface = font.render(text, True, BLACK)
return text_surface, text_surface.get_rect(center=pos)
def button(msg, x, y, w, h, inactive_color, active_color):
"""Create a button dictionary with the images and a rect."""
text_surf, text_rect = text_objects(msg, (w/2, h/2), st)
# Create the normal and hover surfaces and blit the text onto them.
surface = pygame.Surface((w, h))
surface.fill(inactive_color)
surface.blit(text_surf, text_rect)
surface_hover = pygame.Surface((w, h))
surface_hover.fill(active_color)
surface_hover.blit(text_surf, text_rect)
return {'active_surface': surface,
'surface': surface,
'surface_hover': surface_hover,
'rect': pygame.Rect(x, y, w, h),
}
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused()
DS.fill((50, 50, 50))
pygame.draw.circle(DS, (0, 90, 190), (100, 100), 50)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
This is the code I have started to use to make a start menu.
# we need some colours!!
black = (0,0,0)
white = (255,255,200)
red = (200,0,0)
green = (0, 200, 0)
bright_red = (255, 0 ,0)
bright_green = (0, 255, 0)
bright_white = (255, 255, 255)
def main():
pygame.init()
screen = pygame.display.set_mode((600, 600))
pygame.display.set_caption("CrazyPongMainMenu")
menu = cMenu(50, 50, 20, 5, "vertical", 100, screen,
[("Start Game", 1, None),
("Options", 2, None),
("Exit", 3, None)])
menu.set_center(True, True)
menu.set_alignment("center", "center")
state = 0
prev_state = 1
rect_list = []
pygame.event.set_blocked(pygame.MOUSEMOTION)
while 1:
if prev_state != state:
pygame.event.post(pygame.event.Event(EVENT_CHANGE_STATE, key = 0))
prev_state = state
e = pygame.event.wait()
if e.type == pygame.KEYDOWN or e.type == EVENT_CHANGE_STATE:
if state == 0:
rect_list, state = menu.update(e, state)
elif state == 1:
print ("Start Game!")
state = 0
elif state == 2:
print ("Options!")
state = 0
else:
print ("Exit!")
pygame.quit()
sys.exit()
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
mouse = pygame.mouse.get_pos()
#print(mouse)
if 200+150 > mouse[0] > 200 and 250+30 > mouse[1] > 250:
pygame.draw.rect(screen, bright_green,(200, 250, 150, 30))
else:
pygame.draw.rect(screen, green,(200, 250, 150, 30))
if 200+150 > mouse[0] > 200 and 290+21 > mouse[1] > 290:
pygame.draw.rect(screen, bright_white,(200, 290, 150, 21))
else:
pygame.draw.rect(screen, white,(200, 290, 150, 21))
if 200+150 > mouse[0] > 200 and 318+25 > mouse[1] > 318:
pygame.draw.rect(screen, bright_red,(200, 318, 150, 25))
else:
pygame.draw.rect(screen, red,(200, 318, 150, 25))
pygame.display.update(rect_list)
if __name__ == ("__main__"):
main()
I would like to put text onto the 3 rectangles but i don't know how to. If anybody could please tell my how to put the text onto the rectangles it will be much appreciated!
Check out this stack overflow question:
How to add text into a pygame rectangle
Specifically these bits:
self.font = pygame.font.SysFont('Arial', 25)
def addText(self):
self.screen.blit(self.font.render('Hello!', True, (255,0,0)), (200, 100))
pygame.display.update()
Basically you want to define a font
Then blit it onto the screen, where render takes the args (text, antialias (you want true), color)
and finally update