Sign in to follow this  

Tilemap Scrolling problem- please help!

This topic is 4694 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

OK, I am really looking for ideas to try rather than an absolute answer as I think that will be a bit complicated. Here is my problem. I have created a tilemap (its for a top-down driving game). The car drives on it fine and the map scrolls fine. The problems start when I add a second vehicle to the game. This is not under user control and so should remain in the same place on the map. I originally implemented this by simply subtracting the starting coordinates for screen drawing from the x and y coordinates of the second car. However this doesn ot seem to work, and when the cars are both on screen, the supposedly stationary car moves around the map - well, the map moves around it as the cars coordinates are stationary. My probelm therefore is that I dont seem to be able to convert accurately from map coordinates to screen space coordinates. The simple idea I had does not work, for what reason I cannot fathom. Each car has an x and y coordinate, an angle of rotation, a normalized vector of direction and a velocity - for the second car this is always 0. Map scrolling is calcuated using the vector and vecloity of the player controlled car. I have a feeling that the problem is to do with the vector and the velocity differences between the two cars, but really cant find the answer AT ALL. I hope I have given enough detail and that someone can give me a push in the right direction. Any help much appreciated, Ols

Share this post


Link to post
Share on other sites
Thanks for replying.

The code is quite split-up as parts are taken from files for the Player, the other cars and the map. Below is some relevant code from each file. The most important bits would seem to be for the movement and rendering...


//This is how the player moves and it works fine
void CPlayerCar::Move()
{
//create vector of current direction by retrieving the cos(angle) and sin(angle)
//from the previously constructed rotation matrix
_vecDirection = D3DXVECTOR2(_matRot._11, _matRot._12);
//normalize the vector
D3DXVec2Normalize(&_vecDirection, &_vecDirection);
//increase the offset of the map i.e. scroll the map appropriately
_pMap->AddToOffsetX(_fVelocity*_vecDirection.x);
_pMap->AddToOffsetY(_fVelocity*_vecDirection.y);
//then increase the position of the car onscreen appropriately
_fPosX += (_vecDirection.x * _fVelocity);
_fPosY += (_vecDirection.y * _fVelocity);
}

//player rendering
//renders the car
bool CPlayerCar::Render(LPDIRECT3DDEVICE9 pDevice)
{
if(!pDevice)
return false;

RECT srcRect;
srcRect.top = 0;
srcRect.left = 0;
srcRect.bottom = srcRect.top + _pTextureInfo.Height;
srcRect.right = srcRect.left + _pTextureInfo.Width;

D3DXVECTOR3 vCentre(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vPosition(_fPosX, _fPosY, 0.0f);

_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
_pSprite->Draw(_pTexture, &srcRect, &vCentre, &vPosition, D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f));
_pSprite->End();

return true;
}




//These are the two functions that control the scrolling of the map
//adds 'x' to current offset value and ensures that offset does not exceed its max
void CMap::AddToOffsetX(float x)
{
_fOldOffsetX = _fOffsetX;

if((_fOffsetX + x) < 0.0f)
_fOffsetX = 0.000001f;
else if((_fOffsetX + x) > MAXOFFSET_X)
_fOffsetX = MAXOFFSET_X;
else
_fOffsetX += x;
}

void CMap::AddToOffsetY(float y)
{
_fOldOffsetY = _fOffsetY;

if((_fOffsetY + y) < 0.0f)
_fOffsetY = 0.000001f;
else if((_fOffsetY + y) > MAXOFFSET_Y)
_fOffsetY = MAXOFFSET_Y;
else
_fOffsetY += y;
}




//this is the AI movement function
void CAICar::Move(float TimeScale)
{
if(_fVelocity < _fMaxVelocity)
_fVelocity += (TimeScale * ACCELERATION);

Rotate();

_vecDirection = D3DXVECTOR2(_matRot._11, _matRot._12);
D3DXVec2Normalize(&_vecDirection, &_vecDirection);
_fPosX += (_vecDirection.x * _fVelocity);
_fPosY += (_vecDirection.y * _fVelocity);
}

