Jump to content
  • Advertisement
Sign in to follow this  
JDUK

Need help with tile engine collision(links to game demo and code inside)

This topic is 4940 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, Im still having problems making collision in my game work without the player sticking to walls was woundering if any one could take a look at the game and the code and make some suggestions please. A quick explinaion of the demo: *The player is the green block *He is only meant to collide with ORANGE brick blocks and Black blocks. *The read outs on screen are the X,Y of the player as relates to the level (so screen position + screen offset) and boolean displays of if a character can move in a given direction. * The cursor keys move the player ESC exits the program Code istructions: * After downloading unzip the "tiletest" folder onto the C:\ drive (so the game files are @ C:\tiletest ) * execute 2DGameEngine * TileEngine.cs is the game code that controls the player and level movment and loading, etc i included this so it could be browsed at your leasire. If you weary of this file please virus check it ... im running Sophos myself but do not have this months update for it... so while its not "bleeding edge" new its still very recent. Link to demo: http://www.monkeycmonkeydo.co.uk/tiletest.zip TileEngine code below and also found in the zip file above^ Cheers, James,
using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.IO;


namespace _2DGameEngine
{
	/// <summary>
	/// Summary description for TileEngine.
	/// </summary>
	public class TileEngine
	{
		#region Variables
		private Form gameForm;
		private DataSet GameData = new DataSet();
		private Graphics gr = new Graphics();
		private int LevelWidth;
		private int LevelHeight;
		private string LevelPath;
		private string TilePath;
		private int TilesInWidth;
		private int TilesInHeight;
		private int tmWidth;
		private int CollideRange;
		private int TileSize;
		private int[,] Level;
		const int ScreenWidth= 800;
		const int ScreenHeight= 600;
		private int ScreenLimitRight;
		private int ScreenLimitLower;
		private bool 
			CanGoUp = true,
			CanGoDown = true,
			CanGoLeft = true , 
			CanGoRight = true;
		private Point ScreenStart ;
		private Point OffSet ;
		private Point playerPos= new Point(0,0);
		GameState state;
		private Point p;
		private Point pp;
		private Point LPP = new Point(0,0);
		bool escape = false;
		Input input;
		private int Tile;
		private double CurrentTick;
		private double LastUpdate;
		private double UpdateFreq = 1000/80;
		
		Microsoft.DirectX.DirectInput.Key[] keys;
		bool levelInitialised = false;
		private int MovementIncrement = 1;
		#endregion
		
	
		public TileEngine(Form form)
		{
			gameForm = form;					
		}
        
		public void ReadXML(string path)
		{
			GameData.ReadXml(@path);// Read in XML File	
						
		}
		public void InitGFX()
		{
			gr.InitializeGraphics(@TilePath, gameForm);
		}
		public void ReadLevel(int CurrentLevel)
		{
			DataView LDV = new DataView();// Crete DataView to search/sort record.
			LDV.Table = GameData.Tables[0]; //Assign LevelData to a tablein the D'V'
			LDV.Sort = "Level Number";//Sort by level order.
			
			//Fill variables from file;
			LevelHeight = Int32.Parse(LDV[CurrentLevel]["Height"].ToString());
			LevelWidth = Int32.Parse(LDV[CurrentLevel]["Width"].ToString());
			TileSize = Int32.Parse(LDV[CurrentLevel]["TileSize"].ToString());
			CollideRange = Int32.Parse(LDV[CurrentLevel]["Collidable"].ToString());
			TilePath = LDV[CurrentLevel]["TilePath"].ToString();
			LevelPath = LDV[CurrentLevel]["LevelPath"].ToString();
			//Build Level in an Array
			Level = new int[(LevelWidth/TileSize),(LevelHeight/TileSize)];
			//Set screen roaming limitations
			if(LevelWidth - ScreenWidth >0)ScreenLimitRight = (LevelWidth - ScreenWidth);
			else ScreenLimitRight = 0;
			Console.Write(ScreenLimitRight.ToString());
			if(LevelHeight - ScreenHeight >0)ScreenLimitLower= (LevelHeight - ScreenHeight);
			else ScreenLimitLower = 0;
			tmWidth = (Bitmap.FromFile(@TilePath).Width)/TileSize;
			ReadFromTXT(@LevelPath);			
		}
		
