Ive been trying to draw a simple cube in xna but its showing up completely black. Ive tried multiple diffirent FBX models. Played around with the settings for the models in the pipeline. Ive also to apply basic lightning in every way possible. Its still appearing black.
My code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
namespace Game1
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
BasicEffect effect;
Texture2D floor;
Model model;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
effect = new BasicEffect(graphics.GraphicsDevice);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
floor = Content.Load<Texture2D>("floor");
model = Content.Load<Model>("cube");
}
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();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
var cameraPosition = new Vector3((float)Math.Cos((double)gameTime.TotalGameTime.TotalMilliseconds/1000)*20, 40, (float)Math.Cos((double)gameTime.TotalGameTime.TotalMilliseconds / 1000) * 20);
var cameraLookAtVector = Vector3.Zero;
var cameraUpVector = Vector3.UnitZ;
effect.View = Matrix.CreateLookAt(
cameraPosition, cameraLookAtVector, cameraUpVector);
float aspectRatio =
graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight;
float fieldOfView = Microsoft.Xna.Framework.MathHelper.PiOver4;
float nearClipPlane = 1;
float farClipPlane = 200;
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
fieldOfView, aspectRatio, nearClipPlane, farClipPlane);
effect.TextureEnabled = true;
effect.Texture = floor;
drawModel(model, effect.World, effect.View, effect.Projection);
foreach (var pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
drawQuad(new Vector3[] {
new Vector3(20,-20,0),
new Vector3(-20,-20,0),
new Vector3(-20,20,0),
new Vector3(20,20,0),
},2f);
}
base.Draw(gameTime);
}
public void drawQuad(Vector3[] p, float tiling)
{
VertexPositionNormalTexture[] verts = new VertexPositionNormalTexture[6];
verts[0].Position = p[0];
verts[1].Position = p[1];
verts[2].Position = p[3];
verts[3].Position = p[1];
verts[4].Position = p[2];
verts[5].Position = p[3];
verts[0].Normal = p[0];
verts[1].Normal = p[1];
verts[2].Normal = p[3];
verts[3].Normal = p[1];
verts[4].Normal = p[2];
verts[5].Normal = p[3];
verts[0].TextureCoordinate = new Vector2(0, 0);
verts[1].TextureCoordinate = new Vector2(0, tiling);
verts[2].TextureCoordinate = new Vector2(tiling, 0);
verts[3].TextureCoordinate = verts[1].TextureCoordinate;
verts[4].TextureCoordinate = new Vector2(tiling, tiling);
verts[5].TextureCoordinate = verts[2].TextureCoordinate;
graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, 2);
}
public void drawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (var mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.DiffuseColor = Color.White.ToVector3();
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
}
}
FBX doesn't embed textures in the model file itself, it just stores a path to the texture file. This path is usually relative to the export location (but it depends on the tool).
Try placing the texture file in the same relative path as it was with the export location, but in the output directory of the executable. Otherwise, FBX files are human readable IIRC, so you should be able to determine where it is looking for the texture, and put it there.
Related
I'm building a breakout type game and I'm having a little issue with collision detection. How should I create the rectangle(s), do I do one rectangle per block but then how do I detect which side has been hit, or do I do 4 rectangles for each side of the block and base an if statement around them.
I tried to create 4 rectangles per block, one for top, bottom etc etc but I couldn't get it correct.
heres my code to see if you can work out the best way to handle it.
Brick class:
class Bricks
{
Texture2D redbrickimg;
Texture2D blueBrickimg;
Texture2D greenBrickimg;
Texture2D pinkBrickimg;
Texture2D aquaBrickimg;
/*Rectangle aquaBrickrectangle;
Rectangle redBrickrectangle;
Rectangle blueBrickrectangle;
Rectangle greenBrickrectangle;
Rectangle pinkBrickrectangle;
*/
Rectangle[,] topHit = new Rectangle[12,12];
Rectangle[,] bottomHit = new Rectangle[12,12];
Rectangle[,] rightHit = new Rectangle[12,12];
Rectangle[,] leftHit = new Rectangle[12,12];
int[,] redBrickXPos = new int [12,12];
int[,] redBrickYPos = new int [12,12];
int[,] colourBrick = new int[12, 12];
public Bricks(
Texture2D Redbricks,
Texture2D blueBricks,
Texture2D greenBricks,
Texture2D pinkBricks,
Texture2D aquaBricks
)
{
redbrickimg = Redbricks;
blueBrickimg = blueBricks;
greenBrickimg = greenBricks;
pinkBrickimg = pinkBricks;
aquaBrickimg = aquaBricks;
}
public void Initialize()
{
for (int j = 0; j < 12; j++)
{
for (int i = 0; i < 12; i++)
{
redBrickXPos[j,i] = 1 + i * redbrickimg.Width;
redBrickYPos[j,i] = 1 + j * redbrickimg.Height;
colourBrick[j,i] = j/2;
}
}
}
public void Update()
{
}
public void Draw(SpriteBatch spritebatch)
{
for (int j = 0; j < 12; j++)
{
for (int i = 0; i < 12; i++)
{
if (colourBrick[j, i] == 0)
{
spritebatch.Draw(redbrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
}
else if (colourBrick[j, i] == 1)
{
spritebatch.Draw(blueBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
}
else if (colourBrick[j, i] == 2)
{
spritebatch.Draw(greenBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]), Color.White);
}
else if (colourBrick[j, i] == 3)
{
spritebatch.Draw(pinkBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
}
else if (colourBrick[j, i] == 4)
{
spritebatch.Draw(aquaBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]), Color.White);
}
}
}
}
}
My main class:
public class Breakout : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D BackgroundImg;
Bricks bricks;
Paddle paddle;
GameBall gameball;
bool iskeyLeft = false;
bool iskeyRight = false;
bool Flag;
int moveBy;
float ballX;
float ballY;
public Breakout()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 960;
graphics.PreferredBackBufferHeight = 768;
graphics.ApplyChanges();
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
bricks.Initialize();
paddle.Initialize();
gameball.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);
BackgroundImg = Content.Load<Texture2D>("starfield");
bricks = new Bricks(
Content.Load<Texture2D>("red brick"),
Content.Load<Texture2D>("brickblue"),
Content.Load<Texture2D>("greenbrick"),
Content.Load<Texture2D>("pinkbrick"),
Content.Load<Texture2D>("aquaBrick")
);
paddle = new Paddle(Content.Load<Texture2D>("Paddle"),
new Rectangle(0, 0, 110, 30),iskeyLeft,iskeyRight);
gameball = new GameBall(Content.Load <Texture2D>("ball"),
new Rectangle(0, 0, 60, 60));
IsMouseVisible = true;
// TODO: use this.Content to load your game content here
}
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();
// call update on paddle
moveBy = paddle.Update();
Flag = gameball.Update();
if (Flag == false)
{
gameball.moveBall(moveBy);
}
// TODO: Add your update logic here
// mainmenu = new mainmenu(mainmenuISon, Content.Load<Texture2D>("option_menu"),
Content.Load<Texture2D>("start_button"), Content.Load<Texture2D>("exit_button"));
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
spriteBatch.Begin();
spriteBatch.Draw(BackgroundImg, Vector2.Zero, Color.White);
bricks.Draw(spriteBatch);
paddle.Draw(spriteBatch);
gameball.Draw(spriteBatch);
spriteBatch.End();
}
}
You left out the most interesting part of your code where you're actually attempting the collision test.
I would go with one rect for your brick (and thereby only one collision test per brick) and only if that passes you need to figure out what side was hit. You can easily rule out two sides by the direction of the GameBall (you cannot hit the "backside"). For the remaining two sides you check if the "front" corner is on the left or right of your current line of movement.
currently trying to animate an array of enemy sprites for within a game I'm producing in C# using XNA 4.0
Using this animation code
namespace Rotationgame
{
class Animation
{
Texture2D texture;
Rectangle rectangle;
Vector2 position;
Vector2 origin;
Vector2 velocity;
int currentFrame;
int frameHeight;
int frameWidth;
float timer;
float interval = 150;
public Animation(Texture2D newTexture, Vector2 newPosition, int newFrameHeight, int newFrameWidth)
{
texture = newTexture;
position = newPosition;
frameHeight = newFrameHeight;
frameWidth = newFrameWidth;
}
public void Update(GameTime gameTime)
{
rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
origin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);
position = position + velocity;
if (Keyboard.GetState().IsKeyUp(Keys.F1))
{
AnimateRight(gameTime);
velocity.X = 0;
}
else if (Keyboard.GetState().IsKeyUp(Keys.F2))
{
AnimateLeft(gameTime);
velocity.X = -0;
}
else velocity = Vector2.Zero;
}
public void AnimateRight(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
if (timer > interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 1)
currentFrame = 0;
}
}
public void AnimateLeft(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
if (timer > interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 1)
currentFrame = 0;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, rectangle, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
}
}
}
And this code for the array
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Animation[] invaders;
protected override void Initialize()
{
invaders = new Animation[13];
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Array of Space Invaders
invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
invaders[12] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// Drawing Invaders
foreach (Animation invader in invaders)
invaders.Draw(spriteBatch);
}
spriteBatch.End();
Everything works in the code in visual Studio however I get a error on the Draw method saying: "Error 1 'System.Array' does not contain a definition for 'Draw' and no extension method 'Draw' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)"
Any ideas what's gone wrong?
Edit: Here is full code of game1 file
namespace Rotationgame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Animation[] invaders;
// Different Windows
enum GameState
{
MainMenu,
Playing,
}
GameState CurrentGameState = GameState.MainMenu;
// Screeb Adjustments
int screenWidth = 1250, screenHeight = 930;
// Main Menu Buttons
button btnPlay;
button btnQuit;
// Pause Menu & buttons
bool paused = false;
button btnResume;
button btnMainMenu;
// Player's Movement
Vector2 spriteVelocity;
const float tangentialVelocity = 0f;
float friction = 1f;
Texture2D spriteTexture;
Rectangle spriteRectangle;
Vector2 spritePosition;
float rotation;
// The centre of the image
Vector2 spriteOrigin;
// Background
Texture2D backgroundTexture;
Rectangle backgroundRectangle;
// Shield
Texture2D shieldTexture;
Rectangle shieldRectangle;
// Bullets
List<Bullets> bullets = new List<Bullets>();
KeyboardState pastKey;
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()
{
invaders = new Animation[12];
// 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);
// Load Player's Shield (Cosmetic at moment as not set up fully
shieldTexture = Content.Load<Texture2D>("Shield");
shieldRectangle = new Rectangle(517, 345, 250, 220);
// Load Player's Ship
spriteTexture = Content.Load<Texture2D>("PlayerShipright");
spritePosition = new Vector2(640, 450);
// Load Game background
backgroundTexture = Content.Load<Texture2D>("Background");
backgroundRectangle = new Rectangle(0, 0, 1250, 930);
// Screen Adjustments
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.ApplyChanges();
IsMouseVisible = true;
// Main menu Buttons & locations
btnPlay = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
btnPlay.setPosition(new Vector2(550, 310));
btnQuit = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
btnQuit.setPosition(new Vector2(550, 580));
// Array of Space Invaders
invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
invaders[6] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);
// Pause menu buttons & locations
btnResume = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
btnResume.setPosition(new Vector2(550, 310));
btnMainMenu = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
btnMainMenu.setPosition(new Vector2(550, 580));
// 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)
{
MouseState mouse = Mouse.GetState();
// Allows the game to exit
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
switch (CurrentGameState)
{
case GameState.MainMenu:
if(btnPlay.isClicked == true) CurrentGameState = GameState.Playing;
btnPlay.Update(mouse);
if (btnQuit.isClicked == true)
this.Exit();
btnQuit.Update(mouse);
break;
case GameState.Playing:
if (!paused)
{
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
{
paused = true;
btnResume.isClicked = false;
}
}
else if (paused)
{
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
if (btnResume.isClicked)
paused = false;
if (btnMainMenu.isClicked) CurrentGameState = GameState.MainMenu;
}
break;
}
// TODO: Add your update logic here
if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
Shoot();
pastKey = Keyboard.GetState();
spritePosition = spriteVelocity + spritePosition;
spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y,
spriteTexture.Width, spriteTexture.Height);
spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);
if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f;
if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
}
else if (Vector2.Zero != spriteVelocity)
{
float i = spriteVelocity.X;
float j = spriteVelocity.Y;
spriteVelocity.X = i -= friction * i;
spriteVelocity.Y = j -= friction * j;
base.Update(gameTime);
}
UpdateBullets();
}
public void UpdateBullets()
{
foreach (Bullets bullet in bullets)
{
bullet.position += bullet.velocity;
if (Vector2.Distance(bullet.position, spritePosition) > 760)
bullet.isVisible = false;
}
for (int i = 0; i < bullets.Count; i++)
{
if(!bullets[i].isVisible)
{
bullets.RemoveAt(i);
i--;
}
}
}
public void Shoot()
{
Bullets newBullet = new Bullets(Content.Load<Texture2D>("bullet"));
newBullet.velocity = new Vector2((float)Math.Cos(rotation),(float)Math.Sin(rotation)) * 3f + spriteVelocity;
newBullet.position = spritePosition + newBullet.velocity * 5;
newBullet.isVisible = true;
if(bullets.Count() < 25)
bullets.Add(newBullet);
}
/// <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();
switch (CurrentGameState)
{
case GameState.MainMenu:
spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnPlay.Draw(spriteBatch);
btnQuit.Draw(spriteBatch);
break;
case GameState.Playing:
// Drawing Background
spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White);
// Drawing Shield
spriteBatch.Draw(shieldTexture, shieldRectangle, Color.White);
// Drawing Invaders
foreach (Animation invader in invaders)
invader.Draw(spriteBatch);
// Drawing Bullets
foreach (Bullets bullet in bullets)
bullet.Draw(spriteBatch);
// Drawing Player's Character
spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0);
if (paused)
{
spriteBatch.Draw(Content.Load<Texture2D>("PauseMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnResume.Draw(spriteBatch);
btnMainMenu.Draw(spriteBatch);
}
break;
}
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
2nd Edit: Button class
namespace Rotationgame
{
class button
{
Texture2D texture;
Vector2 position;
Rectangle rectangle;
Color colour = new Color(255, 255, 255, 255);
public Vector2 size;
public button(Texture2D newTexture, GraphicsDevice graphics)
{
texture = newTexture;
// ScreenW = 1250 (currently atm 800), ScreenH = 930 (currently atm 600)
//ImgW = 100 , ImgH = 20
size = new Vector2(graphics.Viewport.Width / 8, graphics.Viewport.Height / 30);
}
bool down;
public bool isClicked;
public void Update(MouseState mouse)
{
rectangle = new Rectangle((int)position.X,(int)position.Y,
(int)size.X, (int)size.Y);
Rectangle mouseRectangle = new Rectangle(mouse.X, mouse.Y, 1, 1);
if (mouseRectangle.Intersects(rectangle))
{
if (colour.A == 255) down = false;
if (colour.A == 0) down = true;
if (down) colour.A += 3; else colour.A -= 3;
if (mouse.LeftButton == ButtonState.Pressed) isClicked = true;
}
else if (colour.A < 255)
{
colour.A += 3;
isClicked = false;
}
}
public void setPosition(Vector2 newPosition)
{
position = newPosition;
}
public void Draw(SpriteBatch spritebatch)
{
spritebatch.Draw(texture, rectangle, colour);
}
}
}
C# has wonderful library of collection classes to replace list. I highly discourage to use Array as it is not flexible enough. If you are writing code specifically for low end hardware and knowing in and out of code and managing every bit of it than and only then go for array.
But I like the way you structured classes. It is pretty good. Now, if you have list then you can add any number of class at any moment of time. You don't have to decide above time how to do that.
Now, that class has collection of Rectangles which gives the position of sprite in your sprite collection, then you just need to use the in draw method with your animation logic. Which you already have.
And one more thing, There is no need to add
Content.Load<Texture2D>("SpaceInvaderbefore")
multiple time. Instead store it to variable and use it.
With this here is the line of two wonderful article. 1 and 2. Which provide details about how to do animation with XNA.
And there is must have course of Plural Sight for game development. You can also try that.
I hope my answer helps you. please let me know if any further details required.
I'm trying to render a triangle using custom vertex data in XNA, but the output is totally messed up:
My GPU (Radeon HD7610M) supports DX11.
Either I am doing something wrong or it's my GPU drivers.
Here's my code:
public class MyGame : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
VertexBuffer vertexBuffer;
VertexPositionColor[] vertices;
BasicEffect effect;
public MyGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
TargetElapsedTime = TimeSpan.FromTicks(333333);
InactiveSleepTime = TimeSpan.FromSeconds(1);
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
effect = new BasicEffect(GraphicsDevice);
effect.VertexColorEnabled = true;
vertices = new VertexPositionColor[]
{
new VertexPositionColor(new Vector3(-0.8F, -0.8F, 0), Color.Black),
new VertexPositionColor(new Vector3(-0.8F, 0.8F, 0), Color.Black),
new VertexPositionColor(new Vector3( 0.8F, -0.8F, 0), Color.Black),
//new VertexPositionColor(new Vector3( 0.8F, 0.8F, 0), Color.Black),
};
vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
vertexBuffer.SetData<VertexPositionColor>(vertices);
}
protected override void UnloadContent() {}
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.CornflowerBlue);
GraphicsDevice.SetVertexBuffer(vertexBuffer);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
}
base.Draw(gameTime);
}
}
I'm fairly new to XNA. Am I doing something wrong?
Fixed it.
I had to either set the GDM to fullscreen:
graphics.IsFullScreen = true;
Or set the dimensions of the back buffer explicitly:
graphics.PreferredBackBufferWidth = width;
graphics.PreferredBackBufferWidth = height;
I have 2 textures 800x480 (foreground/backgound) which are .png files in XNA Windows Phone 7 application.
I want to fadeout/transision foreground to reveal background. I have huge problem with performance. My idea is only to maipulate Alpha channel in one Texture2D so i created such a code:
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D _background, _foreground;
private BlendState _blendState;
private uint[] _pixelsForeground;
private uint[] _pixelsBackground;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
TargetElapsedTime = TimeSpan.FromTicks(333333);
graphics.IsFullScreen = true;
graphics.SupportedOrientations = DisplayOrientation.Portrait;
graphics.PreferredBackBufferHeight = 840;
graphics.PreferredBackBufferWidth = 480;
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
_background = this.Content.Load<Texture2D>(#"background");
_foreground = this.Content.Load<Texture2D>(#"foreground");
_pixelsForeground = new uint[_foreground.Width * _foreground.Height];
_pixelsBackground = new uint[_foreground.Width * _foreground.Height];
_background.GetData(_pixelsBackground);
_foreground.GetData(_pixelsForeground);
_blendState = new BlendState
{
AlphaBlendFunction = BlendFunction.Add,
ColorBlendFunction = BlendFunction.Add,
AlphaSourceBlend = Blend.SourceAlpha,
ColorSourceBlend = Blend.SourceAlpha,
AlphaDestinationBlend = Blend.InverseSourceAlpha,
ColorDestinationBlend = Blend.InverseSourceAlpha
};
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
this.GraphicsDevice.Textures[0] = null;
for (int x = 0; x < _foreground.Width; x++)
{
for (int y = 0; y < _foreground.Height; y++)
{
uint pixelCanvas = _pixelsForeground[y * _foreground.Width + x];
uint newPixelCanvas = pixelCanvas - 0x05000000;
_pixelsForeground[y*_foreground.Width + x] = newPixelCanvas;
_pixelsForeground[y * _foreground.Width + x] = (newPixelCanvas & 0xFF000000) > (pixelCanvas & 0xFF000000)
? pixelCanvas & 0x00FFFFFF
: newPixelCanvas;
}
}
Rectangle rect = new Rectangle(0, 0, _foreground.Width, _foreground.Height);
_foreground.SetData<uint>(0, rect, _pixelsForeground, 0, _foreground.Height * _foreground.Width);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.FrontToBack, _blendState);
spriteBatch.Draw(_foreground, Vector2.One, null, Color.White);
spriteBatch.Draw(_background, Vector2.One, null, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Problem is that it generates poor performance because of:
_foreground.SetData<uint>(...)
What technique I can use to manage this better?
I'd rather need that manipulation of Alpha channel for other purposes.
Keep in mind that foreground pixels can have different alpha channel already on start something like transparent spots.
This is definitely the wrong way to approach this. What you want to do is pass a Color to the sprite batch's Draw method that has the appropriate alpha channel.
int alpha = 150;
spriteBatch.Draw(tex, pos, new Color(255,255,255,alpha));
That way, the GPU handles the alpha blending on your behalf, and your performance issues dissapear :-)
"Object reference not set to an instance of an object."
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 XNAdev
{
class Sprite
{
//The size of the Sprite
public Rectangle Size;
//Used to size the Sprite up or down from the original image
public float Scale = 1.0f;
//The current position of the Sprite
public Vector2 Position = new Vector2(115, 0);
//The texture object used when drawing the sprite
private Texture2D mSpriteTexture;
//Load the texture for the sprite using the Content Pipeline
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
//Draw the sprite to the screen
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);
}
}
}
I am very new at this C# so any help would be great.
I have no idea what my error is.
namespace XNAdev
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Sprite mSprite;
Sprite mSpriteTwo;
Sprite mBackgroundOne;
Sprite mBackgroundTwo;
Sprite mBackgroundThree;
Sprite mBackgroundFour;
Sprite mBackgroundFive;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
mSprite = new Sprite();
mSpriteTwo = new Sprite();
mBackgroundOne = new Sprite();
mBackgroundOne.Scale = 2.0f;
mBackgroundTwo = new Sprite();
mBackgroundTwo.Scale = 2.0f;
mBackgroundThree = new Sprite();
mBackgroundThree.Scale = 2.0f;
mBackgroundFour = new Sprite();
mBackgroundFour.Scale = 2.0f;
mBackgroundFive = new Sprite();
mBackgroundFive.Scale = 2.0f;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
mSprite.Position = new Vector2(125, 245);
mSpriteTwo.LoadContent(this.Content, "SquareGuy");
mSpriteTwo.Position.X = 300;
mSpriteTwo.Position.Y = 300;
mBackgroundOne.LoadContent(this.Content, "Background01");
mBackgroundOne.Position = new Vector2(0, 0);
mBackgroundTwo.LoadContent(this.Content, "Background02");
mBackgroundTwo.Position = new Vector2(mBackgroundOne.Position.X + mBackgroundOne.Size.Width, 0);
mBackgroundThree.LoadContent(this.Content, "Background03");
mBackgroundThree.Position = new Vector2(mBackgroundTwo.Position.X + mBackgroundTwo.Size.Width, 0);
mBackgroundFour.LoadContent(this.Content, "Background04");
mBackgroundFour.Position = new Vector2(mBackgroundThree.Position.X + mBackgroundThree.Size.Width, 0);
mBackgroundFive.LoadContent(this.Content, "Background05");
mBackgroundFive.Position = new Vector2(mBackgroundFour.Position.X + mBackgroundFour.Size.Width, 0);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
if (mBackgroundOne.Position.X < -mBackgroundOne.Size.Width)
{
mBackgroundOne.Position.X = mBackgroundFive.Position.X + mBackgroundFive.Size.Width;
}
if (mBackgroundTwo.Position.X < -mBackgroundTwo.Size.Width)
{
mBackgroundTwo.Position.X = mBackgroundOne.Position.X + mBackgroundOne.Size.Width;
}
if (mBackgroundThree.Position.X < -mBackgroundThree.Size.Width)
{
mBackgroundThree.Position.X = mBackgroundTwo.Position.X + mBackgroundTwo.Size.Width;
}
if (mBackgroundFour.Position.X < -mBackgroundFour.Size.Width)
{
mBackgroundFour.Position.X = mBackgroundThree.Position.X + mBackgroundThree.Size.Width;
}
if (mBackgroundFive.Position.X < -mBackgroundFive.Size.Width)
{
mBackgroundFive.Position.X = mBackgroundFour.Position.X + mBackgroundFour.Size.Width;
}
Vector2 aDirection = new Vector2(-1, 0);
Vector2 aSpeed = new Vector2(160, 0);
mBackgroundOne.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
mBackgroundTwo.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
mBackgroundThree.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
mBackgroundFour.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
mBackgroundFive.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
mBackgroundOne.Draw(this.spriteBatch);
mBackgroundTwo.Draw(this.spriteBatch);
mBackgroundThree.Draw(this.spriteBatch);
mBackgroundFour.Draw(this.spriteBatch);
mBackgroundFive.Draw(this.spriteBatch);
mSprite.Draw(this.spriteBatch);
mSpriteTwo.Draw(this.spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Thats the rest of the code
Lookup how to set Visual Studio to break on exceptions.
Learn how to use the debugger so you can step through your code to see where the error occurs.
I've had a look through it and managed to get it to work using validation, if the sprite you are drawing has a null reference (No texture) it will ignore it and carry on drawing everything else.
Change your Draw() method in the Sprite.cs to this:
//Draw the sprite to the screen
public void Draw(SpriteBatch theSpriteBatch)
{
if (mSpriteTexture != null)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height), Color.White,
0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
}
}
The problem occurs because you never give "Sprite mSprite;" a texture, only a position.
Quick snippet:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
mSprite.Position = new Vector2(125, 245);
mSpriteTwo.LoadContent(this.Content, "SquareGuy");
mSpriteTwo.Position.X = 300;
mSpriteTwo.Position.Y = 300;
As you can see you only give mSprite a position of 125,245, simply assign it a texture like you have with the rest of the sprites and it will work fine.
You don't need to remove the if(mSpriteTexture != null) from the Draw() method after you assign the texture though, if you don't it simply means you won't notice if something isn't being assigned correctly, could be a pain if you're debugging something else later.
Probably you should check
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
if (mSpriteTexture != null)
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
And in the Draw function too.
This error means that one of the fields or methods of an object has been tried to be accessed without the object being instantiated.
For you code seems that this is happening with the object mSpriteTexture.
You should add
mSpriteTexture = new Texture2D();
somewhere, but I can not tell where only with this piece of code.