2D Depth System Method XNA C# - c#

I am creating a 2D Top-Down RPG game like the Legend of Zelda: A link to the past.
when the player is drawn i want to update the tree depth so that it is over and under the player when the player Y position is higher or lower than the trees Y position, i think whether the tree is on top or not should be decided by the players Y position, being lower or higher. is it possible to do this in this way? can i change the layer depth in the update method?
I'm not sure you can. i'm not very experienced when coding. If there's a right way of doing this even without useing the spriteBatch layer depth i would appreciate any help.
I have discovered how to use the layer depth in the
spriteBatch.Draw();
Method.
What i am attempting to do is shown in the images below
The code i am using to separate trees from grass tiles uses layer depth like below:
spriteBatch.Begin(SpriteSortMode.FrontToBack, blendState = null, samplerState = null, DepthStencilState.DepthRead);
spriteBatch.Draw(tree, treePos, null, null, Vector2.Zero, 0, null, Color.White, SpriteEffects.None, 0.6f);
spriteBatch.End();
Tile draw method for the
tile
has the float value set
0.5f

Here's a way to do it:
Slice your sprites and do tile-based rendering, starting from the ground up to the sky.
Say you have a tile grid whose each is 32*32 pixels, if you have a tree that is 32*96 pixels, then when sliced it will be like:
A // layer 2
A // layer 1
A // layer 0 (floor)
Logic:
draw all tiles on floor 0
draw all tiles on floor 1
etc ...
Then obviously the part that should hide your player will be drawn correctly (before, if player is behind).
(note that the lowest tile of the tree should not be walk-able)

Related

Translate coordinates to another plane

My main plane is Rectangle(0,0,10000,10000) for example.
My screen plane (ie virtual position) is Rectangle(1000,1000,1920,1080).
My Texture2D is Rectangle(1500,1200,200,100) in main plane.
I need to translate my Texture2D coordinates to my screen plane. I tried with Matrix.Translate without success.
I must get Texture2D = Rectangle(500,200,200,100) in screen plane.
In order to get the Texture2D from (1500, 1200) to (500, 200) you have to use a translation of (-1000, -1000) which are the inverse numbers from your screen plane's coordinates. In code your translation would be something like this
Matrix transform = Matrix.CreateTranslation(-screenPlane.x, -screenPlane.y, 0);
The theory is that you want to move the texture like if your camera was on (0, 0) instead of (1000, 1000). You have to move the texture by (-1000, -1000) in order to do so.
Check the web for 2D camera classes, always usefull to know how cameras work :)
This one for example: http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/

Get the bounds of the plane visible at a specific z coordinate

Using OpenTK, I've created a window (800x600) with a vertical FOV of 90°.
I want to make a 2D game with a background image that fits on the whole screen.
What I want is the plane at a variable z coordinate as a RectangleF.
Currently my code is:
var y = (float)(Math.Tan(Math.PI / 4) * z);
return new RectangleF(aspectRatio * -y, -y, 2 * aspectRatio * y, 2 * y);
The rectangle calculated by this is always a little to small, this effect seems to decrease with z increasing.
Hoping someone will find my mistake.
I want to make a 2D game with a background image that fits on the whole screen.
Then don't bother with perspective calculations. Just switch to an orthographic projection for drawing the background, disabling depth writes. Then switch to a perspective projection for the rest.
OpenGL is not a scene graph, it's a statefull drawing API. Make use of that fact.
To make a 2D game using OpenGL, you should use an orthographic projection, like this tutorial shows.
Then its simple to fill the screen with whatever image you want because you aren't dealing with perspective.
However, IF you were to insist on doing things the way you say, then you'd have to gluProject the 4 corners of your screen using the current modelview matrix and then draw a quad in 3D space with those corners. Even with this method, it is likely that the quad might not cover the entire screen sometimes due to floating point errors.

XNA SpriteBatch.Draw 3D Vectors HLSL

