Tile System with moving Platforms - c#

Using a tile based system I need to separate platform block from the rest and then allow them to move up and down at a constant speed.
How would I make the tile that is labeled '=' (Vertical Moving Platform) to move up or down until it hits either a '#' (Wall) or an end point '+' (Vertical Moving Platform Movement Area)?
There is a camera class that follows the player, a player class that controls the movement and a Block class that controls the collision of blocks.
List were the blocks are stored:
List<Block> Blocks;
List were the levels are stored:
List<char[,]> Levels = new List<char[,]>();
Here is where the levels are created(Test Map):
protected override void Initialize()
{
Blocks = new List<Block>();
char[,] Level2 = {{'.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.','.','.','.','.','.','.','+','.'},
{'.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.','.','.','.','.','#','.','.','.'},
{'.','.','.','.','.','.','.','-','-','-','.','.','#','.','.','.'},
{'.','.','.','.','.','.','.','.','.','.','.','.','#','.','.','.'},
{'.','.','.','-','-','-','.','.','.','.','.','.','#','.','.','.'},
{'.','.','.','.','.','.','.','.','.','.','.','.','#','.','.','.'},
{'#','#','.','.','.','.','.','.','.','P','.','.','#','.','=','.'},
{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'}};
Levels.Add(Level2);
base.Initialize();
}
Here is the void LoadLevel that will give meaning the to level(This is called when the player completes the level and in the LoadContent Method):
void LoadLevel(int level)
{
Blocks.Clear();
player.Position = Vector2.Zero;
tileWidth = Levels[level].GetLength(1);
tileHeight = Levels[level].GetLength(0);
for (int x = 0; x < tileWidth; x++)
{
for (int y = 0; y < tileHeight; y++)
{
//Background
Blocks.Add(new Block(background, new Vector2(x * 50, y * 50), 0));
//Impassable Blocks
if (Levels[level][y, x] == '#')
{
Blocks.Add(new Block(blockSpriteA, new Vector2(x * 50, y * 50), 1));
}
//Blocks that are only passable if going up them
if (Levels[level][y, x] == '-')
{
Blocks.Add(new Block(blockSpriteB, new Vector2(x * 50, y * 50), 2));
}
//Vertical Moving Platform Movement Area
if (Levels[level][y, x] == '+')
{
Blocks.Add(new Block(movingArea, new Vector2(x * 50, y * 50), 3));
}
//Vertical Moving Platform
if (Levels[level][y, x] == '=')
{
Blocks.Add(new Block(movingPlatform, new Vector2((x * 50), (y * 50) + movingPlatform.Height), 4));
}
//PlayerSpawn
if (Levels[level][y, x] == 'P' && player.Position == Vector2.Zero)
{
player.Position = new Vector2(x * 50, (y + 1) * 50 - player.Texture.Height);
player.Velocity = new Vector2(0, 0);
player.initialVelocity = 0;
player.Time = 0;
player.isJumping = false;
}
else if (Levels[level][y, x] == 'P' && player.Position != Vector2.Zero)
{
throw new Exception("Only one 'P' is needed for each level");
}
}
}
if (player.Position == Vector2.Zero)
{
throw new Exception("Player Position needs to be set with 'P'");
}
}
Update Method:
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
HandleInput(Keyboard.GetState());
player.Update(gameTime);
Time += (float)gameTime.ElapsedGameTime.TotalSeconds;
foreach (Block b in Blocks)
{
player = b.BlockCollision(player);
}
camera.thing(player);
prevKB = Keyboard.GetState();
base.Update(gameTime);
}
Draw Method:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend, null, null, null, null, camera.Transform());
//spriteBatch.Begin();
foreach (Block b in Blocks)
{
b.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}

Make a class like Block( something like MovingBlock )
Add an update method in the class so the block moves up and down.
Use the class in your LoadLevel
if (Levels[level][y, x] == '=')
{
MovingBlocks.Add(new MovingBlock(movingPlatform,
new Vector2((x * 50), (y * 50) + movingPlatform.Height)
, 4));
}

Related

How to move the ball in different directions?

