I am trying to make a very simple terraria-like game in C# XNA for a school project. I have very limited time otherwise I would probably have spent more time trying to figure this out myself. I created a tilemap but I just can't figure out how to make the tiles "solid" and not passable.
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 TileEngine {
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D character;
Vector2 cPosition;
Rectangle cBounds, t1Bounds;
List<Texture2D> tileTextures = new List<Texture2D>();
int[,] tileMap = new int[,]
{
{ 0, 1, 1, 0, 2, 1, 1, 1, 0, 1, },
{ 0, 1, 1, 0, 2, 1, 1, 1, 0, 1, },
{ 0, 1, 1, 0, 2, 1, 1, 1, 0, 1, },
{ 0, 1, 1, 0, 2, 1, 1, 1, 0, 1, },
};
int tileWidth = 64;
int tileHeight = 36;
int cameraPositionX = 0;
int cameraPositionY = 0;
int vSpeed = 0;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
IsMouseVisible = true;
graphics.IsFullScreen = false;
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
graphics.ApplyChanges();
cPosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 - 15, graphics.GraphicsDevice.Viewport.Height / 2 - 20);
cBounds = new Rectangle((int)(cPosition.X), (int)(cPosition.Y), character.Width, character.Height);
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
Texture2D texture;
character = Content.Load<Texture2D>("Tiles/character");
texture = Content.Load<Texture2D>("Tiles/green");
tileTextures.Add(texture);
texture = Content.Load<Texture2D>("Tiles/red");
tileTextures.Add(texture);
texture = Content.Load<Texture2D>("Tiles/blue");
tileTextures.Add(texture);
cBounds = new Rectangle((int)(cPosition.X), (int)(cPosition.Y),
character.Width, character.Height);
// 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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
KeyboardState keyState = Keyboard.GetState();
vSpeed += 1;
cameraPositionY += vSpeed;
if (keyState.IsKeyDown(Keys.Right))
cameraPositionX += 5;
if (keyState.IsKeyDown(Keys.Left))
cameraPositionX -= 5;
if (keyState.IsKeyDown(Keys.Space))
vSpeed = -15;
if (cBounds.Intersects(t1Bounds))
{
cameraPositionY = 0;
vSpeed = 0;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
int tileMapWidth = tileMap.GetLength(1);
int tileMapHeight = tileMap.GetLength(0);
spriteBatch.Draw(character, cPosition, Color.White);
for (int x = 0; x < tileMapWidth; x++)
{
for (int y = 0; y < tileMapHeight; y++)
{
int textureIndex = tileMap[y, x];
Texture2D texture = tileTextures[textureIndex];
spriteBatch.Draw(
texture, t1Bounds =
new Rectangle(
320 + x * tileWidth - cameraPositionX,
540 + y * tileHeight - cameraPositionY,
tileWidth,
tileHeight),
Color.White);
}
}
spriteBatch.End();
base.Draw(gameTime);
}
} }
As you can see I tried to make Rectangles around all the sprites and detect when they intersect, but it doesn't seem to work. And even if I get the Rectangle-thing to work I just don't know what to do if they intersect. If I set the velocity to 0 then it will still slowly "fall" through the blocks as there is a default vertical acceleration.
0
, you need to see how far the player is into the tile, also known as the intersection depth, and subtract the depth to set the player back on the tile. – Cyral