Click here to Skip to main content
15,893,161 members
Articles / Mobile Apps

Windows Phone Labyrinth

Rate me:
Please Sign up or sign in to vote.
4.95/5 (53 votes)
31 Jan 2012CPOL10 min read 131.1K   53.8K   115  
A Windows Phone application using accelerometer emulator and Farseer physics engine
using System.Collections.Generic;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FarseerPhysics.SamplesFramework;

namespace Labyrinth
{
    public enum ObjectType
    {
        Circle,
        Rectangle,
        Gear,
        Star
    }

    public class Objects
    {
        private List<Body> _bodies;
        private Category _collidesWith;
        private Category _collisionCategories;
        private Sprite _object;
        private PhysicsGameScreen _screen;

        public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, Vector2 endPosition, int count,
                       float radius, ObjectType type)
        {
            CreateObjects(world, screen, ref startPosition, ref endPosition, count, radius, type, false);
        }

        public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, Vector2 endPosition, int count,
               float radius, ObjectType type, bool isStatic)
        {
            CreateObjects(world, screen, ref startPosition, ref endPosition, count, radius, type, isStatic);
        }

        public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, float radius, ObjectType type, bool isStatic)
        {
            CreateObject(world, screen, ref startPosition, radius, type, isStatic);
        }

        private void CreateObjects(World world, PhysicsGameScreen screen, ref Vector2 startPosition, ref Vector2 endPosition, int count, float radius, ObjectType type, bool isStatic)
        {
            _bodies = new List<Body>(count);
            CollidesWith = Category.All;
            CollisionCategories = Category.All;

            for (int i = 0; i < count; ++i)
            {
                switch (type)
                {
                    case ObjectType.Circle:
                        _bodies.Add(BodyFactory.CreateCircle(world, radius, 1f));
                        break;
                    case ObjectType.Rectangle:
                        _bodies.Add(BodyFactory.CreateRectangle(world, radius, radius, 1f));
                        break;
                    case ObjectType.Star:
                        _bodies.Add(BodyFactory.CreateGear(world, radius, 10, 0f, 1f, 1f));
                        break;
                    case ObjectType.Gear:
                        _bodies.Add(BodyFactory.CreateGear(world, radius, 10, 100f, 1f, 1f));
                        break;
                }
            }

            for (int i = 0; i < _bodies.Count; ++i)
            {
                Body body = _bodies[i];
                body.BodyType = BodyType.Dynamic;
                body.Position = Vector2.Lerp(startPosition, endPosition, i / (float)(count - 1));
                body.Restitution = .7f;
                body.Friction = .2f;
                body.CollisionCategories = CollisionCategories;
                body.CollidesWith = CollidesWith;
                body.IsStatic = isStatic;
            }

            _screen = screen;

            //GFX
            AssetCreator creator = _screen.ScreenManager.Assets;
            switch (type)
            {
                case ObjectType.Circle:
                    _object = new Sprite(creator.CircleTexture(radius, MaterialType.Dots, Color.DarkRed, 0.8f));
                    break;
                case ObjectType.Rectangle:
                    _object =
                        new Sprite(creator.TextureFromVertices(PolygonTools.CreateRectangle(radius / 2f, radius / 2f),
                                                                MaterialType.Dots, Color.Blue, 0.8f));
                    break;
                case ObjectType.Star:
                    _object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 0f, 1f),
                                                                      MaterialType.Dots, Color.Yellow, 0.8f));
                    break;
                case ObjectType.Gear:
                    _object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 100f, 1f),
                                                                      MaterialType.Dots, Color.DarkGreen, 0.8f));
                    break;
            }
        }

        private void CreateObject(World world, PhysicsGameScreen screen, ref Vector2 startPosition, float radius, ObjectType type, bool isStatic)
        {
            _bodies = new List<Body>(1);
            CollidesWith = Category.All;
            CollisionCategories = Category.All;

            switch (type)
            {
                case ObjectType.Circle:
                    _bodies.Add(BodyFactory.CreateCircle(world, radius, 1f));
                    break;
                case ObjectType.Rectangle:
                    _bodies.Add(BodyFactory.CreateRectangle(world, radius, radius, 1f));
                    break;
                case ObjectType.Star:
                    _bodies.Add(BodyFactory.CreateGear(world, radius, 10, 0f, 1f, 1f));
                    break;
                case ObjectType.Gear:
                    _bodies.Add(BodyFactory.CreateGear(world, radius, 10, 100f, 1f, 1f));
                    break;
            }

            Body body = _bodies[0];
            body.BodyType = BodyType.Dynamic;
            body.Position = startPosition;
            body.Restitution = .2f;
            body.Friction = .2f;
            body.CollisionCategories = CollisionCategories;
            body.CollidesWith = CollidesWith;
            body.IsStatic = isStatic;

            _screen = screen;

            //GFX
            AssetCreator creator = _screen.ScreenManager.Assets;
            switch (type)
            {
                case ObjectType.Circle:
                    _object = new Sprite(creator.CircleTexture(radius, MaterialType.Dots, Color.DarkRed, 0.8f));
                    break;
                case ObjectType.Rectangle:
                    _object =
                        new Sprite(creator.TextureFromVertices(PolygonTools.CreateRectangle(radius / 2f, radius / 2f),
                                                                MaterialType.Dots, Color.Blue, 0.8f));
                    break;
                case ObjectType.Star:
                    _object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 0f, 1f),
                                                                      MaterialType.Dots, Color.Yellow, 0.8f));
                    break;
                case ObjectType.Gear:
                    _object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 100f, 1f),
                                                                      MaterialType.Dots, Color.DarkGreen, 0.8f));
                    break;
            }
        }

        public Category CollisionCategories
        {
            get { return _collisionCategories; }
            set
            {
                _collisionCategories = value;

                foreach (Body body in _bodies)
                {
                    body.CollisionCategories = _collisionCategories;
                }
            }
        }

        public Category CollidesWith
        {
            get { return _collidesWith; }
            set
            {
                _collidesWith = value;

                foreach (Body body in _bodies)
                {
                    body.CollidesWith = _collidesWith;
                }
            }
        }

        public void Draw()
        {
            Draw(_object.Texture, null, new Vector2(0,0));
        }

        public void Draw(Texture2D texture, Texture2D shadowTexture, Vector2 shadowOffset)
        {
            SpriteBatch batch = _screen.ScreenManager.SpriteBatch;

            for (int i = 0; i < _bodies.Count; ++i)
            {
                if (shadowTexture != null)
                {
                    batch.Draw(shadowTexture, ConvertUnits.ToDisplayUnits(_bodies[i].Position) - shadowOffset, null,
                        Color.White, 0f, _object.Origin, 1f, SpriteEffects.None, 0f);
                }

                batch.Draw(texture, ConvertUnits.ToDisplayUnits(_bodies[i].Position), null,
                            Color.White, 0f, _object.Origin, 1f, SpriteEffects.None, 0f);
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Instructor / Trainer Alura Cursos Online
Brazil Brazil

Comments and Discussions