Now when I hit spacebar it will go left or right, I want the ball to go straight first time.Then when the ball hit a wall, block or line after that I want the ball to go random directions with "-1" somehow. This is my first school game project, it's a one line pong game.
Edit: Edit I've added "boll_speed.X = random.Next(-1, 1);", and that works perfectly!
linje = line
liv = lives
boll = ball
poang = points
I don't use "blockröd = blockred" right now
blockgrön = blockgreen
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spritefont;
Texture2D linje_texture;
Texture2D boll_texture;
Texture2D blockröd_texture;
Texture2D blockgrön_texture;
Texture2D gameover_texture;
Rectangle linje_rect;
Rectangle boll_rect;
Rectangle blockröd_rect;
Rectangle blockgrön_rect;
Rectangle gameover_rect;
Vector2 linje_speed;
Vector2 boll_speed;
Random random;
int liv;
int poang;
int highscore;
List<Rectangle> block = new List<Rectangle>();
bool Start = false;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 760;
graphics.PreferredBackBufferHeight = 620;
}
protected override void Initialize()
{
linje_speed.X = 5f;
boll_speed.X = boll_speed.X = random.Next(-1, 1);
boll_speed.Y = 6f;
liv = 3;
poang = 0;
random = new Random();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spritefont = Content.Load<SpriteFont>("Fonts/Myfont");
linje_texture = Content.Load<Texture2D>("Pics/linje-lång");
boll_texture = Content.Load<Texture2D>("Pics/boll");
blockgrön_texture = Content.Load<Texture2D>("Pics/block-grön");
blockröd_texture = Content.Load<Texture2D>("Pics/block-röd");
gameover_texture = Content.Load<Texture2D>("Pics/GameOver");
linje_rect = new Rectangle((Window.ClientBounds.Width - linje_texture.Width) / 2, 580, linje_texture.Width, linje_texture.Height);
boll_rect = new Rectangle((Window.ClientBounds.Width - boll_texture.Width) / 2, 556, boll_texture.Width, boll_texture.Height);
gameover_rect = new Rectangle((Window.ClientBounds.Width / 2) - (gameover_texture.Width / 2), (Window.ClientBounds.Height / 2) - gameover_texture.Height / 2, gameover_texture.Width, gameover_texture.Height);
block.Add(blockgrön_rect);
block.Add(blockröd_rect);
for (int i = 1; i < 5; i++)
{
for (int g = 1; g < 13; g++)
{
block.Add(new Rectangle((g * 63) - 60, (i * 40), blockgrön_texture.Width, blockgrön_texture.Height));
}
}
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Start == true)
{
boll_rect.X += (int)boll_speed.X;
boll_rect.Y += (int)boll_speed.Y;
}
if(Start == false)
{
boll_rect.X = linje_rect.X + ((linje_texture.Width / 2) - (boll_texture.Width / 2));
}
if (boll_rect.X > Window.ClientBounds.Width - boll_texture.Width || boll_rect.X < 0)
boll_speed.X *= -1;
if (boll_rect.Y > Window.ClientBounds.Height - boll_texture.Height || boll_rect.Y < 0)
boll_speed.Y *= -1;
if (boll_rect.Y > Window.ClientBounds.Height - boll_texture.Height)
{
liv -= 1;
Start = false;
boll_rect.X = (Window.ClientBounds.Width - boll_texture.Width) / 2;
boll_rect.Y = 556;
linje_rect.X = (Window.ClientBounds.Width - linje_texture.Width) / 2;
linje_rect.Y = 580;
}
KeyboardState ks = Keyboard.GetState();
if (ks.IsKeyDown(Keys.Left))
{
linje_rect.X -= (int)linje_speed.X;
}
else if (ks.IsKeyDown(Keys.Right))
{
linje_rect.X += (int)linje_speed.X;
}
else if (ks.IsKeyDown(Keys.Space))
{
Start = true;
}
if (linje_rect.X > Window.ClientBounds.Width - linje_texture.Width)
linje_rect.X = (Window.ClientBounds.Width - linje_texture.Width);
if (linje_rect.X < 0)
linje_rect.X = 0;
if (linje_rect.Intersects(boll_rect))
{
boll_speed.Y *= -1;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
if (liv > 0)
{
spriteBatch.Draw(linje_texture, linje_rect, Color.White);
spriteBatch.Draw(boll_texture, boll_rect, Color.White);
spriteBatch.DrawString(spritefont, "Liv kvar: " + liv, Vector2.Zero, Color.White);
spriteBatch.DrawString(spritefont, "Points: " + poang, new Vector2(350, 0), Color.White);
spriteBatch.DrawString(spritefont, "Highscore: " + highscore, new Vector2(660, 0), Color.White);
foreach (Rectangle g in block)
{
spriteBatch.Draw(blockgrön_texture, g, Color.White);
}
}
if (liv == 0)
{
spriteBatch.Draw(gameover_texture, gameover_rect, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
Having trouble with these parts:
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Start == true)
{
boll_rect.X += (int)boll_speed.X;
boll_rect.Y += (int)boll_speed.Y;
}
if (boll_rect.X > Window.ClientBounds.Width - boll_texture.Width || boll_rect.X < 0)
boll_speed.X *= -1;
if (boll_rect.Y > Window.ClientBounds.Height - boll_texture.Height || boll_rect.Y < 0)
boll_speed.Y *= -1;
else if (ks.IsKeyDown(Keys.Space))
{
Start = true;
}
if (linje_rect.Intersects(boll_rect))
{
boll_speed.Y *= -1;
boll_speed.Y += random.Next(-100, 101) / 100.0f;
boll_speed.X *= -1;
boll_speed.X += random.Next(-100, 101) / 100.0f;
}
I will give you the generic idea. Please adapt it to your example
Lets say you want to move to all directions on the board, now imagine your board as a bi-dimensional array(all your pixels has an x,y representation on that board)
The (0,0) marks the left upper corner of your board, and your (width, height) mark the lower right corner. Your ball is on the middle of the board on the (x, y) position, where x > 0 and x < width(of the board) and y > 0 and y < height.
You have 8 different directions base on the picture below
Now it is time to translate those directions to a logical structure. You need to create an array for that, lets say we want to start from the NW direction. I will create an array with the numbers that you need to add to your (x, y) position in order to keep going in the direction you choose. If you see I am creating a bidimentional array
Now this is the pseudocode for your idea:
int[,] directions = new int[,]{{-1,-1,-1,0,1,1,1,0}, {-1,0,1,1,1,0,-1,-1}};
public void Move(Game game)
{
Point currentPosition = GetYourCurrentPosition(); //the x, y
int direction = GetYourRandomDirection() //this should be a random number between 0 and 7, beucase the array for directions has 8 positions.
int xDirection = directions[0, direction];
int yDirection = directions[1, direction];
//move inside the board forever
while(true)
{
while(ICanMoveTo(currentPosition.X + xDirection, currentPosition.Y + yDirection)
{
//keep moving on the same direction
currentPosition.X += xDirection;
currentPosition.Y += yDirection;
}
//if you can't move anymore in the same direction, then change
direction = GetYourRandomDirection();
xDirection = directions[0, direction];
yDirection = directions[1, direction];
}
}
Random.Next(-1) should give you out of bounds error.
You can use something like Random.Next(-200, 0)/100.0f, which will return a negative number between -2 and 0 (including -2, excluding 0).
But notice that this multiplication will lead to slowdown of ball over time. It might speed up to double of current speed, but it can slow down to nearly 0 in a single step. So I would rather first invert ball speed in y direction and keep it the same in x if you hit horizontal lines, and invert in x and keep in y if you hit vertical lines. Then do a random addition of a zero-means constant.
boll_speed.Y *= -1;
boll_speed.Y += random.Next(-100, 101)/100.0f; // Add random number between -1 and 1 with 0.01 precision.
// and nearly the same for X. Depending on the lines hit.
I'm thinking you mean you want the ball to change directions randomly when it hits the window boundaries or line. If so:
You're using constant values for your direction changes. Add a randomizer to multiply your boll_speed by.
For example, in pseudocode, instead of -1, do random(-1).

XNA Loading Models

I am pretty new to the 3D side of XNA and am converting a 2D game.
Its basically designed as a grid and I am drawing with the code below. This works but is a bit laggy, am I doing this completely wrong? Presumably there shouldn't be much lag at this point when we are only talking about a few small models.
protected override void Draw(GameTime gameTime)
{
fpsTimer += gameTime.ElapsedGameTime;
fpsCount++;
if (fpsTimer >= TimeSpan.FromSeconds(1))
{ fpsTimer = TimeSpan.FromSeconds(0); fps = fpsCount; fpsCount = 0; }
GraphicsDevice.Clear(Color.CornflowerBlue);
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 1000.0f);
world = Matrix.CreateTranslation(new Vector3(0, 0, 0));
view = Matrix.CreateLookAt(new Vector3(xPos, yPos, zHeight), new Vector3(xPos, yPos + zRotation, 0), new Vector3(0, 5, 0));
// DRAW OBJECTS ON MAP
drawMap(view, world, projection);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
spriteBatch.DrawString(font, "" + fps, new Vector2(100, 100), Color.Black);
spriteBatch.End();
base.Draw(gameTime);
}
private void drawMap(Matrix view, Matrix world, Matrix projection)
{
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
int scale = Globals.scale;
int screenWidthScale = Globals.screenwidth / scale;
int screenHeightScale = Globals.screenheight / scale;
int mapXtile = Convert.ToInt32(xPos/2);
int mapYtile = Convert.ToInt32(yPos/2);
for (int i = Convert.ToInt32(xPos/2) - 30; i < Convert.ToInt32(xPos/2) + 30; i++)
{
for (int a = Convert.ToInt32(yPos/2); a < Convert.ToInt32(yPos/2) + 50; a++)
{
if (mapXtile > 0 && mapYtile > 0 && mapXtile < Globals.mapsizex && mapYtile < Globals.mapsizey)
{
int currentTile = Globals.levelArray[mapXtile, mapYtile].TyleType;
// DRAW TREES
if (currentTile == tyleType.tree)
{
if (Globals.levelArray[mapXtile, mapYtile].typeModifier == 1)
{
Matrix worldMatrix = Matrix.CreateScale(0.8f, 0.8f, 0.8f) * Matrix.CreateRotationX(1.5f) * Matrix.CreateTranslation(new Vector3(i * 2 + 0.2f, a * 2 - 0.4f, -0.1f));
tree.Draw(worldMatrix, view, projection);
}
if (Globals.levelArray[mapXtile, mapYtile].typeModifier == 2)
{
Matrix worldMatrix = Matrix.CreateScale(0.8f, 0.8f, 0.8f) * Matrix.CreateRotationX(1.5f) * Matrix.CreateTranslation(new Vector3(i * 2+0.2f, a * 2-0.4f, -0.1f));
tree2.Draw(worldMatrix, view, projection);
}
}
}
mapYtile = mapYtile + 1;
//mapYtile++;
}
mapXtile = mapXtile + 1;
mapYtile = Convert.ToInt32(yPos / 2);
}
}

Isometric tile engine optimisation for better FPS

I have an isometric tile engine written in XNA (Monogame). It can only draw tile map surface. But when I have bigger map (for example 50x50 tiles) then is very slow (about 15 FPS). When I have small map (for example 10x10 tiles) than framrate is perfect (60 FPS).
I'm trying to find way how to optimise my code but I have no idea how to do it.
This is my code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using System;
namespace IsoEngine
{
public class Game1 : Game
{
GraphicsDeviceManager _graphics;
SpriteBatch _spriteBatch;
Texture2D Tile1;
Texture2D Tile2;
MouseState mouseState;
bool isMousePressed = false;
int[,] map = { {1, 1, 1, 1},
{1, 0, 0, 1},
{1, 0, 0, 1},
{1, 1, 1, 1} };
int tileWidth = 64;
int tileHeight = 32;
Vector2 scrollSpan = new Vector2(0, 0);
Vector2 mouseDragPos = new Vector2(0, 0);
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.IsMouseVisible = true;
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
Tile1 = Content.Load<Texture2D>("1");
Tile2 = Content.Load<Texture2D>("2");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
mouseState = Mouse.GetState();
if (mouseState.LeftButton == ButtonState.Pressed && !isMousePressed)
{
isMousePressed = true;
mouseDragPos.X = mouseState.X;
mouseDragPos.Y = mouseState.Y;
}
if (mouseState.LeftButton == ButtonState.Pressed && isMousePressed)
{
if (mouseDragPos.X < mouseState.X)
{
scrollSpan.X += mouseState.X - mouseDragPos.X;
mouseDragPos.X = mouseState.X;
}
if (mouseDragPos.X > mouseState.X)
{
scrollSpan.X -= mouseDragPos.X - mouseState.X;
mouseDragPos.X = mouseState.X;
}
if (mouseDragPos.Y < mouseState.Y)
{
scrollSpan.Y += (mouseState.Y - mouseDragPos.Y) * 2;
mouseDragPos.Y = mouseState.Y;
}
if (mouseDragPos.Y > mouseState.Y)
{
scrollSpan.Y -= (mouseDragPos.Y - mouseState.Y) * 2;
mouseDragPos.Y = mouseState.Y;
}
}
if (mouseState.LeftButton == ButtonState.Released && isMousePressed)
isMousePressed = false;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin();
DrawMap();
_spriteBatch.End();
base.Draw(gameTime);
}
private void DrawMap()
{
for (int osaY = 0; osaY < map.GetLength(0); osaY++)
{
for (int osaX = 0; osaX < map.GetLength(1); osaX++)
{
int x = osaX * 32;
int y = osaY * 32;
Texture2D thisTile = Tile1;
if (map[osaY, osaX] == 0)
thisTile = Tile1;
if (map[osaY, osaX] == 1)
thisTile = Tile2;
PlaceTile(thisTile, CartToIso(new Vector2(x, y)), new Vector2(osaX, osaY));
}
}
}
public void PlaceTile(Texture2D tileImage, Vector2 tilePos, Vector2 tileCoords)
{
_spriteBatch.Draw(tileImage, new Vector2(tilePos.X - (tileWidth / 2), tilePos.Y - tileHeight), Color.White);
}
public Vector2 CartToIso(Vector2 cartCoords)
{
Vector2 isoCoords = new Vector2(0, 0);
isoCoords.X = (cartCoords.X + scrollSpan.X) - cartCoords.Y;
isoCoords.Y = (cartCoords.X + scrollSpan.Y + cartCoords.Y) / 2;
return isoCoords;
}
public Vector2 IsoToCart(Vector2 isoCoords)
{
Vector2 cartCoords = new Vector2(0, 0);
cartCoords.X = (2 * isoCoords.Y + isoCoords.X - scrollSpan.X - scrollSpan.Y) / 2;
cartCoords.Y = (2 * isoCoords.Y - isoCoords.X + scrollSpan.X - scrollSpan.Y) / 2;
return cartCoords;
}
}
}
I'd suggest you to take a look at an answer I wrote a while ago, it does draw only the only the visible part of a level, no matter how big the level is :
I'm not copying and pasting the answer here as I wrote it already, so go and have a look at it here :
https://gamedev.stackexchange.com/a/29930/16262
Generally, to increase performace avoid creating unessesary objects and dont do anything you dont have to. For example you create one useless local texture in DrawMap(), also for single call of method PlaceTile you create 3 new vectors, while you need one.etc. also note, these are only minor improvements.
Another ways of speeding up might be using buffers(not sure what is default for XNA)
But most importantly, parallelize wherever you can.
Before doing anything else, profile your code and see where the most time is being spent. Only then can you begin to optimize

whats wrong with using depth image for lighting

I want use a depth image to lighting a RawColor image but it not seems good
i want know whats wrong with my code , or its all depth image can do :|
the output image shape like Cone instead of circle and there are many noise on it , what i want to know is my code wrong or its not right way to do this?!
for that i get normal for each pixel and add it to a texture and send it to pixel shader to use for lighting. result image and code are added here
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D depth;
Texture2D image;
Texture2D texNormal;
Vector3 cameraPos = new Vector3(0.5f, 0.5f, -0.0999f);
Effect mEffect;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
graphics.PreferredBackBufferWidth = 1000;
graphics.PreferredBackBufferHeight = 1000;
graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
depth = Content.Load<Texture2D>("depth");
image = Content.Load<Texture2D>("image");
texNormal = getNormalFromDepth(depth);
mEffect = Content.Load<Effect>("depthEffect");
// TODO: use this.Content to load your game content here
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
if (Keyboard.GetState().IsKeyDown(Keys.W))
{
cameraPos.Y += 0.01f;
}
if (Keyboard.GetState().IsKeyDown(Keys.S))
{
cameraPos.Y -= 0.01f;
}
if (Keyboard.GetState().IsKeyDown(Keys.A))
{
cameraPos.X -= 0.01f;
}
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
cameraPos.X += 0.01f;
}
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
cameraPos.Z += 0.01f;
}
if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
cameraPos.Z -= 0.01f;
}
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.Textures[1] = texNormal;
mEffect.Parameters["LightPos"].SetValue(cameraPos);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, mEffect);
spriteBatch.Draw(image, new Rectangle(0, 0, 500, 500), Color.White);
spriteBatch.End();
spriteBatch.Begin();
spriteBatch.Draw(texNormal, new Rectangle(500, 0, 500, 500), Color.White);
spriteBatch.Draw(image, new Rectangle(500, 500, 500, 500), Color.White);
spriteBatch.Draw(depth, new Rectangle(0, 500, 500, 500), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Texture2D getNormalFromDepth(Texture2D depth)
{
Texture2D output = new Texture2D(GraphicsDevice, depth.Width, depth.Height);
Color[] outbyte = new Color[depth.Width * depth.Height];
Color[] colors1D = new Color[depth.Width * depth.Height];
depth.GetData(colors1D);
Color[,] colors2D = new Color[depth.Width, depth.Height];
for (int x = 0; x < depth.Width; x++)
{
for (int y = 0; y < depth.Height; y++)
{
colors2D[x, y] = colors1D[x + y * depth.Width];
}
}
for (int x = 0; x < depth.Width; x++)
{
for (int y = 0; y < depth.Height; y++)
{
float left = GetHeight(colors2D, ref depth, x - 1, y);
float right = GetHeight(colors2D, ref depth, x + 1, y);
float top = GetHeight(colors2D, ref depth, x, y - 1);
float bottom = GetHeight(colors2D, ref depth, x, y + 1);
// Compute gradient vectors, then cross them to get the normal.
Vector3 dx = new Vector3(1, 0, (right - left) * 1);
Vector3 dy = new Vector3(0, 1, (bottom - top) * 1);
Vector3 normal = Vector3.Cross(dx, dy);
normal.Normalize();
// Store the result.
float alpha = colors2D[x, y].A;
outbyte[y * depth.Width + x] = new Color(new Vector4(normal, alpha));
}
}
output.SetData(outbyte);
return output;
}
float GetHeight(Color[,] depth, ref Texture2D depthImage, int x, int y)
{
if (x < 0)
{
x = 0;
}
else if (x >= depthImage.Width)
{
x = depthImage.Width - 1;
}
if (y < 0)
{
y = 0;
}
else if (y >= depthImage.Height)
{
y = depthImage.Height - 1;
}
Color mColor = (depth[x, y]);
float output = (mColor.R + mColor.G + mColor.B) / 3;
return output;
}
}
and shader Code is here
sampler normalSampler : register(s1);
sampler imageSampler : register(s0);
float3 LightPos = (1,0,-0.5);
float3 AmbientColor = (0.1,0.1,0.1);
float3 LightColor = (0.9,0.9,0.9);
float4 main(float4 color : COLOR0 ,float2 texCoord : TEXCOORD0):COLOR0
{
float4 output = float4(1,1,1,1);
float4 normal = tex2D(normalSampler,texCoord);
float4 imageColor = tex2D(imageSampler,texCoord);
float3 tex3DCoord = float3(texCoord.x,texCoord.y,0);
float3 lighting = AmbientColor;
float3 lightDir = (LightPos - tex3DCoord);
lighting += ( LightColor* max(dot(normal.xyz, lightDir), 0));
output = float4 (imageColor*lighting,1);
return output;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 main();
}
}

