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
Related
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))
I'm trying to select the center of my image to make a hitbox some pixels around it.
I was able to inflate() the hitbox to make it the right size, but it always uses the top left corner of the image. This is fine when i'm moving left, but when i turn right it goes away from the character (in the image the character is dragging a sword, so it goes way off center).
I've been reading about Vector2, pos and offset, but i can't get it to work.
In conclusion i need to learn a way to find the center of my image in order to place it's hitbox a few pixels to each side. Either that or how to "shift" the corner the hitbox uses so it's always in the front of the char.
Use a pygame.Rect object. Get the rectangle from the pygame.Surface object (image) and set the top left corner position (x, y) of the rectangle. e.g.:
rect = image.get_rect()
rect.topleft = (x, y)
respectively
rect = image.get_rect(topleft = (x, y))
pygame.Rect provides a lot of virtual attributes, which can be used to retrieve the corners, borders, center and size of the rectangle. .center returns the center of the rectangle:
center_x, center_y = rect.center
Here is what I understand so far about Rect, it is a data type that contains all the properties of a given rectangular surface. And is used along the pygame.draw.rect() function as the third argument in order for it to work.
The code follows this syntax (from the official documentation):
Rect(left, top, width, height)
I understand about the third and fourth argument, which suppose to represent the dimensions of the rectangular surface. What I don't understand is the first 2 argument - what is it suppose to represent and what does it do? Why does it always start at (0,0) and what can we use it for?
The first two arguments get assigned to the x and y attributes of the rect, the coordinates of the topleft corner. So if you want to create a rect that is positioned at the coordinates (200, 300), you can write: rect = pygame.Rect(200, 300, 40, 50). The third and fourth argument are indeed the dimensions of the resulting rect instance.
pygame.Rects also have a lot of other attributes which you can use to position your rect.
x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
If you want to move a rect, you can assign the new position to the x, y, topleft or one of the other attributes.
rect.x = 5
rect.y = 10
# That's pretty much the same as writing:
rect.topleft = (5, 10)
# You can also increment the position.
rect.x += 5
# Or use the `rect.move_ip` method.
rect.move_ip(5, 10)
Rects are used to store the blit position of sprites or images and for collision detection, for example with the colliderect or collidepoint methods.
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.
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))