//and its rendering function
bool CAICar::Render(LPDIRECT3DDEVICE9 pDevice)
{
if(!pDevice)
return false;

//if car is onscreen, then draw it
if((_pMap->GetOffsetX()-_pTextureInfo.Width) < _fPosX &&
((_pMap->GetOffsetX()+_fViewWidth)+_pTextureInfo.Width) > _fPosX &&
(_pMap->GetOffsetY()-_pTextureInfo.Height) < _fPosY &&
((_pMap->GetOffsetY()+_fViewHeight)+_pTextureInfo.Height) > _fPosY)
{
RECT srcRect;
srcRect.top = 0;
srcRect.left = 0;
srcRect.bottom = srcRect.top + _pTextureInfo.Height;
srcRect.right = srcRect.left + _pTextureInfo.Width;

tempX = _fPosX-_pMap->GetOffsetX();
tempY = _fPosY-_pMap->GetOffsetY();

D3DXVECTOR3 vCentre(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vPosition(tempX, tempY, 0.0f);

_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
_pSprite->Draw(_pTexture, &srcRect, &vCentre, &vPosition, D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f));
_pSprite->End();

return true;
}

return false;
}



The final section of the code is presumably where the problem occurs, but I just cant get it right!

Thanks for any help you can give

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
I can't seem to find any issue with your code.


THATS THE PROBLEM!!

The code runs fine but the car moves at times it is not supposed to and i have NO idea why. Would it be possible to send you the current build so you can see the problem in action?

Share this post


