I'm trying to make a Final Fantasy Tactics-style combat engine, and I'm starting with character movement. At this point, I've got everything working fine...except when I move the character far enough away from the 0,0 location to have the map scroll. Then things get all fucked up.
You see, each time the player's turn comes up, a grid of translucent blue boxes is supposed to appear, centered on the player, to show exactly which squares the player can move to. If the player's movement is 3, for instance, he can move two squares (each square being 16x16 pixels) over and one up, or three over, or two up and one over, etc. Well, as the map begins to scroll beneath the character, this grid shifts from being centered on the character. The farther down I move, the farther away the grid appears from my character below me. The same is true when I move to the right (since I start in 6,6). Now, my code is a mess, so I'm not sure if it can easily be understood, but I'll post it below.
Basically, I have a function called Combat in the map's vc file which initializes on startup. That function loops, calling CombatMovement below until esc is hit. MovementScore is derived from the global variable PlayerMovement, which is set to 4. Also the array current_cursor is global.
I'm hoping that someone will be able to give me at least an indication of what might be wrong from what I've said above, as I'm doubting my code is very understandable at this point.
void CombatMovement(int MovementScore) //Deals with moving a character in combat
{
int Cursor;
current_cursor[0] = entity.x[player];//sets initial Cursor location, x
current_cursor[1] = entity.y[player];//sets initial Cursor location y
SetMovementTiles(MovementScore);//Sets up all of the blue movement indication tiles
while(!b1)//Keeps the squares on-screen until enter is pressed
{
Cursor = LoadImage('MoveCursor.pcx');//loads our cursor image
UpdateControls();//checks to see what is being pressed currently
HookKey(SCAN_UP,'UpPressed');//executes UpPressed when up arrow is pressed
HookKey(SCAN_DOWN,'DownPressed');//executes DownPressed when down arrow is pressed
HookKey(SCAN_RIGHT,'RightPressed');//executes RightPressed when right arrow is pressed
HookKey(SCAN_LEFT,'LeftPressed');//executes LeftPressed when left arrow is pressed
ShowPage();//prints the blue tiles first, then below the cursor tile. This way the cursor tile seems to move, as opposed to making copies of itself all over the screen
BlitLucent(current_cursor[0],current_cursor[1],60,Cursor,screen);//print cursor to screen
FreeImage(Cursor);//removes Cursor image from memory
}
Unpress(1);//Unpresses Enter
//string CharMoveX = str(current_cursor[0]/16);
//string CharMoveY = str(current_cursor[1]/16);
ShowPage();
PlayerMove('y'+str(current_cursor[1]/16)+'x'+str(current_cursor[0]/16));
TextBox('X = '+str(current_cursor[0]/16)+'&'+str(entity.x[player])+' and Y = '+str(current_cursor[1]/16)+'&'+str(entity.y[player])+'.');
}
void UpPressed()// Moves the cursor up one square, checks to see if it has reached it's limit
{
if(current_cursor[1] > (entity.y[player] - (16 * PlayerMovement)))
{
SetMovementTiles(PlayerMovement);
current_cursor[1] -= 16;
}
}
void DownPressed()// Moves the cursor down one square, checks to see if it has reached it's limit
{
if(current_cursor[1] < (entity.y[player] + (16 * PlayerMovement)))
{
SetMovementTiles(PlayerMovement);
current_cursor[1] += 16;
}
}
void RightPressed()// Moves the cursor right one square, checks to see if it has reached it's limit
{
if(current_cursor[0] < (entity.y[player] + (16 * (PlayerMovement))))
{
SetMovementTiles(PlayerMovement);
current_cursor[0] += 16;
}
}
void LeftPressed()// Moves the cursor left one square, checks to see if it has reached it's limit
{
if(current_cursor[0] > (entity.y[player] - (16 * PlayerMovement)))
{
SetMovementTiles(PlayerMovement);
current_cursor[0] -= 16;
}
}
void SetMovementTiles(int MovementScore)//Sets all of the blue translucent squares denoting where you can move
{
int BlueBox = LoadImage('Blue.pcx');
int AxisNumber = MovementScore;
int NonAxisNumber;
int BoxXR;
int BoxYR;
int BoxXL;
int BoxYL;
int BoxXU;
int BoxYU;
int BoxXD;
int BoxYD;
int BoxesUpRX;
int BoxesUpRY;
int BoxesDownRX;
int BoxesDownRY;
int BoxesUpLX;
int BoxesUpLY;
int BoxesDownLX;
int BoxesDownLY;
Render();
while(AxisNumber > 0)//Sets the blue squares along the X and Y axis
{
NonAxisNumber = MovementScore - AxisNumber;
BoxXR = entity.x[player] + (16 * AxisNumber);
BoxYR = entity.y[player];
BoxXL = entity.x[player] - (16 * AxisNumber);
BoxYL = entity.y[player];
BoxXU = entity.x[player];
BoxYU = entity.y[player] + (16 * AxisNumber);
BoxXD = entity.x[player];
BoxYD = entity.y[player] - (16 * AxisNumber);
BlitLucent(BoxXR,BoxYR,60,BlueBox,screen);
BlitLucent(BoxXL,BoxYL,60,BlueBox,screen);
BlitLucent(BoxXU,BoxYU,60,BlueBox,screen);
BlitLucent(BoxXD,BoxYD,60,BlueBox,screen);
while (NonAxisNumber > 0)//Sets all the squares not on X and Y axis, based off of x axis
{
BoxesUpRX = entity.x[player] + (16 * AxisNumber);
BoxesUpRY = entity.y[player] - (16 * NonAxisNumber);
BoxesDownRX = entity.x[player] + (16 * AxisNumber);
BoxesDownRY = entity.y[player] + (16 * NonAxisNumber);
BoxesUpLX = entity.x[player] - (16 * AxisNumber);
BoxesUpLY = entity.y[player] - (16 * NonAxisNumber);
BoxesDownLX = entity.x[player] - (16 * AxisNumber);
BoxesDownLY = entity.y[player] + (16 * NonAxisNumber);
BlitLucent(BoxesUpRX,BoxesUpRY,60,BlueBox,screen);
BlitLucent(BoxesDownRX,BoxesDownRY,60,BlueBox,screen);
BlitLucent(BoxesUpLX,BoxesUpLY,60,BlueBox,screen);
BlitLucent(BoxesDownLX,BoxesDownLY,60,BlueBox,screen);
NonAxisNumber --;
}
AxisNumber --;
}
FreeImage(BlueBox);
}