Pygame Collision on Rect - python

I'm a student in Computer Programming at my high school and really need help to make the square an obstacle that ships can't enter and bullets disappear once you shoot at the square also for the circle the same thing. And both ships die if they collide with each other. Please help I know my question isn't the best worded but i really need help.
the link to the code is here https://docs.google.com/file/d/0B-Pb_T-Vgr3-TnhRY0lvVjJHX0U/edit?usp=sharing

I would suggest that you create a GameObject class which extends pygame.sprite.Sprite and both Ship and Bullet classes which extend GameObject. This allows you to then easily add properties that both will need, such as velocity and acceleration, and you can create a collide method that is overridden by both for specific behavior. The added bonus here is that pygame.sprite.collide_rect will work properly as such:
if (pygame.sprite.collide_rect(sprite1, sprite2)):
# sprite1 and sprite2 are colliding!
# do something, such as calling sprite1.collide(sprite2)
# and sprite2.collide(sprite1)
So, pygame.sprite.collide_rect checks if two sprites collide using the Sprite.rect property of each. This functionality could also be recapitulated using rect.colliderect:
sprite1.rect.colliderect(sprite2.rect)

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/

How can I check collisions between actors in pygame using "actor.collidepoint(pos)"

I'm very new to pygame and am trying to make a game where the actor try's to hit the gem, but I cant figure out how to use the "actor.collidepoint(pos)" function for that! Answers are greatly appreciated!
See Actor:
Actors have all the same attributes and methods as Rect, including methods like .colliderect() which can be used to test whether two actors have collided.
Supposing you have to Actor objects:
player = Actor("player_image.png")
gem = Actor("gem_image.png")
Use colliderect method to detect the collision between the actors:
if player.colliderect(gem):
print("hit")
For more information about collisions in Pygame, see the answers to the questions:
How do I detect collision in pygame?
How to detect collisions between two rectangular objects or images in pygame

Pygame - How to destroy an asteroid and create smaller ones in its place

I'm making this classic style asteroids game and I've beaten all the challenges that come with it. Right now there's a new one.
When a bullet hits one of the asteroids, the expected behavior is that it disappear, then three or four smaller asteroids appear in its place, each with random velocity so it looks like a kind of explosion. But instead this weird behavior show in this video I just recorded:
https://youtu.be/2ZJvOcB-ZKM
As you can see it does 90% of what it's supposed to do, the asteroid dissapear, then I create four new and smaller asteroids in its pace but then, for some reason they dissapear when they should behave like normal asteroids, since they inherit everything.
The game source code can be found here: https://github.com/JuanBonnett/pysteroids
The classes in charge of handling the collision Bullet->Asteroid are:
asteroids.py Main file creates all the objects, the ship, the asteroids generator and the collision detector object.
physics.py Where the CollisionDetector class is and which detects when they collide and call its dependencies to do stuff with the collision
asteroid.py has an asteroid generator that generates smaller asteroids in the place of the collision, which I call debris.
When an asteroid blows up, you are passing it a pos vector of where to start.
You are applying that same vector instance to all resulting asteroids.
All smaller asteroids have the same self.pos value as their siblings that came from the same parent asteroid.
It looks weird because the self.points property is working just fine and updated/translated correctly and so you're seeing two positions fight each other and give chaotic/unpredictable behavior.
Basically the problem is the pos = _pos line in AsteroidGenerator.generate. It should be making a copy of the vector instead of assigning the reference directly to the new asteroid.
I discovered this by putting print statements in your asteroid render code printing the position: print(self.pos.x, self.pos.y). I noticed all asteroids had the same self.pos but were being given supposedly random velocity vectors, so I figured it was probably an object reference problem and followed where that was being assigned.

Finding all collisions within 1 group of sprites (efficiently)

