Visual studio doesn't recognize my constructor? - c#

I recently started working with monogame and everything went great until this happened.
I am not very experienced so this might just seem stupid but I've tried everything and this is my only option, so this is my constructor:
public void qlayer(Vector2 position, Texture2D texture)
{
this.position = position;
this.texture = texture;
}
"qlayer" is the name of my class but and it keeps saying: "member names cannot be the same as their enclosing type" which would make sense if i didn't want to make a constructor!
Just to be safe, here's the entire class:
class qlayer
{
Vector2 position;
Point speed;
Rectangle hitbox;
Texture2D texture;
Point currentFrame;
int timeSinceLastFrame = 0;
int millisecondsPerFrame;
bool isFront = true;
Point sheetSize = new Point(2,3);
public void qlayer(Vector2 position, Texture2D texture, SpriteBatch spritebatch)
{
this.position = position;
this.texture = texture;
}
enum PlayerAni
{
left, front, right
};
PlayerAni currentAni = PlayerAni.front;
public void Update(GameTime gameTime)
{
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame = 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
currentFrame.Y = 0;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A))
{
position.X -= 3;
currentAni = PlayerAni.left;
}
else
{
if (Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D))
{
position.X += 3;
currentAni = PlayerAni.right;
}
else
{
currentAni = PlayerAni.front;
}
}
}
public void Draw(GameTime gameTime, SpriteBatch spritebatch)
{
spritebatch.Begin();
spritebatch.Draw(texture,
position, new Rectangle(currentFrame.X * 76,
currentFrame.Y * 54,
76, 54),
Color.White, 0, Vector2.Zero,
1f, SpriteEffects.None, 0);
spritebatch.End();
}
}

public void qlayer
Take out the word void. Constructors don't have a "return" type, including void. Your constructor should look like this:
public qlayer(Vector2 position, Texture2D texture)
and/or
public qlayer(Vector2 position, Texture2D texture, SpriteBatch spritebatch)

Related

Making Kitty Cannon in Monogame, how do I align a cannonball with its cannon?