you all know the layerDepth value of the spriteBatch.draw() call. I'm using 3D vectors for my 2D game. Is it possible to get the layerDepth as the z value within the vertex shader? Or can I call the draw function with 3d vectors?
I need the depth of a sprite for postprocessing.
Yes, the layerDepth is passed as the Z position of each vertex.
Normally there is a range limit of between 0 and 1 for this parameter. Although I think this is only due to position near/far planes of the SpriteBatch default projection matrix. So it might not apply to you - I don't think the values are clamped or anything.

XNA Rotation Help(Interesting...)

Hello Stack Overflow users, I have a fun problem that I have in my XNA Game.
So basically I have an asteroid, 80x80, and I set the origin as imageW / 2, imageH / 2 (If order would matter, it wouldn't, the asteroid is a square).
Here is an image, explaining the problem! Visualization FTW :D
http://i.imgur.com/dsawS.png
So, any ideas on what is causing this? I spend 1 hour, I looked at examples, I found out it is supposed to rotate like this:
http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/rotation.jpg
But it's not.
Here is a code sample. I have a object named Drawable that has properties which hold the vector position, etc.
Vector2 asteroidOrigin = new Vector2(asteroidImgs[asteroid.asteroidType].Width / 2, asteroidImgs[asteroid.asteroidType].Height / 2);
drawableList.Add(new Drawable(asteroidImgs[asteroid.asteroidType], asteroid.asteroidPos, asteroid.angle, asteroidOrigin));
Here is the Draw Method:
foreach (Drawable drawable in renderManager.getRenderList)
{
spriteBatch.Draw(drawable.image, drawable.position, drawable.sourceRectangle, drawable.tint, drawable.angle, drawable.origin, drawable.imageScale, drawable.spriteEffects, drawable.depth);
}
And yes, the Drawable Class has multiple constructors and they assign default values.
When you define an Origin in SpriteBatch.Draw, you are defining the new point on your texture which will draw at the Position argument. Obviously this affects translation as well as your desired rotation. When you set the origin to the center of the image, the image is translated so that the center is at your Position, then rotated around that point. When you set the origin to Vector2.Zero, the translation is not changed, but the image rotates around its top left corner.
The solution is to either redefine what you mean as "Position" for sprites to be where the CENTER of the image draws on screen (I recommend this, makes things nice) or perform a bit of work before drawing by adding the Origin to the Position before calling Draw.
I, again, recommend the first solution, because then when you want to draw a circle in the center of the screen you can just set its position to be the center of the screen and be done. You won't need to take its size into account. And so on.

How to translate a sprite and a vertex geometry by the same distance?

I'm trying to build up a 2.5 engine with XNA. Basically, I want to display a 2D sprites (the main hero and other monsters) in a 3D background. The game will be a platform.
Now, using a translation matrix on a sprite doesn't yield the same result of translate a vertex geometry in world space.
I mean, if I apply
Matrix.CreateTranslation(new Vector3(viewportWidth / 2, viewportHeight / 2, 0));
the sprite will be translate at the middle of screen (starting from the display upper left origin). But, if I apply the same transform to a cube in world space, it will translate very far. This doesn't suprising me, but I wonder of to translate a sprite and a 3D object by the same distance, ignoring all the project/unproject coord stuffs.
Thanks!
There are traditionally three matrices: World, View and Project.
BasicEffect, and most other 3D Effects, simply have those matrices. You use Project to define how points are projected from the 3D world onto the 2D viewport ((-1,-1) in the bottom-left of the viewport to (1,1) in the top-right). You set View to move your camera around in world space. And you use World to move your models around in world space.
SpriteBatch is a bit different. It has an implicit Project matrix that causes your world space to match the viewport's client space ((0,0) in the top-left and (width,height) in the bottom-right). You can pass a transformMatrix matrix to Begin which you can generally think of like the View matrix. And then the parameters you pass to Draw (position, rotation, scale, etc) work like the World matrix would.
If you need to do "weird" things to your World or Project matrices in SpriteBatch, you can just build those transforms into your transformMatrix. It may just involve some maths to "undo" the built-in transformations.
In XNA 4 you can also use an Effect (like BasicEffect) directly in SpriteBatch, which you can provide with arbitrary matrices (details).

Categories

Resources