Problem with Blitting
Displaying 1-6 of 6 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
Parslip

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);
}

Posted on 2005-05-06 05:26:07 (last edited on 2005-05-19 15:12:58)

Kildorf

I think I see the problem... it's actually something I forget about all the time too. ^_^

Entity.x[] and entity.y[] give you the entity's location on the map. Blitting is done based on screen location. In other words, you've got to subtract the current screen location (xwin and ywin) from all the blitting location of your blue rectangles. Specifically:

BlitLucent(BoxesUpRX - xwin,BoxesUpRY - ywin,60,BlueBox,screen);


... and the same change for each of the other blits, too. You could also subtract the xwin and ywin out when you're first calculating BoxesUp*. As long as it gets taken out at some point.

Good luck. :)

Posted on 2005-05-06 08:18:33

Parslip

Wow, thank you! I'll try it out here in a bit.

Posted on 2005-05-06 14:14:16

Parslip

Oh hell yeah, sweet, it works perfectly! Thank you very much!

Posted on 2005-05-06 14:17:24

Kildorf

Woo! I'm glad it worked. :3

Posted on 2005-05-06 14:48:48

basil

Look up xwin/ywin camera tracking in the docs...once you start shifting between players spread over the map and want to have the camera center on them cameratracking will be something you need to know about. Notice while you're there that Zip has written a very nice function for smoothly panning between characters which should be quite useful.

Posted on 2005-05-06 20:40:04


Displaying 1-6 of 6 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.