Pygame Rect, what are the arguments? - python

I know this may sound stupid, but the pygame documentation on their website says that it is:
x = pygame.Rect(left,top,width,height)
However, in my program, I cannot figure out if that is true, or if the arguments are actually two sets of coordinates. I'm not nearly experienced to find out by looking through the pygame source code.

Both of them work:
class pygame.Rect
pygame object for storing rectangular coordinates
Rect(left, top, width, height) -> Rect
Rect((left, top), (width, height)) -> Rect
Rect(object) -> Rect
So, if you have coordinates (x1, y1) and (x2, y2), both of the following would work:
pygame.Rect(x1, y1, x2-x1, y2-y1)
pygame.Rect((x1, y1), (x2-x1, y2-y1))

Related

Pygame shape border not appearing [duplicate]

I want to draw a solid black rectangle with only the middle part(have an accurate position for the hollow place) being fully transparent. How can I do that?
Use pygame.draw.rect(). The last parameter of pygame.draw.rect is the thickness of line the outline. If the parameter is 0 (or default), then the rectangle is filled, else a rectangle with the specified line thickness is drawn. e.g:
pygame.draw.rect(surf, color, (x, y, w, h), outlineThickness)
the corners of the rectangle are jagged. However, the corner radius can be set (border_radius) to get a better result:
pygame.draw.rect(surf, color, (x, y, w, h), outlineThickness, border_radius=1)

How do I make a sprite "stand' on another sprite in pygame?

I've got two sprites that can detect collisions, but I'm not sure how I can make my character sprite "stand" on my platform. Nothing I've done seems to work.
If you have 2 pygame.Rect objects, you can move the 2nd rectangle on the 1st rectangle by setting the bottom of the 2nd rectangle with the top of the 1st rectangle. With the virtual attributes of pygame.Rect it is easy to do so:
rect2.bottom = rect1.top
Or if you have 2 pygame.sprite.Sprite objects:
sprite2.rect.bottom = sprote1.rect.top
If you have 2 pygame.Surface objects (surf1 and surf2) and the 2 corresponding positions (x1, y1) and (x2, y2), use get_rect() to create pygame.Rect objects from the Surfaces. Move the 2nd rectangle on the 1st rectangle and update the position of the 2nd rectangle:
rect1 = surf1.get_rect(topleft = (x1, y1))
rect2 = surf2.get_rect(topleft = (x2, y2))
rect2.bottom = rect1.top
y2 = rect2.y

pygame: mask non-image type surfaces

I know how to mask images. But if I simply want to create a circle and mask it, it would be annoying to create an image of a simple circle outside of my code, especially when I need to create different kinds of circles. Appearantly you can create Rect objects in pygame but there is no class Circle.
pygame.mask.from_surface requires a surface. Can I pass a non-image type surface as a parameter? If so how can I mask circles and/or other objects?
Here's something I imagined which obviously throws an error:
circle = pygame.Circle((10, 10), 5) # (center coordinates), radius
pygame.mask.from_surface(circle)
There is no way to create a circular mask directly. See pygame.mask. You need to draw a circle on a Surface. Create a function that creates a Surface and draw a circle on the Surface:
def circleSurface(color, radius):
shape_surf = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA)
pygame.draw.circle(shape_surf, color, (radius, radius), radius)
return shape_surf
Create the Mask from the Surface:
circle = circleSurface((255, 255, 255), 5) # (center coordinates), radius
pygame.mask.from_surface(circle)
However, if you want to use a circle to clip an area of the display, see the answers to the following questions:
how to make circular surface in PyGame
How to fill only certain circular parts of the window in PyGame?

python tkinter rectangle resize

how can i resize my rectangle(canvas_bar) ?
am making hp bar to follow the object(monster)
and need to resize by it hp
hp = 100
hp_x = 100/5
canvas.create_rectangle(self.x, self.y, self.x+20, self.y+hp_x,
fill='red')
self.canvas.move(self.canvas_bar, self.vx, self.vy)
enter image description here
You can use the coords method to change the coordinates of an object.
The following example gets the current coordinates for the item identified by self.canvas_bar, and then makes the bar 100px wider:
(x0, y0, x1, y1) = self.canvas.coords(self.canvas_bar)
self.canvas.coords(self.canvas_bar, (x0, y0, x1+100, y1))

Pygame circle and its associated rect for collision detection

I am having an issue with Pygame drawing a circle and its associated rect. When I draw a circle such as pygame.draw.circle(surface, color, center, radius) it creates a rect. I am attempting to do collision detection using pygame.collidepoint(event.pos) where event.pos is the position of a mouse click. The size of my window is 500x400 and has a black background and the drawn circle is blue. When I click outside of the circle (in the black background), the circle should increase in size by multiplying the radius by an int. Conversely, when a click is registered inside of the circle, the circle shrinks by dividing the radius by an int.
The problem I am having is that the rect is not actually the same size as the circle such that when you click on the background when the circle is large but not completely filling the window, it shrinks instead of getting bigger (i.e. it registers a click inside the circle). At a certain point, the rect associated with the circle becomes the same size as the window even if the circle is not completely filling it which results in registering a click inside.
My question is how can I use hit detection for the circle only and not the rect which is larger than the actual circle?
Here is the relevant code:
def handleMouseDown(self, position):
if self.circle.collidepoint(position):
self.radius = self.radius // 2
else:
self.radius = self.radius * 2
self.draw()
def draw(self):
self.surface.fill(self.black)
self.circle = pygame.draw.circle(self.surface, self.color, self.center, self.radius)
Just calculate the distance between the center of the circle and the position of the mouse click:
x1, y1 = position
x2, y2 = self.circle.center
distance = math.hypot(x1 - x2, y1 - y2)
Then check if this distance is smaller or equal the radius of the circle:
if distance <= self.radius:
self.radius = self.radius // 2
...
When a click is detected, have the handler determine if it is actually inside the circle. Otherwise ignore it.

Categories

Resources