how to change the queue to List?

The original code is:
partial class Game1 : Microsoft.Xna.Framework.Game
{
public enum GameState
{
StateMainMenu,
StatePlaying,
StateGameOver,
StateHelp,
}
GameState currentState = GameState.StateMainMenu;
KeyboardState kbState;
Keys[] pressedKeys;
Queue<FallingCharacter> Letters = new Queue<FallingCharacter>();
float nextLetterTime = 0.6f;
int NextSpeedup = 20; // in 20 points lets speed it up
int iSpeed = 2;
int Score = 0;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spriteFont;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteFont = Content.Load<SpriteFont>("GameFont");
base.LoadContent();
}
public void OnKeyPressed(Keys k)
{
if ((currentState == GameState.StateMainMenu ||
currentState == GameState.StateGameOver)
&& k == Keys.Enter)
{
currentState = GameState.StatePlaying;
nextLetterTime = 0.0f;
NextSpeedup = 20; // in 20 points lsets speed it up
iSpeed = 1;
Score = 0;
}
else if (currentState == GameState.StatePlaying)
{
string sName = Enum.GetName(typeof(Keys), k);
if (Letters.Count > 0 &&
String.Compare(Letters.Peek().character.ToString(), sName) == 0)
{
Score += 100;
Letters.Dequeue();
NextSpeedup--;
if (NextSpeedup <= 0)
{
iSpeed++;
NextSpeedup = 20;
}
}
}
if (k == Keys.Escape)
{
this.Exit();
}
}
protected override void Update(GameTime gameTime)
{
// The time since Update was called last
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
kbState = Keyboard.GetState();
Keys[] newKeys = (Keys[])kbState.GetPressedKeys().Clone();
if (pressedKeys != null)
{
foreach (Keys k in newKeys)
{
bool bFound = false;
foreach (Keys k2 in pressedKeys)
{
if (k == k2)
{
bFound = true;
break;
}
}
if (!bFound)
{
OnKeyPressed(k);
}
}
}
pressedKeys = newKeys;
if (currentState == GameState.StatePlaying)
{
foreach (FallingCharacter fc in Letters)
{
if (fc.Pos.Y + 50 > graphics.PreferredBackBufferHeight)
{
currentState = GameState.StateGameOver;
Letters.Clear();
break;
}
else
{
fc.Pos.Y += (elapsed * (float)(iSpeed * 40));
}
}
nextLetterTime -= elapsed;
if (nextLetterTime <= 0 && currentState != GameState.StateGameOver)
{
nextLetterTime = 0.75f - (iSpeed * .03f);
Random r = new Random();
Letters.Enqueue(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth - 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
switch (currentState)
{
case GameState.StateMainMenu:
{
spriteBatch.DrawString(spriteFont,
"Press Enter to begin",
new Vector2(graphics.PreferredBackBufferWidth / 4,
graphics.PreferredBackBufferHeight / 2),
Color.White);
}
break;
case GameState.StatePlaying:
{
spriteBatch.DrawString(spriteFont,
"Score: " + Score.ToString(),
new Vector2(10, 10), Color.White);
foreach (FallingCharacter fc in Letters)
{
fc.Render(spriteBatch, spriteFont);
}
}
break;
case GameState.StateGameOver:
{
spriteBatch.DrawString(spriteFont,
"Score: " + Score.ToString(),
new Vector2(10, 10), Color.White);
spriteBatch.DrawString(spriteFont,
"Game Over",
new Vector2(graphics.PreferredBackBufferWidth / 3,
graphics.PreferredBackBufferHeight / 2),
Color.LightBlue);
spriteBatch.DrawString(spriteFont,
"Press Return to Continue",
new Vector2(graphics.PreferredBackBufferWidth / 6,
graphics.PreferredBackBufferHeight / 2 + 50),
Color.LightBlue);
}
break;
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
and I need change the quque to list().
after I changed Queue Letters = new Queue();
to List Letters = new List();
Can anyone help me what need change next.
I feel really confused about this, thank you very much.
If you want to keep the same behavior of the Queue (First-In-First-Out), you must do the following changes(changes in bold):
if (Letters.Count > 0 &&
String.Compare(Letters.Peek().character.ToString(),
sName) == 0)
changes to
if (Letters.Count > 0 &&
String.Compare(Letters.First().character.ToString(),
sName) == 0)
to keep the behavior where Peek returns the first character.
Letters.Dequeue();
changes to
Letters.RemoveAt(0);
to remove the first element like Dequeue does.
Note that you could do a check to make sure that the List is not empty.
Letters.Enqueue(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth
- 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
changes to
Letters.Add(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth
- 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
to append the FallingCharacter to the end of the list.

Categories