		private void ReadFromTXT(string path)
		{
			if(File.Exists(@path) != false)//Check .txt files exists
			{
				StreamReader sr = new StreamReader(File.Open(LevelPath,FileMode.Open));//Create a reader for thefile
				try
				{
					for(int y = 0; y<(LevelHeight/TileSize) ;y++)
					{
						for(int x = 0; x<(LevelWidth/TileSize) ;x++)
						{
							Level[x,y]= Int32.Parse(sr.ReadLine().ToString());
						}
					}					
					
					sr.Close();
				}			
				catch{}
			}			
		}
		private void DrawTiles()
		{
			for (int i = 0; i<(TilesInHeight); i++)
			{
				for(int j = 0; j<(TilesInWidth); j++)
				{
					Rectangle to = new 
						Rectangle(OffSet.X+(j*TileSize),OffSet.Y+(i*TileSize),TileSize,TileSize);	
								
					Tile = Level[(ScreenStart.X)+j,(ScreenStart.Y)+i];	
									
					Rectangle from = new 
						Rectangle((Tile % tmWidth)*TileSize,(Tile / tmWidth)*TileSize, TileSize,TileSize);
					
					gr.DrawTile(to,from);
				}
			}
		}

		public void TileUpdate(ref Point ScreenPos)
		{
			
			ScreenStart = new Point(0,0);
			OffSet = new Point(0,0);
			
			if(ScreenPos.X < 0)
				ScreenPos.X =0;

			if(ScreenPos.X > ScreenLimitRight)
				ScreenPos.X =ScreenLimitRight; 
			
			ScreenStart.X = (ScreenPos.X/TileSize);

			if(ScreenPos.Y > ScreenLimitLower)
				ScreenPos.Y = ScreenLimitLower;
		
			if(ScreenPos.Y < 0)
				ScreenPos.Y = 0;
			
			ScreenStart.Y = (ScreenPos.Y/TileSize);

			OffSet.X -= (ScreenPos.X%TileSize);
			OffSet.Y -= (ScreenPos.Y%TileSize);	


			if((ScreenPos.X % TileSize)!=0)
				TilesInWidth =(ScreenWidth/TileSize)+1;
			else
				TilesInWidth  =(ScreenWidth/TileSize);

			if((ScreenPos.Y % TileSize)!=0)
				TilesInHeight =(ScreenHeight/TileSize)+1;
			else
				TilesInHeight  =(ScreenHeight/TileSize);                
			
		}
		public void PlayerUpdate(ref Point PlayerPos)
		{					
			if(PlayerPos.X < TileSize)
				PlayerPos.X =TileSize;

			if(PlayerPos.X > (ScreenWidth-TileSize))
				PlayerPos.X =(ScreenWidth-TileSize); 
			
			if(PlayerPos.Y > (ScreenHeight-TileSize))
				PlayerPos.Y = (ScreenHeight-TileSize);
		
			if(PlayerPos.Y < TileSize)
				PlayerPos.Y = TileSize;
			playerPos = PlayerPos;
		}
		public void DrawPlayer()
		{			
			
			gr.DrawPlayer(new Rectangle(pp.X,pp.Y,32,32),new Rectangle(64,32,32,32));
			
		}
		public void Draw()
		{
			gr.Prepare();
			DrawTiles();
			DrawPlayer();
			gr.DrawCoOrd( 30,30,(pp.X+p.X).ToString() +" "+(pp.Y+p.Y).ToString());
			gr.DrawCoOrd( 30,50,"Up =" +CanGoUp.ToString());
			gr.DrawCoOrd( 30,70,"Down =" +CanGoDown.ToString());
			gr.DrawCoOrd( 30,90,"Left =" +CanGoLeft.ToString());
			gr.DrawCoOrd( 30,110,"Right =" +CanGoRight.ToString());
			gr.Update();			
		}
		public void Begin(string path)
		{
			p = new Point(0, 0);
			input = new Input(gameForm);
			ReadXML(path);
			ReadLevel(1);
			InitGFX();
			GameLoop();
		}	/// <summary>
		/// Takes the relevant action depending on which key(s) have been pressed.
		/// </summary>
		private void HandleInput()
		{
			keys = input.GetPressedKeys();
			if (keys.Length > 0)
			{				
				if (keys[0] == Microsoft.DirectX.DirectInput.Key.Escape)
				{
					//If escape has been pressed
					escape = true;
					return;
				}
				if(keys[0] == Microsoft.DirectX.DirectInput.Key.Right)
				{		
					if(CanGoRight != false)
					{
						p.X += 1;
						pp.X += 1;
					}
				}
				if(keys[0] == Microsoft.DirectX.DirectInput.Key.Left)
				{
					if(CanGoLeft != false)
					{
						p.X -= 1;
						pp.X -= 1;
					}
				}
				if(keys[0] == Microsoft.DirectX.DirectInput.Key.Down)
				{					
					if(CanGoDown != false)
					{
						p.Y += 1;
						pp.Y += 1;
					}			
				}
				if(keys[0] == Microsoft.DirectX.DirectInput.Key.Up)
				{					
					if(CanGoUp != false)
					{
						p.Y -= 1;
						pp.Y -= 1;
					}
				}				
				escape = false;				
			}
		}
		/// <summary>
		/// Plays the actual game.
		/// </summary>
		private void GameLoop()
		{
			state = GameState.Title;
			while (!escape)
			{
				//Check for key presses.
				switch (state)
				{
					case GameState.Title:
						//Display the title
						//DisplayTitle();
						state = GameState.Level1; //Temporary fix cus we have no title!! :-D
						break;
					case GameState.Level1:
						
						if (levelInitialised == true)
						{
							CurrentTick = System.Environment.TickCount;
							if(CurrentTick > LastUpdate + UpdateFreq)
							{										
								LastUpdate = CurrentTick;
								HandleInput();
								CollideTest(pp,p);	
								PlayerUpdate(ref pp);
								TileUpdate(ref p);
								Draw();									
							}														
						}
						else
						{
							levelInitialised = true;
						}
						break;
					case GameState.GameOver:
						//Display some game over type stuff
						//GameOver();
						state = GameState.Title; //Back to the title screen.
						break;
				}
				
				}
			//Escape has been pressed, return from the game loop so the application can exit.
			return;
		}
		/// <summary>
		/// Move all objects by their velocity * (frameLength / 1000)
		/// </summary>
		/// <param name="frameLength">the length of the last frame</param>
		
