How to get the scaled output with the same ratio - python

I'm trying to make a game using pygame but I came up with an issue of people getting annoyed of the resolution they're working with, and can't resize window without stretching it.
Here is an example picture of what I'm trying to achieve.
here's what I tried.
window.blit(pg.transform.scale(screen, (window.get_size())), (0, 0)) # The game screen stretching
PS: It's hard to explain so I had to show an image

Use the following algortihm:
Get the bounding rectangle of the image and set the center of the rectangle to the center of the destination rectangle.
Use pygame.Rect.fit() to resize and move the aspect ratio rectangle into the destination rectangle.
Use the size of the new rectangle to scale the image.
blit the image at the position of the rectangle.
def blit_fit(dest_surf, image, dest_rect):
image_rect = image.get_rect(center = dest_rect.center)
fit_rect = image_rect.fit(dest_rect)
scaled_image = pygame.transform.scale(image, fit_rect.size)
dest_surf.blit(scaled_image, fit_rect)
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
image = font.render("Screen", True, (255, 255, 0))
pygame.draw.rect(image, (255, 255, 255), image.get_rect(), 1)
def blit_fit(dest_surf, image, dest_rect):
image_rect = image.get_rect(center = dest_rect.center)
fit_rect = image_rect.fit(dest_rect)
scaled_image = pygame.transform.scale(image, fit_rect.size)
dest_surf.blit(scaled_image, fit_rect)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
blit_fit(window, image, window.get_rect())
pygame.display.flip()
clock.tick(100)
pygame.quit()
exit()

Related

Image and Hitbox in pygame [duplicate]

I have created an image's rectangle of a sprite using the command, pygame.image.get_rect(). When locating coordinates of key points on the rectangle such as bottomleft by drawing dots, I see that the rectangle's dimensions are completely different to the image's dimensions. In this case, the image is just the arrow head. The top right coordinate of the rectangle is correct, however the bottom left coordinate isn't.
Test to see rectangle
code to draw dots:
pygame.draw.circle(simulation_screen, red, velocity_arrow.rect.topright, 2)
pygame.draw.circle(simulation_screen,red,velocity_arrow.rect.bottomleft,2)
How can I resize the rectangle so that it fits the image?
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object. This function does not consider the drawing area in the image. You can find the bounding rectangle of the painted area in the surface, with pygame.Surface.get_bounding_rect:
bounding_rect = image.get_bounding_rect()
bounding_rect.move_ip(target_rect.topleft)
See the example. The black rectangle is the Surface rectangle and the red rectangle is the union of the mask component rectangles:
repl.it/#Rabbid76/ImageHitbox
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
try:
my_image = pygame.image.load('icon/Bomb-256.png')
except:
my_image = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.circle(my_image, (0, 128, 0), (60, 60), 40)
pygame.draw.circle(my_image, (0, 0, 128), (100, 150), 40)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = window.get_rect().center
my_image_rect = my_image.get_rect(center = pos)
bounding_rect = my_image.get_bounding_rect()
bounding_rect.move_ip(my_image_rect.topleft)
window.fill((255, 255, 255))
window.blit(my_image, my_image_rect)
pygame.draw.rect(window, (0, 0, 0), my_image_rect, 3)
pygame.draw.rect(window, (255, 0, 0), bounding_rect, 3)
pygame.display.flip()
pygame.quit()
exit()
I have the same problem, and I think because of this line:
image = pygame.transform.scale(image, (x, y))
After scaling the image in gimp, everything is working as intended.

Modifying Pygame Hitboxes with different object classes [duplicate]

I have created an image's rectangle of a sprite using the command, pygame.image.get_rect(). When locating coordinates of key points on the rectangle such as bottomleft by drawing dots, I see that the rectangle's dimensions are completely different to the image's dimensions. In this case, the image is just the arrow head. The top right coordinate of the rectangle is correct, however the bottom left coordinate isn't.
Test to see rectangle
code to draw dots:
pygame.draw.circle(simulation_screen, red, velocity_arrow.rect.topright, 2)
pygame.draw.circle(simulation_screen,red,velocity_arrow.rect.bottomleft,2)
How can I resize the rectangle so that it fits the image?
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object. This function does not consider the drawing area in the image. You can find the bounding rectangle of the painted area in the surface, with pygame.Surface.get_bounding_rect:
bounding_rect = image.get_bounding_rect()
bounding_rect.move_ip(target_rect.topleft)
See the example. The black rectangle is the Surface rectangle and the red rectangle is the union of the mask component rectangles:
repl.it/#Rabbid76/ImageHitbox
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
try:
my_image = pygame.image.load('icon/Bomb-256.png')
except:
my_image = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.circle(my_image, (0, 128, 0), (60, 60), 40)
pygame.draw.circle(my_image, (0, 0, 128), (100, 150), 40)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = window.get_rect().center
my_image_rect = my_image.get_rect(center = pos)
bounding_rect = my_image.get_bounding_rect()
bounding_rect.move_ip(my_image_rect.topleft)
window.fill((255, 255, 255))
window.blit(my_image, my_image_rect)
pygame.draw.rect(window, (0, 0, 0), my_image_rect, 3)
pygame.draw.rect(window, (255, 0, 0), bounding_rect, 3)
pygame.display.flip()
pygame.quit()
exit()
I have the same problem, and I think because of this line:
image = pygame.transform.scale(image, (x, y))
After scaling the image in gimp, everything is working as intended.