As the title says, I'm trying to make a simple 2D game similar to Kitty Cannon in Monogame. However I'm having trouble with aligning the cannonball with the pipe, since it's rotatable. How do I connect the cannonball's spawn point with the correct angle and position?
I'm posting the code I currently have below, hope it's understandable!
class CannonBallSprite
{
private Texture2D texture;public bool shootingActive = false;
public bool shootCannon = false;
public bool keyPressed = false;
public Vector2 position;
public Vector2 origin;
public Vector2 speed = new Vector2(0, 0.1f);
public Vector2 originalSpeed = new Vector2(0, 0.1f);
public Vector2 angle; //Trajectory
public float scale;
public float minPower = 10;
public float maxPower = 15;
public float power = 10;
public CannonBallSprite(Texture2D texture)
{
this.texture = texture;
}
public void Update(float rotation, Sprite sprite)
{
if (Keyboard.GetState().IsKeyDown(Keys.Left) && power > minPower && !keyPressed)
{
power -= 1;
keyPressed = true;
}
else if (Keyboard.GetState().IsKeyDown(Keys.Right) && power < maxPower && !keyPressed)
{
power += 1;
keyPressed = true;
}
if (Keyboard.GetState().IsKeyUp(Keys.Left) && keyPressed)
{
System.Threading.Thread.Sleep(300);
keyPressed = false;
}
else if(Keyboard.GetState().IsKeyUp(Keys.Right) && keyPressed)
{
System.Threading.Thread.Sleep(300);
keyPressed = false;
}
if (Keyboard.GetState().IsKeyDown(Keys.Space) && !shootingActive)
{
position = new Vector2(107, 365); // here maybe?
sprite.hasHit = false;
shootCannon = true;
}
if(shootCannon)
{
Move(angle, power);
speed += new Vector2(0, 0.1f); //standard gravitation
angle = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
Debug.Write("test");
position += speed; //Definiera marken
}
else
{
speed = originalSpeed;
}
}
public void Move(Vector2 rot, float shootPower)
{
position.X += rot.X * shootPower;
position.Y += rot.Y * shootPower;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, null, Color.White, 0, origin, scale, SpriteEffects.None, 0f);
}
}
Game1 Class:
namespace CannonShoot
{
public class Game1 : Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private Texture2D cannon;
private Texture2D cannonball;
private Texture2D man;
private SpriteFont font;
private Sprite spriteCannon;
private Sprite manSprite;
private CannonBallSprite cannonBallSprite;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
font = Content.Load<SpriteFont>("fontfile");
cannon = Content.Load<Texture2D>("cannon");
cannonball = Content.Load<Texture2D>("cannonball");
man = Content.Load<Texture2D>("man");
spriteCannon = new Sprite(cannon)
{
position = new Vector2(100, 400),
origin = new Vector2(cannon.Width / 2, cannon.Height / 2),
scale = 0.12f
};
cannonBallSprite = new CannonBallSprite(cannonball)
{
position = new Vector2(1150, 3750),
scale = 0.2f
};
manSprite = new Sprite(man)
{
position = new Vector2(700, 250),
origin = new Vector2(man.Width / 2, man.Height / 2),
scale = 0.4f
};
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if(!cannonBallSprite.shootCannon)
{
spriteCannon.Update();
}
//cannonBallSprite = (spriteCannon.position.X, spriteCannon.position.Y);
cannonBallSprite.Update(spriteCannon.rotation, manSprite);
manSprite.UpdateHitbox(cannonBallSprite);
if(cannonBallSprite.position.X >= 1000 || cannonBallSprite.position.Y >= 600) //respawn
{
cannonBallSprite.shootCannon = false;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteCannon.Draw(spriteBatch);
manSprite.Draw(spriteBatch);
cannonBallSprite.Draw(spriteBatch);
spriteBatch.DrawString(font, "Power: " + cannonBallSprite.power, new Vector2(16, 16), Color.Black);
spriteBatch.DrawString(font, "Hits: " + manSprite.hit, new Vector2(16, 62), Color.Black);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Sprite class:
namespace CannonShoot
{
class Sprite
{
private Texture2D texture;
public Vector2 position;
public Vector2 origin;
public float scale;
public float rotationVelocity = 3f;
public float linearVelocity = 4f;
public float minRot = -1f;
public float maxRot = 0f;
public float rotation;
public float hit = 0;
public bool hasHit = false;
public Sprite(Texture2D texture)
{
this.texture = texture;
}
public void Update()
{
if (rotation <= maxRot && rotation >= minRot)
{
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
rotation -= MathHelper.ToRadians(rotationVelocity);
}
else if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
rotation += MathHelper.ToRadians(rotationVelocity);
}
if(rotation < minRot)
{
rotation = minRot;
}
if (rotation > maxRot)
{
rotation = maxRot;
}
}
}
public void UpdateHitbox(CannonBallSprite cbSprite) //hitbox och
{
if(cbSprite.position.X >= 700 && cbSprite.position.Y <= 350 && cbSprite.position.Y >= 150 && !hasHit)
{
hit++;
hasHit = true;
cbSprite.shootCannon = false;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, null, Color.White, rotation, origin, scale, SpriteEffects.None, 0f);
}
}
}
Here is how I draw something (object B) at a specific position of something else (object A).
First, you need to have a method (or something) to get the X and Y position of object A:
public float getPosX()
{
return pos.X;
}
Then you simply set the position of your object B in Update method as below:
objectB.setPos(objectA.getposX() + offsetX, objectA.getposY() + offsetY);
I would recommend you draw your object A in a specific scale to your screen's width and height (for example, objectA.width = screenWidth / 10). After doing this, if your object A is moving, your object B will always follow object A's position.
Edit: The image below is the result of my code:
The code to get the barrel position of a rotating object:
angle = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
SpawnPosition = position + angle * TextureWidth * scale; // + .5f * TextureHeight * scale; if origin is at 0,0.
The width and height are based on the cannon texture pointing to the right.

Move enemy sprite depending on which side it spawns. c# monogame

