I am using pygame to make a simple game. I am having issues with circle collisions. I am getting the following error:
"AttributeError: 'pygame.Rect' object has no attribute 'rect'"
Here is the particular code I am having issues with below:
if pygame.sprite.collide_circle(hero_circle, enemy_circle):
gameover()
Use pygame.mask to create a collision mesh for your objects and use the mesh to do collision detections.
In more detail:
Create an image file for both of your circles and set the bg color to something you will not use anywhere else.
Set that color to "transparent" in your image editor.
Import the images.
Create a mesh for them with pygame.mask and set it to make transparent pixels non-collidable.
Use the generated mask as your collision detection mesh.
PROFIT
(Technically this is just doing collision detection of a circle shaped area on a rectangle, but who cares!)
pygame.draw.rect()
draw a rectangle shape
rect(Surface, color, Rect, width=0) -> Rect
Draws a rectangular shape on the Surface. The given Rect is the area of the rectangle. The width argument is the thickness to draw the outer edge. If width is zero then the rectangle will be filled.
Keep in mind the Surface.fill() method works just as well for drawing filled rectangles. In fact the Surface.fill() can be hardware accelerated on some platforms with both software and hardware display modes.
The best way I've found to check circle collision detection is to calculate the distance between the center points of two circles. If the distance is less than the sum of the two circle's radii, then you've collided.
Just like how gmk said it but if your are using circles instead of rectangles, you should use this pygame function :
pygame.draw.circle(surface, color, center_point, radius, width)
This draws a circle on your surface (which would go in the surface area). Clearly the color requires a list of numbers (RGB anyone?). Your center_point decides the location of your circle since it will be the location of the center of your circle. The radius will need a number to set the radius of the circle (using the number like 25 will set your radius at 25 pixels/diameter at 50 pixels). the width section is optional as it sets the thickness of the perimeter of your circle (having 0 will have none at all). If you are not using circles, you should change your title... But anyways, I hope this helps you!
Related
I'm using Pygame to draw some shapes on the screen.
The problem is, I get those shapes from a different application, which exports a txt with the parameters of the arc, like this:
ARC1:
start_x=,
start_y=,
center_x=,
center_y=,
end_x=,
end=y=,
radius=,
start_angle=,
end_angle=
These are the parameters pygame needs to draw an arc:
surface (Surface) -- surface to draw on
color (Color or int or tuple(int, int, int, [int])) -- color to draw with, the alpha value is optional if using a tuple (RGB[A])
rect (Rect) -- rectangle to indicate the position and dimensions of the ellipse which the arc will be based on, the ellipse will be centered inside the rectangle
start_angle (float) -- start angle of the arc in radians
stop_angle (float) -- stop angle of the arc in radians
This function asks a rect, is there a way to calculate the rect with the parameters I have (from the txt) and keep its original shape and position?
The rect argument of pygame.draw.arc specifies the bounding rectangle of the circle the arc is on:
rect -- rectangle to indicate the position and dimensions of the ellipse which the arc will be based on, the ellipse will be centered inside the rectangle
The bounding rectangle of a circle with a given center and radius is:
bounding_rect = pygame.Rect(center_x-radius, center_y-radius, radius*2, radius*2)
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?
I am trying to calculate all the red dots in areas between two concentric circles. Finding the red dots is easy, I simply search using a for loop everything of red color, but the problem is finding that inside a contour, especially when I try to run over all the areas between the circles.
Code as bellow:
img2=Image.open("C:\Python27\Image.png")
pixels=list(img2.getdata())
for pixel in pixels:
if pixel==(255,0,0): print pixel
Bellow you can see the sample picture I'm working on to try my algorithm.
enter image description here
If you know where the circle's center is you simply calculate the distance between the red dot and the center. This tells you in which circle band your dot's are.
If you don't know where the circles are apply techniques for finding circles. Hough transform for example.
If you start scanning a single row of pixels in the middle of the edge of the image from left to right you can determine when a pixel is black.
When you record a series of white then black then white pixels you know you've found the edge of a circle. Scanning the same row from right to left will let you figure out the opposite side of the circle. Then you can calculate the equation of that circle from the diameter.
If you keep recording each circle as you move towards the center, you'll find the equation of each circle. Then when you find red pixels, you can determine which area they belong to by using the (x, y) coordinates of the red pixel and the equations of the circles.
If I have a ball in tkinter with radius 20 at coordinates x,y. What's the best method to find out if another object is touching it or partially overlapping it. I tried equating the coordinates of the two objects however that would only happen in very specific cases. Is there a away I can build a list that contains all the coordinates the ball occupies using its center coordinates and its radius?
Thank you
The circle's circumference consists of all the points that are exactly 20 units from the center. Therefore, if the distance from an edge of your object to the circle's center is less than 20, it will be inside the circle. If it's exactly 20, it will be touching the circle.
Im trying to rotate a loaded image but I need it rotated by a specific axis.
I was doing this:
arm = pygame.image.load('w1.png').convert()
arms = [pygame.transform.rotate(arm, deg) for deg in range(0, 360, 4)]
I was then iterating through the indicies of arms with:
count+=1
arms[count]
The rotation does work but it is not rotating on the axis properly. I have written algorithms that rotate lines made with pygame.draw.line but I do not know how to achieve this with an image.
Any and all insight appreciated,
thanks
After rotating your image, and before blitting, get the new rect for the image, and change the positional attributes of the rect back to the original position.
IE: save rect center, rotate image, get new rect, set newrect center, blit.
Using the center attribute with only rotate it around the center of the image, but maybe using one of the corners will put you on the right path.
def RESET_ROTATED_RECT(old_rect,rotated_image):
old_pos=old_rect.center
newrect=rotated_image.get_rect()
newrect.center=old_pos
return newrect
I use the center often, but haven't used the other positions. It may be worth tinkering with.