Display a sprite with no image - PyGame - python

I am working on a game project meant for learning and I was thinking if I create a sprite without a set image. I need this because I have an ideea to keep the value of the rect tiles that need collision in a sprite group. Is it possible?

Create a list of sprites excluding the invisible sprite(s):
all_sprites_list.draw(screen)
Then for collision just make a barrier list and put your invisible sprites that need collision in it.

Related

How do I get sprites to appear overtop of drawings?

When making a drawing in pygame, for example the rectangle, how do I make my other sprites show up ontop of the rectangle? Currently they are underneath it
when you draw all the objects, sprites should be last drawn on screen.
So first rectangles will be draw and sprites on top

pygame sprite collision on left

I want to do special collisions with pygame. I have a Ball sprite and a Block sprite and I want to know on which side of the block the ball has collided.
Maybe it's possible with pygame.sprite.groupcollide() and a custom collided as they call it. But I found no answser for that question. Is there any way to do it ?
Yes, it is possible. You are correct about the collided argument too.
What you need to do is write a function that will take 2 sprites and return a boolean value.
In this function you can then check on which side they have collided, and inform the sprites of the collision, or even return true only when a certain type of collision has happened.
Since every sprite has a rect attribute, you can check there way of movement as well as their positions to see where they have collided.
For example, if we have two sprites, A,B one going up and the other going left, they can collide in two ways. You can test if A has collided from the top, if after the collision, the second sprite is higher than A.
Heres a link to the pygame documentation I found:
pygame documentation
If your using a browser with a search page function search for:
pygame.sprite.spritecollide()
Im not too good with pygame, but understand the basics. I think the correct function is
pygame.sprite.collide_mask()
Which as the docs say:
"Returns first point on the mask where the masks collided, or None if there was no collision.
Tests for collision between two sprites, by testing if thier bitmasks overlap. If the sprites have a “mask” attribute, that is used as the mask, otherwise a mask is created from the sprite image. Intended to be passed as a collided callback function to the *collide functions. Sprites must have a “rect” and an optional “mask” attribute.
You should consider creating a mask for your sprite at load time if you are going to check collisions many times. This will increase the performance, otherwise this can be an expensive function because it will create the masks each time you check for collisions."
Hope it helped.
-Harry

Blitting a Pygame Tile-map Efficiently

My game map is a 2d-matrix that consists of different tiles (ex. map[y][x] = tile). Each tile has an image, and a rectangle. Currently the map is nearly 1000 tiles in size, and it takes quite some time to blit every one of them to the screen.
My current goal is to find a way to reduce the amount of time it takes to access each item of the matrix, and blit only the necessary tile-objects to the screen. Here is my main obstacle in trying to find a solution:
- Because it is a side-scrolling game, none of the tiles are static (the rectangles are always being adjusted with the player's movement, thus making it mandatory to re-blit the entire screen).
Here is generally how the map functions in the game:
For tile in tile matrix: blit tile to screen
Blit player and NPCs
Update player position
If player moves: adjust all tiles (camera system)
I'm looking for more efficient ideas of doing the same thing. As I said above, blitting every darn tile takes a lot of time, and to add to that, I'm not sure how to selectively blit different tiles when they are constantly changing location.
All ideas are welcome. Thank you.
When you're iterating over your tiles you can do a test to check if the current tile is contained within the camera's view port, if it is you can draw, otherwise you can skip blitting the tile.
for tile in tiles:
if camera.viewport.contains(tile.rect):
tile.draw()
The contains method is determining if a rectangle is inside another. You'll also need to use 2 different frames of reference, screen space and world space.

Moving Sprite groups

I've been reading the Pygame documentation for Sprite Groups, on its section for sprites it says:
The groups are designed for high efficiency in removing and adding
Sprites to them. They also allow cheap testing to see if a Sprite
already exists in a Group. A given Sprite can exist in any number of
groups. A game could use some groups to control object rendering, and
a completely separate set of groups to control interaction or player
movement. Instead of adding type attributes or bools to a derived
Sprite class, consider keeping the Sprites inside organized Groups.
This will allow for easier lookup later in the game.
My aim is to get movement on sprite groups, but I can't find any examples online. Is it possibly to move all or some individual sprites in a sprite group, If so how?
To move all Sprites in a Group, just use a simple for loop:
for spr in my_sprites_that_shall_move:
spr.rect.move_ip(d_x, d_y)
The Group class does not conatin any functionality to control the movement of its Sprites

(pygame) Empty squares displaying copies of what was previously there instead of background

I made a 2D project with a lot of tile sprites, and one player sprite. I'm trying to get the camera to follow the player, and for the most part it's working. However, there's one problem:
If you go to the edge of the map, it scrolls normally, but instead of the black background, it displays copies of the sprites on the edge of the map instead of the background (black). It has the same problem if I leave some squares empty, when I move it displays a copy of the tile that was previously there.
The camera works like this:
Select sprites that should be visible
Do sprite.visible = 1 for them, and sprite.visible = 0 for all other sprites
Set the position sprite.rect of all sprites to coords - offset
Update the screen (I use flip(), because the camera moves every turn, so the whole screen has to be updated every turn)
All DirtySprites have dirty = 2.
Does anyone know why it's displaying copies of the sprites on the edge instead of the background?
Help would be appreciated!
Unless you manually clear your screen surface, flip will not change its content.
Thus, if you neglect to draw to a certain location, it will remain the same.
If you want to get rid of this effect, usually called "hall of mirrors", you will have to keep track of what portions of the screen have not been drawn to yet and draw over these yourself.
It may be easier to define background sprites around your map's contours and block your camera from going off too far.
Since you use a "dirty/clean" approach to only redrawing what's changed, you won't have the option to just fill the whole screen surface before you draw your frame, because that would draw over anything that's stayed the same since the last frame.

Categories