So I have a code where the sprite spawn outside the window and I want it to move on a specific straight line depending on where it spawn say if the sprite spawn at the top it goes at the bottom and vise versa if the sprite then spawn to the left it will go right and vise versa.
Game1.cs code:
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player;
List<Enemy> enemies = new List<Enemy>();
public Vector2 ecords
{
get { return ecords; }
set { ecords = value; }
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//player
Texture2D playertexture = Content.Load<Texture2D>("Player");
player = new Player(new Vector2(350, 175), playertexture);
//enemy
Texture2D enemytexture = Content.Load<Texture2D>("Enemy");
Random random = new Random();
var width = GraphicsDevice.Viewport.Width;
var height = GraphicsDevice.Viewport.Height;
for (int i = 0; i < 20; i++)
{
enemies.Add(new Enemy(new Vector2(random.Next(width, width + 100), random.Next(0, height)), enemytexture));
enemies.Add(new Enemy(new Vector2(random.Next(0 - 100, 0), random.Next(0, height)), enemytexture));
enemies.Add(new Enemy(new Vector2(random.Next(0, width), random.Next(-100, 0)), enemytexture));
enemies.Add(new Enemy(new Vector2(random.Next(0, width), random.Next(height, height + 100)), enemytexture));
}
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
foreach (Enemy enemy in enemies)
{
enemy.Update(gameTime);
}
player.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
foreach (Enemy enemy in enemies)
{
enemy.Draw(spriteBatch);
}
player.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Enemy.cs
class Enemy
{
Texture2D enemytexture;
Vector2 enemyposition;
public Enemy(Vector2 enemyposition, Texture2D enemytexture)
{
this.enemyposition = enemyposition;
this.enemytexture = enemytexture;
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(enemytexture, enemyposition, Color.White);
}
}
One option would be to add a velocity (or you can name it movement/direction) to Enemy, passed to the constructor in a parameter just like your existing enemyposition. Then update the current position by adding the velocity in the Update method of Enemy:
public void Update(GameTime gameTime)
{
this.enemyposition += this.velocity;
}
You can use unit vectors (optionally multiplied by speed) for the velocity value:
var (left, right) = (-Vector2.UnitX, Vector2.UnitX);
var (up, down) = (-Vector2.UnitY, Vector2.UnitY);
float enemySpeed = 5.0f;
enemies.Add(new Enemy(
new Vector2(random.Next(width, width + 100), random.Next(0, height)),
enemytexture, velocity: left * enemySpeed));
// etc.

Difficulty loading a texture and passing it to a class in XNA 4.0

This is an assignment for a c#/XNA 4.0 class, and no, I'm not a HWgrade-zombie. I'd let you know the circumstances for my asking about this, the amount of "research" I've done, and that I wish to learn rather than get a grade, but it'd be considered fluff and deleted.
Anyhow, the problem I'm having is that my content (a sprite sheet) which I'm trying to load into "textureImage" in Game1.cs, which is then passed to "Sprite.cs" to be drawn, via "userControlledSprite.cs", isn't being drawn when I compile my program. Being new to c# and XNA both, I understand the issue (that the content loads, but isn't passed correctly), but I'm lost regarding a way to address it.
Here are the full three classes that my program consists of:
Game1.cs -- Calls the userControlledSprite.
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 Proj06
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
static Texture2D textureImage;
static Point frameSize = new Point(52,50);
static Point currentFrame = new Point(0, 0);
static Point sheetSize = new Point(4, 1);
static Vector2 position = Vector2.Zero;
static int collisionOffset = 1;
static Vector2 speed;
userControlledSprite UserControlledSprite1;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(#"images/Picture");
UserControlledSprite1 = new userControlledSprite(textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
}
protected override void UnloadContent()
{
/// Ignore this void
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
UserControlledSprite1.Draw(gameTime, spriteBatch);
base.Draw(gameTime);
}
}
}
Sprite.cs -- Draws and animates the sprite, as well as checks for collisions.
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 Proj06
{
abstract class Sprite
{
Texture2D textureImage;
protected Point frameSize;
Point currentFrame;
Point sheetSize;
int collisionOffset;
int timeSinceLastFrame = 0;
int millisecondsPerFrame;
const int defaultMillisecondsPerFrame = 16;
protected Vector2 speed;
protected Vector2 position;
public Sprite(Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed)
: this(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, defaultMillisecondsPerFrame)
{
}
public Sprite(Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed,
int millisecondsPerFrame)
{
this.textureImage = textureImage;
this.position = position;
this.frameSize = frameSize;
this.collisionOffset = collisionOffset;
this.currentFrame = currentFrame;
this.sheetSize = sheetSize;
this.speed = speed;
this.millisecondsPerFrame = millisecondsPerFrame;
}
public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame = 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
{
currentFrame.Y = 0;
}
}
}
}
public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(textureImage,
position,
new Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y,
frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero,
1f, SpriteEffects.None, 0);
spriteBatch.End();
}
public abstract Vector2 direction
{
get;
}
public Rectangle collisionRect
{
get
{
return new Rectangle(
(int)position.X + collisionOffset,
(int)position.Y + collisionOffset,
frameSize.X - (collisionOffset * 2),
frameSize.Y - (collisionOffset * 2));
}
}
}
}
and userControlledSprite.cs -- deals with the sprite's movement and position
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
class userControlledSprite : Sprite
{
public userControlledSprite(Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed)
: base(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed)
{
}
public userControlledSprite(Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed, int millisecondsPerFrame)
: base(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, millisecondsPerFrame)
{
}
public override Vector2 direction
{
get
{
Vector2 inputDirection = Vector2.Zero;
if (Keyboard.GetState().IsKeyDown(Keys.Left))
inputDirection.X -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Right))
inputDirection.X += 1;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
inputDirection.Y -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
inputDirection.Y += 1;
return inputDirection * speed;
}
}
public override void Update(GameTime gameTime, Rectangle clientBounds)
{
position += direction;
if (position.X < 0)
position.X = 0;
if (position.Y < 0)
position.Y = 0;
if (position.X > clientBounds.Width - frameSize.X)
position.X = clientBounds.Width - frameSize.X;
if (position.Y > clientBounds.Height - frameSize.Y)
position.X = clientBounds.Height - frameSize.Y;
base.Update(gameTime, clientBounds);
}
}
}
I will continue searching online for any helpful resources, and will post edits if I find anything. Thanks for your time.
Leave the field definition for UserControlledSprite1 where it is, but don't initialize it there:
public class Game1 : Microsoft.Xna.Framework.Game
{
userControlledSprite UserControlledSprite1;
}
Then initialize it in the LoadContent() method right after loading the texture:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(#"images/Picture");
UserControlledSprite1 = new userControlledSprite(textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
}
Also, make sure you're calling the UserControlledSprite1.Draw() method in Game1.Draw().
It's pretty simple here, your Draw and Update methods are never called.
If you want them to be called automatically by XNA, your Sprite class needs to extend DrawableGameComponent and be registered within Game1. For that, you'll need to pass Game as an argument. The Draw method you'll override will also need a SpriteBatch, so pass it in the constructor too. It's not really a clean way to do it, but it will work. Then call Components.Add on each DrawableGameComponent you have.
Once that's done, simply call spriteBatch.Begin() and spriteBatch.End() in Game1 (to do only one call on Begin and End), each Sprite will then draw itself.
I also took the liberty to remove useless usings and fix your class names to fit C# conventions (PascalCase).
The important parts that changed are :
userControlledSprite now receives the spriteBatch and Game class
userControlledSprite is registered as a component
Sprite now extends DrawableGameComponent
spriteBatch.Begin and End are now called
Sprite now overrides the correct Draw method.
Please note I've left your Update method unchanged. It will not be called unless you change it for public override void Update(GameTime gameTime).
If you set a breakpoint in Draw, it should be called by XNA.
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D textureImage;
private Point frameSize = new Point(52, 50);
private Point currentFrame = new Point(0, 0);
private Point sheetSize = new Point(4, 1);
private Vector2 position = Vector2.Zero;
private int collisionOffset = 1;
private Vector2 speed;
private UserControlledSprite userControlledSprite1;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(#"images/Picture");
userControlledSprite1 = new UserControlledSprite(this, spriteBatch, textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
Components.Add(userControlledSprite1);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
spriteBatch.Begin();
base.Draw(gameTime);
spriteBatch.End();
}
}
}
UserControlledSprite.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
class UserControlledSprite : Sprite
{
public UserControlledSprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed)
: base(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed)
{
}
public UserControlledSprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed, int millisecondsPerFrame)
: base(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, millisecondsPerFrame)
{
}
public override Vector2 direction
{
get
{
Vector2 inputDirection = Vector2.Zero;
if (Keyboard.GetState().IsKeyDown(Keys.Left))
inputDirection.X -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Right))
inputDirection.X += 1;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
inputDirection.Y -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
inputDirection.Y += 1;
return inputDirection * speed;
}
}
public override void Update(GameTime gameTime, Rectangle clientBounds)
{
position += direction;
if (position.X < 0)
position.X = 0;
if (position.Y < 0)
position.Y = 0;
if (position.X > clientBounds.Width - frameSize.X)
position.X = clientBounds.Width - frameSize.X;
if (position.Y > clientBounds.Height - frameSize.Y)
position.X = clientBounds.Height - frameSize.Y;
base.Update(gameTime, clientBounds);
}
}
}
Sprite.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Proj06
{
abstract class Sprite : DrawableGameComponent
{
Texture2D textureImage;
protected Point frameSize;
Point currentFrame;
Point sheetSize;
int collisionOffset;
int timeSinceLastFrame = 0;
int millisecondsPerFrame;
const int defaultMillisecondsPerFrame = 16;
protected Vector2 speed;
protected Vector2 position;
private SpriteBatch spriteBatch;
public Sprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed)
: this(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, defaultMillisecondsPerFrame)
{
}
public Sprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed,
int millisecondsPerFrame) : base(game)
{
this.textureImage = textureImage;
this.position = position;
this.frameSize = frameSize;
this.collisionOffset = collisionOffset;
this.currentFrame = currentFrame;
this.sheetSize = sheetSize;
this.speed = speed;
this.millisecondsPerFrame = millisecondsPerFrame;
spriteBatch = sb;
}
public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame = 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
{
currentFrame.Y = 0;
}
}
}
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Draw(textureImage,
position,
new Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y,
frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero,
1f, SpriteEffects.None, 0);
base.Draw(gameTime);
}
public abstract Vector2 direction
{
get;
}
public Rectangle collisionRect
{
get
{
return new Rectangle(
(int)position.X + collisionOffset,
(int)position.Y + collisionOffset,
frameSize.X - (collisionOffset * 2),
frameSize.Y - (collisionOffset * 2));
}
}
}
}
As an addendum, I'd strongly suggest you move to MonoGame. XNA is not supported anymore (It was killed off by Microsoft a long time ago) and MonoGame is the open source implementation. Not much have changed, but you'll still need to use XNA's content pipeline (the .XNB files).
If you want to stick to XNA, start projects with the Platformer Starter Kit. You will better see how XNA works, as your architecture is quite weird.