I do run my code, and its suddenly gone, and I get this error, what should I do?, and how can I pick the right size for my background image?

I do run my code, but its suddenly gone, and I get this error saying "screen.fill(background_img)TypeError: invalid color argument"enter image description here.
I dont also know how to resize the background image that i want to use for my screen background
pygame.init()
background_img = pygame.image.load("C:\\Users\\lenovo\\Pictures\\maxresdefault.jpg")
(width, height) = (800, 800)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Hop Along')
screen.fill(background_img)
pygame.display.update()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
You cannot fill the display with an image. You must blit an image:
screen.fill(background_img)
screen.blit(background_img, (0, 0))
If the background image is a different size than the window, you can use pygame.transform.smoothscale to scale the image:
background_img = pygame.image.load("C:\\Users\\lenovo\\Pictures\\maxresdefault.jpg")
scaled_background = pygame.transform.smoothscale(background_img, (width, height))
screen.blit(scaled_background, (0, 0))

How to inject Margin class into triangle class? [duplicate]

I have created an image's rectangle of a sprite using the command, pygame.image.get_rect(). When locating coordinates of key points on the rectangle such as bottomleft by drawing dots, I see that the rectangle's dimensions are completely different to the image's dimensions. In this case, the image is just the arrow head. The top right coordinate of the rectangle is correct, however the bottom left coordinate isn't.
Test to see rectangle
code to draw dots:
pygame.draw.circle(simulation_screen, red, velocity_arrow.rect.topright, 2)
pygame.draw.circle(simulation_screen,red,velocity_arrow.rect.bottomleft,2)
How can I resize the rectangle so that it fits the image?
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object. This function does not consider the drawing area in the image. You can find the bounding rectangle of the painted area in the surface, with pygame.Surface.get_bounding_rect:
bounding_rect = image.get_bounding_rect()
bounding_rect.move_ip(target_rect.topleft)
See the example. The black rectangle is the Surface rectangle and the red rectangle is the union of the mask component rectangles:
repl.it/#Rabbid76/ImageHitbox
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
try:
my_image = pygame.image.load('icon/Bomb-256.png')
except:
my_image = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.circle(my_image, (0, 128, 0), (60, 60), 40)
pygame.draw.circle(my_image, (0, 0, 128), (100, 150), 40)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = window.get_rect().center
my_image_rect = my_image.get_rect(center = pos)
bounding_rect = my_image.get_bounding_rect()
bounding_rect.move_ip(my_image_rect.topleft)
window.fill((255, 255, 255))
window.blit(my_image, my_image_rect)
pygame.draw.rect(window, (0, 0, 0), my_image_rect, 3)
pygame.draw.rect(window, (255, 0, 0), bounding_rect, 3)
pygame.display.flip()
pygame.quit()
exit()
I have the same problem, and I think because of this line:
image = pygame.transform.scale(image, (x, y))
After scaling the image in gimp, everything is working as intended.

Is it possible to change sprite colours in Pygame?

I'm making a game in Python using Pygame that includes a small avatar maker before the game starts, but instead of creating a big sprite sheet with 88 different combinations of hairstyles and colours, is there a way that I can just use a generic .png image of each hairstyle and apply colour to it in-game?
The hairstyles are saved as .png images with alpha and anti-aliasing, so they are not just one shade of colour. I've got 8 different hairstyles and 11 different colours. It wouldn't be a problem to load them in as a sprite sheet and clip them in-game, but if there was a way to apply colour (or hue) in the game then not only would it be easier on the memory, but would open it up to more possibilities.
If the image is a "mask" image, with a transparent background and a white (255, 255, 255) mask, then you can "tint" the image with ease.
Load the image:
image = pygame.image.load(imageName)
Generate a uniform colored image with an alpha channel and the same size:
colorImage = pygame.Surface(image.get_size()).convert_alpha()
colorImage.fill(color)
Blend the image with maskImage, by using the filter BLEND_RGBA_MULT:
image.blit(colorImage, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
A sprite class may look like this:
class MySprite(pygame.sprite.Sprite):
def __init__(self, imageName, color):
super().__init__()
self.image = pygame.image.load(imageName)
self.rect = self.image.get_rect()
colorImage = pygame.Surface(self.image.get_size()).convert_alpha()
colorImage.fill(color)
self.image.blit(colorImage, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
Minimal example: repl.it/#Rabbid76/PyGame-ChangeColorOfSurfaceArea-4
import pygame
def changColor(image, color):
colouredImage = pygame.Surface(image.get_size())
colouredImage.fill(color)
finalImage = image.copy()
finalImage.blit(colouredImage, (0, 0), special_flags = pygame.BLEND_MULT)
return finalImage
pygame.init()
window = pygame.display.set_mode((300, 160))
image = pygame.image.load('CarWhiteDragon256.png').convert_alpha()
hue = 0
clock = pygame.time.Clock()
nextColorTime = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
color = pygame.Color(0)
color.hsla = (hue, 100, 50, 100)
hue = hue + 1 if hue < 360 else 0
color_image = changColor(image, color)
window.fill((96, 96, 64))
window.blit(color_image, color_image.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
Sprite:

Categories

Resources