I have a method that recieves a Group of sprites. For each sprite, I need to find every other sprite it collides with and call its handle_collision method.
How can I find all the sprites each sprite in the group collides with? Here's my idea for finding all collisions within a group.
#staticmethod
def check_collision_group(most_sprites: pygame.sprite.Group, screen):
for sprite in most_sprites:
most_sprites.remove(sprite)
collided_sprites = pygame.sprite.Group()
for sprite2 in most_sprites:
if pygame.sprite.collide_rect(sprite, sprite2):
collided_sprites.add(sprite2)
sprite.handle_collision(collided_sprites)
most_sprites.add(sprite)
However, this is slow. The amount of collisions this had to check astonished me when I printed them out.
A bit of searching and I've found 2 ideas that are probably a lot faster.
Making the first sprite a Group and using collidegroup from pygame.sprite library.
Only testing the sprites around the sprite you are testing. Idea from https://gamedev.stackexchange.com/questions/45392/how-do-i-detect-multiple-sprite-collisions-when-there-are-10-sprites .
To restate question: What is a fast (but hopefully still relatively simple) way to find every other sprite in the group that each sprite collides with?
To find all collisions between a sprite and everything else in it's group.
def check_collision_group(most_sprites, screen):
single = pygame.sprite.GroupSingle()
for sprite in most_sprites:
most_sprites.remove(sprite)
single.add(sprite)
collided_sprites_dict = pygame.sprite.groupcollide(
single, most_sprites, False, False)
most_sprites.add(sprite)
Note: It's important to use add on the groupsingle, reassignment will keep adding more and more groups to your system and bog down your game. I am not sure why, but changing it to my groupsingle and adding to it fixed the issue.
The speed of this seems to be relatively fast. To calculate all the collisions in a group of ~50 sprites it took about 1.4 milliseconds. I have not tried method 2, which is only checking collisions based on proximity, but I do not see a reason to, as the speed of groupcollide is rather decent.

Pygame: Updating Rects with scrolling levels

I'm currently making a 2D side-scrolling run'n'jump platform game in PyGame. Most of the stuff is working OK and very well in fact - I am exploiting the fast pyGame Sprite objects & groups.
What I'm interested to know is how people usually deal with Rects for scrolling games. I obviously have a level that is much bigger than visible area, and the player, enemies, bullets etc each have their own (x,y) coordinates which describe where they are in the level.
But now, since we use the "spriteGroup.draw(surface)" call, it will not display them in the right spot unless each objects Rects have been adjusted so that the right part displays on the screen. In other words, everytime a player/enemy/bullet/whatever else is updated, the Camera information needs to be passed, so that their Rect can be updated.
Is this the best method to use? It works but I don't really like passing the camera information to every single object at every update to offset the Rects.
Obviously the ideal method (I think) is to use Rects with "real" coordinates, blit everything to a buffer as big as the level, and then just blit the visible part to the screen, but in practice that slows the game down A LOT.
Any comments/insight would be appreciated.
Thanks
You could extend de Sprite.Group so it recives the camera information.
Then do one of these options:
A. Override the update method so it updates the on-screen coordinates of every sprite.
B. Override the draw method so it updates the on-screen coordinates of every sprite and then calls its parent draw method.
I think A it's easier and cleaner.
I don't really like passing the camera information to every single
object at every update to offset the Rects.
Camera may be global, or, a member of a global Game() class instance. Then your sprite class's draw method doesn't need an argument.
You can override draw yourself, so it does:
dest = game.camera.topleft + self.rect.topleft
screen.blit( self.surface, dest )
This keeps the bullet's rect in world-coordinates, yet blits using screen-coordinates.
One method I found is to keep track of a scrollx and a scrolly. Then, just add scrollx and scroll y to the coordinates when you move the rectangles.
You can have a 2 variables level_landlevel_d which see where you are in the level, Then check which sprites are in the visible area
level_d+height and level_l+width,
and draw them on the screen.
The simple way to do it is like that:
Create a CameraX and CameraY variables, and when you blit objects on the screen use this:
blit(surface, (x -CameraX, y -CameraY))
any object that gets affected by the camera should be drawn like that, but keep in mind that there are objects that you may want to remain uneffected (like health bars or status windows)
just keep in mind everytime you want to move camera do this
#Move Camera Right
CameraX += 10
#Move Camera Left
CameraX -= 10
#Move Camera Down
CameraY += 10
#Move Camera Up
CameraY -= 10
Just keep in mind that if they get negative values they may not work correctly, also you must probably define some limits (you dont want your camera to move over the limits of your map

Categories

Resources