Dealing With Sprite Collisions when spritre image has spaces [duplicate] - python

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.

Related

Pygame colliderect returning true way too soon [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.

How can I change the hitbox of my character if I'm using self.image.get_rect()? [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.

Missing Corner on Rectangle Pygame [duplicate]

This question already has answers here:
How to Make a Border in Pygame
(1 answer)
How can I draw a rectangular outline (not filled) with PyGame?
(1 answer)
Closed 1 year ago.
When working on my game, I noticed that shapes have "missing corners." I have tested this with lines and a rectangle. How do I fix this?
import pygame
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
PASCOLOR = (199, 121, 121)
# add font
gameFont = pygame.font.Font('PressStart2P.ttf', 25)
gameDisplay = pygame.display.set_mode((1200, 650))
pygame.display.set_caption('test game')
exitgame = False
while not exitgame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exitgame = True
gameDisplay.fill(BLACK)
# add outside rectangle
pygame.draw.rect(gameDisplay, WHITE, (100, 100, 1000, 450), 5)
# Add images
addimg = pygame.image.load('addimg.png')
# resize ranta
addimg = pygame.transform.scale(addimg, (63.5, 87))
def loadImages():
gameDisplay.blit(addimg, (110,110))
loadImages()
# add text to screen
titletxt = gameFont.render("test game", True, PASCOLOR)
gameDisplay.blit(titletxt, (400, 40))
pygame.display.flip()
pygame.quit()
quit()
Is this how Pygame renders rectangles or an error?
See that the pixels on the corners are missing.
Set the corner radius (border_radius) to get a better result (see pygame.draw.rect):
pygame.draw.rect(gameDisplay, WHITE, (100, 100, 1000, 450), 5)
pygame.draw.rect(gameDisplay, WHITE, (100, 100, 1000, 450), 5, border_radius=1)
See also How can I draw a rectangular outline (not filled) with PyGame?.

How to get the correct dimensions for a pygame rectangle created from an image

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.

How do I focus light or how do I only draw certain circular parts of the window in pygame?

For this, if you're familiar with it, think the dark mode in the boo levels in Super Mario Maker 2. I'm trying to create a circular spotlight around the character that will also make anything within the circles range visible (eg part of the floor being stood on, an enemy or anything else from the scene). My plan to do that is to first draw the circle/spotlight, then the scene and then the character. Then I want anything not highlighted by the spotlight to be blacked out.
So my question is:
Does anybody know how to fill the entire screen with the exception of what's within the circle?
I suggest a solution, which combines a clipping region pygame.Surface.set_clip and drawing a black rectangle with a circular transparent area in the center.
Define a radius and create a square pygame.Surface with twice the radius.
radius = 50
cover_surf = pygame.Surface((radius*2, radius*2))
Set a white color key which identifies the transparent color (set_colorkey) a nd draw a white (transparent) circle on the surface:
cover_surf.set_colorkey((255, 255, 255))
pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)
Define the center of the circular region which you want to see (in the following clip_center).
In the main application loop, clear the display and set the clipping region, the draw the scene. Before you update the display draw cover_surf in the clipping region:
while run:
# [...]
# clear screen and set clipping region
screen.fill(0)
clip_rect = pygame.Rect(clip_center[0]-radius, clip_center[1]-radius, radius*2, radius*2)
screen.set_clip(clip_rect)
# draw the scene
# [...]
# draw transparent circle and update display
screen.blit(cover_surf, clip_rect)
pygame.display.flip()
Minimal example: repl.it/#Rabbid76/PyGame-ClipCircularRegion-2
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
radius = 50
cover_surf = pygame.Surface((radius*2, radius*2))
cover_surf.fill(0)
cover_surf.set_colorkey((255, 255, 255))
pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
clip_center = pygame.mouse.get_pos()
# clear screen and set clipping region
screen.fill(0)
clip_rect = pygame.Rect(clip_center[0]-radius, clip_center[1]-radius, radius*2, radius*2)
screen.set_clip(clip_rect)
# draw the scene
for x in range(10):
for y in range(10):
color = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)
pygame.draw.rect(screen, color, (x*50, y*50, 50, 50))
# draw transparent circle and update display
screen.blit(cover_surf, clip_rect)
pygame.display.flip()
If you want multiple circular drawing areas, then create a pygame.Surface.set_clip with the same size as the display and set whit color key:
cover_surf = pygame.Surface((400, 400))
cover_surf.set_colorkey((255, 255, 255))
Fill the entire surface black and draw white circles on the surface:
cover_surf.fill(0)
pygame.draw.circle(cover_surf, (255, 255, 255), (100, 100), 50)
pygame.draw.circle(cover_surf, (255, 255, 255), (300, 300), 70)
Blit the cover_surf on the window, before updating the display:
while run:
# [...]
# draw transparent circle and update display
screen.blit(cover_surf, (0, 0))
pygame.display.flip()
Minimal example: repl.it/#Rabbid76/PyGame-ClipCircularRegion-3
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
cover_surf = pygame.Surface((400, 400))
cover_surf.set_colorkey((255, 255, 255))
px = [100, 200, 300]
dx = [1, 2, 3]
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# create cover surface
cover_surf.fill(0)
for i in range(3):
radius = 40 + i*20
pygame.draw.circle(cover_surf, (255, 255, 255), (px[i], 100+(i*100)), radius)
px[i] += dx[i]
if px[i] < radius or px[i] > 400 - radius:
dx[i] = -dx[i]
# draw the scene
for x in range(10):
for y in range(10):
color = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)
pygame.draw.rect(screen, color, (x*50, y*50, 50, 50))
# draw transparent circle and update display
screen.blit(cover_surf, (0, 0))
pygame.display.flip()

Categories