I was wondering if someone could give me simple example of how to always draw sprites in pygame on --the top layer-- whilst an animation is being blitted on screen?
The senario I'm trying to solve is having an animated sprite (eg a man walking on the spot) and various other objects passing him, whilst he is still animated.
My solution so far has the animation layering on top of the "passing objects" which is not what I want.
Thanks in advance.
I think you've partially answered your own question here.
It's a matter of organizing what gets drawn first. Some side-scrolling 2D games use a "layer" solution, in which there is a background layer, a middleground layer, and a foreground layer, and the drawing system renders one layer after another.
I've also seen Pokémon top-down style games simply sort the sprites by their vertical position, so sprites "nearest" to the camera are drawn last, and thus on top of the other sprites.
See how the current implementation of Scene2D in libGDX gives each Actor a z-index property which can later be used to organize Actors into layers.
Just draw your sprites with a LayeredUpdates group:
class pygame.sprite.LayeredUpdates
LayeredUpdates is a sprite group that handles layers and draws like OrderedUpdates.
LayeredUpdates(*spites, **kwargs) -> LayeredUpdates
You can set the default layer through kwargs using ‘default_layer’ and an integer for the layer. The default layer is 0.
If the sprite you add has an attribute layer then that layer will be used. If the **kwarg contains ‘layer’ then the sprites passed will be added to that layer (overriding the sprite.layer attribute). If neither sprite has attribute layer nor **kwarg then the default layer is used to add the sprites.
and give your sprites the correct layer value.
Related
I have a project in Godot that renders billboarded quads on top of enemies. The quads(meshinstances) are children nodes of the enemy nodes. I want to render just the quads to a viewport for post-processing, but the quads need to have the same position on screen that the enemies have (like a target reticle).
How can I apply a shader effect to the billboards only and not to the rest of the scene?
The Camera has a cull_mask property that lets you filter which layers it will see. And VisualInstances (such as MeshInstances) have a layers property that lets you specify to which layers they belong (by default they all belong to the first layer).
You can configure the layers names in Project Settings -> General -> Layer Names -> 3d Render. Do not confuse them with 3d Physics.
Thus, you can give a different layer to those quad MeshInstance you want, and then setup a new Viewport with a new Camera as child (make sure it is current) with a cull_mask that will only render that layer. That way only those MeshInstance will be rendered on that Viewport.
You probably want to to keep the properties of the Camera in sync with the Camera on main Viewport (not only its global_transform, but also fov or any other property you might change). You can archive this by copying its properties on _process of a script attached to the Camera which is inside the new Viewport.
Using tile maps is pretty convenient, but there is one drawback. All tiles are on the same layer. This does not allow performing some operations with graphics, as, for example, in my case
I need that when my character is in front of some tile (wall), his sprite is drawn in front, and when in the back, vice versa.
This can be achieved by changing the position of the tilemap layer, but then only one tile will be drawn correctly. The tiles on the other side of the character will be drawn at the same level. How can the problem be solved?
Add a YSort node to your scene and place your player inside of it. The YSort arranges nodes so that the lower they are on the screen, the closer they are to it.
For example, if my player were below a fence, he would stand in front. If he were above the fence, he would be drawn behind it.
This video displays the effect you're going for, using autotile and YSort together https://www.youtube.com/watch?v=RPgTlxb7Bno.
I'm getting the feeling this won't be possible, but worth asking anyway I guess.
I have a background sprite and a foreground sprite, both are the same size as the window/view.
As the player sprite moves across the screen I want to delete the pixels it touches to reveal the background sprite.
This is not just for display purposes, I want the gaps the player has drawn or "dug" out of the foreground layer to allow enemies to travel through, or objects to fall into. So hit detection will be needed with the foreground layer.
This is quite complex and maybe Cocos2D-JS is not the best platform to use, if not possible could you recommend another which would be easier to achieve this effect with?
I believe it's possible, but I'm not capable of giving you a proper answer.
All I can say is that you'll most likely have two choices:
a. Make a physics polygonal shape and deform it, then use it as a "filter" to display your terrain image (here's a proof of concept example in another language using box2d).
b. Directly manipulate pixels and use a mask for collision detection (here's pixel-perfect collision detection in cocos2d-js, sadly I've got no info in modifying pixels).
Let's say I have a Sprite Sheet of a character in a game. There are 4 frames of him walking to the right direction, his shape changing in each frame. How do I define the shape for each individual frame when I add a physics body to this sprite?
I'm under the impression that I have to split the sprite sheet into individual images and define the shape for each image, but if that's the case I don't know what to do from there, programming-wise.
You cannot have different physics bodies for each frame of a sprite. You can try to get it close for most of the frames. If you choose to go the separate frame route, you will have to write your own animation function to animate the sprites.
Please don't try to do that. It'll completely kill your physics simulation.
The problem with it is that the mass of a shape is calculated from its area. If you have a character animation - e.g. walking, swinging his - he would gain weight when the arms are stretched and loose weight when the arms are next to the body.
Try not to be too exact about the collision shapes - the player usually won't see the difference anyways. Just make it good enough.
One option is to approximate the shape by using a union or intersection of your animation frames.
Take a look at this tutorial - it's for cocos2d - but the physics shape creation section is basically the same for corona.
http://www.raywenderlich.com/33525/how-to-build-a-monkey-jump-game-using-cocos2d-2-x-physicseditor-texturepacker-part-1
Near the center is a more detailed explanation how to create collision shapes for animations.
I've been struggling with this for a while.
Presently, I have a grid of 100 by 100 tiles, which belong to a Map.
The Map implements IDrawable. I call Draw() and it draws itself at 0,0 which is fine.
However, I want to expand this to draw essentially a viewport. The player will be drawn on the screen in the middle, and thus I want to display say, 10 tiles in each direction (rather than the entire map).
I'm having trouble thinking up the architecture for this one. I'm in the mindset that things should draw themselves, ie I say player1.Draw() and it draws itself. This would have worked before, where it drew the player at x,y on the screen, but with a viewport it will no longer know where to draw itself.
So should the viewport be told to draw, and examine every object in the game and draw those which are visible? Should the map tiles be objects that are subjected to this? Or should the viewport intelligently draw the map by coupling both together?
I'd love to know how typical scrolling tile games accomplish this.
If it matters, I'm using XNA
Edit to add: Can you do graphics manipulation such as trying the HTML rendering approach, where you tell things to draw, and they return a graphic of themselves, and then the parent places the graphic in the correct location? I'm thinking, if I had 2 viewports side by side for splitscreen, how would I stop them drawing outside the edges?
Possible design:
There's a 2D "world" that contains object instances.
"Object instance" is a sprite reference + its coordinates in the world.
When you draw scene, you request list of visible objects that exist in given 2D area, THEN you draw them.
With such design world can be very huge.
I'm in the mindset that things should draw themselves, ie I say player1.Draw() and it draws itself.
visible things should draw themselves. Objects outside of viewport are not visible.
, how would I stop them drawing outside the edges?
Not sure about XNA, but OpenGL has "scissors test"/"glViewport" and Direct3D 9 has "SetViewport" method that allows you to use part of the screen/window for rendering. There are also clipplanes and stencil buffer (using stencil for 2D clipping is overkill, though) You could also render to texture then render the texture. There are many ways to deal with this.
So should the viewport be told to draw, and examine every object in the game and draw those which are visible?
For a large world, you shouldn't examine every object, because it will be slow. You should be able to find visible object without testing every one of them. For that you'll need some kind of space partitioning - quad trees (because we are in 2D), k-d trees, etc. This way you should be able to handle few thousands (or even hundreds of thousands) of objects, as long as you don't see them all at once.
Should the map tiles be objects that are subjected to this?
If you keep drawing invisible things, FPS will drop.
and they return a graphic of themselves
For 2D game this may be very slow. Remember KISS principle.
Some basic ideas, not specifically for XNA:
objects draw themselves to a "virtual screen" in world coordinates, they don't draw themselves to the screen directly
drawable objects get a "graphics context" object which offers you a drawing API. The "graphics context" knows about the current viewport bounds and realizes the coordinate transformation from world coordinates to screen coordinates (for every drawing operations). The graphics context also does the direct drawing to the screen (or to a background screen buffer, if you need double buffering).
when you have many objects outside the visible bounds of your viewport, then as a performance optimization, your drawing loop can make a before-hand bounds-check for your objects and test if they are completely outside the visible area. If so, there is no need to let them draw themselves.