Unable to set texture in constructor

I have a problem with source Rectangle and because of this my texture does not show on the screen.
When I use Draw method with source as null the texture works.
I have no idea what is wrong with this.
Also if I put this into the constructor: source=new Rectangle((int)position.x,(int)position.Y, texture.Width/frameas, texture.Height). I get the error
"use new keyword to create an object"
There is no error in my Game1 for sure as I only load texture,update, and draw in there.
public class Player
{
public Texture2D texture;
public Vector2 position;
public int speed, width,frames, jump;
public float scale;
public Vector2 velocity;
public float gravity;
public bool hasJumped;
public Rectangle source;
public Player(int x, int y)
{
speed = 5;
position.X = x;
position.Y = y;
scale = 1.8f;
frames = 4;
source = new Rectangle(x,y, 30,30);
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("player");
}
public void Update(GameTime gameTime)
{
position += velocity;
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.D))
{
velocity.X = 3f;
}
if (keyState.IsKeyDown(Keys.A))
{
velocity.X = -3f;
}
if (keyState.IsKeyDown(Keys.Space) && hasJumped==false)
{
position.Y -= 10f;
velocity.Y = -5f;
hasJumped = true;
}
if (hasJumped == true)
velocity.Y += 0.15f;
else
velocity.Y = 0f;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, source, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f);
}
}
}
You can't reference texture within your constructor because it doesn't exist yet. It's not set to an actual value until you load the texture in LoadContent(), so when you try to use it to build your rectangle it's throwing a NullReferenceException.
Create your source rectangle after this line:
texture = Content.Load<Texture2D>("player");

