I can click around my button and it still activates? - python

I've made 2 buttons and made them send a message "START" or "EXIT" when I click them but the range that I can click them is greater than the actual button, so I can click around the button and it still works. It also, sends both messages when clicking near both of them. I've tried changing the picture, but that it still does the same thing. I don't know what I should do? I am new so pls help.
This is my main:
import pygame
import button
window_width, window_height = 1000, 650
win = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("My game!")
grey = (25, 25, 25)
FPS = 60
start_img = pygame.image.load("img/start_button.png")
exit_img = pygame.image.load("img/exit_button.png")
start_button = button.Button(250, 220, start_img, 1.2)
exit_button = button.Button(265, 350, exit_img, 1.2)
def draw_window():
win.fill(grey)
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
draw_window()
if start_button.draw_button(win):
print("START")
if exit_button.draw_button(win):
print("EXIT")
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
and this is my button:
import pygame
class Button:
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, ((width * scale), (height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw_button(self, surface):
action = False
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
I don't know what it could be pls give any suggestion, help is appreciated.

There is no problem with your code, I tested it. The problem is with the button images. Likely your images have a large transparent area.You can compensate for this by creating a smaller hit rectangle using get_bounding_rect().
See also How to get the correct dimensions for a pygame rectangle created from an image
import pygame
class Button:
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, ((width * scale), (height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
self.hit_rect = self.image.get_bounding_rect()
self.hit_rect.x += x
self.hit_rect.y += y
def draw_button(self, surface):
action = False
pos = pygame.mouse.get_pos()
if self.hit_rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
surface.blit(self.image, (self.rect.x, self.rect.y))
return action

Related

Why wont my display update with my background? The window just opens black. Pygame

I'm trying to learn OOP but my pygame window wont update with the background I'm trying to put in. The gameObject class is in another file. Filling it with white color also isn't working and I don't know why. I was able to display a background on another project I did but I cant now and I have no idea what's different. I have compared the code and they seem like they should be doing the same thing.
gameObject.py
import pygame
class GameObject:
def __init__(self, x, y, width, height, image_path):
self.background= pygame.image.load(image_path)
self.background = pygame.transform.scale(self.background, (width, height))
self.x = x
self.y = y
self.width = width
self.height = height
main.py
import pygame
from gameObject import GameObject
pygame.init()
class Player(GameObject):
def __init__(self, x, y, width, height, image_path, speed):
super().__init__(x, y, width, height, image_path)
self.speed = speed
def move(self, direction, max_height):
if (self.y >= max_height - self.height and direction > 0) or (self.y <= 0 and direction < 0):
return
self.y += (direction * self.speed)
class Game:
def __init__(self):
self.width = 800
self.height = 800
self.color = (255, 255, 255)
self.game_window = pygame.display.set_mode((self.width, self.height))
self.clock = pygame.time.Clock()
self.background = GameObject(0, 0, self.width, self.height, 'assets/background.png')
self.player1 = Player(375, 700, 50, 50, 'assets/player.png', 10)
self.level = 1.0
def draw_objects(self):
self.game_window.fill(self.white_color)
self.game_window.blit(self.background.image, (self.background.x, self.background.y))
pygame.display.update()
def run_game_loop(self):
gameRunning = True
while gameRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameRunning = False
if gameRunning == False:
pygame.quit()
self.draw_objects()
self.clock.tick(60)
game = Game()
game.run_game_loop()
quit()
I have tried basic research on it and looking at other code that uses a custom background with pygame
It is a matter of indentation. self.draw_objects() must be called in the application loop not after the application loop:
class Game:
# [...]
def run_game_loop(self):
gameRunning = True
while gameRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameRunning = False
if gameRunning == False:
pygame.quit()
# INDENTATION
#-->|
self.draw_objects()
self.clock.tick(60)
Your loop never actually does anything but clear the event queue looking for pygame.QUIT.
You need to indent the calls to self.draw_objects() and self.clock.tick(60) so they are inside the loop.

How to make a pause and resume in pygame [duplicate]

This question already has answers here:
How to create a pause button in Pygame?
(1 answer)
How to add pause mode to Python program
(1 answer)
Pygame level/menu states
(2 answers)
Closed 26 days ago.
I have been having trouble making a pause and resume function in my game, i can click the pause button once and it will work and bring up the resume button but when i click the resume button nothing happens, i believe it is caused by my if else statement which locks the game into the paused state and doesn't allow it to come back out but i don't know how to solve this issue.
paused = False
resumed = False
def run_game():
global paused
if pause_button.clicked:
paused = True
resume_button.resume_button_visible = True
resume_button.draw()
print(paused)
else:
boxer_1.update()
boxer_2.update()
draw_health_bar(boxer_1.health, 50, 30)
draw_health_bar(boxer_2.health, 650, 30)
boxer_1.move(SCREEN_WIDTH, screen, boxer_2)
boxer_2.move_enemy(SCREEN_WIDTH, screen, boxer_1)
boxer_1.draw(screen)
boxer_2.draw(screen)
paused = False
resume_button.resume_button_visible = False
pause_button.draw()
print(paused)
run = True
while run:
draw_bg()
clock.tick(FPS)
start_button.draw()
exit_button.draw()
if start_button.clicked or resume_button.clicked:
run_game()
exit_button.visible = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
print('if x button is pressed game will stop')
run = False
sys.exit()
if exit_button.clicked:
run = False
print('game will stop')
pygame.display.update()
sys.exit()
Here is the code for the button
import pygame
# Screen width, and height in pixels
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 500
# Set screen size and caption
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Fighter Game Menu!')
class Button:
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), (int(height * scale))))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
self.visible = True
def draw(self):
action = False
pos = pygame.mouse.get_pos()
left_click = pygame.mouse.get_pressed()[0]
if self.visible:
screen.blit(self.image, (self.rect.x, self.rect.y))
if self.rect.collidepoint(pos):
if left_click == 1 and self.clicked == False:
self.clicked = True
self.visible = False
action = True
elif left_click == 0:
self.clicked = False
return action
class Pause(Button):
def __init__(self, x, y, image, scale):
Button.__init__(self, x, y, image, scale)
self.resume_button_visible = False
def draw(self):
pause_action = False
pos = pygame.mouse.get_pos()
left_click = pygame.mouse.get_pressed()[0]
if self.resume_button_visible:
screen.blit(self.image, (self.rect.x, self.rect.y))
if self.rect.collidepoint(pos):
if left_click == 1 and self.clicked == False:
self.clicked = True
pause_action = True
elif left_click == 1 and self.clicked == True:
self.clicked = False
pause_action = False
elif left_click == 0:
self.clicked = False
return pause_action
Any help would be greatly appreciated.
When the pause button is clicked, you could set a flag to stop everything else and show the resume button
when the resume button is clicked, set that flag back to false

Return from a function from class isn't working for button for pygame

For some reason, my return isn't working. This is from a tutorial. When I download the file and edit it from there it works, but if I copy and paste it from the exact file it doesn't work. Sorry, I am a beginner - open to any suggestions
The is the tutorial I used:
https://www.youtube.com/watch?v=G8MYGDf_9ho
Code:
import pygame
import sys
pygame.init()
WinHeight = 600
WinWidth = 900
Window = pygame.display.set_mode((WinWidth,WinHeight))
#button class
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw(self, surface):
action = False
#get mouse position
pos = pygame.mouse.get_pos()
#check mouseover and clicked conditions
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
#draw button on screen
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
Good_ball_img = pygame.image.load("GoodBall.png")
Bad_ball_img = pygame.image.load("BadBall.png")
#Button instances
Good_ball = Button(100,100,Good_ball_img,2)
Bad_ball = Button(200,200,Bad_ball_img,3)
def drawwin():
Window.fill((202,241,208))
Good_ball.draw(Window)
Bad_ball.draw(Window)
pygame.display.update()
def Main():
run = True
while run:
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window)=="t":
print("red clicked")
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
drawwin()
checkpress()
if __name__ == "__main__":
Main()
Code works for me if I change order - first process all events later check mouse position.
Problema can be because PyGame updates values in pygame.mouse and pygame.key only if you run pygame.event.get() - so it may need pygame.event.get() or at least pygame.event.pump() before other functions.
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window):
print("red clicked")
EDIT:
In documentation for pygame.event there is
To get the state of various input devices, you can forego the event queue and
access the input devices directly with their appropriate modules: `pygame.mouse`,
`pygame.key` and `pygame.joystick`. If you use this method, remember
that pygame requires some form of communication with the system window manager
and other parts of the platform. To keep pygame in sync with the system,
you will need to call `pygame.event.pump()` to keep everything current.
Minimal working code - with surfaces instead images so everyone can simply copy and run it
import pygame
import sys
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WINDOW_WIDTH = 900
WINDOW_HEIGHT = 600
# --- classes --- # PEP8: `CamelCaseNames`
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def check_click(self):
action = False
# get mouse
pos = pygame.mouse.get_pos()
left_button = pygame.mouse.get_pressed()[0]
# check mouseover and clicked conditions
if left_button:
if self.rect.collidepoint(pos) and not self.clicked:
self.clicked = True
action = True
else:
self.clicked = False
return action
def draw(self, surface):
# draw button on screen
surface.blit(self.image, self.rect)
# --- functions --- # PEP8: `lower_case_names`
def draw_window(window):
window.fill((202, 241, 208))
good_ball.draw(window)
bad_ball.draw(window)
pygame.display.update()
# --- main ---
pygame.init()
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# button class
#good_ball_img = pygame.image.load("GoodBall.png")
good_ball_img = pygame.Surface((100, 50))
good_ball_img.fill((0, 255, 0))
#bad_ball_img = pygame.image.load("BadBall.png")
bad_ball_img = pygame.Surface((100, 50))
bad_ball_img.fill((255,0,0))
# Button instances
good_ball = Button(100, 100, good_ball_img, 2) #
bad_ball = Button(200, 200, bad_ball_img, 3)
run = True
while run:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
# - checks and updates -
if good_ball.check_click():
print("green clicked")
if bad_ball.check_click():
print("red clicked")
#checkpress()
# - draws -
draw_window(window)
PEP 8 -- Style Guide for Python Code

