Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

C# and .NET Tips and Tricks

Quests in programming in .NET

Παρουσίαση με Ετικέτες

Όλες οι Ετικέτε... » XNA   (RSS)
Λυπούμαστε, αλλά υπάρχουν άλλα διαθέσιμες Ετικέτες για να φιλτράρετε με αυτές.
XNA and WP7–Simple Demos to get you started!

Below you can find a series of simple demos that can give you a nice insight on the XNA’s power for WP7. All of them are original. Feel free to use them in your code as you wish. There is also a PowerPoint presentation about those demos but unfortunately it is only in Greek. So let the games begin!

 

The basics

Initializes the game and draws a simple image on the display

Sprite rotation and movement, Frame rate calculation, writing strings on the display,

Same as Demo2 but now Frame Rate calculator and bouncing sprite are implemented as game components leading to a more reusable and readable code. Now we can add more bouncing balls in an instant! Parameters are passed to game components through the use of game services

Multi-touch. Understanding where are the user’s fingers and what they do. A line is drawn and follows each finger that touches the display. The information is passed through game services to the components.

Gestures. Extending the previous demo to accelerate the ball through flicking of the display.

Accelerometer. Using the device’s accelerometer to find out device orientation and calculate g.

Saving state, using the windows phone input,sending SMS and taking snapshots from the phone’s camera from within your game!

Basic 3D drawing with axis and a pyramid with different colors.

Loading a model from a 3D modeling tool. Moving the camera with gestures.

Textures and lighting in the previous models!

 

And some more complete demos.

A simple spaceship constantly shoots laser beams to its enemy.

Creates a terrain based on a heightmap provided by a color coded bmp. You can navigate in the terrain using the drawn HUD and its implementation!

Using the Farseer physics engine to make the world bounce. Demo is the one from this linkthat I totally recommend for you to read.

 

Custom collision detection

If you want to know when two objects of your 2D world collide check out the following link.

Also check this series for a more gentle introduction to XNA.

 

The complete presentation for all of the above (in Greek)

Part of it will be presented in Hackathon 2012 for WP7.5

 

An of course the App Hub main game development page.

Finally read about the exciting new feature of integrating Silverlight and XNA in a single application .

Posted: Κυριακή, 12 Φεβρουαρίου 2012 6:16 μμ από iwannis | 2 σχόλια
Δημοσίευση στην κατηγορία:
XNA for Windows Phone 7 and Physics

In this post, we will see how easy it is to create an XNA world for Windows Phone 7 that obeys the laws of physics. To our quest, our weapon will be the Farseerphysics engine. You will be amazed when you realize how interesting a simple circle on the phone’s display becomes when you add some physics to its world! So let our quest begin…

Download the zip file from the project’s site. Unzip its contents and locate the folder containing the sources of the Farseer engine (at the time of this writing the folder is named “Farseer Physics Engine 3.2 XNA”).

Open Visual Studio and create a new project of “Windows Phone Game'” type (important note: if you are a newbie in XNA game development you are strongly encouraged to follow thisseries of blog posts and also download the developer tools from here).

The game we will be making will be as follows: The user sees a sprite on the screen and it gives momentum to the sprite (yellow ball) by applying a gesture to the phones display. The sprite should be bouncing at randomly placed obstacles on the display and it should hit the randomly placed silver balls (ouaou that’s interesting!)

 

SpaceGame

 

In an XNA Game for WP7 your canvas is 800x480 pixels size. Therefore we have created a background image in Photoshop of this size. The sprites that will be used in our game are the following:

 

Sprites

 

And now it is time to get started. When you have created your “Windows Phone Game” project, Visual Studio has created an extra project where you will add your sprites. We add all the aforementioned images (sprites) there following the well known “Add Item” procedure:

image

 

Now go to your solution’s folder and copy the Farseer project you have located before along with its containing folder to your solution folder. Right-click on your solution and select “Add/Existing Project”. Select the .csproj file for WP7 of the Farseer physics engine located in the folder you ‘ve just copied. Finally add a reference at your XNA game project to the engine (if you feel lost download the project at the end of this post and you will see the final state of the folders/projects). If you did everything correctly the solution will compile successfully. And this is all the plumbing you have to do. Now, let us do some physicz!

 

First we create the definitions of our sprites along with some lists of the positions of the obstacles and balls:

 

private Texture2D _background;
private Texture2D _myBall;
private Texture2D _floor;
private Texture2D _otherBall;
private Texture2D _obstacle;

private List<Vector2> _otherBallPositions;
private List<Vector2> _obstaclePositions;

private Random _r;

 

