Related
I'm trying to pass an array that comes from the Base class in the constructor of the Child class, however I feel like there might be conflict in terms of constructors getting called as the getFullArray() method of the Base class returns null.
Base class looks like this:
protected Byte[,] _byteTileArray; //is going to be implemented in child class
private Object[,] objectTileArray;
public Level_Manager(ContentManager content)
{
CreateTileArray();
objectTileArray = new Object[_byteTileArray.GetLength(0), _byteTileArray.GetLength(1)];
CreateWorld(content);
}
protected abstract void CreateTileArray();
private void CreateWorld(ContentManager content)
{
for(int row = 0; row < _byteTileArray.GetLength(0); row++)
{
for (int col = 0; col < _byteTileArray.GetLength(1); col++)
{
switch (_byteTileArray[row,col])
{
case 0: objectTileArray[row, col] = null; break;
case 1: objectTileArray[row, col] = new Cube(new Vector2(col * (852/12), row * (480/7)), content, 124, 33, new Vector2(0, 0)); break;
case 2: objectTileArray[row, col] = new Ladder(new Vector2(col * (852 / 12), row * (480 / 7)-33), content, 50, 107, new Vector2(0, 0)); break;
}
}
}
}
public Object[,] getFullArray(){
return objectTileArray;
}
I need the objectTileArray from getFullArray()
This is the Child class constructor:
private Object[,] arrayObjects;
#endregion
public Level1(ContentManager content, GraphicsDevice device) : base(content)
{
this.content = content;
arrayObjects = getFullArray();
hero = new Hero(new Vector2(1, device.Viewport.Height-40), this.content, arrayObjects);
}
arrayObjects is null here.
EDIT:
Apparently I misunderstood the debugging and my arrayObjects wasn't null but the elements inside were.
protected override void CreateTileArray()
{
base._byteTileArray = new Byte[,]
{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1},
{1, 1, 0, 2, 1, 0, 1, 1, 1, 1, 1, 2},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
}
this was the byteTileArray I was passing on to the Parent class, it was inserting null on the 0's (intentionally) but this was giving me a NullReferenceException in another part which was fixed by just adding if not null clause.
Thank you to everyone and sorry!
I am building a 2D platform game. But the guy making the videos just showed how to create a map and tile class and loaded the level from an array he made. I heard that's a bad practice and people should load their levels from files... I know how to load files with the stream reader but since that's not my code, I was following the tutorial and I have difficulties in implementing it.
So here's the code I have for the level:
private Map map;
// This is in my LoadContent() method
map.Generate(new int[,]
{
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2},
{2, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 2, 2},
{2, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 2, 2},
{2, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2},
{2, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
}, 64);
So I'm loading tiles like this:
// Tiles.cs class
public CollisionTiles(int i, Rectangle newRectangle)
{
texture = Content.Load<Texture2D>("Graphics/Tiles/tile_" + i);
this.Rectangle = newRectangle;
}
And each one of the above integers are added to the string of the filename and diretly loaded and drawn on the screen (like this: map.Draw(spriteBatch);). The 64 int is the size the actual tiles are drawn into. That's what I want to avoid, having to write these arrays for each level, instead I need a way of loading levels from files. When loading the tiles of the level, the tile size shouldn't be forgotten in the .txt file. Maybe have it stay alone on the first or the last line of the level file? That way each level can have different size of tiles if needed.
Here are my Map.cs and Tiles.cs classes. I didn't paste them on SO directly it would make the question too long...
So how would you approach this? What kind of solution is best? I think loading levels similar to tiles like this: "Levels/level_" + i is also I nice way and just have the game increment the int i every time the player finishes a level (I should be able to do this myself), but I'm just asking how you would read a file. I will make any suggested modifications to my code and also I think Splitting the contents of the file by , is opinion based, could also use spaces , but since that's an array in the class I had to use ,s. In the text file I should also remove the { } braces. Anyway I thank you for any feedback and code examples with an explanation would be great!
EDIT:
So should I add the tiles to collisionTiles like this?
public int[,] LoadLevelData(string filename)
{
using (var streamReader = new StreamReader(filename))
{
var serializer = new JsonSerializer();
Generate((int[,])serializer.Deserialize(streamReader, typeof(int[,])), 64);
return (int[,])serializer.Deserialize(streamReader, typeof(int[,]));
}
}
So how would you approach this? What kind of solution is best?
The best solution to this problem really depends on how you plan to edit your levels.
With your current approach (storing level data in code) you can actually edit the level manually by hand. This is not spectacular, but it is manageable for small games.
The next approach is to store levels in a text file. I answered a similar question about this the other day. Many games have used this approach in the past with great success.
If you want to keep things really simple, you could take the data you've got now and use JSON.NET to deserialize it. The cool thing is, the data represented in JSON looks almost exactly as it appears in code and can be edited by your favorite text editor.
[
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2],
[2, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 2, 2],
[2, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 2, 2],
[2, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2],
[2, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
]
The load method is really simple too.
public int[,] LoadLevelData(string filename)
{
using (var streamReader = new StreamReader(filename))
{
var serializer = new JsonSerializer();
return (int[,])serializer.Deserialize(streamReader, typeof(int[,]));
}
}
To use the method, you can pass the result into your Generate method:
// This is in my LoadContent() method
var levelData = LoadLevelData(filename);
map.Generate(levelData, 64);
That'll work just fine if you're always using size 64 blocks, although, you could store the block size in the JSON file as well if you like. It's a bit more complicated though, and probably too much for this answer. The JSON.NET library has excellent documentation.
Since you're using MonoGame you probably want to use TitleContainer.OpenStream instead of a StreamReader to keep things working on all platforms. Alternately, you could write a content reader for the MonoGame Pipeline tool but that's beyond the scope of this question.
The last, but not least, thing you might want to consider is using 3rd party level editor software like Tiled. There's a great Tiled map loader in my MonoGame.Extended library or a number of other existing map loaders to choose from.
Whatever approach you choose, my suggestion is to keep things simple. Each approach has pros and cons, and simple solutions are usually the easiest to get started. Once you've got the basics working you can upgrade to the the complex approaches for added benefits.
Loading levels and binary data, I like to use the BinaryReader and BinaryWriter. For arrays, I write the size first, and then the data. Like this:
void Write(string fileName, int[,] data)
{
using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(fileName)))
{
writer.Write(data.GetLength(0));
writer.Write(data.GetLength(1));
for (int x = 0; x < data.GetLength(0); x++)
{
for (int y = 0; y < data.GetLength(1); y++)
{
writer.Write(data[x, y]);
}
}
}
}
int[,] Read(string fileName)
{
using (BinaryReader reader = new BinaryReader(File.OpenRead(fileName)))
{
int width = reader.ReadInt32();
int height = reader.ReadInt32();
int[,] result = new int[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
result[x, y] = reader.ReadInt32();
}
}
return result;
}
}
I am trying to make to put adjust brightness thing but I am getting does not exist in current context error for "NewBitmap" in this code
picBox.Image = AdjustBrightness(NewBitmap, trackBar1.Value);
Here is my code
private void trackBar1_Scroll(object sender, EventArgs e)
{
lblBrightNum.Text = trackBar1.Value.ToString();
picBox.Image = AdjustBrightness(NewBitmap, trackBar1.Value);
}
public static Bitmap AdjustBrightness(Bitmap Image, int Value)
{
Bitmap TempBitmap = (Bitmap)Image.Clone();
float FinalValue = (float)Value / 255.0f;
Bitmap NewBitmap = new Bitmap(TempBitmap.Width, TempBitmap.Height);
Graphics NewGraphics = Graphics.FromImage(NewBitmap);
float[][] FloatColorMatrix ={
new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {FinalValue, FinalValue, FinalValue, 1, 1}
};
ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix);
ImageAttributes Attributes = new ImageAttributes();
Attributes.SetColorMatrix(NewColorMatrix);
NewGraphics.DrawImage(TempBitmap, new Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, GraphicsUnit.Pixel, Attributes);
Attributes.Dispose();
NewGraphics.Dispose();
return NewBitmap;
}
Your program mainly contains two methods, one is trackBar1_Scroll, another one is AdjustBrightness, visual studio knows what is "NewBitmap" in the AdjustBrightness method, but it doesn't know what is "NewBitmap" in the trackBar1_Scroll
private void trackBar1_Scroll(object sender, EventArgs e)
{
lblBrightNum.Text = trackBar1.Value.ToString();
//Visual studio is complaining about this, you haven't define "NewBitmap", you can fix by adding below:
Bitmap NewBitmap = //your bitmap
picBox.Image = AdjustBrightness(NewBitmap, trackBar1.Value);
}
public static Bitmap AdjustBrightness(Bitmap Image, int Value)
{
Bitmap TempBitmap = (Bitmap)Image.Clone();
float FinalValue = (float)Value / 255.0f;
Bitmap NewBitmap = new Bitmap(TempBitmap.Width, TempBitmap.Height);
Graphics NewGraphics = Graphics.FromImage(NewBitmap);
float[][] FloatColorMatrix ={
new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {FinalValue, FinalValue, FinalValue, 1, 1}
};
ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix);
ImageAttributes Attributes = new ImageAttributes();
Attributes.SetColorMatrix(NewColorMatrix);
NewGraphics.DrawImage(TempBitmap, new Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, GraphicsUnit.Pixel, Attributes);
Attributes.Dispose();
NewGraphics.Dispose();
return NewBitmap;
I've been looking through the other questions but just can't seem to figure this out.. I'm using XNA in a custom tilemap loader. Here is the code.
http://pastebin.com/cuatQHTb
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;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace Pressure
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D player;
Vector2 pos = Vector2.Zero;
Vector2 playersp = new Vector2(50.0f, 50.0f);
Texture2D road1;
Texture2D road2;
Texture2D brickwall;
Texture2D floor1;
Texture2D floor2;
Texture2D floor3;
Texture2D grass;
Texture2D sidewalk1;
Texture2D wood;
Texture2D road3;
private Vector2 origin;
KeyboardState currentState;
Camera camera = new Camera();
Vector2 motion;
List<Texture2D> tiles = new List<Texture2D>();
static int tileWidth = 64;
static int tileHeight = 64;
int tileMapWidth;
int tileMapHeight;
static int screenWidth;
static int screenHeight;
static int mapWidthInPixels;
static int mapHeightInPixels;
int[,] map = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 6, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 6, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 1, 1, 1, 2, 2, 1, 8, 7, 5, 6, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 1, 1, 1, 2, 2, 1, 8, 7, 5, 5, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 1, 1, 1, 1, 1, 1, 8, 7, 5, 5, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 1, 3, 3, 3, 1, 1, 8, 7, 5, 6, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 8, 8, 1, 1, 8, 8, 8, 8, 7, 5, 6, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,},
{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,},
{9, 9, 9, 5, 5, 9, 9, 9, 5, 5, 9, 9, 9, 5, 5, 5, 5, 5, 9, 9, 9, 5, 5, 9, 9, 9, 5, 5, 9,},
{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,},
{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
};
public static int ScreenWidth
{
get { return screenWidth; }
}
public static int ScreenHeight
{
get { return screenHeight; }
}
public static int MapWidthInPixels
{
get { return mapWidthInPixels; }
}
public static int MapHeightInPixels
{
get { return mapHeightInPixels; }
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
player = Content.Load<Texture2D>("haz");
origin.X = player.Width /2;
origin.Y = player.Height /2;
grass = Content.Load<Texture2D>("grass");
floor1 = Content.Load<Texture2D>("floor1");
floor2 = Content.Load<Texture2D>("floor2");
floor3 = Content.Load<Texture2D>("floor3");
wood = Content.Load<Texture2D>("wood");
road1 = Content.Load<Texture2D>("road1");
road2 = Content.Load<Texture2D>("road2");
sidewalk1 = Content.Load<Texture2D>("sidewalk1");
brickwall = Content.Load<Texture2D>("brickwall");
road3 = Content.Load<Texture2D>("road3");
tiles.Add(grass); //0
tiles.Add(floor1);//1
tiles.Add(floor2);//2
tiles.Add(floor3);//3
tiles.Add(wood);//4
tiles.Add(road1);//5
tiles.Add(road2);//6
tiles.Add(sidewalk1);//7
tiles.Add(brickwall);//8
tiles.Add(road3);//9
tileMapWidth = map.GetLength(1);
tileMapHeight = map.GetLength(0);
mapWidthInPixels = tileMapWidth * tileWidth;
mapHeightInPixels = tileMapHeight * tileHeight;
screenWidth = GraphicsDevice.Viewport.Width;
screenHeight = GraphicsDevice.Viewport.Height;
}
protected override void UnloadContent()
{
}
private float RotationAngle;
private float oldx;
private float oldy;
protected override void Update(GameTime gameTime)
{
oldx = playersp.X;
oldy = playersp.Y;
currentState = Keyboard.GetState();
pos = playersp;
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
IsMouseVisible = true;
MouseState Mouses = Mouse.GetState();
Vector2 mouseLook = new Vector2(Mouses.X, Mouses.Y);
motion = Vector2.Zero;
Vector2 direction = (playersp ) - mouseLook;
float angle = (float)(Math.Atan2(direction.Y, direction.X));
RotationAngle = angle ;
if (currentState.IsKeyDown(Keys.W))
{
if (playersp.Y > screenHeight /4)
{
playersp.Y = playersp.Y - 1;
}
else
{
ScrollUp();
}
}
if (currentState.IsKeyDown(Keys.A))
{
if (playersp.X > screenWidth / 4)
{
playersp.X = playersp.X - 1;
}
else
{
ScrollLeft();
}
}
if (currentState.IsKeyDown(Keys.S))
{
if (playersp.Y > screenHeight / 1.5f)
{
ScrollDown();
}else{
playersp.Y = playersp.Y + 1;
}
}
if (currentState.IsKeyDown( Keys.D))
{
if (playersp.X > screenWidth / 1.5f)
{
ScrollRight();
}
else
{
playersp.X = playersp.X + 1;
}
}
if (motion != Vector2.Zero)
{
motion.Normalize();
camera.Position += motion * camera.Speed;
}
base.Update(gameTime);
}
private void ScrollUp()
{
motion.Y = -0.5f;
}
private void ScrollRight()
{
motion.X = 0.5f;
}
private void ScrollDown()
{
motion.Y = 0.5f;
}
private void ScrollLeft()
{
motion.X = -0.5f;
}
private Point VectorToCell(Vector2 vector)
{
return new Point(
(int)(vector.X / tileWidth),
(int)(vector.Y / tileHeight));
}
private Vector2 ViewPortVector()
{
return new Vector2(
screenWidth + tileWidth,
screenHeight + tileHeight);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
DrawMap();
base.Draw(gameTime);
}
private void DrawMap()
{
Point cameraPoint = VectorToCell(camera.Position);
Point viewPoint = VectorToCell(camera.Position +
ViewPortVector());
Point min = new Point();
Point max = new Point();
min.X = cameraPoint.X;
min.Y = cameraPoint.Y;
max.X = (int)Math.Min(viewPoint.X, map.GetLength(1));
max.Y = (int)Math.Min(viewPoint.Y, map.GetLength(0));
Rectangle tileRectangle = new Rectangle(
0,
0,
tileWidth,
tileHeight);
spriteBatch.Begin();
for (int y = min.Y; y < max.Y; y++)
{
for (int x = min.X; x < max.X; x++)
{
tileRectangle.X = x * tileWidth - (int)camera.Position.X;
tileRectangle.Y = y * tileHeight - (int)camera.Position.Y;
spriteBatch.Draw(tiles[map[y, x]],
tileRectangle,
Color.White);
spriteBatch.Draw(player, pos, null, Color.White, RotationAngle,
origin, 1.0f, SpriteEffects.None, 0f);
}
}
spriteBatch.End();
}
}
}
How would I detect the tiles position and make sure the player doesn't enter that tile? thanks!
You could do something like this:
private static float scalingFactor = 10;
private static float mapSizeX = 19;
private static float mapSizeY = 29;
in Update:
if (playersp.Y > screenHeight /4) {
int mapX = (int) (playersp.X / scalingFactor);
int mapY = (int) (playersp.Y / scalingFactor) - 1;
if (isMovable(mapX, mapY)) {
playersp.Y = playersp.Y - scalingFactor;
}
} else {
ScrollUp();
}
and a new method:
public bool isMovable(int mapX, int mapY)
{
if (mapX < 0 || mapX > 19 || mapY < 0 || mapY > 29) {
return false;
}
int tile = map[mapX, mapY];
if (tile == 4 || tile == 8) {
return false;
}
return true;
}
Similarly for the other directions.
The above code calls the function isMovable to decide whether the player can move to the new location based on the type of tile stored in the map at that position. The decision is false (the player cannot move there) if it is wood or brick wall, otherwise it is true.
The scaling factor is to map between the screen position (captured in playersp) and the tile map. In this case each tile is equivalent to 10 screen "pixels" (You can break it into two separate scales if you want to: one for X dimention, the other for Y).
Note, you need to make sure the values mapSizeX and mapSizeY are correct.
It would be best if you introduced named constants for the type of tile instead of using the numbers -- it will make your code more readable (for you in the future and for others reading it).
EDIT: updated code & explanation
I am trying to setup a 2d array in C# to act as a maze to move a character around, I am having a few issues initialising the array, I am trying to do the below
but the InitialiseMaze method is saying the maze is not declared
Can anyone advise
thanks
simon
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GameMan
{
public class Maze
{
#region Variables
static int[,] maze;
#endregion
#region Constructors/Destructors
public Maze()
{
InitaliseMaze();
}
~Maze()
{
}
#endregion
#region Methods
public void InitaliseMaze()
{
maze = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 3, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 3, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0},
{0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 4, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0 ,0, 2, 0, 0},
{0, 0, 3, 2, 0, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 0, 2, 3, 0, 0},
{0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
}
#endregion
}
}
You can't initialize an array like that other than in a variable declaration. However, the change is simple:
maze = new int[,] {
// As before
};
As asides:
It looks like maze should be an instance variable rather than a static variable. After all, you're initializing it each time you create an instance of Maze
You have a finalizer for no reason. Finalizers are very rarely required (or indeed advisable) in C#
Ok, well here is some extract from the msdn :
int[,] myArray = {{1,2}, {3,4}, {5,6}, {7,8}};
extracted from MSDN multidimensional arrays
you should also read up concerning Destructors, finalizers etc ... , I bet your coming from C++ ? Differences between the 2 languages arent always obvious :).
Just to make Jon's post a bit clearer:
maze = new int[,]{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 3, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 3, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0},
{0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 4, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0 ,0, 2, 0, 0},
{0, 0, 3, 2, 0, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 0, 2, 3, 0, 0},
{0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0},
{0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0},
{0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
Boy, that was a big maze array...
You need to declare maze
numbers = new int[X,Y]; where X and Y are how big it is
Two-Dimensional Arrays
The simplest form of the multidimensional array is the 2-dimensional array. A 2-dimensional array is a list of one-dimensional arrays.
A 2-dimensional array can be thought of as a table, which has x number of rows and y number of columns. Following is a 2-dimensional array, which contains 3 rows and 4 columns −
Two Dimensional Arrays in C#
Thus, every element in the array a is identified by an element name of the form a[ i , j ], where a is the name of the array, and i and j are the subscripts that uniquely identify each element in array a.
Initializing Two-Dimensional Arrays
int [,] a = new int [3,4] {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
Explain above code:
new int [**3**,4] **3** denoting to rows like how may object in array
eg:
{0, 1, 2, 3} ,
{4, 5, 6, 7} ,
{8, 9, 10, 11}
new int [3,**4**] **4** denoting to columns like total value in object (4 columns)
eg:
{0, 1, 2, 3}
Let us check the program to handle a two dimensional array
using System;
namespace ArrayApplication {
class MyArray {
static void Main(string[] args) {
/* an array with 5 rows and 2 columns*/
int[,] a = new int[5, 2] {{0,0}, {1,2}, {2,4}, {3,6}, {4,8} };
int i, j;
/* output each array element's value */
for (i = 0; i < 5; i++) {
for (j = 0; j < 2; j++) {
Console.WriteLine("a[{0},{1}] = {2}", i, j, a[i,j]);
}
}
Console.ReadKey();
}
}
}
Output:
a[0,0]: 0
a[0,1]: 0
a[1,0]: 1
a[1,1]: 2
a[2,0]: 2
a[2,1]: 4
a[3,0]: 3
a[3,1]: 6
a[4,0]: 4
a[4,1]: 8