How do I play MouseOver sound effect only once in pygame?

I am trying to play my sound only once when my mouse is over the the green button but it doesn't seem to work — plays repeatedly.
mouseisover = True
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
my whole game _intro code at the main loop for my game intro first I set a mouseisover variable and made it True then after in my main loop I said if thats True then play the sound then under it I said mouseisover = False but still it plays my sound again and again none stop
# start screen
def game_intro():
carsound = pygame.mixer.Sound("carsound1.wav") #
mouseisover = True
mouseover = pygame.mixer.Sound("lols (2).wav") # MOUSEOVERSOUND
class button():
def __init__(self, color, x,y,width,height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self,window,outline=None):
#Call this method to draw the button on the screen
if outline:
pygame.draw.rect(window, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
pygame.draw.rect(window, self.color, (self.x,self.y,self.width,self.height),0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0,0,0))
window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))
def isOver(self, pos):
#Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
white = (250,250,250)
greenbutton = button((0,255,0),60,449,200,80, 'Click Me )')
greenbutton2 = button((0,255,0),50,518,200,80, 'Click Me )')
greenbutton3 = button((0,255,0),50,600,200,70, 'Click Me )')
bls2 = pygame.image.load("about2.png")
bls3 = pygame.image.load("credits25.png")
bls4 = pygame.image.load("playgame1.png")
def fade(width, height):
fade = pygame.Surface((width, height))
fade.fill((0,0,0))
for alpha in range(0, 100):
fade.set_alpha(alpha)
window.blit(fade, (0,0))
pygame.display.update()
pygame.time.delay(15)
def redraw():
bls = pygame.image.load("bgs.png")
window.blit(bls,(0,0))
# this makes it
snow_list=[]
no_of_circles=100;
clock = pygame.time.Clock()
FPS = 60
clock.tick(FPS)
for i in range(no_of_circles):
x = random.randrange(0, 800)
y = random.randrange(0, 700)
snow_list.append([x,y])
red = (200,0,0)
green = (255,250,250)
bright_red = (255,250,0)
bright_green = (0,255,0)
clock = pygame.time.Clock()
intro = True
while intro:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
intro = False
pygame.quit()
redraw()
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton.isOver(pos):
fade(800,800)
main_loop()
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
fade(800,800)
menu()
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
if greenbutton3.isOver(pos):
mouseover.play()
window.blit(bls3,(0,0))
if greenbutton.isOver(pos):
mouseover.play()
window.blit(bls4,(0,0))
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton3.isOver(pos):
fade(800,800)
creditss()
# GAME INTRO IMAGE
for point in snow_list:
point[1]+=1
pygame.draw.circle(window, (255,255,255), point, 2)
if(point[1] >= 600):
point[0] = random.randrange(0, 600)
point[1] = random.randrange(-10, -5)
clock.tick(FPS)
partics()
pygame.display.update()
It is difficult to answer without any more context, but my best guess is that this code is located in a loop.
This would mean that every time the loop runs, the variable mouseisover is assigned the value True, discarding the previous value.
Assuming this is your case you want to initialize your variable outside of the loop.
what your code looks like right now
while (loop):
mouseisover = True
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
what you should do
mouseisover = True
while (loop):
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
This, however, means that the sound will play only once and never again.
Update :
You can add a method like this to your button class :
def playSoundIfMouseIsOver(self, pos, sound):
if self.isOver(pos):
if not self.over:
sound.play()
self.over = True
else:
self.over = False
and then to make them beep simply call playSoundIfMouseIsOver with the position of the mouse and the sound you want to play
greenbutton2.playSoundIfMouseIsOver(pos, mouseover)
greenbutton3.playSoundIfMouseIsOver(pos, mouseover)
greenbutton.playSoundIfMouseIsOver(pos, mouseover)
This simply remembers the last value of isOver, and if it changes from False to True, it plays a sound.
These changes will require you to change every if that handled playing a sound with the new method
If you have more buttons you could place all your buttons inside a list and then iterate on the list to do the same action for every button
Creating the list (place this after creating the different buttons):
myButtonList = [greenbutton, greenbutton2, greenbutton3]
Iterating on that list (replaces the three similar lines) :
for myButton in myButtonList:
myButton.playSoundIfMouseIsOver(pos, mouseover)
Also, I saw some weird stuff in your code, you have 4 button classes that are the exact same. You can define the button class a single time by simply placing it at the very beginning of the program, outside of any loop.
If you place your class definitions inside loops, they will only be accessible inside that loop!

How do I make my buttons, objects, etc. size DEPENDENT on the window size?

I know how to make the window resizable, but if I run the code only the window get's resized. The buttons, objects, etc. don't. What do I have to do to make them get resized dependent of the window? If this question is somehow hard to understand you can go to my question where I asked how to make the window resize and read the comments there. Here's the code, just if you guys need it:
import pygame
from pygame.locals import *
pygame.init()
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
icon = pygame.image.load("Baloon war icon.png")
pygame.display.set_icon(icon)
centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def redrawMenuWindow():
win.fill((0, 255, 110))
greenButton.draw(win, (0, 0, 0))
redButton.draw(win, (0, 0, 0))
def redrawGameWindow():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110),(0, 450, 800, 250))
greenButton = button((0, 255, 0), 280, 255, 250, 100, "Start")
redButton = button ((255, 0, 0), 280, 380, 250, 100, "Quit")
game_state = "menu"
run = True
while run:
if game_state == "menu":
redrawMenuWindow()
elif game_state == "game":
redrawGameWindow()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
if event.type == pygame.MOUSEBUTTONDOWN:
if greenButton.isOver(pos):
print("clicked the button")
game_state = "game"
if redButton.isOver(pos):
print("clicked the 2button")
run = False
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
if greenButton.isOver(pos):
greenButton.color = (105, 105, 105)
else:
greenButton.color = (0, 255, 0)
if redButton.isOver(pos):
redButton.color = (105, 105, 105)
else:
redButton.color = (255, 0, 0)
pygame.display.update()
Something like this will solve the issue hopefully, in your Button class (classes begin with capital letters), add this method:
def resize_button(self, width, height, x, y):
self.width = width
self.height = height
self.x = x
self.y = y
then, in main_loop when you are catching the VIDEORESIZE event:
elif event.type == pygame.VIDEORESIZE:
win = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
greenButton.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
Use coefficients to multiply parameters to get the desired results. Play around with this. But the main idea is to make button size and position relative to the current window size.
Also insert the clock.tick(FPS) in your main_loop and don't forget to add clock = pygame.clock.Time() before the loop. This way you can control FPS leading to smaller processor usage.
What #kaktus_car answers is correct. The code needs to respond to the window size, re-scaling on-screen elements accordingly.
The base problem with the OP's code is that the window size is "hard coded", and even when the re-size event is received, the new window size is forgotten. This means the code does not know the size of the window, and thus cannot re-scale graphics/controls.
win = pygame.display.set_mode((800, 600), pygame.RESIZABLE) # <-- FIXED SIZE
...
elif event.type == pygame.VIDEORESIZE:
win = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE) # <-- NEW SIZE
This is relatively simple to fix.
The first step is to store the window size, and use it for scaling on-screen objects. Don't have a "50x50" box, have a box 12% the width of the screen-width.
(The size can be retrieved from the surface every time, but I find this cumbersome.)
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
This means doing some things a little harder than just inserting co-ordinates. For example where is the centre of the window, not "200,200", but:
centre_point = ( WINDOW_WIDTH//2, WINDOW_HEIGHT//2 )
So later when the window-size event happens, these variables can simply be updated, and the on-screen objects scale to suit:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.VIDEORESIZE ):
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
If you have sprite objects, these can be re-scaled too. Record the original size as a scaling factor. When the window size increases or decreases, re-applying this factor in combination with the new size on the sprite bitmap rescales it accordingly.
class AlienSprite( pygame.sprite.Sprite ):
def __init__( self, bitmap, x, y ):
self.original = bitmap
self.image = bitmap
self.rect = self.image.get_rect()
self.rect.center = ( x, y )
# Keep the existing scale factor from startup to preserve the size ratio
self.scale_factor = self.rect.width / WINDOW_WIDTH
def rescale( self ):
new_size = int( WINDOW_WIDTH * self.scale_factor ) # new size
x, y = self.rect.center # existing centre position
# Re-size the bitmap
self.image = pygame.transform.smoothscale( self.original, ( new_size, new_size ) )
self.rect = self.image.get_rect()
self.rect.center = ( x, y ) # restore to the centre point
When the pygame.VIDEORESIZE event happens:
elif ( event.type == pygame.VIDEORESIZE ):
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
for s in sprite_group: # rescale all the sprites
s.rescale()
Use the pygame.display.toggle_fullscreen() command. You can read the documentation for it (Link: https://www.pygame.org/docs/ref/display.html#pygame.display.toggle_fullscreen).
Here is an example code:
if event.key == K_f:
pygame.display.toggle_fullscreen()
You do not have to do more. You could make a button on which you can press and then use this command. It is really easy to use. Hope I could help you, old me! :) I just found it today and so I wanted to answer so you and others can find this answer!

Categories

Resources