My problem is that I have an object I want to move forward in the direction it’s facing, right now I’m able to rotate it, but unable to make it move forward. can anyone tell me how to fix this ? Some of the code (the comments are in Swedish, but it should be understandable what the function do)
Game Code:
namespace MultiPlayerTanks
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Tank Player1, Player2; //skapa två spelare/tanks
GameObj Bana; //Skapa ett GameObj som ska användas som bana
SpriteFont font; //Spritefont för utskrift
Meter PowerMeter,PowerMeter2, Player1LifeMeter, Player2LifeMeter; //Mätare för liv och kraft
List<Shot> allShots = new List<Shot>();
List<Shot> allShots2 = new List<Shot>();//Ny lista för alla skott(-objekt)
Texture2D shot1Gfx; //Grafik till skotten
List<Explosion> allExplosions = new List<Explosion>();
List<Explosion> allExplosions2 = new List<Explosion>();//Ny lista för alla explosioner
Texture2D explosionGfx; //Grafik till explosionen
string displayMessage = ""; //Text som skalman skrivas ut
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Change of resolution.
this.graphics.PreferredBackBufferWidth = 800;
this.graphics.PreferredBackBufferHeight = 600;
//this.graphics.IsFullScreen = true;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//Ladar in grafiken
Texture2D greenTankGfx = Content.Load<Texture2D>("green_tank");
Texture2D redTankGfx = Content.Load<Texture2D>("red_tank");
Texture2D level1Gfx = Content.Load<Texture2D>("level");
Texture2D redMeterGfx = Content.Load<Texture2D>("meter");
Texture2D lifeMeterGfx = Content.Load<Texture2D>("life_meter");
shot1Gfx = Content.Load<Texture2D>("shot");
explosionGfx = Content.Load<Texture2D>("explosion");
//Load basic texture to make it recognizable :)
//Skapa Objekt
//Tilldelning av properties direkt.. slipper skriva konstruktorer
Player1 = new Tank()
{
Gfx = greenTankGfx,
Position = new Vector2(400, 300),
Speed = 0,
Direction = new Vector2(0, -1),
Enemy = false
};
Player2 = new Tank()
{
Gfx = redTankGfx,
Position = new Vector2(400, 300),
Speed = 0,
Direction = new Vector2(0, -1),
Enemy = true
};
Bana = new GameObj() { Gfx = level1Gfx, Position = new Vector2(0, 0), Angle = 0 };
PowerMeter = new Meter() { Gfx = redMeterGfx, Position = new Vector2 (Player1.Position.X,Player1.Position.Y) };
PowerMeter2 = new Meter() { Gfx = redMeterGfx, Position = new Vector2(Player2.Position.X,Player2.Position.Y) };
Player1LifeMeter = new Meter() { Gfx = lifeMeterGfx, Position = new Vector2(50, 50) };
Player2LifeMeter = new Meter() { Gfx = lifeMeterGfx, Position = new Vector2(250, 50) };
font = Content.Load<SpriteFont>("SpriteFont1");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
Player1.Update(gameTime); //Uppdatera spelare1
Player2.Update(gameTime);
//Sätter Kraftmätarens värde till vår spelares "skottkraft"
PowerMeter2.Value = Player2.ShotPower;
PowerMeter.Value = Player1.ShotPower;
//Sätter Livmätarnas värde till resp. spelares liv-värde
Player1LifeMeter.Value = Player1.Life;
Player2LifeMeter.Value = Player2.Life;
#region player 2 shotfired
if (Player2.ShotFired) //Ifall ett skott avfyrats
{
//Lägger till ett nytt skott i listan
allShots2.Add(new Shot()
{
Gfx = shot1Gfx,
Position = Player2.Position + (Player2.Direction * (Player2.Gfx.Height) / 2) +
(Player2.Direction * shot1Gfx.Height / 2),
Angle = Player2.Angle,
Speed = 5.0F + Player2.Speed,
Power = Player2.ShotPower,
Direction = Player2.Direction
});
Player2.ShotPower = 0;
Player2.ShotFired = false;
}
for (int i = 0; i < allShots2.Count; i++) //Loopar igenom alla skott
{
allShots2[i].Update(gameTime); //uppdaterar skott
if (allShots2[i].Power < 0) //Är skottets "kraft" slut?
{
//Lägg till en ny Explosion
allExplosions2.Add(new Explosion() { Gfx = explosionGfx, Position = allShots2[i].Position });
allShots2.RemoveAt(i); //Tar bort skottet
}
}
for (int i = 0; i < allExplosions2.Count; i++) //Loopa igenom alla explosioner
{
allExplosions2[i].Update(gameTime); //Uppdatera explosion
//Ta bort "färdiga" explosioner
if (allExplosions2[i].Active == false) allExplosions2.RemoveAt(i);
}
#endregion
if (Player1.ShotFired) //Ifall ett skott avfyrats
{
//Lägger till ett nytt skott i listan
allShots.Add(new Shot()
{
Gfx = shot1Gfx,
Position = Player1.Position + (Player1.Direction * (Player1.Gfx.Height) / 2) +
(Player1.Direction * shot1Gfx.Height / 2),
Angle = Player1.Angle,
Speed = 5.0F + Player1.Speed,
Power = Player1.ShotPower,
Direction = Player1.Direction
});
Player1.ShotPower = 0;
Player1.ShotFired = false;
}
for (int i = 0; i < allShots.Count; i++) //Loopar igenom alla skott
{
allShots[i].Update(gameTime); //uppdaterar skott
if (allShots[i].Power < 0) //Är skottets "kraft" slut?
{
//Lägg till en ny Explosion
allExplosions.Add(new Explosion() { Gfx = explosionGfx, Position = allShots[i].Position });
allShots.RemoveAt(i); //Tar bort skottet
}
}
for (int i = 0; i < allExplosions.Count; i++) //Loopa igenom alla explosioner
{
allExplosions[i].Update(gameTime); //Uppdatera explosion
//Ta bort "färdiga" explosioner
if (allExplosions[i].Active == false) allExplosions.RemoveAt(i);
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
//Ritar ut bana, spelare och mätare
Bana.Draw(spriteBatch, new Vector2(0,0));
PowerMeter.Draw(spriteBatch, Player1.Position);
PowerMeter2.Draw(spriteBatch, Player2.Position);
Player1.Draw(spriteBatch, Player1.Position);
Player2.Draw(spriteBatch, Player2.Position);
Player1LifeMeter.Draw(spriteBatch, new Vector2(0, 0));
Player2LifeMeter.Draw(spriteBatch, new Vector2(0, 0));
//Loopar igenom alla skott och ritar ut dem
for (int i = 0; i < allShots.Count; i++)
{
allShots[i].Draw(spriteBatch, Player1.Position);
}
//Loopar igenom alla explosioner och ritar ut dem
for (int i = 0; i < allExplosions.Count; i++)
{
allExplosions[i].Draw(spriteBatch, Player1.Position);
}
///////////////////////////////////////////////////
for (int i = 0; i < allShots2.Count; i++)
{
allShots2[i].Draw(spriteBatch, Player2.Position);
}
//Loopar igenom alla explosioner och ritar ut dem
for (int i = 0; i < allExplosions2.Count; i++)
{
allExplosions2[i].Draw(spriteBatch, Player2.Position);
}
//Skriver ut spelarnas namn och liv mm..
string nameFormat = "{0}\nLife: {1}%\n\nKills: {2}";
displayMessage = string.Format(nameFormat, "Player1", Player1.Life, Player1.Kills);
spriteBatch.DrawString(font, displayMessage, new Vector2(51, 4), Color.Black);
spriteBatch.DrawString(font, displayMessage, new Vector2(50, 5), Color.White);
displayMessage = string.Format(nameFormat, "Player2", Player2.Life, Player2.Kills);
spriteBatch.DrawString(font, displayMessage, new Vector2(251, 4), Color.Black);
spriteBatch.DrawString(font, displayMessage, new Vector2(250, 5), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
GameObject Code:
namespace MultiPlayerTanks
{
class GameObj
{
public Vector2 Position //Objektets position
{
get;
set;
}
public Texture2D Gfx //Objektets grafik
{
get;
set;
}
public float Angle //Objektets vinkel
{
get;
set;
}
public virtual void Draw(SpriteBatch spriteBatch, Vector2 DrawOffset)
{
spriteBatch.Draw(Gfx,
Position - DrawOffset + new Vector2(400, 300), null,
Color.White, Angle + (float)Math.PI / 2,
new Vector2(Gfx.Width / 2, Gfx.Height / 2), 1.0f,
SpriteEffects.None, 0);
}
}
}
Moving Game Object Code:
namespace MultiPlayerTanks
{
class MovingGameObj : GameObj
{
public Vector2 Direction //Riktning
{
get;
set;
}
public float spriterotation //Hastighet
{
get;
set;
}
public float Speed //Hastighet
{
get;
set;
}
public virtual void Update(GameTime gameTime)
{
Position += Direction * Speed;
}
}
}
Tank Code:
namespace MultiPlayerTanks
{
class Tank : MovingGameObj
{
public Tank()
{
MaxSpeed = 2.5F;
ShotPower = 0;
prevKs = Keyboard.GetState();
prevKs2 = Keyboard.GetState();
Life = 100F;
Kills = 0;
Angle = -(float)(Math.PI / 2);
}
public bool Enemy
{
get;
set;
}
public float MaxSpeed
{
get;
set;
}
public float ShotPower
{
get;
set;
}
public int WeaponType
{
get;
set;
}
public bool ShotFired
{
get;
set;
}
public float Life
{
get;
set;
}
public int Kills
{
get;
set;
}
protected KeyboardState prevKs;
protected KeyboardState prevKs2;
public void Respawn()
{
Life = 100F;
Random randomerare = new Random();
Position = new Vector2(randomerare.Next(1000), randomerare.Next(1000));
Angle = 0;
}
public override void Update(GameTime gameTime)
{
KeyboardState ks = Keyboard.GetState();
KeyboardState ks2 = Keyboard.GetState();
#region Player 1
if (Enemy == false)
{
if (ks.IsKeyDown(Keys.Up))
{
if (Speed < 0) Speed = 0;
if (Speed < MaxSpeed) Speed = Speed * 1.005F + 0.01F;
else Speed = MaxSpeed;
}
if (ks.IsKeyDown(Keys.Down))
{
if (Speed > -1.0F) Speed -= 0.04F;
else Speed = -1.0F;
}
if (ks.IsKeyUp(Keys.Down) && ks.IsKeyUp(Keys.Up) && Speed > 0)
{
Speed -= 0.01F;
if (Speed <= 0) Speed = 0;
}
if (ks.IsKeyUp(Keys.Down) && ks.IsKeyUp(Keys.Up) && Speed < 0)
{
Speed += 0.01F;
if (Speed >= 0) Speed = 0;
}
if (ks.IsKeyUp(Keys.Left))
{
Angle += 0.02F;
}
if (ks.IsKeyUp(Keys.Right))
{
Angle -= 0.02F;
}
if (ks.IsKeyDown(Keys.Space))
{
if (ShotPower < 100)
ShotPower += 0.5F;
else
ShotPower = 100;
}
if (ks.IsKeyUp(Keys.Space) && prevKs.IsKeyDown(Keys.Space))
{
//ShotPower = 0;
ShotFired = true;
}
}
#endregion
prevKs = ks;
Direction = new Vector2((float)Math.Cos(Angle), (float)Math.Sin(Angle));
base.Update(gameTime);
}
}
}
I have tried many different things but nothing seems to work. What I want is that when I press W the “tank” moves forward in the direction its facing.
I haven’t checked your code deeply, but usually it’s as simple as
Keep in mind that you can use a debugger to locate the problem, adding a
breakpointin theif(Enemy == false)to see which condition you assume works that doesn’t.Also, in code like this, always use your
deltaTimewhen incrementing / decrementing values, otherwise you will have different results on different frame rates (for example, the game will play faster on a faster computer)Edit: while your code looks “functional” to me, keep in mind that going forward / backward is mapped on the Up and Down arrows… not W like you are asking in the question, is this the only thing not working? If so, simply replace
Keys.UptoKeys.W…