Draw segments of circle on xna - c#

How do I draw a circle sector (as in a slice of pizza shape) in xna?
I'd like to use one as a timer indicator, so would like to be able change its angle dynamically.
In an ideal world I'm looking for something like this:
Drawsector (float startAngle, float endAngle, ... )
Does such a thing exist?
And if it does - how would I go about drawing a more graphically involved one (as opposed to just block colour)

No. XNA only provides an API for drawing primitive elements called surprisingly primitives.
All is not lost because drawing a circle can be viewed as simply drawing a series of very short interconnected line segments, small enough that you can't tell they are lines, but not too small so as to be inefficient.
In XNA you would draw a PrimitiveType.LineStrip.
MSDN:
The data is ordered as a sequence of line segments; each line segment is described by one new vertex and the last vertex from the previous line seqment. The count may be any positive integer.
e.g. (from MSDN)
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineStrip,
primitiveList,
0, // vertex buffer offset to add to each element of the index buffer
8, // number of vertices to draw
lineStripIndices,
0, // first index element to read
7 // number of primitives to draw
);
You would need to create your own function to determine the vertices that match the arc you want to draw. You should save that into a permanent index and vertice buffer rather than performing a DrawSector() all the time in your game loop.
Tell me more
Drawing 3D Primitives using Lists or Strips

Related

Voxel Tree Generator

My challenge is to randomly generate a voxel tree that looks something like these: https://imgur.com/a/LT17der (not my own voxel work in photo)
For now i'm Just looking for ideas on how best to approach creating the trunk. I was thinking I'd start with setting the width and height of the the trunk and add each block at coordinate positions layer by layer with some degree of randomness as to where exactly the blocks are placed.
Any thoughts and suggestions are appreciated - for now i'm looking to keep it simple.
I would try to make a recursive function to generate the voxel tree.
It would take 3 arguments:
A vector representing the base of the current node
A vector representing the extent of the node
A 3-dimensional array of booleans, which represents the cells of the tree which are filled by the algorithm.
A counter, to limit the recursion depth
In Unity3D C#, it would look like:
void fillTree(Vector3 base, Vector3 extent, bool[,,] output, int depth)
And the first call to this recursive function would be
bool[,,] output = new bool[sizeX, sizeY, sizeZ];
fillTree(Vector3.zero, Vector3.up, output, 0)`.
This function will then:
Check that depth is not greater than the maximum, else return
Using a voxelization algorithm, write output with a capsule going from base to base + extent, with a thickness equal to something like 0.5^depth, so that each subtree is twice less thick as its parent (This can be pretty hard, so if performance is not a problem, just iterate naively over the whole grid, filling all voxel whose distance to the line segment [base; base + extent] is less than the thickness. Don't forget to map the float coordinates to the grid coordinates, by adding to each component of the vector the half of the grid size in the same dimension)
Choose a random number of subtrees (>= 2)
For each subtree :
Set a random horizontal angle alpha to be close to the horizontal angle of the parent, which can be retrieved using atan2(extent.z, extent.x) (Beward, an angle is cyclic, so 1 is considered as close to 359)!. The greater depth is, the closer the new angle must be from the parent one (the range must be proportional to something like 0.5^depth, the same as the thickness).
Set a vertical angle beta to be less than the vertical angle of the parent tree, so that branches seem to fall (the vertical angle of the parent can be computed as atan2(extent.y, sqrt(extent.x*extent.x + extent.z * extent.z)))
Compute the extent of the subtree, newExtent with the coordinates (cos(alpha)*cos(beta), sin(beta), sin(alpha)*sin(beta)). Normalize this vector and multiply it with something like 0.5^depth
call fillTree(base + extent, newExtent, output, depth + 1)
I have neither tested this algorithm yet, nor implemented it, and it is for sure far less beautiful as what you are trying to achieve, but I hope it helps you.

How to avoid shimmering with rotated spriteBatch?

I am writing a camera module to my XNA project and I encountered a problem lately.
I allowed camera rotation to my module and I got a fabulous bug - every time I draw multiple sprites in the same position, spriteBatch once draws one in front, second time the second one in front, and what is even funnier, sometimes two sprites are shown, with different alphas.
I've made few experiments:
When I set SpriteBatch mode to Deffered it is all ok - but I want to have access to z-index.
When I draw a whole 500x500 tiles array (all the sprites loaded), it is all ok, but when I get like 50x50 square from the array (containing the whole desired screen content) it gets bugged.
Finally different states are always happening for the same angle.
I must add that I do translation myself - in order to get double precision. Here is the method for translations:
public void DrawSprite(Sprite toDraw)
{
// TODO: Think about converting constructor
Vector2D drawingPostion;
Vector2 drawingPos;
drawingPostion = toDraw.Position - Position;
drawingPos.X = (float) drawingPostion.X * GraphicsManager.Instance.UnitToPixels;
drawingPos.Y = (float) drawingPostion.Y * GraphicsManager.Instance.UnitToPixels;
spriteBatch.Draw(toDraw.Texture, drawingPos, toDraw.Source, toDraw.Color,
toDraw.Rotation, toDraw.Origin, toDraw.Scale, toDraw.Effects, toDraw.LayerDepth);
}
My ideas for the problem:
Fix the bug somehow (if it's possible)
Force XNA to sort first by z-index and then by drawing order.
Apply some z-indexes everywhere, where overlapping can occur (don't like this)
Abandon z-index (don't want that either)
As lukegravitt suggested, you should use SpriteSortMode.FrontToBack:
Sprites are sorted by depth in front-to-back order prior to drawing.
This procedure is recommended when drawing opaque sprites of varying
depths.
Reference MSDN.
So you can easily set the z-index with the last parameter of SpriteBatch.Draw:
float layerDepth
The depth of a layer. By default, 0 represents the front layer and 1
represents a back layer. Use SpriteSortMode if you want sprites to be
sorted during drawing.
Reference MSDN.
I've finally picked the option C), here is how it works in my code:
public void DrawSprite(Sprite toDraw)
{
// TODO: Think about converting constructor
Vector2D drawingPostion;
Vector2 drawingPos;
drawingPostion = toDraw.Position - Position;
drawingPos.X = (float) drawingPostion.X * GraphicsManager.Instance.UnitToPixels;
drawingPos.Y = (float) drawingPostion.Y * GraphicsManager.Instance.UnitToPixels;
// proceeding to new z-index
zsortingValue += 0.000001f;
spriteBatch.Draw(toDraw.Texture, drawingPos, toDraw.Source, toDraw.Color,
toDraw.Rotation, toDraw.Origin, toDraw.Scale, toDraw.Effects, toDraw.LayerDepth + zsortingValue);
}
where zsortingValue is zeroed whenever a frame begins. This way each sprite can have its own sorting value, which is being enhanced only.

How do I draw a TriangleStrip / Filling it in XNA?

I'm trying to wrap my head around:
http://msdn.microsoft.com/en-us/library/bb196409.aspx
And the reference isn't much to go on. It's short, vague and nothing that you can learn from.
I want to create a method that that takes a list of Triangle = (A class of 3 Vectors), and render it, and later be able to fill it with a color or a texture.
Can someone explain the above mentioned method? Because what I'm trying simply isn't working. I've tried adding one triangle. My understanding below, please correct me where I'm wrong.
Method when creating "One Triangle":
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>
(
PrimitiveType.TriangleStrip,
"array of 3 VertexPositionColor?",
0,
(3? 9?),
"I have no clue what to put here and why I should put it here?",
"What do I put here?",
"If 1 triangle, value should be = 1? 1 Triangle = 1 Primitive"
);
What do I need to make this work? Depending on how many Triangles I pass on to my methods, do I render and what values do change depending on how many Triangles there are?
...and if successful (hopefully sometime) how do I fill it?
Please, no vague short answers because the reference does that very very well.
One clarification to your way of thinking before we begin. In XNA - you draw a wireframe (outline) triangle, or a filled triangle or a textured triangle. There isn't anything lile "draw now" and "fill later". You can only draw something else on top of what's already in the framebuffer.
Also here is some background on what an indexed mesh is. This is the data fed into DrawUserIndexedPrimitives (vertices and triangles composed of indices into the sett of vertices).
Given that, here's how the draw call works
_effect.Texture = texture; // This sets the texture up so the
// shaders associated with this effect can access it
// The color in each vertex is modulated with the texture color
// and linearly interpolated across vertices
_effect.VertexColorEnabled = true;
foreach (var pass in _effect.CurrentTechnique.Passes)
{
pass.Apply(); // This sets up the shaders and their state
// TriangleList means that the indices are understood to be
// multiples of 3, where the 3 vertices pointed to are comprise
// one triangle
_device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
// The vertices. Note that there can be any number of vertices in here.
// What's important is the indices array (and the vertexOffset, primitivecount, vertexCount) that determine
// how many of the provided vertices will actually matter for this draw call
_vertices,
// The offset to the first vertex that the index 0 in the index array will refer to
// This is used to render a "part" of a bigger set of vertices, perhaps shared across
// different objects
0,
// The number of vertices to pick starting from vertexOffset. If the index array
// tried to index a vertex out of this range then the draw call will fail.
_vertices.Count,
// The indices (count = multiple of 3) that comprise separate triangle (because we said TriangleList -
// the rules are different depending on the primitive type)
_indices,
// Again, an offset inside the indices array so a part of a larger index array can be used
0,
// Number of indices. This HAS to be a multiple of 3 because we said we're rendering
// a list of triangles (TrangleList).
kvp.Value.Indices.Count / 3);
}
I hope that is clear. Do let me know if you have any specific questions about each of the parameters and/or concepts and I can edit this post to clarify those points.
Hope this helps!

Drawing Ball Flight using XNA

I am currently making a golf ball game using C# and XNA.
So far I have been able to make the ball fly, bounce, and roll, while displaying the position and velocity.
Now I want to be able to see the ball path (similar to images below), in order to check the whole ball movement.
http://www.golf-simulators.com/images/ms4.jpg
My code updates the ball position at a fixed time interval. I am thinking of:
1) using these position,
2) insert them to an array of VertexPositionColor[],
3) and draw them using GraphicsDevice.DrawUserPrimitives() method
but I have no luck so far, the VertexPositionColor is static array, while the amount of position data is always increasing.
I am thinking of using List, but the GraphicsDevice.DrawUserPrimitives() method refuse to take that as an input
protected override void Draw(GameTime gameTime)
{
trail_vertice = new VertexPositionColor;
trail_vertice.Position = Position;
trail_vertice.Color = Color.Black;
trail_amount += 1;
trailList.Add(trail_vertice);
basicEffect.CurrentTechnique.Passes[0].Apply();
graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, trailList, 0, trail_amount);
}
I do not need advanced effects like using particle engine. Just a single line is enough. Any suggestion?
The C# List<> class has a handy .ToArray() function on it that you can call each time you want to draw the primitives. Hope that helps!
graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, trailList.ToArray(), 0, trail_amount);
Instead of transforming the list to an array every frame, which seems to me very inefficient, you can calculate the estimated number of vertices you will need to display the trail, create an array of that size and fill it with more values each frame. (One of the argument you pass to DrawUserPrimitives is the number of primitives to draw from the array)
If you can't calculate this, you can also try setting a max length the trail can reach, so that when it reaches that length, it starts overriding the old values. This shouldn't matter much if the camera follows the ball around. If none of these solutions fit your needs, go ahead and use the ToArray function.

How To Make a Tetris Clone?

I am working on coding a Tetris clone in XNA C# and am unsure of the best way to approach the data structure side of the game on a high level.
I am totally fine with the collision detection, rotations, animation etc. What I need to know the best way to do the storing of "dropped blocks" - ie blocks that are no longer under tha player's control.
I think that each Tetromino block should be stored in its own class that consists of a 4x4 array so that the block can easily be rotated. The problem is then how to I store the tetromino's final position into the game grid by then cutting the tetromino up into individual blocks(for each cell) and then set the main game grid's corresponding positions to hold these same blocks, then disappearing the tetromino once it has reached its final position. Maybe there is some drawback to my method.
Should I create a 10x20 matrix for the main game grid which can then store? or should I use stacks or queues to somehow store the dropped blocks. Or maybe there is some better method/data structure to store things?
I am sure my way would work, but I am reaching out to see if anybody knows a better way or if my way is good enough?
P.S. Not homework, this will be a project for my portfolio. Thanks.
Once a block is immobile, there's nothing that distinguishes it from any other block that is now immobile. In that regard, I think it makes the most sense to store the entire grid as a matrix, where each square is either filled or not (along with the color of the block if it is).
I feel like the matrix has many advantages. It'll make collision detection simple (no having to compare with multiple objects, just locations on a matrix). Storing it as a matrix will also make it easier to determine when a full line has been created. On top of that, you don't have to worry about splicing an immobile Tetromino when a line disappears. And when one does, you can just shift the entire matrix down in one fell swoop.
This smells like homework, but my take on an object-oriented approach to Tetris would be to have each individual square be an object, and both "blocks" (tetrominos) and the grid itself would be collections of the same square objects.
Block objects manage the rotation and position of the falling squares, and the grid handles displaying them and detroying completed rows. Each block would have a colour or texture associated with it that would be provided by the original block object it came from, but otherwise squares at the base of the grid would have no other indication that they were ever part of the same original block.
To elaborate, when you create a new block object, it creates a set of 4 squares with the same colour/texture on the grid. The grid manages their display. So when the block hits the bottom, you just forget about the block, and the squares remain referenced by the grid.
Rotations and dropping are operations only a block need deal with, and only one its four squares (though it will need to be able to query the grid to make sure the rotation can fit).
Not making blocks actually look like autonomous blocks is - in my opinion - a big failing of many a Tetris clone. I put special effort into ensuring my clone always looked right, whether the block is still "in play" or dropped. This meant going slightly beyond the simple matrix data structure and coming up with something that supported the concept of "connection" between block parts.
I had a class called BlockGrid that is used as a base class for both a Block and the Board. BlockGrid has an abstract (pure virtual in C++) method called AreBlockPartsSameBlock that subclasses must override to determine whether two different block parts belong to the same block. For the implementation in Block, it simply returns true if there are block parts at both locations. For the implementation in Board, it returns true if both locations contain the same Block.
The BlockGrid class uses this information to "fill in" the details in the rendered blocks, so that they actually look like blocks.
Using arrays would be the easiest way to handle tetris. There is a direct correlation between what you see on screen and the structures used in memory. Using stack/queues would be an overkill and unnecessarily complicated.
You can have 2 copies of a falling block. One will be for display (Alpha) and the other one will be movement (Beta).
You will need a structure like
class FallingBlock
{
int pos_grid_x;
int pos_grid_y;
int blocks_alpha[4][4];
int blocks_beta[4][4];
function movedDown();
function rotate(int direction();
function checkCollision();
function revertToAlpha();
function copyToBeta()
};
The _beta array would be move or rotated and checked against the board for collisions. If there is a collision, revert it to _alpha, if not, copy _beta onto _alpha.
And if there is a collision on movedDown(), the block's life is over and the _alpha grid would have to copied onto the game board and the FallingBlock object deleted.
The board would of course have to be another structure like:
class Board
{
int gameBoard[10][20];
//some functions go here
}
I used int to represent a block, each value (like 1,2,3) representing a different texture or color (0 would mean an empty spot).
Once the block is part of the gameboard, it would only need a texture/color identifier to be displayed.
I actually just did this a few days ago except in WPF rather than XNA. Here's what I did:
Edit:
Seems like I define "Block" differently than other people. What I define as a Block is one of 4 cells that make up a Tetromino, and an actual Tetromino itself as a Piece.
Have a Block as a struct that had X, Y coordinates and Color. (I later added a bool IsSet to indicate whether it was in a floating piece or on the actual board, but that was just because I wanted to distinguish them visually)
As methods on Block, I had Left, Right, Down, and Rotate(Block center) which returned a new shifted Block. This allowed me to rotate or move any piece without knowing the shape or orientation of the piece.
I had a generic Piece object that had a List of all the blocks it contained and the index of the Block that was the center, which is used as the center of rotation.
I then made a PieceFactory that could produce all the different pieces, and with a Piece not needing to know what kind of piece it was, I could (and did) easily add variation of Pieces consisting of more or less than 4 Blocks without needing to create any new classes
The Board consisted of a Dictionary which was all the blocks that were currently on the board, as well as the dimensions of the board that was configurable. You can use a Matrix just as well probably, but with a Dictionary I only needed to iterate through Blocks without white spaces.
My Solution (design), with examples in Python as a good substitute for pseudo code.
Use a grid 20 x 10, that the tetrominoes fall down.
Tetrominoes are made up of blocks, which have attributes of coordinate (x,y) and colour.
So, for example, the T-shape tetrominoe looks like this...
. 4 5 6 7 8 .
.
19 # # #
20 #
.
Thus, the T-shape is a collection of blocks with the coords (5,19), (6,19), (7,19), (6,20).
Moving the shape is a matter of applying a simple transformation to all the coords in the group. e.g. to move the shape down add (0,1), left (-1,0) or right (1,0) to all coords in the collection that make the shape.
This also lets you use some simple trig to rotate the shape by 90-degrees. The rule is that when rotating 90-degrees relative to an origin, then (x,y) becomes equal to (-y,x).
Here is an example to explain it. Taking the T-shape from above, use the (6,19) as the centre block to rotate around. For simplicity, make this the first coordinate in the collection, so...
t_shape = [ [6,19], [5,19], [7,19], [6,20] ]
Then, here is a simple function to rotate that collection of coordinates by 90-degrees
def rotate( shape ):
X=0 # for selecting the X and Y coords
Y=1
# get the middle block
middle = shape[0]
# work out the coordinates of the other blocks relative to the
# middle block
rel = []
for coords in shape:
rel.append( [ coords[X]-middle[X], coords[Y]-middle[Y] ] )
# now rotate 90-degrees; x,y = -y, x
new_shape = []
for coords in rel:
new_shape.append( [ middle[X]-coords[Y], middle[Y]+coords[X] ] )
return new_shape
Now, if you apply this function to our collection of coordinate for the T-shape...
new_t_shape = rotate( t_shape )
new_t_shape
[[6, 19], [6, 18], [6, 20], [5, 19]]
Plot this out in the coordinate system and it looks like this...
. 4 5 6 7 8 .
.
18 #
19 # #
20 #
.
That was the hardest bit for me, hope this helps someone.
Keep in mind that a previous winner of the Obfuscated C Code Contest implemented a pretty good tetris game (for VT100 terminals on BSD unix) in fewer than 512 bytes of obfuscated C:
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
"stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI\
;cat HI","w");fprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}
http://www.ioccc.org/1989/tromp.hint
I'm by no means a Tetris expert, but as you described a 10x20 matrix seems like a natural choice to me.
It will make it very easy when the time comes to check if you have completed a line or not, and dealing with it. Simply iterating over the 2d-array looking at boolean values of each position to see if they add up to 10 block positions.
However, you'll have some manual clean up to do if there is a completed line. Having to shift everything down. All though it isn't that big of a deal when it comes down to it.
Using Simon Peverett logic, here is what I ended up with in c#
public class Tetromino
{
// Block is composed of a Point called Position and the color
public Block[] Blocks { get; protected internal set; }
// Constructors, etc.
// Rotate the tetromino by 90 degrees, clock-wise
public void Rotate()
{
Point middle = Blocks[0].Position;
List<Point> rel = new List<Point>();
foreach (Block b in Blocks)
rel.Add(new Point(b.Position.x - middle.x, b.Position.y - middle.y));
List<Block> shape = new List<Block>();
foreach (Point p in rel)
shape.Add(new Block(middle.x - p.y, middle.y + p.x));
Blocks = shape.ToArray();
}
public void Translate(Point p)
{
// Block Translation: Position+= p;
foreach (Block b in Blocks)
b.Translate(p);
}
}
Note: Using XNA, Point structure could be swapped for Vector2D
in my example (Java) - all figures have lists of blocks - which can be removed whenever needed. Also in my Board class I have a list of figures and a field variable figure - which is controlled by the user. When the figure is "landed" - it goes into the list of other figures, and a new figure is made controllable by the user.
A better explanation here: http://bordiani.wordpress.com/2014/10/20/tetris-in-java-part-i-overview/

Categories

Resources