The game stopped working when the following function is called:
The error is: shotmanager object wont be passed and always will be null! I was following a tutorial and did exactly as he did!
I clearly initiated it.
Some coding here
namespace SpaceShip
{
class Enemy: Sprite
{
public shotmanager shotmanager;
private double timesincelastshot;
private const int timedelay = 1;
private Vector2 pos;
public Enemy(Texture2D Text, Vector2 VEC, Rectangle REC, shotmanager shotmanager)
: base(Text, VEC, REC)
{
shipspeed = 300;
this.shotmanager = shotmanager;
}
public override void Update(KeyboardState keyboard, GameTime gameTime)
{
var random = new Random();
if (Velocity == Vector2.Zero)
{
var direction = random.Next(2);
Velocity = new Vector2(direction == 0 ? -1 : 1, 0);
}
else if (gameTime.ElapsedGameTime.Seconds % 2 == 0)
{
if (random.Next(15) == 0)
Velocity = new Vector2(-velocity.X, velocity.Y);
}
timesincelastshot += gameTime.ElapsedGameTime.TotalSeconds;
if (timesincelastshot > timedelay)
{
if (random.Next(2) == 0)
pos = calculateposition();
shotmanager.fireenemyshot(pos);
timesincelastshot = 0;
}
base.Update(keyboard, gameTime);
}
private Vector2 calculateposition()
{
return VEC + new Vector2(TEXT.Width/2, TEXT.Height/2);
}
}
}
namespace SpaceShip
{
public class shotmanager
{
private Shot shot;
public Texture2D shottexture;
private Rectangle bounds;
private List<Shot> shotgroup = new List<Shot>();
//public shooting shot;
Vector2 vec;
public shotmanager(Texture2D shottexture, Rectangle bounds)
{
// TODO: Complete member initialization
this.shottexture = shottexture;
this.bounds = bounds;
}
public void fireenemyshot(Vector2 shotposition)
{
var inflatebounds = bounds;
vec = shotposition;
inflatebounds.Inflate(10, 10);
shot.Velocity = new Vector2(0, 1);
shotgroup.Add(shot);
shot = new Shot(shottexture, shotposition, inflatebounds);
}
public void draw(SpriteBatch spriteBatch)
{
foreach (var i in shotgroup)
shot.draw(spriteBatch);
}
public void Update(KeyboardState keyboard, GameTime gameTime)
{
foreach (var i in shotgroup)
shot.Update(keyboard, gameTime);
}
}
}
namespace SpaceShip
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Sprite background;
shipclass spaceship;
//Sprite spaceship;
SpriteFont score;
EnemyManger enemy;
Texture2D shottexture;
public shotmanager shotmanager;
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.
var alienship = Content.Load<Texture2D>("flying_saucer_2");
Texture2D spaceshiptexture;
spriteBatch = new SpriteBatch(GraphicsDevice);
spaceshiptexture = Content.Load<Texture2D>("1358114942_kspaceduel");
var positionx = (graphics.GraphicsDevice.Viewport.Width - spaceshiptexture.Width) / 2;
var positiony = (graphics.GraphicsDevice.Viewport.Height - spaceshiptexture.Height );
var ship = new Rectangle(0, graphics.GraphicsDevice.Viewport.Height - spaceshiptexture.Height -150 , graphics.GraphicsDevice.Viewport.Width, spaceshiptexture.Height+150);
background = new Sprite(Content.Load<Texture2D>("large_space_1920x1200"), Vector2.Zero, graphics.GraphicsDevice.Viewport.Bounds);
spaceship = new shipclass(spaceshiptexture, new Vector2(positionx, positiony), ship);
score = Content.Load<SpriteFont>("SpriteFont1");
shottexture = Content.Load<Texture2D>("64px-SpaceInvadersLaserDepiction");
shotmanager = new shotmanager(shottexture, graphics.GraphicsDevice.Viewport.Bounds);
enemy = new EnemyManger(alienship, graphics.GraphicsDevice.Viewport.Bounds, shotmanager);
public void fireenemyshot(Vector2 shotposition)
{
var inflatebounds = bounds;
vec = shotposition;
inflatebounds.Inflate(10, 10);
// CULPRIT HERE
shot.Velocity = new Vector2(0, 1);
shotgroup.Add(shot);
// THIS IS DONE TOO LATE.
shot = new Shot(shottexture, shotposition, inflatebounds);
}
The problem is that you are attempting to set the Velocity on shot, but you have never instantiated it before here. You are instantiating it after you are attempting to use.
EDIT - FYI The pos that you are passing into this method from Enemy is also never set. It's a struct so it should be initialized, however, you are never giving it a value. Nevermind, I saw where it gets set.
Related
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);
}
}
}
when i start to debug my code it loads fine but only the fade in happens when i press Z the Enter key does not cause the fade or the next menu with text "Title Screen"to appear i wonder if anyone could tell me where i went wrong ill upload the full code below.
p.s. there is no error message.
what should happen when the game starts "Splash screen"
should appear on the screen pressing enter fades out the screen to the Title screen saying "Title Screen", the splash screen loads and when Z is pressed the fade animation happens but the Enter key has 0 effect on the game.
namespace Platformer
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
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()
{
Screen_Manager.Instance.Initiaize();
Screen_Manager.Instance.Dimensions = new Vector2(800, 600);
graphics.PreferredBackBufferWidth = (int)Screen_Manager.Instance.Dimensions.X;
graphics.PreferredBackBufferHeight = (int)Screen_Manager.Instance.Dimensions.Y;
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);
Screen_Manager.Instance.LoadContent(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();
Screen_Manager.Instance.Update(gameTime);
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();
Screen_Manager.Instance.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
{
public class Game_Screen
{
protected ContentManager content;
public virtual void LoadContent(ContentManager Content)
{
content = new ContentManager(Content.ServiceProvider, "content");
}
public virtual void UnloadContent()
{
content.Unload();
}
public virtual void Update(GameTime gameTime)
{
}
public virtual void Draw(SpriteBatch spriteBatch)
{
}
}
}
{
public class Screen_Manager
{
#region variables
ContentManager content; // creating custom ContentManger
Game_Screen currentScreen; // screen being currently displayed
Game_Screen newScreen; // new screen taking effect
private static Screen_Manager instance; // Screen Manger instance
// Dictionary<string, Game_Screen> screens = new Dictionary<string, Game_Screen>(); // Game Screen storage
Stack<Game_Screen> screenStack = new Stack<Game_Screen>(); // screens Stack
Vector2 dimensions; // width&Height of Screens
bool transition;
Fade_Animation fade;
Texture2D fadeTexture;
#endregion
#region Properties
public static Screen_Manager Instance
{
get
{
if (instance == null)
instance = new Screen_Manager();
return instance;
}
}
public Vector2 Dimensions
{
get { return dimensions; }
set { dimensions = value; }
}
#endregion
#region Main Methods
public void AddScreen(Game_Screen screen)
{
transition = true;
newScreen = screen;
fade.IsActive = true;
fade.Alpha = 1.0f;
fade.ActivateValue = 1.0f;
}
public void Initiaize()
{
currentScreen = new Splash_Screen();
fade = new Fade_Animation();
}
public void LoadContent(ContentManager Content)
{
content = new ContentManager(Content.ServiceProvider, "Content");
currentScreen.LoadContent(Content);
fadeTexture = content.Load<Texture2D>("fade");
fade.LoadContent(content, fadeTexture, "", Vector2.Zero);
fade.Scale = dimensions.X;
}
public virtual void Update(GameTime gameTime)
{
if (!transition)
currentScreen.Update(gameTime);
else
Transition(gameTime);
}
public virtual void Draw(SpriteBatch spriteBatch)
{
currentScreen.Draw(spriteBatch);
if (transition)
fade.Draw(spriteBatch);
}
#endregion
#region Provate Methods
private void Transition(GameTime gameTime)
{
fade.Update(gameTime);
if(fade.Alpha == 1.0f && fade.Timer.TotalSeconds == 1.0f)
{
screenStack.Push(newScreen);
currentScreen.UnloadContent();
currentScreen = newScreen;
currentScreen.LoadContent(content);
}
else if (fade.Alpha == 0.0f)
{
transition =false;
fade.IsActive = false;
}
}
#endregion
}
}
{
public class Splash_Screen : Game_Screen
{
KeyboardState keystate;
SpriteFont font;
public override void LoadContent(ContentManager Content)
{
base.LoadContent(Content);
if (font == null)
font = content.Load<SpriteFont>("Font1");
}
public override void UnloadContent()
{
base.UnloadContent();
}
public override void Update(GameTime gameTime)
{
keystate = Keyboard.GetState();
if (keystate.IsKeyDown(Keys.Z))
Screen_Manager.Instance.AddScreen(new Title_Screen());
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.DrawString(font, "SplashScreen",
new Vector2(100, 100), Color.Black);
}
}
}
{
public class Title_Screen : Game_Screen
{
KeyboardState keystate;
SpriteFont font;
public override void LoadContent(ContentManager Content)
{
base.LoadContent(Content);
if (font == null)
font = content.Load<SpriteFont>("Font1");
}
public override void UnloadContent()
{
base.UnloadContent();
}
public override void Update(GameTime gameTime)
{
keystate = Keyboard.GetState();
if (keystate.IsKeyDown(Keys.Enter))
Screen_Manager.Instance.AddScreen(new Splash_Screen());
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.DrawString(font, "Title Screen",
new Vector2(100, 100), Color.Black);
}
}
}
{
public class Animation
{
protected Texture2D image;
protected string text;
protected SpriteFont font;
protected Color color;
protected Rectangle sourceRect;
protected float rotation, scale, axis, alpha;
protected Vector2 origin, position;
protected ContentManager content;
protected bool isActive;
public virtual float Alpha
{
get { return alpha; }
set { alpha = value; }
}
public bool IsActive
{
set { isActive = value; }
get { return isActive; }
}
public float Scale
{
set { scale = value; }
// get { return scale; }
}
public virtual void LoadContent(ContentManager Content, Texture2D image,
string text, Vector2 position)
{
content = new ContentManager(Content.ServiceProvider, "Content");
this.image = image;
this.text = text;
this.position = position;
if (text != string.Empty)
{
font = Content.Load<SpriteFont>("Font1");
color = new Color(114, 77, 225);
}
if (image != null)
sourceRect = new Rectangle(0, 0, image.Width, image.Height);
rotation = 0.0f;
axis = 0.0f;
scale = 1.0f;
alpha = 1.0f;
isActive = false;
}
public virtual void UnloadContent()
{
content.Unload();
text = string.Empty;
position = Vector2.Zero;
sourceRect = Rectangle.Empty;
image = null;
}
public virtual void Update(GameTime gameTime)
{
}
public virtual void Draw(SpriteBatch spriteBatch)
{
if (image != null)
{
origin = new Vector2(sourceRect.Width / 2,
sourceRect.Height / 2);
spriteBatch.Draw(image, position + origin, sourceRect,
Color.White * alpha, rotation, origin, scale,
SpriteEffects.None, 0.0f);
}
if (text != String.Empty)
{
origin = new Vector2(font.MeasureString(text).X / 2,
font.MeasureString(text).Y / 2);
spriteBatch.DrawString(font, text, position + origin,
color * alpha, rotation, origin, scale, SpriteEffects.None,
0.0f);
}
}
}
}
{
class Fade_Animation : Animation
{
bool increase;
float fadespeed;
TimeSpan defaultTime, timer;
bool startTimer;
float activatevalue;
bool stopUpdateing;
float defaultAlpha;
public TimeSpan Timer
{
get { return timer; }
set { defaultTime = value; timer = defaultTime; }
}
public float FadeSpeed
{
get { return fadespeed; }
set { fadespeed = value; }
}
public override float Alpha
{
get
{
return alpha;
}
set
{
alpha = value;
if (alpha == 1.0f)
increase = false;
else if (alpha == 0.0f)
increase = true;
}
}
public float ActivateValue
{
get { return activatevalue; }
set { activatevalue = value; }
}
public override void LoadContent(ContentManager Content,
Texture2D image, string text, Vector2 position)
{
base.LoadContent(Content, image, text, position);
increase = false;
fadespeed = 1.0f;
defaultTime = new TimeSpan(0, 0, 1);
timer = defaultTime;
activatevalue = 0.0f;
stopUpdateing = false;
defaultAlpha = alpha;
}
public override void Update(GameTime gameTime)
{
if (isActive)
{
if (!stopUpdateing)
{
if (!increase)
alpha -= fadespeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
else
alpha += fadespeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
if (alpha <= 0.0f)
alpha = 0.0f;
else if (alpha >= 1.0f)
alpha = 1.0f;
}
if (alpha == activatevalue)
{
stopUpdateing = true;
timer -= gameTime.ElapsedGameTime;
if (timer.TotalSeconds <= 0)
{
increase = !increase;
timer = defaultTime;
stopUpdateing = false;
}
}
}
else
{
alpha = defaultAlpha;
}
}
}
}
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.
im working on a pong game, and im trying to make so when the ball collides the paddle, it bounces off..as simple as that. But when i use rectangles, cus i think using if(ballRect.Intersects(gPaddle.gRect)) is the best way of making a collision.
But when i start my game, everything goes wrong, the ball dissappears, and the paddle textures gets wierd, a part of it doesnt follow the paddle and yeah.. heres the code:
GreenPaddle.cs:
public class GreenPaddle
{
public Texture2D gPtexture;
public Vector2 position;
public Rectangle gpRect;
public Vector2 origin;
public int speed = 2;
public GreenPaddle()
{
}
public void LoadContent(ContentManager Content)
{
gPtexture = Content.Load<Texture2D>("greenpaddle");
position = new Vector2(20, 200);
gpRect = new Rectangle((int)position.X, (int)position.Y,
gPtexture.Width, gPtexture.Height);
}
public void Update(GameTime gameTime)
{
KeyboardState keyState = Keyboard.GetState();
//Movement
PaddleMovement();
//Border Collision
isCollidingWithBorders();
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(gPtexture, position, gpRect, Color.White);
}
public Boolean isCollidingWithBorders()
{
if (position.Y < 83 && gpRect.Y < 83)
{
position.Y = 83;
gpRect.Y = 83;
return true;
}
if (position.Y > 400 && gpRect.Y > 400)
{
position.Y = 400;
gpRect.Y = 400;
return true;
}
else { return false; }
}
public void PaddleMovement()
{
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.W))
{
position.Y -= speed;
gpRect.Y -= speed;
}
if (keyState.IsKeyDown(Keys.S))
{
position.Y += speed;
gpRect.Y += speed;
}
}
}
Ball.cs:
public class Ball
{
GreenPaddle gPaddle = new GreenPaddle();
Texture2D ballTexture;
Vector2 ballPosition;
Rectangle ballRect;
int speed = 2;
bool movingUp, movingLeft;
public Ball()
{
movingLeft = true;
movingUp = true;
}
public void LoadContent(ContentManager Content)
{
ballTexture = Content.Load<Texture2D>("ball");
ballPosition = new Vector2(380, 225);
ballRect = new Rectangle((int)ballPosition.X, (int)ballPosition.Y,
ballTexture.Width, ballTexture.Height);
}
public void Update(GameTime gameTime)
{
BallMovement();
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(ballTexture, ballPosition, ballRect, Color.White);
}
public void BallMovement()
{
if (movingUp) { ballPosition.Y -= speed; ballRect.Y -= speed; }
if (!movingUp) { ballPosition.Y += speed; ballRect.Y += speed; }
if (movingLeft) { ballPosition.X -= speed; ballRect.X -= speed; }
if (!movingLeft) { ballPosition.X += speed; ballRect.X += speed; }
if (ballRect.Intersects(gPaddle.gpRect))
movingLeft = false;
if (ballPosition.Y < 85)
{
movingUp = false;
}
}
}
Game1.cs:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D BackGround;
GreenPaddle gPaddle = new GreenPaddle();
Ball ball = new Ball();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 500;
}
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);
BackGround = Content.Load<Texture2D>("pongBG");
gPaddle.LoadContent(Content);
ball.LoadContent(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();
gPaddle.Update(gameTime);
ball.Update(gameTime);
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(BackGround, new Vector2(0f, 0f), Color.White);
gPaddle.Draw(spriteBatch);
ball.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
What should i do? What am i missing?
Thanks in advance :)
The collision test is inside the Ball class. In it you are testing whether the ball collides with a private member of the class called gPaddle, NOT the one that your game uses and that you update and draw.
Replace
GreenPaddle gPaddle = new GreenPaddle();
with
GreenPaddle gPaddle;
...
public Ball(GreenPaddle paddle)
{
this.gPaddle = paddle;
}
Also, don't use 2 booleans and a scalar to denote velocity. Use a Vector2. Your BallMovement method is wrong as well. You should reflect the ball upon intersection in the paddle which means to reverse its direction in BOTH x and y axes:
With 2 bools:
if (ballRect.Intersects(gPaddle.gpRect))
{
movingLeft = !movingLeft
movingTop = !movingTop;
}
With a Vector2 as speed:
if (ballRect.Intersects(gPaddle.gpRect))
{
velocity = -velocity;
}
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.