Hi there forum,
I am currently working on creating a game with similar movement to Pacman.
Using a 2D array I create a grid of floor and wall objects. When an arrow key is pressed I do
a check on a function that tells me what directions my character can move in, North, South, East and West,
based on the x and y coordinates I give it (for example (canMove(x,y)) would return true if no walls are present
above the character.
My goal now is to have the character move continuously upon a key press until they hit a wall, then the player can move again, with the character moving continuously until the next wall and so on.
Below I have included my attempt which has thus far proved unsuccessful (Due to the fact that once the character moves the first time it never gets the next currGridPos in testSouth). I would appreciate and help or a different perspective in this matter.
function Update()
{
if (Input.GetKeyDown (KeyCode.DownArrow))
{
//Get the characters current position
var currPos3 = currGridPos;
var spCurrPos3 = currPos3.Split("_"[0]);
var x3 = parseInt(spCurrPos3[0]);
var y3 = parseInt(spCurrPos3[1]);
print ("current position - "+x3+"_"+y3);
//Can the character move south
if(Test(x3,y3,Edges.South))
{
//if yes start moving the character south until a wall is hit
testSouth(x3,y3);
}else{
//character can't move
}
}
}
function testSouth(x : int, y : int)
{
while(Test(x,y,Edges.South))
{
print ("can move south to -"+x+"_"+y);
moveSouth(x,y);
yield;
}
return;
}
function moveSouth(x : int, y : int)
{
print ("moving South");
var chStartPos = char11.transform.position;
print ("curr pos -" +x+"_"+y);
var y1 = y+1;
print ("pos to move to-"+x+"_"+y1);
var chEndPosObj = gameObject.Find(x+"_"+y1);
print (chEndPosObj.name);
var chEndPos = chEndPosObj.transform.position;
currGridPos = x+"_"+y1;
print ("new curr pos -"+x+"_"+y1);
var i = 0.0;
var rate = 1.0/0.3;
while (i < 1.0) {
i += Time.deltaTime * rate;
char11.transform.position = Vector3.Lerp(chStartPos, chEndPos, i);
yield;
}
}
kind regards.
Perhaps you are looking at this in to complex a fasion create a texture and save it as a png or tga for use in unity. In this texture, you have black objects which represent walls, and white objects which represent floors. possibly, you could have other colors to represent other things.
Each pixel in your texture then is defined as a tile on your map. So say you start off in a hallway, and you are moving left. move until you reach the center of a tile, then do a check to see if you can move into the next tile.
If the color you get is black, you cant move to the next tile. if it is anything else, you can.’
As for pacman… we add a few more tiles in. Red is a dot, and blue is a powerup. You would then have 4 bots which wandered around the maze until they are within 5 units of the player then they chase him. Lastly, you have another bot this one wanders aimlessly until it finds an exit. This bot moves until it hits a wall, then it chooses a new direction (but does not backtrack) and follows it.
Every frame you do an overlap test to see if Player is less than one unit away from any bot and does whatever accordingly.
Also, you need to do a check at the center of each tile that asks what that tile is. If it is red, it adds a point, and makes the tile white. If it is blue, then it makes the 4 bots blue and immediately run the opposite way.
The eyeballs travel in the shortest path back to home, so that is about as much pathing as you need.
Many thanks for your reply BigMisterB. I can definitely see some advantages to doing it your way using textures as a map and Get Set Pixel to get the tile type.
My main problem is the movement part which I believe would be the same in either case. I understand what I want to do in that my character from the beginning of the game:
- Gets a starting direction
- move to next tile
- if next tile is a wall (stop)
- otherwise continue to next tile
- if user inputs direction while moving
- then go to next tile in that direction
- continue moving
- go back to 2)
Getting this kind of functionality has been quite difficult! 
I think you have the right idea. Basically you just need to generate a set of mapdata based on whatever input you want and store it (multi-dimensional array, maybe a Dictionary<coordinate,tiledata>… however you want really).
You need a movement loop that moves towards the next valid tile in your current direction, or stands still if your current direction is blocked. To do this I’d set it up in such a way that it only checks your current direction when it’s beginning a movement (so that your guy is always in the center of a tile) - at least that’s how I’ve almost always seen this sort of movement set up.
You could do it all in an update loop, but I like coroutines for things like this. This is how I’d probably set it up (uber-sloppy/quick pseudo code). Creating your own classes to store the information would make this a lot cleaner… An alternative to Coroutines is using something like iTween with callback delegates.
I’d probably set it up like…
public enum Direction {North, South, East, West}
Direction _currentDirection
bool[10][10] _mapData;
int _currentX;
int _currentY;
void Update(){
// Capture input, set _currentDirection
}
void Awake(){
// Set map data, in this example I'm just using bools where true == canwalk and false == cannot walk, but you'd probably want a custom data type to hold all pertinent data about the tile. For example, you could do all sorts of fun stuff like cache viable neighbors, save the tile x/y coordinate as well as the world coordinate of the center of the tile...
}
void Start(){
_currentX=0;
_currentY=0; // set your starting position
_currentDirection = Direction.East;
StartCoroutine(MovementRoutine());
}
IEnumerator MovementRoutine(){
while (true){
// Pick your next tile based on your current direction, and whether the destination tile is walkable
bool traveling = (destination is valid);
while (traveling){ // If you have no valid destination the while loop will just be skipped
// Move towards your destination
if (destination reached){
traveling = false;
}
yield return null;
}
yield return null;
}
}
Hi Kyle, I have to extend my most excellent thanks to you, with your pseudo code I was able to put
together the functionality I was after.
Many thanks again!