The definition of the random number generator will be used in the creation of the scene. In the LoadContent() method we create out Textures and select their positions on the display (note the random creation of a number of obstacles and balls and their positions):

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    
    _background = Content.Load<Texture2D>("Background");
    _floor = Content.Load<Texture2D>("Floor");
    _myBall = Content.Load<Texture2D>("MyBall");
    _obstacle = Content.Load<Texture2D>("Obstacle");
    _otherBall = Content.Load<Texture2D>("OtherBall");

    _obstaclePositions = new List<Vector2>();
    for (int i = 0; i < _r.Next(1, 6); i++)
        _obstaclePositions.Add(new Vector2(_r.Next(100, 700), _r.Next(100, 400)));

    _otherBallPositions = new List<Vector2>();
    for (int i = 0; i < _r.Next(1, 6); i++)
        _otherBallPositions.Add(new Vector2(_r.Next(100, 700), _r.Next(100, 400)));

}

Initially we will draw everything on the display in the Draw() method as follows:

 

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.Draw(_background, new Vector2(0, 0), Color.White);
    spriteBatch.Draw(_floor, new Vector2(0, 459), Color.White);
    spriteBatch.Draw(_myBall, new Vector2(40, 432), Color.White);
    for (int i = 0; i < _obstaclePositions.Count; i++)
        spriteBatch.Draw(_obstacle, _obstaclePositionsIdea, Color.White);
    for (int i = 0; i < _otherBallPositions.Count; i++)
        spriteBatch.Draw(_otherBall, _otherBallPositionsIdea, Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
}

 

This will generate a nice scene but everything will be static. Here is where we apply out physics engine to bring everything to life. Define a World object and create it in the Initialize method:

 

private World _world;

protected override void Initialize()
{
    _r = new Random();
    _world = new World(new Vector2(0,9.81F));
    base.Initialize();
}

 

The parameter is the gravity which we set it as a vector perpendicular to our x-axis (as is in real life). Now for every sprite in your world  you need to define its Body (mass, physical properties) and its Shape (its geometry). In the Farseer physics world you have to define the two and then connect them (to represent a single object) with a Fixture, actually saying that a body with mass X will be represented as a rectangle (for example) with Y,Z dimensions. Since this may be too much code to write, you may use a factory to do the job for you. For example for the floor (a rectangular body at the bottom of our game scene) we define:

In the LoadContent() method we create the Fixture for the floor which automatically defines a body of mass with density 1 and a rectangular shape of size the same as the floor’s texture:

 

private Fixture _floorFixture;
protected override void LoadContent()
{
    (…)
    _floor = Content.Load<Texture2D>("Floor");
    (…)
    _floorFixture=FixtureFactory.CreateRectangle(_world,_floor.Width,_floor.Height,1);
    _floorFixture.Body.BodyType = BodyType.Static; 
    _floorFixture.Body.Position=new Vector2(0, 459);

    (…)
}

 

Note that there is no connection with the texture, at least in code. The only thing we use the texture for is when we draw it on the position of the body. In the update method, we tell our world to process the position of the bodies (the Step method gets a parameter defining how much time has passed since the last step for the world) and then in the draw we use the result to draw the floor. The time that has passed is the actual-real time:

 

protected override void Update(GameTime gameTime)
{
    (…)
    _world.Step(gameTime.ElapsedGameTime.TotalSeconds);
    base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
    (…)
    spriteBatch.Draw(_floor, _floorFixture.Body.Position, Color.White);
    (…)
    base.Draw(gameTime);
}

 

Here is the first tricky part. If you use the aforementioned placement, the position of the floor texture will not correspond to the position of the floor body. This is because FarSeer considers the local shape’s origin point (0,0) to be at the center of the rectangle while XNA considers the same point (0,0) to be at the top left cornet of the rectangle. This is illustrated in the following figure:

image

Due to this, the “FarSeer world” and the “Visible world” have different opinions on where the body is located since the position of a body/texture defines the position of its local origin:

image

To compensate for this you need to do two things. First, place the floor to location (400,469), which will place the body in the correct position in the FarSeer world (left) and then change the local origin when drawing the texture from (0,0) to (400,10) (right) which will also position correctly the texture in the “Visible world”:

image

 

This in code is translated as follows:

 

    (…)
    // The following is in the LoadContent() method!
    _floorFixture=FixtureFactory.CreateRectangle(_world,_floor.Width,_floor.Height,100);
    _floorFixture.Body.BodyType = BodyType.Static;
    _floorFixture.Body.Position=new Vector2(400, 469); //THIS IS DIFFERENT NOW
    (…)
    // The following is in the Draw() method! 
    spriteBatch.Draw(_floor, _floorFixture.Body.Position, null, Color.White, _floorFixture.Body.Rotation, 
                      new Vector2(_floor.Width / 2,_floor.Height/2), 1, SpriteEffects.None, 1);
        

 

