Using spritecollide in Pygame - with rotated surfaces - python

I have created a surface that is intended to be used as a 'wall' for an rpg style game, however I rotated this surface so it takes the form of a diamond since this is how the game design looks. My question is when using spritecollide it only works in rect arguments (rectangles). How can I make a 'wall' surface that has been rotated and essentially gives a rotated rect argument for a diamond? Thanks for the help!!

You can use collision masks for anything more complex than a rectangle or circle.
http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.collide_mask

Related

Box-box collision detection with PyOpenGL and Pygame at 3d

I'm writing a player class that, among other things, has mesh attributes (I use the py3d library and the mesh class from it) and collider (a class that I need to implement myself). The collider is a simple cube and should have a method to determine whether it collided with another collider-cube or not. I have a class that allows you to rotate and move 3d objects, I inherit the collider from it. The main problem is precisely to write a collision check function
I tried to use the methods built into Pygame to detect collisions, but it didn't work, because when the camera is removed, the collider remains the same size, and it can't be rotated. I'm bad at math, and all the guides I found were in C.game example
One way to detect box-box collisions in 3D using PyOpenGL and Pygame is to use the Bullet physics engine. Bullet is a 3D physics engine that can be used to detect collisions, apply forces, and simulate the motion of rigid bodies. To use Bullet, you would need to implement the collider class as a Bullet body, and then use the Bullet functions to detect collisions between the collider objects. You can also use the Bullet functions to rotate and move the colliders, which will allow you to keep the same size collider regardless of the camera position.
Here's a link to a tutorial on how to integrate bullet
http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-a-physics-library/

Is there a class in pygame to represent a non-AABB polygon?

I am making a game in python with pygame, and I am wondering if there is any class (with collisions) in pygame that supports non-AABB polygons. I know there is the pygame.draw.polygon function, but that takes a list of points instead of a rect like pygame.draw.rect.
Is there any way to do this in pygame?
If not, are there any pygame-compatible libraries that could do this?
If there are no libraries, how could I implement it?
The pygame.draw module does not generate objects. It just draws something on a Surface. You cannot use this for collision detection. I think you're confusing pygame.Rect and the pygame.draw module.
The collision detection in pygame is based on rectangles or circles. See How do I detect collision in pygame?.
Another option is to use pygame.mask.Mask objects, which you can use to detect overlapping shapes and sprites. See Pygame mask collision

What is Pygame.Rect() is used for in a program?

Can anyone tell me the use of Pygame.Rect. I am creating a simple program to draw and display rectangle in screen and check for collision with screen. I saw a video on youtube where the Youtuber uses the following code:
moving_rect=pygame.Rect(300,300,100,100)
Now I don't know what is Pygame.Rect is used for and what the above line of code actually does.
A pygame.Rec describes a rectangular area. It can be use to define the bounding box of an object. This can be useful for a collision test. See How do I detect collision in pygame?.
Actually it is used to define the location of a pygame.sprite.Sprite object.
Notice that a pygame.Surface object has no position. It only contains the pixel information. However, a Rect and a Surface together define the position of an image (Sprite) in the window.

Pygame Surface Positioning

As I understood pygame drawing method, the 2nd argument of the blit function (screen.blit(surface, (0,0))) tells pygame where to draw the given surface (like an offset to start drawing from, or rather a placement of the surface on the screen). Although, from recent experimenting, it seems that pygame surfaces placements are fixed, and that (0,0) is used to crop the surface before pygame blit it to the screen, for efficiency purposes.
Are surfaces placement really fixed (is my latter observation correct)? and if so, is there another way to conveniently move an already drawn surface to another position on the screen? Or should i implement my own way of moving complex "drawable" objects?
Thanks!
A pygame.Surface object has no position, it has a size only. Note, the location of the Rect object which is returned by pygame.Surface.get_rect() is always (0, 0).
When you blit a Surface on another Surface, then each pixel is copied and placed at the corresponding position of the destination Surface. Thus always a position has to be specified, when a Surface is blit on a destination Surface.
See also Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
[...] if so, is there another way to conveniently move an already drawn surface to another position [...]
You have a basic misunderstanding. A Surface cannot be "moved". A Surface is copied on the Surface object which is associated to the game window.
A Surface appears to be moving, because the entire scene is drawn in every frame. First the background is drawn, then the objects (Sprites, Surfaces) are drawn on top of the background and finally the display is updated (in every frame). If an object is placed at a slightly different position in every frame, then the object appears to be moving smoothly.

How do I display a large black rectangle with a moveable transparent circle in pygame? [duplicate]

This question already has an answer here:
How do I focus light or how do I only draw certain circular parts of the window in pygame?
(1 answer)
Closed 2 years ago.
That question wasn't very clear.
Essentially, I am trying to make a multi-player Pac-Man game whereby the players (when playing as ghosts) can only see a certain radius around them. My best guess for going about this is to have a rectangle which covers the whole maze and then somehow cut out a circle which will be centred on the ghost's rect. However, I am not sure how to do this last part in pygame.
I'd just like to add if it's even possible in pygame, it would be ideal for the circle to be pixelated and not a smooth circle, but this is not essential.
Any suggestions? Cheers.
The best I can think of is kind of a hack. Build an image outside pygame that is mostly black with a circle of zero-alpha in the center, then blit that object on top of your ghost character to only see a circle around it. I hope there is a better way but I do not know what that is.
If you only want to show the scene inside a circular area, then you can do the following:
Clear the display.
Limit the drawing region to a square area around the circular area
Draw the scene
Draw a transparent circle surface on top of the square area
The circle surface can be created with ease on runtime. Define the radius of the circular area (areaRadius). Create a square pygame.Surface with the doubled radius of the circular area. Fill it with opaque black and draw a transparent circle in the middle:
circularArea = pygame.Surface((areaRadius*2, areaRadius*2), pygame.SRCALPHA)
circularArea.fill((0, 0, 0, 255))
pygame.draw.circle(circularArea, (0,0,0,0), (areaRadius, areaRadius), areaRadius)
The drawing region of a surface can be limited by .set_clip(). Calling the function with the parameter None removes the clipping area. In the following screen is the surface which represents the window and areaCenter is the center of the circular area on the screen:
while run:
# [...]
# remove clipping region and clear the entire screen
screen.set_clip(None)
screen.fill(0)
# set the clipping region to square around the circular area
areaTopleft = (areaCenter[0]-areaRadius, areaCenter[1]-areaRadius)
clipRect = pygame.Rect(areaTopleft, (areaRadius*2, areaRadius*2))
screen.set_clip(clipRect)
# draw the scene
# [...]
# draw the transparent circle on top of the rectangular clipping region
screen.blit(circularArea, areaTopleft)
# clear the dripping region and draw all the things which should be visible in any case
screen.set_clip(None)
# [...]
pygame.display.flip()

Categories

Resources