Link to post
Share on other sites
Yeah, sure. Upload it to some webspace and post a link. Also, if you want(but I don't know if I have time) you could post your full source and I might be able to go over that. However, I'm don't have a lot of time to learn and figure out how a new game works.

Share this post


Link to post
Share on other sites
Thanks for your help thus far.

Current build is available from: http://members.gamedev.net/ols/zip/tiles.zip

The AI car is set on a straight course. Controlling the other car with arrow keys will quite quickly make the problem evident. Any help is so appreciated.

Thanks again for having a look

Ols

Share this post


Link to post
Share on other sites
Difficult to see exactly what might be going wrong, but it seems as if you are drawing the AI car relative to the center of the screen, so that when the center of the screen changes, the AI car slides. The AI car should be drawn at an absolute position that does not take the center of the screen into account at all, so that changing the center doesn't affect the drawing position. It's hard to say exactly, though, without seeing more code.

Share this post


Link to post
Share on other sites
Hi,

The third of the code segments above shows that the centre is being taken as (0,0,0). Is this then wrong?

I can upload all the code if it will help - but be warned that it is probably quite messy!

Share this post


Link to post
Share on other sites
The car went right off the screen for me without pushing any buttons. Has the build been changed since you made the last post?? Also you need to put some sort of "time-based" delay in the render loop so that the frame rate isn't hardware dependent. I have 1370fps as an average on my computer. I would like to help so let me know.

-Nightbird

Share this post


Link to post
Share on other sites
no, there has been no build changes at all. very odd!

was going to look into how to restrict the frame rate once it was completed, but will see what i can do now - well infact will be tomorrow as its almost 3am here! - thanks for taking an interest and will post when i have uploaded one with a restriction.

Share this post


Link to post
Share on other sites
The issue is in your drawing code somewhere. Somewhere, you're drawing the AI car relative to the player car, or that's happening through indirection. The world-relative position of the AI car is fine. Least wise, it doesn't change in relation to the world. Your issue is the on-screen representation. Look at where you're calculating it's x and y. That's where your issue is. Your math is probably off.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
The issue is in your drawing code somewhere. Somewhere, you're drawing the AI car relative to the player car, or that's happening through indirection. The world-relative position of the AI car is fine. Least wise, it doesn't change in relation to the world. Your issue is the on-screen representation. Look at where you're calculating it's x and y. That's where your issue is. Your math is probably off.


Thanks for replying again.

The map is moved according to the velocity and vector of the player-controlled car as shown in the first two code boxes above i.e.
_pMap->AddToOffsetX(_fVelocity*_vecDirection.x);
_pMap->AddToOffsetY(_fVelocity*_vecDirection.y);

and the AI car is updated according to the scrolling i.e.
tempX = _fPosX-_pMap->GetOffsetX();
tempY = _fPosY-_pMap->GetOffsetY();
(see the third of the code boxes for clarification). The GetOffset function gets the amount the map has moved from its original position of 0,0

I thought that this was causing the problem, but have been completely lost as to why it is doing it and how to fix it. I have tried so many different combinations of calculations, but nothing seems to improve it and its getting to a maddeningly frustrating point!

Is there any specific suggestion(s) that you can come up with for me to try?

Thanks again for the help

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
You just posted the same thing 5 times, btw. Wanted to let you know.


Yeah, sorry about that!
Keep getting ASP errors.
Think there is just the one now!

Share this post


Link to post
Share on other sites
A possible solution, that comes to mind: (weird, sort of odd, but may work) Player car is the center of the screen. Therefore, manually calculate the difference between the player car and the AI car, and draw that offset onscreen. If the output doesn't change, it's in your world-relative position. If it fixes it, it's in your drawing code.

Try making the AI car show up based on the immedeate player car world-relative coordinates. Get the distance between the two, convert it to onscreen-distance, draw accordingly.

Share this post


Link to post
Share on other sites
Try killing the lines in AI car render method:
tempX = _fPosX-_pMap->GetOffsetX();
tempY = _fPosY-_pMap->GetOffsetY();

then just use _fPosX and _fPosY as the position as their names indicate.

Share this post


Link to post
Share on other sites
Quote:
Original post by egwenejs
Try killing the lines in AI car render method:
tempX = _fPosX-_pMap->GetOffsetX();
tempY = _fPosY-_pMap->GetOffsetY();

then just use _fPosX and _fPosY as the position as their names indicate.


Thanks for the reply

This would cause the car to drawn in screen coords and not in map. Therefore when the map scrolls the car would remain stuck in its screen position and be out of sync with the rest of the game

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
A possible solution, that comes to mind: (weird, sort of odd, but may work) Player car is the center of the screen. Therefore, manually calculate the difference between the player car and the AI car, and draw that offset onscreen. If the output doesn't change, it's in your world-relative position. If it fixes it, it's in your drawing code.

Try making the AI car show up based on the immedeate player car world-relative coordinates. Get the distance between the two, convert it to onscreen-distance, draw accordingly.


I am trying to do what you say, but getting a bit confused!
If i check the difference between offsets using _fPosX (i.e. the map offset is not taken into account) these remain constant, which i can see is a problem.

When you say
Quote:
Try making the AI car show up based on the immedeate player car world-relative coordinates
do you mean to try and draw the AI car using the coordinates from the Player car?

Am going to try and use the info to get some result, but just thought I would ask for clarification to check if we are on completely different wavelengths!

Cheers

Share this post


Link to post
Share on other sites
SORTED!

After using some of the details that I took from Tarviathun I realised that the problem was due to the angle i.e. the vector of the AI car.

After a large amount of trial-and-error coding and pen-and-paper maths, I came up with the render function as below. It is still in its very first incarnation and needs to be tidied up, but the ideas are there and it works fine as can be seen in the new download if anyone is interested (see bottom of post for link).

I have posted the code so that anyone with similar problems can have a look.


bool CAICar::Render(LPDIRECT3DDEVICE9 pDevice)
{
if(!pDevice)
return false;

RECT srcRect;
srcRect.top = 0;
srcRect.left = 0;
srcRect.bottom = srcRect.top + _pTextureInfo.Height;
srcRect.right = srcRect.left + _pTextureInfo.Width;

D3DXVECTOR4 tempVec;
D3DXMATRIX mtxTranslate;
D3DXMatrixIdentity(&mtxTranslate);
mtxTranslate._41 = _pMap->GetChangeInOffsetX();
mtxTranslate._42 = _pMap->GetChangeInOffsetY();
D3DXVec2Transform(&tempVec, &_vecDirection, &mtxTranslate);
_vecDirection.x = tempVec.x;
_vecDirection.y = tempVec.y;
D3DXVec2Normalize(&_vecDirection, &_vecDirection);

_fPosX-=(_Player.GetVelocity()*_vecDirection.x) + _pMap->GetChangeInOffsetX();
_fPosY-=(_Player.GetVelocity()*_vecDirection.y) + _pMap->GetChangeInOffsetY();

D3DXVECTOR3 vCentre(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vPosition(_fPosX, _fPosY, 0.0f);

_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
_pSprite->Draw(_pTexture, &srcRect, &vCentre, &vPosition, D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f));
_pSprite->End();

return true;
}



New version available from:
http://members.gamedev.net/ols/zip/D2.zip
so you can see it in action

Thanks all for your help,

Ols

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
Glad that I could help a bit. I like the game, btw. A bit touchy on the speed and controls, though. Hehe.


Thanks for the help again.

As for the game, I have got everything running at high speed at the mo cos i figured if it works at that speed its bound to work slower as well!

Considering keeping the speed high but maybe reducing the sensitvity on turning.

Cheers for the feedback.

Keep a look at my journal members.gamedev.net/ols/journal for updates and info.

Thanks again

Ols

Share this post


Link to post
Share on other sites

This topic is 4694 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this