Archived

This topic is now archived and is closed to further replies.

azjerei

Source available?

Recommended Posts

Is there any source available for a type of game like the older Final Fantasy, the Phantasy Star series etc.? I basically mean a source that can handle a 2-dimensional game like the older 8-/16-bit games. I am having annoying problems getting smooth scrolling to work and I frankly give up.

Share this post


Link to post
Share on other sites
There''s lots of articles covering tile based graphics and smooth scrolling in the articles section, which is likely to be much more use than a big lump of random code you find.

Share this post


Link to post
Share on other sites
quote:
Original post by azjerei
Well, I need code... But I will check the articles.


That''s the point: you don''t.

You''ll learn very little if you try to jump right into a large lump of techniques you aren''t ready for yet. And believe me, you don''t want to rely on oldschool console games. You DON''T. They use a lot of ugly hacks to get around limitations. Even the graphic system on NES is screwy: some weiiird form of palettized RLE.

The last thing you need is code. Learn to do things right via a tutorial/article.

Share this post


Link to post
Share on other sites
If you seriously want to look at someone else's way of doing a 2D engine, then there is open source avalible for full games in lot's of places. http://venosoft.com has a fully completed RPG that's both playable and open source on their site and you can use the code any way you want with no restrictions at all.

"Life is a double edged sword, we always hope to strike though adversity with the shining side..."

jkettles16 of Venosoft

[edited by - jkettles16 on May 20, 2004 9:59:33 AM]

Share this post


Link to post
Share on other sites
Smooth scrolling tripped me up as well, when I was beginning. Once you understand the logic behind it, its not that hard to grasp. The hardest part is the lack of "human explanation", imo.

So I''ll give it a go.

Assuming your screen resolution is 640x480, and your tiles are 32x32, you can fit 20 tiles horizontally and 15 vertically.

Lets say you want the camera to follow an entity (a character, a missile when a gun is shooting, whatever). Your prototype will look something like this:


void CMap :: Render(CBaseEntity *pFocus)


The origin for my entity (the spot they''re standing on) is pixel perfect, so if the map is 20x15 tiles and their origin is 32, 32 then we know they are on tile 1,1. (32 / 32 = 1)

So calculate that information:

int iTileX = pFocus->m_iOriginX / 32;
int iTileY = pFocus->m_iOriginY / 32;
int iOffsetX = pFocus->m_iOriginX % 32;
int iOffsetY = pFocus->m_iOriginY % 32;


In my old DirectDraw engine, my camera was part of the map. Not great, but really this was the only place it was used.

We need to calculate the camera''s position by multiplying by 32 (the width and height of our tiles), add the offsets and subtract half the size of the screen.


m_iCameraX = (iTileX << 5) + iOffsetX - 320;
m_iCameraY = (iTileY << 5) + iOffsetY - 240;
// (640 / 2 = 320, 480 / 2 = 240)


Now snap the camera back if its out of bounds.

if(m_iCameraX < 0)
m_iCameraX = 0;
if(m_iCameraY < 0)
m_iCameraY = 0;
if(m_iCameraX > m_iCameraMaxX)
m_iCameraX = m_iCameraMaxX;
if(m_iCameraY > m_iCameraMaxY)
m_iCameraY = m_iCameraMaxY;


m_iCameraMax was calculated when the level was loaded, its how many tiles the map is horizontally and vertically.

Now we get some values for where to start and where to finish rendering, this should be easy to follow around.


// Divide Camera Coordinates By 32
int iStartX = m_iCameraX >> 5;
int iStartY = m_iCameraY >> 5;
// Add 20 Tiles (640 / 32 = 20) and 15 Tiles (480 / 32 = 15)
int iEndX = iStartX + 20;
int iEndY = iStartY + 15;
int iX, iY;


Now modulus our coordinates so we know exactly what tiles we have to draw.


// Set Original Destination RECT for first tile
// Upper Left Corner Of Screen
RECT rcDest = {0, 0, 32, 32};

// Same as % 32 but faster (apparently).
iX = m_iCameraX & 0x0000001F;
iY = m_iCameraY & 0x0000001F;


A quick check to see if we can save a couple of blits:

if(!iX)
{
// If m_iCameraX Is Divisible By 32, We''re On A Tile.
// So Only 20 Tiles.
iEndX--;
}
else
{
// Not Divisible By 32, So Bring The RECT Back By The Remainder
// So Its Pixel Perfect Scrolling
rcDest.left -= iX;
rcDest.right -= iX;
}

if(!iY)
{
iEndY--;
}
else
{
rcDest.top -= iY;
rcDest.bottom -= iY;
}


And finally, draw our tiles and we''re done!

// Make A Source Rectangle
RECT rcSource;

// Plot Our Tile, Woot Woot
for(iY = iStartY; iY <= iEndY; iY++)
{
for(iX = iStartX; iX <= iEndX; iX++)
{
m_MapTiles.GetTileByIndex(rcSource, m_Map[iX][iY]);
pDXInterface->Blit(rcDest, m_MapTiles.m_Tileset, rcSource, DDBLT_WAIT);

rcDest.left += 32;
rcDest.right += 32;
}

// Reset Our rcDest RECT to left of next row.
// (One Row Down)
rcDest.top += 32;
rcDest.bottom += 32;
// To The Left!
rcDest.left -= ((iEndX - iStartX + 1) << 5);
rcDest.right -= ((iEndX - iStartX + 1) << 5);
}

return;
}


m_MapTiles.GetTileByIndex(rcSource, m_Map[iX][iY]) will fill the source rectangle with the proper tile to blit, based on the index at our location.

Hopefully the spelling isn''t atrocious, I''m in a rush.


Share this post


Link to post
Share on other sites