Sprite Placement Representation in a Level Editor

Started by
6 comments, last by MatthewDiaz 12 years, 4 months ago
I am having difficulty wrapping my head around how exactly my program will move sprites and understand its placement through the use of a level editor. It is a 2d side scrolling game. I decided that in the level editor I will allow the user to specify the exact boundaries of the level in pixels. My program is running at 1024x768 resolution. So a level 3 screens long will be represented by a level that is 3072x768. With my boundaries set I then will allow the user to scroll to the boundaries by pressing the middle mouse button. Once the boundaries are hit at the edge of the screen, the user can't scroll anymore. The exact spot of the mouse arrow will be represented on the screen in two ways, 1 the screen position(middle of screen will always be 512x384), and 2 the level position(relative to the level boundaries I set, don't understand how to implement this part though). My sprites are drawn with a world matrix so their placement is a simple XxY placement relative to the screen though and not the level boundaries. So if move 2 screens to the right I simply subtract 2048 from the x value of all my sprite positions. This is where my problem lies. I want my sprites to have two separate positions, 1 the position relative to the screen which always changes and 2 the level position which is always static, unless the sprite moves of course. Taking a sprite in my level editor and placing it is simple when talking about screen position, but determining where in the level I place it is what I need to determine. How could I go about doing this?I am coding in c++ btw with Directx11.
Advertisement

This is where my problem lies. I want my sprites to have two separate positions, 1 the position relative to the screen which always changes and 2 the level position which is always static, unless the sprite moves of course.

You really want to avoid having your sprite positions be relative to the camera. The screen (or camera) should be looking at the world from it's own perspective, and the sprites should not depend on the camera's position. You can give the camera it's own world position, and have it determine where it should be looking in the world.



Taking a sprite in my level editor and placing it is simple when talking about screen position, but determining where in the level I place it is what I need to determine. How could I go about doing this?I am coding in c++ btw with Directx11.

If the camera has a world position (assuming it represents the top left corner of the screen), you can convert screen coordinates to world coordinates by adding the camera's world position to the screen position of the sprite you are placing.

[quote name='ILoveJesus' timestamp='1322529361' post='4888643']
This is where my problem lies. I want my sprites to have two separate positions, 1 the position relative to the screen which always changes and 2 the level position which is always static, unless the sprite moves of course.

You really want to avoid having your sprite positions be relative to the camera. The screen (or camera) should be looking at the world from it's own perspective, and the sprites should not depend on the camera's position. You can give the camera it's own world position, and have it determine where it should be looking in the world.



Taking a sprite in my level editor and placing it is simple when talking about screen position, but determining where in the level I place it is what I need to determine. How could I go about doing this?I am coding in c++ btw with Directx11.

If the camera has a world position (assuming it represents the top left corner of the screen), you can convert screen coordinates to world coordinates by adding the camera's world position to the screen position of the sprite you are placing.
[/quote]

If my camera starts at the bottom left of my level then the screen coordinates would be equal to the level coordinates I am thinking. So if I had two variables that represented the screens world coordinates, without moving the camera they would be equal to the screens coordinates. If I pan the camera right then can't I just add the amount of pixels I move to the x value variable here to show its position in the world? If I did that then can't I draw my sprites that have static world coordinates using that information but still drawing them relative to the screen? So if I had a level that was 3072x768(3 screen wide) and i moved the screen one screen to the right, then can't I determine through a calculation that any sprite at 1567x384(level position) should be drawn at 512x384 screen position?

Or do I need to change this which is inside my Load Sprite function?




XMMATRIX view = XMMatrixIdentity( );
XMMATRIX projection = XMMatrixOrthographicOffCenterLH( 0.0f, 1024.0f, 0.0f, 768.0f, 0.1f, 100.0f );
vpMatrix_ = XMMatrixMultiply( view, projection );




Do I need to change this to represent my level coordinates? Understand I never tried that. What i am suggesting above is with keeping the world matrix a screen wide which I assume in theory would work.
You cannot use a fixed model-view matrix. Every time you scroll the view (usually every frame), you have to change the horizontal and vertical shifts in your matrix to bring different objects (which keep their world coordinates) into the visible range of view coordinates.
The world coordinates of objects should only change when they actually move, never affected by how you display them; for example, you could render a split screen with two or more different orthographic projections applied to the same objects (even the same vertex buffers, containing points in world coordinates).

Omae Wa Mou Shindeiru


You cannot use a fixed model-view matrix. Every time you scroll the view (usually every frame), you have to change the horizontal and vertical shifts in your matrix to bring different objects (which keep their world coordinates) into the visible range of view coordinates.
The world coordinates of objects should only change when they actually move, never affected by how you display them; for example, you could render a split screen with two or more different orthographic projections applied to the same objects (even the same vertex buffers, containing points in world coordinates).


I understand and that is why I wanted the sprites to have two separate coordinates. One which is the world or level coordinates which stay the same and 2 which is the coordinates used to display the sprites relative to the screen. I thought I could keep track of the cameras world coordinates myself by adding to the world coordinate values of the screen as I move left or right. Then using that info I can determine where to draw sprites using their world coordinates by translating their world coordinates to where they are relative to my screen. Is this ok?
There is more than enough info online explaining how to use cameras in 3d space in Directx 11 and in my book. However, I cannot find any info on how to set up a view Matrix for a camera in 2d space. The book I am learning from is no help. It teaches you how to set up a World x View X Projection Matrix to place sprites by the pixel relative to your screen by multiplying the view Matrix and the projection matrix to create a vpMatrix and then multiplying the vpMatrix times the sprite world Matrix. I tried incorporating the camera class from a 3d exercise into 2d space but to no avail. This is frustrating. There is just so little tutorials and help for Directx 11 online for this issue if none at all. Can someone help me here? I'll give the code for how the sprites are drawn and how the 3d camera is implemented in the book.