When you compile and run the program now nothing seems to have changed but believe me the physics world is there. To prove this just change the definition of Body.BodyType from BodyType.Static to BodyType.Dynamic and the floor will just fall from its position obeying the Newtonian rule of gravity! Let’s now follow the same approach for the other sprites in our world (the principle is exactly the same so below is the complete listing):

 

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    
    _background = Content.Load<Texture2D>("Background");
    _floor = Content.Load<Texture2D>("Floor");
    _myBall = Content.Load<Texture2D>("MyBall");
    _obstacle = Content.Load<Texture2D>("Obstacle");
    _otherBall = Content.Load<Texture2D>("OtherBall");

    _floorFixture=FixtureFactory.CreateRectangle(_world,_floor.Width,_floor.Height,1);
    _floorFixture.Body.BodyType = BodyType.Static;
    _floorFixture.Restitution = 0.7f;
    _floorFixture.Body.Position=new Vector2(400, 469);

    _otherBallFixtures = new List<Fixture>();
    for (int i = 0; i < _r.Next(1, 16); i++)
    {
        Fixture Temp = FixtureFactory.CreateCircle(_world, _otherBall.Height / 2, 1);
        Temp.Body.Position = new Vector2(_r.Next(100, 700), _r.Next(100, 400));
        Temp.Body.IsStatic = false;
        Temp.Restitution = 0.7f;
        _otherBallFixtures.Add(Temp);
    } 

    _obstacleFixtures = new List<Fixture>();
    for (int i = 0; i < _r.Next(1, 6); i++)
    {
        Fixture Temp = FixtureFactory.CreateRectangle(_world,_obstacle.Width,_obstacle.Height,100);
        Temp.Body.BodyType = BodyType.Static;
        Temp.Body.Position=new Vector2(_r.Next(100, 700), _r.Next(100, 400));
        Temp.Restitution = 0.7f;
        _obstacleFixtures.Add(Temp);
    } 
}

 

And the Draw() is as follows:

 

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
        spriteBatch.Draw(_background, Vector2.Zero, Color.White);
        spriteBatch.Draw(_floor, _floorFixture.Body.Position, null, Color.White, 
                         _floorFixture.Body.Rotation, new Vector2(_floor.Width / 2,_floor.Height/2), 
                          1, SpriteEffects.None, 1);
        spriteBatch.Draw(_myBall, new Vector2(40, 432), Color.White);
        for (int i = 0; i < _obstacleFixtures.Count; i++)
            spriteBatch.Draw(_obstacle, _obstacleFixturesIdea.Body.Position, null, Color.White, 
                             _obstacleFixturesIdea.Body.Rotation, 
                             new Vector2(_obstacle.Width / 2, _obstacle.Height / 2), 1, 
                             SpriteEffects.None, 1);
        for (int i = 0; i < _otherBallFixtures.Count; i++)
            spriteBatch.Draw(_otherBall, _otherBallFixturesIdea.Body.Position, null, Color.White, 
                             _otherBallFixturesIdea.Body.Rotation, 
                             new Vector2(_otherBall.Width / 2, _otherBall.Height / 2), 1, 
                             SpriteEffects.None, 1);
    spriteBatch.End();
    base.Draw(gameTime);
}

 

Note that we have also defined the Restitution coefficient for our bodies which defines how much of the initial velocity is lost when the ball will bounce on the obstacle (1 for example will have the ball bouncing endlessly like being made from a very elastic rubber, while a 0 will make the ball behave like it is made from iron).

Now when you run the program all the balls will fall to the floor and will also bounce. But the first thing you will notice is that they are too slow. You can go experimenting by raising the gravity value or increasing the time in the Step() method but those approaches are all trial and error and you will not get to far by this. The actual problem is the fact that you are playing with very large numbers in the FarSeer engine. While gravity and mass are defined in Kg and m/sec2 without any issues, you are defining shapes like the floor that are 800 meters long and 20 meters tall since the pixel to meter ratio is 1:1. This causes the engine to overflow. To get more realistic results you need to define the pixels/meter ratio to something different. In our case, let’s say that 1 pixel is 50 meters. This means that our view will be 16m wide and 9,6m tall (800x480 pixels) which is fine. Define a new private field as follows:

 

private float _pixelsPerMeter = 50;

Now when you define a shape you need you divide by this. For example:

 

_floorFixture = FixtureFactory.CreateRectangle(_world, _floor.Width / _pixelsPerMeter, 
                                                       _floor.Height / _pixelsPerMeter, 1f);
_floorFixture.Body.BodyType = BodyType.Static;
_floorFixture.Restitution = 0.7f;
_floorFixture.Body.Position = new Vector2(400 / _pixelsPerMeter, 469 / _pixelsPerMeter);

 

That is you are translating everything from pixels to meters for the FarSeer world. When you draw you need to do the opposite as follows:

 

