I'm trying to learn how to implement physics in games, so I chose Farseer Physics. I'm trying to implement the falling round object till the obstacle(ground in my case). Here's my code:
using FarseerPhysics;
using FarseerPhysics.Collision.Shapes;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace TestFarseer
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
World world;
Texture2D buttonTexture, groundTexture;
Body buttonBody, groundBody;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
world = new World(new Vector2(0, 1f));
ConvertUnits.SetDisplayUnitToSimUnitRatio(102f);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
buttonTexture = Content.Load<Texture2D>("pause");
groundTexture = Content.Load<Texture2D>("Panel");
groundBody = BodyFactory.CreateRectangle(world, ConvertUnits.ToSimUnits(groundTexture.Width), ConvertUnits.ToSimUnits(groundTexture.Height), 1f);
groundBody.BodyType = BodyType.Static;
groundBody.Position = new Vector2(ConvertUnits.ToSimUnits(groundTexture.Width/2f), ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height-groundTexture.Height));
CircleShape buttonShape = new CircleShape(0.5f, 0.8f);
buttonBody = new Body(world);
buttonBody.Mass = 10f;
buttonBody.CreateFixture(buttonShape);
buttonBody.BodyType = BodyType.Dynamic;
buttonBody.Position = new Vector2(ConvertUnits.ToSimUnits(51f), ConvertUnits.ToSimUnits(51f));
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// TODO: Add your update logic here
world.Step((float)gameTime.ElapsedGameTime.TotalSeconds);
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(buttonTexture, ConvertUnits.ToDisplayUnits(buttonBody.Position), null, Color.White, buttonBody.Rotation, new Vector2(buttonTexture.Width/2, buttonTexture.Height/2), 1f, SpriteEffects.None, 0);
spriteBatch.Draw(groundTexture, ConvertUnits.ToDisplayUnits(groundBody.Position), null, Color.White, groundBody.Rotation, new Vector2(groundTexture.Width/2, groundTexture.Height/2), 1f, SpriteEffects.None, 0);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
And the collision occur, but I can't set ground to be at bottom. Here's the screenshot:
In Farseer the origin of a body is at the center, so :
groundBody.Position = new Vector2(ConvertUnits.ToSimUnits(groundTexture.Width/2f), ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height-(groundTexture.Height / 2)));`
Groover,
Related
I'm trying to draw a triangle primitive using Monogame, and enabling AA. However, I am getting this result- Jagged Triangle
I want a triangle with smooth Anti-Aliased edges.
Here is my code, where I've already enabled AA and set everything properly (maybe not though, as the lines are still extremely jagged)-
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Game1
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
VertexBuffer vertexBuffer;
BasicEffect basicEffect;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
graphics.PreferMultiSampling = true;
graphics.GraphicsProfile = GraphicsProfile.HiDef;
graphics.ApplyChanges();
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
basicEffect = new BasicEffect(GraphicsDevice);
VertexPositionColor[] vertices = new[]{new VertexPositionColor(new Vector3(160.0f, 200.0f, 0), Color.Red), new VertexPositionColor(new Vector3(200.0f, 140.0f, 0), Color.Green), new VertexPositionColor(new Vector3(250.0f, 200.0f, 0), Color.Blue) };
vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), 3, BufferUsage.WriteOnly);
vertexBuffer.SetData<VertexPositionColor>(vertices);
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
basicEffect.World = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1);
basicEffect.VertexColorEnabled = true;
GraphicsDevice.SetVertexBuffer(vertexBuffer);
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
}
base.Draw(gameTime);
}
}
}
`
The easiest solution is to render the primitive to a render target twice the size and then, render the target to the screen at half size.
The resize filtering will handle the anti-aliasing for you.
I wanted to ask how can I load Texture2D image from file (i don't want to use XNA's Content Pipeline) while preserving transparency of my image, because I want skinning in my game.
Code I have:
Initialising Texture using _cursor.Texture = _helper.LoadPicture("skin\\cursor.png");
Drawing Texture using spriteBatch.Draw(Texture, rectangle, Color.BlanchedAlmond);
public Texture2D LoadPicture(string filename) {
FileStream setStream = File.Open(filename, FileMode.Open);
StreamReader reader = new StreamReader(setStream);
Texture2D NewTexture = Texture2D.FromStream(_graphicsDevice, setStream);
setStream.Dispose();
return NewTexture;
}
Screenshot 1 (Result): http://prntscr.com/cxjzwu
Screenshot 2 (Expected): http://prntscr.com/cxk065
You can also handle it from the loading, so you can keep your BlendState to AlphaBlend.
Here is the function I use to load my textures from file :
private Texture2D PremultiplyTexture(String FilePath, GraphicsDevice device)
{
Texture2D texture;
FileStream titleStream = File.OpenRead(FilePath);
texture = Texture2D.FromStream(device, titleStream);
titleStream.Close();
Color[] buffer = new Color[texture.Width * texture.Height];
texture.GetData(buffer);
for (int i = 0; i < buffer.Length; i++)
buffer[i] = Color.FromNonPremultiplied(buffer[i].R, buffer[i].G, buffer[i].B, buffer[i].A);
texture.SetData(buffer);
return texture;
}
I've tried to recreate your problem, but it worked fine for me:
My code behind the scenes:
#region Usings
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion
namespace OpacityTest
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Game
{
private static Texture2D Tested;
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
using (var fileStream = new FileStream("test.png", FileMode.Open))
{
Tested = Texture2D.FromStream(GraphicsDevice, fileStream);
}
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// Important!!!
Tested.Dispose();
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
Exit();
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
spriteBatch.Draw(Tested, Vector2.Zero, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
I'm using this texture:
and put it into my build folder.
[Edit]
Now I see where your problem is - the colors alpha value is set to the maximum. I have tried some things and got to the conclusion, that you have to replace this line:
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
with that line:
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
After that I got your Content.Load result:
If you want to know more about "Premultiplied alpha" click me! :)
There is the second texture I've used for the cursor:
for my university, we have to start with learning Monogame/XNA on VisualStudio 2015. We have to make a Sprite which rotate in a circle and makes a soundeffect by clicking on it abd a soundeffect by missing it. But i can't figure it out how to make it.
Everything else just works fine (after hours of work).
I would be very thankful for any help.
Thank you in advance.
best regards
Alex.
PS: Sorry for my english :)
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Hausaufgabe_Uni_Logo
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager mGraphics;
SpriteBatch mSpriteBatch;
private Texture2D mBackground;
private Texture2D mUniLogo;
private Vector2 mPos = Vector2.Zero;
private SoundEffect mHit;
private SoundEffect mMiss;
private MouseState mPreviousMouseState;
private MouseState mCurrentMouseState;
private double mAngle;
private Vector2 mPosition = new Vector2(640, 512);
private float mX = 0;
private float mY = 0;
public Game1()
{
mGraphics = new GraphicsDeviceManager(this)
{
// Change the windows size into 1280x1024
PreferredBackBufferWidth = 1280,
PreferredBackBufferHeight = 1024
};
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// Set mouse visible
IsMouseVisible = true;
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
mSpriteBatch = new SpriteBatch(GraphicsDevice);
// Load sprites
mBackground = Content.Load<Texture2D>("Background");
mUniLogo = Content.Load<Texture2D>("Unilogo");
mHit = Content.Load<SoundEffect>("Logo_hit");
mMiss = Content.Load<SoundEffect>("Logo_miss");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
mPreviousMouseState = mCurrentMouseState;
mCurrentMouseState = Mouse.GetState();
if (mCurrentMouseState.LeftButton == ButtonState.Pressed && mPreviousMouseState.LeftButton != ButtonState.Pressed)
{
if (Mouse.GetState().Position.X >= mX && Mouse.GetState().Position.X <= mX + 300 &&
Mouse.GetState().Position.Y >= mY && Mouse.GetState().Position.Y <= mY + 300)
{
mHit.Play();
}
else if (new Rectangle(0,0,1280,1024).Contains(Mouse.GetState().X, Mouse.GetState().Y) == true)
{
mMiss.Play();
}
}
mAngle -= 0.01;
mX = (float)Math.Sin(mAngle) * 350;
mY = (float)Math.Cos(mAngle) * 250;
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
var viewport = mGraphics.GraphicsDevice.Viewport;
// Draw our sprites
mSpriteBatch.Begin();
mSpriteBatch.Draw(mBackground, new Rectangle(0,0,1280,1024), Color.White);
mSpriteBatch.Draw(mUniLogo, new Vector2(mX,mY), null, Color.White, 0, new Vector2(512, 512), 0.33f, SpriteEffects.None, 0);
mSpriteBatch.End();
base.Draw(gameTime);
}
}
}
Maybe try something like this? (NOTE: this is only a fragment for collision logic, not everything you might need.)
Rectangle spriteRect;
MouseState ms, oldms;
protected override void Initialize()
{
// Set mouse visible
IsMouseVisible = true;
spriteRect= new Rectangle(/*foo*/);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
mSpriteBatch = new SpriteBatch(GraphicsDevice);
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
ms=Mouse.GetState();
Rectangle mouseRect= new Rectangle((int)ms.X,(int)ms.Y,1,1);
if(ms.LeftButton==ButtonState.Pressed && oldms.LeftButton!=ButtonState.Pressed){
if(mouseRect.Intersects(spriteRect))
{
//play a sound
}
else{
//play a different sound
}
}
base.Update(gameTime);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace Project
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D myTexture;
Rectangle myRectangle;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
Texture myTexture = Content.Load<Texture2D>("character");
myRectangle = new Rectangle(10, 100, 30, 50);
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(myTexture,myRectangle,Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
this is my code but this returns a error on debug which will highlight
spriteBatch.Draw(myTexture,myRectangle,Color.White);
and tell
ArgumentNullExcerption was unhandled
This method does not accept null for this parameter.
Parameter name: texture
what is the error?
In LoadContent you create a new variable and assign the texture to it and myTexture stays null.
replace
Texture myTexture = Content.Load<Texture2D>("character");
with
myTexture = Content.Load<Texture2D>("character");
I am creating a simple XNA game in which you can move the block around. But the block is not moving on keypress I don't why.
Here's my overall Code:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D ball;
Texture2D bar;
Vector2 ballPos;
Vector2 barPos;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Extend battery life under lock.
InactiveSleepTime = TimeSpan.FromSeconds(1);
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
ballPos = new Vector2(10, 10);
barPos=new Vector2(10,GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - 20);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
ball = Content.Load<Texture2D>("ball");
bar = Content.Load<Texture2D>("bar");
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
UpdateBarLocation();
// TODO: Add your update logic here
base.Update(gameTime);
}
private void UpdateBarLocation()
{
KeyboardState newState = Keyboard.GetState();
if (newState.IsKeyDown(Keys.Right) && (barPos.Y < GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height))
barPos.Y = barPos.Y + 5;
else if (newState.IsKeyDown(Keys.Left) && (barPos.Y > 2))
barPos.Y = barPos.Y - 5;
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(ball,ballPos, Color.White);
spriteBatch.Draw(bar, barPos, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
You can see that in the updateBarLocation function i am trying to move the bar but it is not working.
What is the resolution of screen?
This is line is ambiguous
barPos=new Vector2(10,GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - 20);
First parameter is x axis and second is y axis.
So Width is usually dealt in x-axis.
Are you sure what you are assigning is alright?
If yes then where on the screen is bar located initially?
But the block is not moving on keypress I don't why.
you are not even updating the Block's position