How sprites are drawn

//In the load Sprite function the sprite positions and the view x proj is done

XMFLOAT2 sprite1Pos( 100.0f, 300.0f );
sprites_[0].SetPosition( sprite1Pos );

XMFLOAT2 sprite2Pos( 400.0f, 100.0f );
sprites_[1].SetPosition( sprite2Pos );

XMMATRIX view = XMMatrixIdentity( );
XMMATRIX projection = XMMatrixOrthographicOffCenterLH( 0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f );
vpMatrix_ = XMMatrixMultiply( view, projection );


//The render function each sprite is drawn seperately with a new world Matrix multiplied to the static vpMatrix each time
for( int i = 0; i < 2; i++ )
{
XMMATRIX world = sprites_.GetWorldMatrix( );
XMMATRIX mvp = XMMatrixMultiply( world, vpMatrix_ );
mvp = XMMatrixTranspose( mvp );

d3dContext_->UpdateSubresource( mvpCB_, 0, 0, &mvp, 0, 0 );
d3dContext_->VSSetConstantBuffers( 0, 1, &mvpCB_ );

d3dContext_->Draw( 6, 0 );
}




Camera in 3d space code

//In the load function the world,view and proj matrix is created and the proj matrix defined and the camera position set.

d3dResult = d3dDevice_->CreateBuffer( &constDesc, 0, &viewCB_ );

if( FAILED( d3dResult ) )
{
return false;
}

d3dResult = d3dDevice_->CreateBuffer( &constDesc, 0, &projCB_ );

if( FAILED( d3dResult ) )
{
return false;
}

d3dResult = d3dDevice_->CreateBuffer( &constDesc, 0, &worldCB_ );

if( FAILED( d3dResult ) )
{
return false;
}

projMatrix_ = XMMatrixPerspectiveFovLH( XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f );
projMatrix_ = XMMatrixTranspose( projMatrix_ );

camera_.SetPositions( XMFLOAT3( 3.0f, 3.0f, -12.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) );


// In the render function

XMMATRIX worldMat = XMMatrixIdentity( );
worldMat = XMMatrixTranspose( worldMat );

XMMATRIX viewMat = camera_.GetViewMatrix( );
viewMat = XMMatrixTranspose( viewMat );

d3dContext_->UpdateSubresource( worldCB_, 0, 0, &worldMat, 0, 0 );
d3dContext_->UpdateSubresource( viewCB_, 0, 0, &viewMat, 0, 0 );
d3dContext_->UpdateSubresource( projCB_, 0, 0, &projMatrix_, 0, 0 );

d3dContext_->VSSetConstantBuffers( 0, 1, &worldCB_ );
d3dContext_->VSSetConstantBuffers( 1, 1, &viewCB_ );
d3dContext_->VSSetConstantBuffers( 2, 1, &projCB_ );






So I would like to be able to place sprites by the pixel, but have a camera I can control the position of so I will never have to change the sprite coordinates. How could I do this?
I don't know any other way than to just have each object (ie, sprite) have only a world coordinate. And, using your camera's center in world coordinates, you can draw every object within the world based on the offset from that point.

I'm not sure why you want to even know what the screen coordinates might be, except during the time you draw.

So, if your Camera's center world coordinate is 2044x384, and a Sprite's world coord is 1780x540, then it would be drawn on the screen at:

// Assuming Camera.Location is the world coord of the camera
// Sprite.Location is the world coord of the sprite
// and ScreenCenter is the x,y location of the center of the screen (which, in 1024x768 case would be 512/384)
ScreenX = (Sprite.Location.x - Camera.Location.x) + ScreenCenter.x;
ScreenY = (Sprite.Location.y - Camera.Location.y) + ScreenCenter.y;
Sprite->Draw(ScreenX, ScreenY);

where ScreenX = 1780 - 2044 + 512 = 248 and
ScreenY = 540 - 384 + 384 = 540

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)


I don't know any other way than to just have each object (ie, sprite) have only a world coordinate. And, using your camera's center in world coordinates, you can draw every object within the world based on the offset from that point.

I'm not sure why you want to even know what the screen coordinates might be, except during the time you draw.

So, if your Camera's center world coordinate is 2044x384, and a Sprite's world coord is 1780x540, then it would be drawn on the screen at:

// Assuming Camera.Location is the world coord of the camera
// Sprite.Location is the world coord of the sprite
// and ScreenCenter is the x,y location of the center of the screen (which, in 1024x768 case would be 512/384)
ScreenX = (Sprite.Location.x - Camera.Location.x) + ScreenCenter.x;
ScreenY = (Sprite.Location.y - Camera.Location.y) + ScreenCenter.y;
Sprite->Draw(ScreenX, ScreenY);

where ScreenX = 1780 - 2044 + 512 = 248 and
ScreenY = 540 - 384 + 384 = 540


Strange, I believe that is the way I was going to do it, but I thought there was a better way. The reason why i wanted my editor to keep track of my mouse pointers screen position along with world position is so I can have an idea of where I am placing the sprite screenwise. If I wanted to be consistent with let's say ground placement, it would be easier if I have an exact pixel to aim for. I suppose having just world coordinates would serve the same purpose, so maybe that idea was unnecessary and with multiple floors in a level I guess it would only make things confusing. So basically as I scroll the screen I take the sprites world position and translate it to screen position for drawing correct? So techincally I am not changing its world coordinates but the coordinates I use to draw it with correct? The crazy thing is that I was originally going to do that, but other posters have mentioned I shouldn't change the sprites position, but with my way the sprites position to draw is constantly changing so that only confused me.

This topic is closed to new replies.

Advertisement