		private enum GameState
		{
			Title,
			Level1,
			GameOver
		}
		private void CollideTest(Point PlayerPos, Point ScreenPos)
		{
			int PositionX = PlayerPos.X + ScreenPos.X;
			int PositionY = PlayerPos.Y + ScreenPos.Y;
			if(PlayerPos.Y % TileSize == 0)
			{
				if(Level[(PositionX  / TileSize)+1, PositionY / TileSize] <= CollideRange)
					CanGoRight = false;
				else
					CanGoRight = true;
				if(Level[PositionX / TileSize, PositionY / TileSize] <= CollideRange)
					CanGoLeft = false;
				else
					CanGoLeft = true;
			}
			else
			{
				if(Level[(PositionX / TileSize)+1, PositionY / TileSize] <= CollideRange)
					CanGoRight = false;
				else if(Level[(PositionX / TileSize)+1, (PositionY / TileSize)+1] <= CollideRange)
					CanGoRight = false;
				else
					CanGoRight = true;
				if(Level[PositionX/ TileSize, PositionY / TileSize] <= CollideRange)
					CanGoLeft = false;
				else if(Level[PositionX  / TileSize, (PositionY / TileSize)+1] <= CollideRange)
					CanGoLeft = false;
				else
					CanGoLeft = true;
			}
			if(PlayerPos.X % TileSize == 0)
			{
				if(Level[PositionX / TileSize, (PositionY / TileSize)+1] <= CollideRange)
					CanGoDown = false;
				else
					CanGoDown = true;
				if(Level[PositionX / TileSize, (PositionY / TileSize)] <= CollideRange)
					CanGoUp = false;
				else
					CanGoUp = true;
			}
			else
			{
				if(Level[PositionX / TileSize, (PositionY / TileSize)+1] <= CollideRange)
					CanGoDown = false;
				else if(Level[(PositionX / TileSize)+1, (PositionY / TileSize)+1] <= CollideRange)
					CanGoDown = false;
				else
					CanGoDown = true;

				if(Level[PositionX / TileSize, (PositionY / TileSize)] <= CollideRange)
					CanGoUp = false;
				else if(Level[(PositionX / TileSize)+1, (PositionY / TileSize)] <= CollideRange)
					CanGoUp = false;
				else
					CanGoUp = true;
			}
	
		}
	}
}