spriteBatch.Draw(_floor, _floorFixture.Body.Position * _pixelsPerMeter, null, Color.White, 
                         _floorFixture.Body.Rotation * _pixelsPerMeter, 
                          new Vector2(_floor.Width / 2, _floor.Height / 2) , 1, SpriteEffects.None, 1);

Now when you compile and run everything will make more sense. It takes approx. 1 sec for the ball to fall from the top to the bottom (4km) at 9.81 g. Well let’s see:

image

Well as you can see you have a perfectly realistic world that obeys the laws of physics without experimenting. If you change your ratio to 25 your world is bigger, your balls are higher and it will take them twice the time to reach the bottom. The only thing left to do is apply some force to the yellow ball by the use of gestures.

First we define the yellow ball as a body too, like we did for the other sprites and then we add in the Update() method the following:

 

while (TouchPanel.IsGestureAvailable)
{
    GestureSample gesture = TouchPanel.ReadGesture();
    if (gesture.GestureType == GestureType.Flick)
        _myBallFixture.Body.ApplyForce(Vector2.Divide(gesture.Delta, 2.0f));
}

 

This will constantly check for gestures and apply them as a force to the ball. The last thing to be done is to enable this type of gestures at the initialization method as follows:

 

TouchPanel.EnabledGestures = GestureType.Flick;

 

And this concludes our introduction to the physics engine. The project can be downloaded  

.

Posted: Τρίτη, 8 Φεβρουαρίου 2011 10:23 μμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA 2D Basic Collision Detection with Rotation (Scene2Sprite)
In the previous post we have worked with collision detection between roated sprites. In this post we will deal with the situtation where we want to detect whether a specific sprite that can be rotated is in a specific area in the scene (eg a car is on the road in the scene). Suppose that you have the following scenario: A car is driven by the user around the scene. When the car hits the boundaries of the road, the car should lose all of its speed. The user uses the UP/DOWN keys to acelerate/break and LEFT/RIGHT

Διαβάστε περισσότερα »

Posted: Τρίτη, 16 Φεβρουαρίου 2010 7:54 πμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA 2D Basic Collision Detection with Rotation (Sprite2Sprite)
(If you are in a hurry and do not want to no how it's done but just do it, dowload the project and extract the CollisionDetection2D.cs file to include in your project that contains the collision detection methods) In my previous post ,we have seen several collision detection techniques that can be used in 2D games in XNA. In that post, we have left out the changes that affect our code when textures can also be rotated . In this post, I intend to fill this gap by picking up from exactly where we stopped and adding

Διαβάστε περισσότερα »

Posted: Τετάρτη, 10 Φεβρουαρίου 2010 7:26 πμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA 2D Basic Collision Detection
In this post we will explore some basic techniques in XNA for 2D collision detection. Our goal is to provide a solution to the two following scenarios: Detect the collision of two sprites Detect the collision of a sprite with specific areas in the scenery (eg detect when a car hits the boundaries of the road when viewed from the top) A sprite in XNA is usually realized by a DrawableGameComponent class (see previous posts 1 , 2 , 3 ). Therefore sprite collision detection is merely a DrawableGameComponent collision

Διαβάστε περισσότερα »

Posted: Κυριακή, 24 Ιανουαρίου 2010 9:17 μμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA Game Development (Scenes and Game Services)
In the previous post , we have talked about decentralizing our XNA application by taking advantage of the GameComponent and DrawableGameComponent classes. In this post, we will explore two things: The way to decouple the GameComponents' interfaces from the main game logic by using "Game Services". The way to create "Scenes". Scenes in games are those displays that occur before the game starts with th game menu, the help screen, etc etc. Let's start with Game Services . In the project of the

Διαβάστε περισσότερα »

Posted: Παρασκευή, 15 Ιανουαρίου 2010 7:30 πμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA Game Development (Decentralize)
In the previous post , we have talked about drawing and moving 2D textures on the XNA window. In this post, we will explore the basic architecture that XNA uses in order to separate the game logic from the sprite logic. So prior to reading this post, it is suggested to go through the previous one. The main code smell there, was the fact that we had to put all the game logic for moving the Ivan sprite to the Update and Draw methods of the game loop. Imagine how messed up those too methods would look if we placed

Διαβάστε περισσότερα »

Posted: Τετάρτη, 23 Δεκεμβρίου 2009 7:31 πμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία:
XNA Game Development (First Steps)
Welcome to a short introduction in game Development using the XNA Framework! Let's start with the basics by examining how different is Windows programming to XNA Game programming. As we know, windows programming is "event driven". This means that our logic resides in event handlers that get called when a resource or a Control needs to tell us that something happened. So our program is nothing more than a loop that awaits for events to happen and a bunch of event handlers that respond to those events.

Διαβάστε περισσότερα »

Posted: Σάββατο, 19 Δεκεμβρίου 2009 1:32 μμ από iwannis | 0 σχόλια
Δημοσίευση στην κατηγορία: