Scaling an Image/Rectangle in Pygame
You can simply change the width and the height of the rect (the w
and h
attributes). When the mouse gets moved (a MOUSEMOTION
event is added to the queue) and if the rect is selected, add the relative movement event.rel
to the width and the height.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
rect = pg.Rect(100, 100, 161, 100)
rect_selected = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
# Set rect_selected to True when the user clicks on the rect.
if rect.collidepoint(event.pos):
rect_selected = True
elif event.type == pg.MOUSEBUTTONUP:
rect_selected = False
elif event.type == pg.MOUSEMOTION:
if rect_selected:
# Simply adjust the width and the height of the screen
# by subtracting the relative mouse movement.
rect.w += event.rel[0]
rect.h += event.rel[1]
# 10*10 px is the minimal size, so that the rect can
# still be clicked.
rect.w = max(rect.w, 10)
rect.h = max(rect.h, 10)
screen.fill((30, 30, 30))
pg.draw.rect(screen, (0, 100, 250), rect)
pg.display.flip()
clock.tick(30)
If you want to do this with several rects, you can just assign the clicked rect to a variable (selected_rect
in this case) and then scale it.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
rect1 = pg.Rect(100, 100, 161, 100)
rect2 = pg.Rect(300, 200, 161, 100)
selected_rect = None
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
# Set selected_rect to the colliding rect.
for rect in (rect1, rect2):
if rect.collidepoint(event.pos):
selected_rect = rect
elif event.type == pg.MOUSEBUTTONUP:
selected_rect = None # De-select.
elif event.type == pg.MOUSEMOTION:
if selected_rect is not None: # Scale if a rect is selected.
selected_rect.w += event.rel[0]
selected_rect.h += event.rel[1]
selected_rect.w = max(selected_rect.w, 10)
selected_rect.h = max(selected_rect.h, 10)
screen.fill((30, 30, 30))
pg.draw.rect(screen, (0, 100, 250), rect1)
pg.draw.rect(screen, (0, 200, 120), rect2)
pg.display.flip()
clock.tick(30)
How to change an image size in Pygame?
You have to decide if you want to use Use pygame.transform.smoothscale
or pygame.transform.scale
. While pygame.transform.scale
performs a fast scaling with the nearest pixel, pygame.transform.smoothscale
scales a surface smoothly to any size with interpolation of the pixels.
Scaling up a Surface with pygame.transform.scale()
will result in a jagged result. When downscaling you lose information (pixels). In comparison, pygame.transform.smoothscale
blurs the Surface.
pygame.transform.scale()
and pygame.transform.smoothscale
are used in the same way. They do not scale the input Surface itself. It creates a new surface and does a scaled "blit" to the new surface. The new surface is returned by the return value. They:
- Creates a new surface (
newSurface
) with size(width, height)
. - Scale and copy
Surface
tonewSurface
. - Return
newSurface
.
look_1 = pygame.image.load('data\\png\\look1.png').convert_alpha()
look_1 = pygame.transform.scale(look_1, (new_width, new_height))
or
look_1 = pygame.image.load('data\\png\\look1.png').convert_alpha()
look_1 = pygame.transform.smoothscale(look_1, (new_width, new_height))
See also Transform scale and zoom surface
Minimal example: replit.com/@Rabbid76/PyGame-ScaleCenter
import pygame
class ScaleSprite(pygame.sprite.Sprite):
def __init__(self, center, image):
super().__init__()
self.original_image = image
self.image = image
self.rect = self.image.get_rect(center = center)
self.mode = 1
self.grow = 0
def update(self):
if self.grow > 100:
self.mode = -1
if self.grow < 1:
self.mode = 1
self.grow += 1 * self.mode
orig_x, orig_y = self.original_image.get_size()
size_x = orig_x + round(self.grow)
size_y = orig_y + round(self.grow)
self.image = pygame.transform.scale(self.original_image, (size_x, size_y))
self.rect = self.image.get_rect(center = self.rect.center)
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
sprite = ScaleSprite(window.get_rect().center, pygame.image.load("Banana64.png"))
group = pygame.sprite.Group(sprite)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
group.update()
window.fill(0)
group.draw(window)
pygame.display.flip()
pygame.quit()
exit()
Set the width and height of a pygame surface
Changing the width and height of the self.rect
attribute does effect the size of the pygame.Surface
. Even if a rectangle is passed to the dest argument of pygame.Surface.blit
, only the position of the rectangle is considered when the surface is _blit__ onto the target surface.
You have to scale the original image to the desired size by either pygame.transform.scale
or pygame.transform.smoothscale
.
Keep the original image (self.original_image
) and create a scaled image when the size the width or height is changed:
self.image = pygame.transform.smoothscale(self.original_image, self.rect.size)
Class UIComponent
:
class UIComponent(pg.sprite.Sprite):
def __init__(self, width, height):
pg.sprite.Sprite.__init__(self)
self.width_percent, height_percent = 0, 0
self.alignments = []
self.original_image = pg.Surface((width, height))
self.image = self.original_image
self.rect = self.image.get_rect()
ui_elements.add(self)
def set_colour(self, colour_value):
self.image.fill(colour_value)
def update(self, win):
for i in self.alignments:
i(win)
def center_x(self, win):
self.rect.x = (win.s_width/2)-self.image.get_width()/2
def center_y(self, win):
self.rect.y = (win.s_height/2)-self.image.get_height()/2
def relative_width(self, win):
self.rect.width = 25
self.image = pygame.transform.smoothscale(self.original_image, self.rect.size)
def relative_height(self, win):
self.rect.height = 25
self.image = pygame.transform.smoothscale(self.original_image, self.rect.size)
Image not centered on my rectangle python
self.idle
is a list, hence would you've to get a Surface object from the list by subscription (e.g. self.idle[0]
).
But most likely you want to put the image which is currently draw (player_image
) in the middle of the rectangle which is get by self.get_rect()
:
player_rect = self.idle.get_rect(center = center.get_rect)
player_rect = player_image.get_rect(center = self.get_rect().center)
window.blit(player_image,self.rect)
window.blit(player_image, player_rect)
how can i change the size of a rectangle
All you have to do is reduce the size of the input rectangle. Use pygame.Rect.inflate
with with negative values to reduce the size of the rectangle:
def draw_rect_angle(surf, orig_rect, pivot, angle):
rect = orig_rect.inflate(-25, -25)
pts = [rect.topleft, rect.topright, rect.bottomright, rect.bottomleft]
pts = [(pygame.math.Vector2(p) - pivot).rotate(-angle) + pivot for p in pts]
pygame.draw.lines(surf, (255, 255, 0), True, pts, 3)
Pygame: How do I add an image to a rect?
Load your image, call its get_rect
method to get a rect with the size of the image, then set the coordinates of the rect (there are several attributes like x, y, topleft, center, etc.
) ...
IMAGE = pg.image.load('an_image.png').convert() # or .convert_alpha()
# Create a rect with the size of the image.
rect = IMAGE.get_rect()
rect.center = (200, 300)
... and pass the rect as the dest
argument to pygame.Surface.blit
to blit the image at the rect.topleft
coordinates.
screen.blit(IMAGE, rect)
Getting width and height of an image in Pygame
There are 2 methods available for getting the width and height of a surface.
The first one is get_size()
, it returns a tuple (width,height)
. To access width for instance, you would do: surface.get_size()[0]
and for height surface.get_size()[1]
.
The second method is to use get_width()
, and get_height()
, which return the width and the height.
I suggest going through the python tutorial, to learn more about basic data structures such as tuples.
is there a way to control the size of rectangle in pygame?
You could create a rectangle where you know the hull will be, if the hull will be in the same place and the same size every time
self.rect = pygame.Rect(hulltop,hullleft,hullwidth,hullheight)
In your case hullwidth
might be the image width and hullheight
looks like your image height minus hulltop
.
If you have different hulls, you might consider having the hull and the mast/sail in separate image files, creating your outline of just the hull, then joining the images. Alternatively you could create a dict of the different hull sizes and use that to determine the size and position of the rectangle to draw.
Related Topics
Opencv Real Time Streaming Video Capture Is Slow. How to Drop Frames or Get Synced with Real Time
How to Set Folder Permissions in Windows
Board-Drawing Code to Move an Oval
How to Make My Player Rotate Towards Mouse Position
Print All Day-Dates Between Two Dates
Compare Two Different Files Line by Line in Python
Extract Number from String in Python
Typeerror: Worker() Takes 0 Positional Arguments But 1 Was Given
Pandas: Filtering Multiple Conditions
How to Request a Url in Python and Not Follow Redirects
Python - Windows Shutdown Events
Numpy.Unique with Order Preserved
Python Request Post with Param Data
How to Increment a Datetime by One Day
Why Is Looping Over Range() in Python Faster Than Using a While Loop