I am currently working on a 2D platformer and the sprites that I have animate from the bottom left point of the animation and when I draw the animation using a x and y point it still animates from the bottom left, so when I draw the animation to the screen the sprite should get shorter but the sprites feet just lift up of the ground like this https://www.dropbox.com/s/ofeggmlcp4f6qsk/Animation_probs_video.mp4
I know the video is not high quality but so what.
His head should go up and down not his feet. If you guy's can help me I would be most greatful. I could also use a program that fixes that I have a Linux computer with a windows xp virtual box and I am using python 2.7 and pygame.
Thanks.
Assuming you are animating a series of rectangular sprites each being an instance of pygame.Surface, you will be adding the difference between the surface with the greatest height and the current sprite's surface to the y position every time you blit.
Find the height of the tallest sprite only once:
max_height = tallest_sprite.get_height()
Now while you are cycling through your sprints each frame with current_sprite:
screen.blit(current_sprite, (x, y+(max_height - current_sprite.get_height())
If framerate is an issue, you may want to calculate these differences beforehand and associate them with each sprite so you have one less get_height() call per frame.
Related
I am making a game using python and pygame. I had a problem a few days ago that I needed to give my games a functionality of being resized and maintain the aspect ratio. Also everything on the screen is resized proportionately. And luckily I got a quick solution to create two different pygame surfaces. One is the screen visible to the user and the other is to manage the blitting functionality. Actually, fake screen has everything blitted and then it itself is blitted to the main screen by using
main_screen.blit((pygame.transform.scale(fake_screen, main_screen.get_rect().size), [0, 0]).
The main problem is that now since the MOUSEBUTTONDOWN events are getting triggered on the main screen and not on fake screen, But
the clicks are getting processed according to the fake screen. This means that when I click on a button after resizing, the button appears to be their but actually its at its respective position on the fake screen. This makes all the buttons loose their functionality after the VIDEORESIZE event. Can anyone help me out with this? I hope that I was able to explain.
Easy answer: use the pygame.SCALED display flag.
It resizes the main screen for you and the mouse events too, without your program needing to know anything about it. Documented on this page: https://www.pygame.org/docs/ref/mixer.html
Using this means you wouldn’t need to use a fake screen at all, or do anything at all with scaling on your end.
DIY answer:
If you still want to control the scaling yourself, you just have to scale the mouse events along with the screen. Like scale then the opposite way you scale the fake screen.
In your case it looks like that would involve dividing the mouse event x by the ratio between fakescreen width and screen width, and same with y (with heights ofc).
I got a very easy solution to this myself. I just after getting mouse x and y coordinates, changed them to proportionately corresponding points. With a simple math. I mean, if x coordinate is 15% of main screen width, then convert it to 15% of fake screen width. This way, the fake screen will get properly scaled coordinates. The mathematical equation can be as follows:-
mouse_x = mouse_x/(xd/100)
mouse_x *= 10
mouse_y = mouse_y/(yd/100)
mouse_y *= 6
Here xd and yd are width and height of the resizable main screen respectively. And 10 and 6 are 1% of 1000 and 600 which are the width and height of the fake screen.
This solved my problem and game is now working perfectly.
Thank You.
I am trying to create a simple scene in 3d (in python) where you have a cube in front of you, and you are able to rotate it around with the mouse.
I understand that you should rotate the complete scene to mimic camera movement but i can't figure out how you should do this.
Just to clarify I want the camera (or scene) to move a bit like blender (the program).
Thanks in advance
Ok I think i have found what you should do
just for the people that have trouble with this like I did this is the way you should do it:
to rotate around a cube with the camera in opengl:
your x mouse value has to be added to the z rotator of your scene
and the cosinus of your y mouse value has to be added to the x rotator
and then the sinus of your y mouse value has to be subtracted of your y rotator
that should do it
I recently just asked this question. I got my answer the only problem is the rotation is weird. It does not have one center point. The best way I can describe the rotation is the image pushed up to some left invisible wall, climbs up and then rotates until so other edge hits the invisible wall. I believe I need to set a constant center. How do I do this and where in my code do I put the center? I've looked at many examples but it seems like this weird rotation keeps occurring. Here is my code:
def update_angle(self):
orig_car = self.car1
loc = orig_car.get_rect().center
car2 = pygame.transform.rotate(orig_car, self.angle)
car2.get_rect().center = loc
return car2
I had a similar problem to you, I managed to pull a small amount of code together to fix it. When you're blitting the car to the screen use this code:
rect = car2.get_rect(center=(200,200)) #Set the centre of rotation
SCREEN.blit(car2, rect)
It allows the image to rotate about a point, hope this helps!
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.
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.