Share this post


Link to post
Share on other sites
Advertisement
I downlaoded the file, but I get an error everytime I run it.

This is what the error dialog says:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.ArgumentException: Value does not fall within the expected range.
at Microsoft.DirectX.DirectDraw.Surface..ctor(String filename, SurfaceDescription desc, Device dev)
at _2DGameEngine.Graphics.InitializeGraphics(String TilePath, Form gameForm)
at _2DGameEngine.TileEngine.InitGFX()
at _2DGameEngine.TileEngine.Begin(String path)
at _2DGameEngine.Form1.Form1_Load(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll
----------------------------------------
2DGameEngine
Assembly Version: 1.0.1964.28971
Win32 Version: 1.0.1964.28971
CodeBase: file:///C:/tiletest/2DGameEngine.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll
----------------------------------------
System
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
----------------------------------------
System.Drawing
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
----------------------------------------
System.Data
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/assembly/gac/system.data/1.0.5000.0__b77a5c561934e089/system.data.dll
----------------------------------------
System.Xml
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.2032
CodeBase: file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll
----------------------------------------
Microsoft.DirectX.DirectDraw
Assembly Version: 1.0.2902.0
Win32 Version: 5.04.00.2904
CodeBase: file:///c:/windows/assembly/gac/microsoft.directx.directdraw/1.0.2902.0__31bf3856ad364e35/microsoft.directx.directdraw.dll
----------------------------------------
Microsoft.DirectX
Assembly Version: 1.0.2902.0
Win32 Version: 5.04.00.2904
CodeBase: file:///c:/windows/assembly/gac/microsoft.directx/1.0.2902.0__31bf3856ad364e35/microsoft.directx.dll
----------------------------------------
Microsoft.DirectX.DirectInput
Assembly Version: 1.0.2902.0
Win32 Version: 5.04.00.2904
CodeBase: file:///c:/windows/assembly/gac/microsoft.directx.directinput/1.0.2902.0__31bf3856ad364e35/microsoft.directx.directinput.dll
----------------------------------------
Microsoft.VisualC
Assembly Version: 7.0.5000.0
Win32 Version: 7.10.3052.4
CodeBase: file:///c:/windows/assembly/gac/microsoft.visualc/7.0.5000.0__b03f5f7f11d50a3a/microsoft.visualc.dll
----------------------------------------

Share this post


Link to post
Share on other sites
Thanks for the heads-up.

I can get the downloaded file to work on my 2 PC's my friends home PC but not his work PC.

Any idea of where the inconsitancy could be? wrong/old DirectDraw/DirectX versions? DirectX being/not-being in debug mode?

It seems odd that it works on some systems and not others :?

Share this post


Link to post
Share on other sites
I have DirectX9.0c Summer Update 2004 installed (I haven't updated to the new one becuase of my compiler).

I have .NET FrameWork 1.1
Windows XP Home Edition

If you want any other information, just ask and I'll tell you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!