Why is my Texture origin is incorrect at runtime?

Alright, so this is the code:
Game1.cs Class:
public class Game1 : Microsoft.Xna.Framework.Game
{
KeyboardState keyboard;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player MyPlayer;
Texture2D Ball;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
IsMouseVisible = true;
graphics.IsFullScreen = true;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Ball = Content.Load<Texture2D>("Images/Ball");
MyPlayer = new Player(new Vector2(700, 700), Ball);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Escape))
this.Exit();
MyPlayer.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
MyPlayer.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Game object class:
abstract class GameObject
{
protected Vector2 position;
protected Texture2D texture;
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero;
this.texture = Texture;
}
protected Vector2 Position { set; get; }
protected Texture2D Texture { set; get; }
protected float X
{
set { position.X = value; }
get { return position.X; }
}
protected float Y
{
set
{
position.Y = value;
}
get
{
return position.Y;
}
}
public int GraphicsWidth { set; get; }
public int GraphicsHeight { set; get; }
}
Player class:
class Player : GameObject
{
KeyboardState keyboard;
bool IsJump = false;
int SpeedX = 5;
int SpeedY = 5;
public Player(Vector2 position, Texture2D tex):base(position,tex)
{
}
public int Height
{
get { return this.texture.Height; }
}
public int Width
{
get { return this.texture.Width; }
}
public void intialize()
{
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, Position, Color.White);
}
public void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.D))
{
X += SpeedX;
}
else if (keyboard.IsKeyDown(Keys.A))
{
X-= SpeedX;
}
if (X > GraphicsWidth)
{
X = GraphicsWidth;
}
}
}
When I'm debugging it, My ball texture is in (0,0) (TOP LEFT). Instead of (700,700).
BTW, If anyone can give me some advices if I made anything wrong, or anything I should change, it Would be great!!
Thanks alot for helpers.
EDIT: Anyone.. please? I suppose it's not so hard to figure it out ><.
In your GameObject constructor you are setting the position to Vector2.Zero and not to your param Position.
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero;
this.texture = Texture;
}
should be
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Position;
this.texture = Texture;
}
There are two issues I see. The first one, answered by CraigW, you've already fixed:
protected Vector2 position;
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero; // <---- this needs to be position = Position
this.texture = Texture;
}
protected Vector2 Position { set; get; }
The second issue is your Position property. When you declare a property using the { get; set; } syntax the compiler is implicitly giving you a backing field to store the value of the property. But you're creating your own position field as well. Your position field is getting set to the value passed in the constructor (assuming you've fixed issue #1 in your constructor that is), but the getter for your Position property is returning the compiler generated field, which you haven't set to anything.
There are two ways you can fix this. Either remove your position field and reference the Position property everywhere, or modify your property to use your position field.
Fix Option #1: just use the Position property
// protected Vector2 position; // <----- remove this
public GameObject(Vector2 Position, Texture2D Texture)
{
this.Position = Position;
this.texture = Texture;
}
Fix Option #2: Change your Position property to use your field
protected Vector2 Position { get { return position; } set { position = value; } }
-7? What did you do deserve this!?
I think there's a logic error somewhere in your code, change this:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, Position, Color.White);
}
To this:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, new Vector2(700,700), Color.White);
}
And see how it works for you (it should work fine) :)
From there you're going to have to work backwards to find where Position is not being set to the value you want.
Personally I've never been a fan of gameobject, much better to create your own base types since you have total control over how they work and can more easily solve issues that pop up.

Categories