I am trying to display my Model that I have created in Blender now I have export it into fbx and when I render it in to the XNA it was not working fine then I download a model from internet to confirm my model is correct or not but when I download a model from internet it was still not working fine too.
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Model myModel;
Vector3 modelPosition = Vector3.Zero,
cameraPosition = new Vector3(0.0f, 50.0f, 5000.0f);
private float GetMaxMeshRadius(Model m)
{
float radius = 0.0f;
foreach (ModelMesh mm in m.Meshes)
{
if (mm.BoundingSphere.Radius > radius)
{
radius = mm.BoundingSphere.Radius;
}
}
return radius;
}
private void DrawModelViaMeshes(Model m, float radius, Matrix proj, Matrix view)
{
Matrix world = Matrix.CreateScale(1.0f / radius);
foreach (ModelMesh mm in myModel.Meshes)
{
foreach (Effect e in mm.Effects)
{
IEffectMatrices iem = e as IEffectMatrices;
if (iem != null)
{
iem.World = GetParentTransform(m, mm.ParentBone) * world;
iem.Projection = proj;
iem.View = view;
}
}
mm.Draw();
}
}
private Matrix GetParentTransform(Model m, ModelBone mb)
{
return (mb == m.Root)?mb.Transform : mb.Transform*GetParentTransform(m,mb.Parent);
}
private void DrawModel(Model m, float radius, Matrix proj, Matrix view)
{
m.Draw(Matrix.CreateScale(1.0f / radius), view, proj);
}
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);
myModel = Content.Load<Model>("Models\\lumberJack");
// 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.CornflowerBlue);
// TODO: Add your drawing code here
float radius = GetMaxMeshRadius(myModel);
Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio,
1.0f, 100.0f);
Matrix view = Matrix.CreateLookAt(new Vector3(2, 3, 4),
Vector3.Zero, Vector3.Up);
////I have tried 3 different mathods to draw my model but still no one is
working non display my Model on screen
DrawModel(myModel, radius, proj, view);
DrawModelViaMeshes(myModel, radius, proj, view);
DrawModelViaVertexBuffer(myModel,radius,proj,view);
base.Draw(gameTime);
}
private void DrawModelViaVertexBuffer(Model m, float radius, Matrix proj, Matrix view)
{
Matrix world = Matrix.CreateScale(1.0f /radius);
foreach (ModelMesh mm in m.Meshes)
{
foreach(ModelMeshPart mmp in mm.MeshParts)
{
IEffectMatrices iem = mmp.Effect as IEffectMatrices;
if ((mmp.Effect != null) && (iem != null))
{
iem.World = GetParentTransform(m, mm.ParentBone) * world;
iem.Projection = proj;
iem.View = view;
GraphicsDevice.SetVertexBuffer(mmp.VertexBuffer,mmp.VertexOffset);
GraphicsDevice.Indices = mmp.IndexBuffer;
foreach (EffectPass ep in mmp.Effect.CurrentTechnique.Passes)
{
ep.Apply();
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
0, 0, mmp.NumVertices, mmp.StartIndex, mmp.PrimitiveCount);
}
}
}
mm.Draw();
}
}
}
}
Related
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);
}
}
I've seen questions similar to what I'm asking, but they don't quite give me the answer I'm looking for. I want 5 instances of my sprites to show up on screen and spawn in different locations. For some reason though instead of 5 instances, each "instance" of the sprite increases the values of the one sprite that does appear on screen.
Sprite.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Lab05_2__Aaron_Benjamin_
{
class Sprite
{
Texture2D mSpriteTexture;
public Vector2 Position;
Color mSpriteColor;
public Rectangle Size;
public string AssetName;
private float mScale = 1.0f;
public float Scale
{
get { return mScale; }
set
{
mScale = value;
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
}
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
//theSpriteBatch.Draw(mSpriteTexture, Position);
}
}
}
Enemy.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Lab05_2__Aaron_Benjamin_
{
class Enemy : Sprite
{
const string ENEMY_ASSETNAME = "gear";
Random Rand = new Random();
int startPos_X;
int startPos_Y;
public void LoadContent(ContentManager theContentManager)
{
Position = new Vector2(startPos_X = Rand.Next(0 , 1000), startPos_Y = Rand.Next(0, 1000)); //= Rand.Next(0, 100),Position.Y = Rand.Next(0,100));
base.LoadContent(theContentManager, ENEMY_ASSETNAME);
}
public void Update(GameTime gameTime)
{
MouseState cState = Mouse.GetState();
if (Position.X > cState.X)
{
Position.X += 1;
}
if (Position.X < cState.X)
{
Position.X -= 1;
}
if (Position.Y < cState.Y)
{
Position.Y -= 1;
}
if (Position.Y > cState.Y)
{
Position.Y += 1;
}
base.Update(gameTime);
}
}
}
Game1.cs
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Lab05_2__Aaron_Benjamin_
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Enemy> enemies = new List<Enemy>();
private void CreateEnemy()
{
Enemy gear = new Enemy();
Random rand = new Random();
//gear = new Enemy();
//gear.Position.X = rand.Next(0, 1000);
//gear.Position.Y = rand.Next(0, 1000);
Console.WriteLine(gear.Position.Y);
enemies.Add(gear);
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
/// <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);
// TODO: use this.Content to load your game content here
for (int i = 0; i < 5; i++)
{
CreateEnemy();
}
foreach (var cog in enemies)
{
cog.LoadContent(this.Content);
}
}
/// <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();
// TODO: Add your update logic here
foreach (var cog in enemies)
{
if (cog.Position.X > Window.ClientBounds.Width - 50)
cog.Position.X = Window.ClientBounds.Width - 50;
if (cog.Position.Y > Window.ClientBounds.Height - 50)
cog.Position.Y = Window.ClientBounds.Height - 50;
if (cog.Position.X < 0)
cog.Position.X = 0;
if (cog.Position.Y < 0)
cog.Position.Y = 0;
}
foreach (var cog in enemies)
{
cog.Update(gameTime);
}
if (Keyboard.GetState().IsKeyDown(Keys.M))
{
// If 'm' is down, we create a new meteor. Note that once this is working
// this is going to make a lot of meteors. That's another issue, though.
CreateEnemy();
}
//Console.WriteLine(enemies.Count);
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();
foreach (var cog in enemies)
{
cog.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Shouldn't you be using gear in this part instead of this.gear ?
foreach (var gear in enemies)
{
this.gear.LoadContent(this.Content);
}
ok I got it to work. So my randoms were being assigned and then reassigned in a different section of the code so that they all stacked on top of each other. Here is the solution.
Sprite.cs
class Sprite
{
Texture2D mSpriteTexture;
public Vector2 Position;
Color mSpriteColor;
public Rectangle Size;
public string AssetName;
private float mScale = 1.0f;
public float Scale
{
get { return mScale; }
set
{
mScale = value;
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
}
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
//theSpriteBatch.Draw(mSpriteTexture, Position);
}
}
}
Enemy.cs
class Enemy : Sprite
{
const string ENEMY_ASSETNAME = "gear";
Random Rand = new Random();
//int startPos_X;
//int startPos_Y;
public void LoadContent(ContentManager theContentManager)
{
Position = new Vector2(Position.X ,Position.Y);
base.LoadContent(theContentManager, ENEMY_ASSETNAME);
}
public void Update(GameTime gameTime)
{
MouseState cState = Mouse.GetState();
if (Position.X > cState.X)
{
Position.X += 1;
}
if (Position.X < cState.X)
{
Position.X -= 1;
}
if (Position.Y < cState.Y)
{
Position.Y -= 1;
}
if (Position.Y > cState.Y)
{
Position.Y += 1;
}
base.Update(gameTime);
}
}
}
Game1.cs
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Enemy> enemies = new List<Enemy>();
Random rand = new Random();
private void CreateEnemy()
{
Enemy gear = new Enemy();
//gear = new Enemy();
gear.Position.X = rand.Next(0, 1000);
gear.Position.Y = rand.Next(0, 1000);
Console.WriteLine(gear.Position.Y);
enemies.Add(gear);
enemies[0].Position.X += 10;
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
/// <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);
// TODO: use this.Content to load your game content here
for (int i = 0; i < 5; i++)
{
CreateEnemy();
}
foreach (var cog in enemies)
{
cog.LoadContent(this.Content);
}
}
/// <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();
// TODO: Add your update logic here
foreach (var cog in enemies)
{
if (cog.Position.X > Window.ClientBounds.Width - 50)
cog.Position.X = Window.ClientBounds.Width - 50;
if (cog.Position.Y > Window.ClientBounds.Height - 50)
cog.Position.Y = Window.ClientBounds.Height - 50;
if (cog.Position.X < 0)
cog.Position.X = 0;
if (cog.Position.Y < 0)
cog.Position.Y = 0;
}
foreach (var cog in enemies)
{
cog.Update(gameTime);
}
if (Keyboard.GetState().IsKeyDown(Keys.M))
{
// If 'm' is down, we create a new meteor. Note that once this is working
// this is going to make a lot of meteors. That's another issue, though.
CreateEnemy();
}
//Console.WriteLine(enemies.Count);
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();
foreach (var cog in enemies)
{
cog.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
I'm trying to make a space invaders-like game and i've found some difficulties tho,
my main player sprite moves correctly according to the keyboard, but not the Banjo!
Can you help?
Game1.CS
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public float displayWidth;
float displayHeight;
float overScanPercentage = 10.0f;
float minDisplayX;
float maxDisplayX;
float minDisplayY;
float maxDisplayY;
player accordian;
baseSprite background;
PlainBanjo Banjo;
float getPercentage(float percentage, float inputValue)
{
return (inputValue * percentage) / 100;
}
private void setScreenSizes()
{
displayWidth = graphics.GraphicsDevice.Viewport.Width;
displayHeight = graphics.GraphicsDevice.Viewport.Height;
float xOverscanMargin = getPercentage(overScanPercentage, displayWidth) / 2.0f;
float yOverscanMargin = getPercentage(overScanPercentage, displayHeight) / 2.0f;
minDisplayX = xOverscanMargin;
minDisplayY = yOverscanMargin;
maxDisplayX = displayWidth - xOverscanMargin;
maxDisplayY = displayHeight - yOverscanMargin;
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
public void update_accordian()
{
accordian.SpriteRectangle.X = (int)accordian.X;
accordian.SpriteRectangle.Y = (int)accordian.Y;
KeyboardState keys = Keyboard.GetState();
if (keys.IsKeyDown(Keys.D))
{
accordian.X = accordian.X + 2;
} if (keys.IsKeyDown(Keys.A))
{
accordian.X = accordian.X - 2;
}
}
/// <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
displayWidth = graphics.GraphicsDevice.Viewport.Width;
setScreenSizes();
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);
accordian = new player(Content.Load<Texture2D>("accordian"), new Rectangle(350, 433,
Window.ClientBounds.Width / 10,
Window.ClientBounds.Height / 10));
accordian.X = 400;
accordian.Y = 400;
background = new baseSprite(Content.Load<Texture2D>("background"), new Rectangle(0, 0,
Window.ClientBounds.Width,
Window.ClientBounds.Height));
Banjo = new PlainBanjo(Content.Load<Texture2D>("PlainBanjo"), new Rectangle(0,0,50,50));
Banjo.setupSprite( 0.05f, 200.0f, 200, 100, true);
// accordian.setupSprite();
// 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();
update_accordian();
Banjo.Update(maxDisplayX, minDisplayY, minDisplayX,maxDisplayY);
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);
// TODO: Add your drawing code here
spriteBatch.Begin();
background.Draw(spriteBatch);
accordian.Draw(spriteBatch);
Banjo.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}`
baseSprite
class baseSprite : Game1
{
public Vector2 Position = new Vector2(0, 0);
public Texture2D SpriteTexture;
public Rectangle SpriteRectangle;
public float X;
public float Y;
public float XSpeed;
public float YSpeed;
public float WidthFactor;
float TicksToCrossScreen;
public bool Visible;
public void setupSprite(
float widthFactor,
float ticksToCrossScreen,
float initialX,
float initialY,
bool initialVisibility)
{
WidthFactor = widthFactor;
TicksToCrossScreen = ticksToCrossScreen;
SpriteRectangle.Width = (int)((displayWidth * widthFactor) + 25f);
float aspectRatio =
(float)SpriteTexture.Width / SpriteTexture.Height;
SpriteRectangle.Height =
(int)((SpriteRectangle.Width / aspectRatio) + 25f);
X = initialX;
Y = initialY;
XSpeed = displayWidth / ticksToCrossScreen;
YSpeed = XSpeed;
Visible = initialVisibility;
}
public void LoadTexture(Texture2D inSpriteTexture)
{
SpriteTexture = inSpriteTexture;
}
public void SetRectangle(Rectangle inSpriteRectangle)
{
SpriteRectangle = inSpriteRectangle;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(SpriteTexture, SpriteRectangle, Color.White);
}
public baseSprite(Texture2D inSpriteTexture, Rectangle inRectangle)
{
SpriteTexture = inSpriteTexture;
SpriteRectangle = inRectangle;
}
}
player.cs
class player : baseSprite
{
public player(Texture2D inSpriteTexture, Rectangle inRectangle)
: base(inSpriteTexture, inRectangle)
{
}
}
PlainBanjo.cs
class PlainBanjo : baseSprite
{
public PlainBanjo(Texture2D inSpriteTexture, Rectangle inRectangle)
: base(inSpriteTexture, inRectangle)
{
}
public void Update(float maxDisplayX, float minDisplayY, float minDisplayX,float maxDisplayY)
{
X = X + XSpeed;
SpriteRectangle.X = (int)(X + 0.5f);
SpriteRectangle.Y = (int)(Y + 0.5f);
if (X + SpriteRectangle.Width >= maxDisplayX)
{
XSpeed = Math.Abs(XSpeed) * -1;
Y += 10;
}
if (X <= minDisplayX)
{
XSpeed = Math.Abs(XSpeed);
}
if (Y + SpriteRectangle.Height >= maxDisplayY)
{
YSpeed = Math.Abs(YSpeed) * -1;
}
if (Y <= minDisplayY)
{
YSpeed = Math.Abs(YSpeed);
}
}
}
It looks like you're calculating the new value of accordian but never actually updating accordian.SpriteRectangle.X and accordian.SpriteRectangle.Y with the new accordian values.
The player box is continuing through walls in an undesired fashion, I have tried making it so that the player moves in 0.1f(u) increments at a time, but this severely drops the performance of the game. Is there any way I can detect if the player is hitting a wall, what side they hit it on and how can I prevent them from clipping into the wall?
Here is the code that I am running (this is minimalistic of course)
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 Platformer
{
public class Player
{
double terminalVelocity;
//AnimatedTexture texture;
public Texture2D texture;
public Vector2 Position, Velocity;
public Rectangle boundingBox;
public Player(Texture2D tex, Vector2 pos, Vector2 vel, Rectangle bb)
{
texture = tex;
Position = pos;
Velocity = vel;
boundingBox = bb;
terminalVelocity = Math.Sqrt((2*bb.Width*bb.Height*Game1.gravity)/-9.8*2);
}
public void updateBoundingBoxes()
{
boundingBox.X = (int)Position.X;
boundingBox.Y = (int)Position.Y;
}
public void onUpdate()
{
updateBoundingBoxes();
Position.X += Velocity.X;
Position.Y += Velocity.Y;
//Velocity = Vector2.Zero;
Velocity.Y += Game1.gravity / 60;
Velocity.X /= 1.2f;
}
public void Draw(SpriteBatch sb)
{
updateBoundingBoxes();
sb.Begin();
sb.Draw(texture,boundingBox,GameLighting.currentColour());
sb.End();
}
}
public enum GameLightingState
{
Red, Dark, Orange, Blue, White
}
public class Platform : Object
{
Texture2D text;
public Rectangle rect;
public Platform(Texture2D t, Vector2 p, int sizeX, int sizeY)
{
text = t;
rect = new Rectangle((int)p.X, (int)p.Y, sizeX, sizeY);
}
public void onPlayerCollision(Player p)
{
p.Velocity.X = -p.Velocity.X / 2;
p.Velocity.Y = -p.Velocity.Y / 2;
}
public void Draw(SpriteBatch sb)
{
sb.Begin();
sb.Draw(text, rect, GameLighting.currentColour());
sb.End();
}
public void onUpdate()
{
}
}
public class GameLighting
{
public static Color currentColour()
{
return eToColour(Game1.currentLightingState);
}
public static Color eToColour(GameLightingState gls)
{
switch (gls)
{
case(GameLightingState.Red):
return Color.Red;
case (GameLightingState.Blue):
return Color.Blue;
case (GameLightingState.Orange):
return Color.Orange;
case (GameLightingState.Dark):
return Color.DarkGray;
case (GameLightingState.White):
return Color.White;
}
return Color.White;
}
}
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
public static float gravity = 9.80665f;
public static GameLightingState currentLightingState;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Platform> platforms;
List<Player> players;
int controlledPlayerIndex = 0;
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
currentLightingState = GameLightingState.White;
platforms = new List<Platform>();
players = new List<Player>();
players.Add(new Player(this.Content.Load<Texture2D>("Images/dirt"), new Vector2(300,0), new Vector2(0,0), new Rectangle(300,0,20,20)));
platforms.Add(new Platform(this.Content.Load<Texture2D>("Images/dirt"),new Vector2(300,450),200,20));
platforms.Add(new Platform(this.Content.Load<Texture2D>("Images/dirt"), new Vector2(20,20), 20, 200));
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);
// 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();
foreach (Player p in players)
{
Boolean intersects = false;
Rectangle tempRectangle = new Rectangle((int)(p.Position.X + p.Velocity.X),(int) (p.Position.Y + p.Velocity.Y), p.boundingBox.Width, p.boundingBox.Height);
foreach (Platform pl in platforms)
{
intersects = intersects || tempRectangle.Intersects(pl.rect);
}
if (!intersects)
{
p.onUpdate();
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
players[controlledPlayerIndex].Velocity.Y -= 0.75f;
}
if (Keyboard.GetState().IsKeyDown(Keys.A))
{
players[controlledPlayerIndex].Velocity.X -= 0.75f;
}
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
players[controlledPlayerIndex].Velocity.X += 0.75f;
}
// 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.CornflowerBlue);
// TODO: Add your drawing code here
foreach (Platform p in platforms)
{
p.Draw(spriteBatch);
}
foreach (Player p in players)
{
p.Draw(spriteBatch);
}
base.Draw(gameTime);
}
}
}
*Updated Source Code based on first comments
One note about this code, you need to run it in XNA and use an icon called dirt.png in a folder called Images, it doesn't matter what the picture looks like, you just need it to fully understand what is happening
Had a similar problem recently myself. Here is what I did.
//variables needed
public bool follow = true;
public Vector2D startpoint;
//puts the startpoint value equal
//to the inital location of the player
public Player()
{
startpoint.X = rectangle.X;
startpoint.Y = rectangle.Y;
}
//if any of the collision tests fail
if(collision occurs)
{
collision();
}
//else update startpoint to new valid location
else
{
startpoint.X = rectangle.X;
startpoint.Y = rectangle.Y;
follow = true;
}
if(follow == true)
{
//movement commands occur
}
else
{
follow = true;
}
//if a condition fails set player
//too last valid location
public void collision()
{
rectangle.X = startpoint.X;
rectangle.Y = startpoint.Y;
follow = false;
}
This worked well enough for me hope it helps.
I am trying to make a simple pong game and i am stuck on the collisions with the paddles and the adding onto the score. Here is my code for the ball class:
namespace Pong
{
class Ball
{
Game1 game;
Player player;
Computer computer;
public Texture2D Texture;
public Vector2 Position;
public Vector2 Motion;
float Speed;
Rectangle ballRectangle;
Rectangle playerPaddle;
Rectangle computerPaddle;
Random random = new Random();
public void Initialize()
{
game = new Game1();
player = new Player();
computer = new Computer();
Start();
}
public void Start()
{
Motion = Vector2.Zero;
Position = new Vector2(391, 215);
Speed = 0.8f;
Motion = new Vector2(random.Next(-1, 1), random.Next(-1, 1));
}
public void Update()
{
Position += Motion * Speed;
CheckForCollision();
}
public void CheckForCollision()
{
ballRectangle = new Rectangle((int)Position.X, (int)Position.Y, 20, 20);
playerPaddle = new Rectangle((int)player.Position.X, (int)player.Position.Y, 25, 105);
computerPaddle = new Rectangle((int)computer.Position.X, (int)computer.Position.Y, 25, 105);
if (ballRectangle.Intersects(playerPaddle))
{
Motion.X *= -1;
}
if (ballRectangle.Intersects(computerPaddle))
{
Motion.X *= -1;
}
if (Position.Y < 0)
{
Motion.Y *= -1;
}
if (Position.Y > 450)
{
Motion.Y *= -1;
}
if (Position.X < 0)
{
game.computerScore += 1;
Start();
}
if (Position.X > 800)
{
game.playerScore += 1;
Start();
}
}
public void LoadContent(ContentManager Content)
{
Texture = Content.Load<Texture2D>("ball");
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position,Color.White);
}
}
}
In the rectangle I have used the actual pixels of the image instead of player.texture.width
and here is my game class:
namespace Pong
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D bgtexture;
Vector2 BGpos = new Vector2(0, 0);
Ball ball;
Player player;
Computer computer;
SpriteFont Score;
Vector2 scorePosition = new Vector2(375, 5);
public int playerScore;
public int computerScore;
string scoreOutput;
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()
{
ball = new Ball();
player = new Player();
computer = new Computer();
ball.Initialize();
player.Initialze();
computer.Initialize();
this.graphics.PreferredBackBufferHeight = 450;
this.graphics.PreferredBackBufferWidth = 800;
this.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);
bgtexture = Content.Load<Texture2D>("PongBG");
Score = Content.Load<SpriteFont>("Score");
ball.LoadContent(this.Content);
player.LoadContent(this.Content);
computer.LoadContent(this.Content);
}
/// <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();
scoreOutput = playerScore + " " + computerScore;
ball.Update();
player.Update();
computer.Update();
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);
spriteBatch.Begin();
spriteBatch.Draw(bgtexture, BGpos, Color.White);
ball.Draw(this.spriteBatch);
player.Draw(this.spriteBatch);
computer.Draw(this.spriteBatch);
spriteBatch.DrawString(Score, scoreOutput, scorePosition, Color.AntiqueWhite);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
The ball bounces off the edge of the screen at the top and bottom fine but it just goes straight through the paddles. Also once it has hit the the edge behind the paddle it goes to the beginning like it should but it doesn't add the points onto the score for the player and the computer.
There's always the possibility that, because you're doing per-pixel collision, that the ball is moving faster than the update method can work out a collision. If the ball is moving too fast, then it could always be that the frame before collision, the ball sits before the paddle, and in the next update, the speed is applied and the ball's new position is behind the paddle. Just a thought - it's happened to me a couple of times.