•      Sign In
• Create Account

### #ActualJTippetts

Posted 22 February 2012 - 09:19 PM

The heart of drawing the map in that post is this bit of code:
void IsometricMap::draw(sf::RenderWindow *win)
{
// Set view
sf::View view=win->GetView();
// Reverse project center
sf::Vector2f center=WorldToScreen(sf::Vector2f(m_centerx,m_centery));
view.SetCenter(center);
win->SetView(view);

// Reverse-project top-left corner
sf::Vector2f viewsize=view.GetSize();
sf::Vector2f topleft=ScreenToWorld(sf::Vector2f(center.x-viewsize.x/2.0f, center.y-viewsize.y/2.0f));
int sx=(int)(topleft.x/(float)m_nodesize);
int sy=(int)(topleft.y/(float)m_nodesize);

// Move start location up and left two nodes to get a little padding. (subtract 2 from sx
sx-=2;

// Calculate how many nodes across to draw
// A node's total width on-screen is calculated as 4*nodesize
int num_nodes_across=(int)viewsize.x / (m_nodesize*4) + 4; // Pad out the end by drawing 4 extra nodes

// Calculate how many rows to draw
// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it
// a little bit by adding a value that approximates the maximum cell height to the size of the
// viewport.
int num_rows=(((int)viewsize.y+512) / (m_nodesize*2))*2;

// Update lighting
m_lightmap.updateRegion(sx,sy,num_nodes_across,num_rows);

// Drawing proceeds as thus:
// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y
// to move to the next node.
// When a row is done, we move to the next row. This is done by:
// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we
// move to the next row by incrementing y instead.
// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.
int rowincx=1, rowincy=0;
int drawnodes=num_nodes_across+1;

int nodex=sx, nodey=sy;
for(int row=0; row<num_rows; ++row)
{
if (row & 1)
{
// Odd row
rowincx=0;
rowincy=1;
drawnodes=num_nodes_across;
}
else
{
rowincx=1;
rowincy=0;
drawnodes=num_nodes_across+1;
}

for(int node=0; node<drawnodes; ++node)
{
// Calculate cell coords
int cellx=nodex+node;
int celly=nodey-node;
if(cellx>=0 && cellx<m_width && celly>=0 && celly<m_height)
{
sf::Color color=m_lightmap.getLightValue(cellx,celly);
m_nodes[celly*m_width+cellx].drawFloors(win,color);
}
}

nodex=nodex+rowincx;
nodey=nodey+rowincy;
}

It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

### #5JTippetts

Posted 22 February 2012 - 09:19 PM

The heart of drawing the map in that post is this bit of code:

void IsometricMap::draw(sf::RenderWindow *win)

{

// Set view

sf::View view=win->GetView();

// Reverse project center

sf::Vector2f center=WorldToScreen(sf::Vector2f(m_centerx,m_centery));

view.SetCenter(center);

win->SetView(view);

// Reverse-project top-left corner

sf::Vector2f viewsize=view.GetSize();

sf::Vector2f topleft=ScreenToWorld(sf::Vector2f(center.x-viewsize.x/2.0f, center.y-viewsize.y/2.0f));

int sx=(int)(topleft.x/(float)m_nodesize);

int sy=(int)(topleft.y/(float)m_nodesize);

// Move start location up and left two nodes to get a little padding. (subtract 2 from sx

sx-=2;

// Calculate how many nodes across to draw

// A node's total width on-screen is calculated as 4*nodesize

int num_nodes_across=(int)viewsize.x / (m_nodesize*4) + 4; // Pad out the end by drawing 4 extra nodes

// Calculate how many rows to draw

// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it

// a little bit by adding a value that approximates the maximum cell height to the size of the

// viewport.

int num_rows=(((int)viewsize.y+512) / (m_nodesize*2))*2;

// Update lighting

m_lightmap.updateRegion(sx,sy,num_nodes_across,num_rows);

// Drawing proceeds as thus:

// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y

// to move to the next node.

// When a row is done, we move to the next row. This is done by:

// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we

// move to the next row by incrementing y instead.

// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.

int rowincx=1, rowincy=0;

int drawnodes=num_nodes_across+1;

int nodex=sx, nodey=sy;

for(int row=0; row<num_rows; ++row)

{

if (row & 1)

{

// Odd row

rowincx=0;

rowincy=1;

drawnodes=num_nodes_across;

}

else

{

rowincx=1;

rowincy=0;

drawnodes=num_nodes_across+1;

}

for(int node=0; node<drawnodes; ++node)

{

// Calculate cell coords

int cellx=nodex+node;

int celly=nodey-node;

if(cellx>=0 && cellx<m_width && celly>=0 && celly<m_height)

{

sf::Color color=m_lightmap.getLightValue(cellx,celly);

m_nodes[celly*m_width+cellx].drawFloors(win,color);

}

}

nodex=nodex+rowincx;

nodey=nodey+rowincy;

}

It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

### #4JTippetts

Posted 22 February 2012 - 09:17 PM

The heart of drawing the map in that post is this bit of code:

void IsometricMap::draw(sf::RenderWindow *win)
{
// Set view
sf::View view=win->GetView();
// Reverse project center
sf::Vector2f center=WorldToScreen(sf::Vector2f(m_centerx,m_centery));
view.SetCenter(center);
win->SetView(view);

// Reverse-project top-left corner
sf::Vector2f viewsize=view.GetSize();
sf::Vector2f topleft=ScreenToWorld(sf::Vector2f(center.x-viewsize.x/2.0f, center.y-viewsize.y/2.0f));
int sx=(int)(topleft.x/(float)m_nodesize);
int sy=(int)(topleft.y/(float)m_nodesize);

// Move start location up and left two nodes to get a little padding. (subtract 2 from sx
sx-=2;

// Calculate how many nodes across to draw
// A node's total width on-screen is calculated as 4*nodesize
int num_nodes_across=(int)viewsize.x / (m_nodesize*4) + 4; // Pad out the end by drawing 4 extra nodes

// Calculate how many rows to draw
// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it
// a little bit by adding a value that approximates the maximum cell height to the size of the
// viewport.
int num_rows=(((int)viewsize.y+512) / (m_nodesize*2))*2;

// Update lighting
m_lightmap.updateRegion(sx,sy,num_nodes_across,num_rows);

// Drawing proceeds as thus:
// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y
// to move to the next node.
// When a row is done, we move to the next row. This is done by:
// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we
// move to the next row by incrementing y instead.
// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.
int rowincx=1, rowincy=0;
int drawnodes=num_nodes_across+1;

int nodex=sx, nodey=sy;
for(int row=0; row<num_rows; ++row)
{
if (row & 1)
{
// Odd row
rowincx=0;
rowincy=1;
drawnodes=num_nodes_across;
}
else
{
rowincx=1;
rowincy=0;
drawnodes=num_nodes_across+1;
}

for(int node=0; node<drawnodes; ++node)
{
// Calculate cell coords
int cellx=nodex+node;
int celly=nodey-node;
if(cellx>=0 && cellx<m_width && celly>=0 && celly<m_height)
{
sf::Color color=m_lightmap.getLightValue(cellx,celly);
m_nodes[celly*m_width+cellx].drawFloors(win,color);
}
}

nodex=nodex+rowincx;
nodey=nodey+rowincy;
}
It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

### #3JTippetts

Posted 22 February 2012 - 09:17 PM

The heart of drawing the map in that post is this bit of code:

[color=#000088]void[/color][color=#000000] [/color][color=#660066]IsometricMap[/color][color=#666600]::[/color][color=#000000]draw[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]RenderWindow[/color][color=#000000] [/color][color=#666600]*[/color][color=#000000]win[/color][color=#666600])[/color]
[color=#666600]{[/color]
[color=#000000]    [/color][color=#880000]// Set view[/color]
[color=#000000]    sf[/color][color=#666600]::[/color][color=#660066]View[/color][color=#000000] view[/color][color=#666600]=[/color][color=#000000]win[/color][color=#666600]->[/color][color=#660066]GetView[/color][color=#666600]();[/color]
[color=#000000]    [/color][color=#880000]// Reverse project center[/color]
[color=#000000]    sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] center[/color][color=#666600]=[/color][color=#660066]WorldToScreen[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#666600]([/color][color=#000000]m_centerx[/color][color=#666600],[/color][color=#000000]m_centery[/color][color=#666600]));[/color]
[color=#000000]    view[/color][color=#666600].[/color][color=#660066]SetCenter[/color][color=#666600]([/color][color=#000000]center[/color][color=#666600]);[/color]
[color=#000000]    win[/color][color=#666600]->[/color][color=#660066]SetView[/color][color=#666600]([/color][color=#000000]view[/color][color=#666600]);[/color]

[color=#000000]    [/color][color=#880000]// Reverse-project top-left corner[/color]
[color=#000000]    sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] viewsize[/color][color=#666600]=[/color][color=#000000]view[/color][color=#666600].[/color][color=#660066]GetSize[/color][color=#666600]();[/color]
[color=#000000]    sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] topleft[/color][color=#666600]=[/color][color=#660066]ScreenToWorld[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#666600]([/color][color=#000000]center[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]-[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]/[/color][color=#006666]2.0f[/color][color=#666600],[/color][color=#000000] center[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]-[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]/[/color][color=#006666]2.0f[/color][color=#666600]));[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] sx[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])([/color][color=#000000]topleft[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]/([/color][color=#000088]float[/color][color=#666600])[/color][color=#000000]m_nodesize[/color][color=#666600]);[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] sy[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])([/color][color=#000000]topleft[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]/([/color][color=#000088]float[/color][color=#666600])[/color][color=#000000]m_nodesize[/color][color=#666600]);[/color]

[color=#000000]    [/color][color=#880000]// Move start location up and left two nodes to get a little padding. (subtract 2 from sx[/color]
[color=#000000]    sx[/color][color=#666600]-=[/color][color=#006666]2[/color][color=#666600];[/color]

[color=#000000]    [/color][color=#880000]// Calculate how many nodes across to draw[/color]
[color=#000000]    [/color][color=#880000]// A node's total width on-screen is calculated as 4*nodesize[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] num_nodes_across[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]x [/color][color=#666600]/[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]m_nodesize[/color][color=#666600]*[/color][color=#006666]4[/color][color=#666600])[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] [/color][color=#006666]4[/color][color=#666600];[/color][color=#000000] [/color][color=#880000]// Pad out the end by drawing 4 extra nodes[/color]

[color=#000000]    [/color][color=#880000]// Calculate how many rows to draw[/color]
[color=#000000]    [/color][color=#880000]// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it[/color]
[color=#000000]    [/color][color=#880000]// a little bit by adding a value that approximates the maximum cell height to the size of the[/color]
[color=#000000]    [/color][color=#880000]// viewport.[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] num_rows[/color][color=#666600]=((([/color][color=#000088]int[/color][color=#666600])[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]+[/color][color=#006666]512[/color][color=#666600])[/color][color=#000000] [/color][color=#666600]/[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]m_nodesize[/color][color=#666600]*[/color][color=#006666]2[/color][color=#666600]))*[/color][color=#006666]2[/color][color=#666600];[/color]

[color=#000000]    [/color][color=#880000]// Update lighting[/color]
[color=#000000]    m_lightmap[/color][color=#666600].[/color][color=#000000]updateRegion[/color][color=#666600]([/color][color=#000000]sx[/color][color=#666600],[/color][color=#000000]sy[/color][color=#666600],[/color][color=#000000]num_nodes_across[/color][color=#666600],[/color][color=#000000]num_rows[/color][color=#666600]);[/color]

[color=#000000]    [/color][color=#880000]// Drawing proceeds as thus:[/color]
[color=#000000]    [/color][color=#880000]// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y[/color]
[color=#000000]    [/color][color=#880000]// to move to the next node.[/color]
[color=#000000]    [/color][color=#880000]// When a row is done, we move to the next row. This is done by:[/color]
[color=#000000]    [/color][color=#880000]// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we[/color]
[color=#000000]    [/color][color=#880000]// move to the next row by incrementing y instead.[/color]
[color=#000000]    [/color][color=#880000]// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] rowincx[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600],[/color][color=#000000] rowincy[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]    [/color][color=#000088]int[/color][color=#000000] drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600]+[/color][color=#006666]1[/color][color=#666600];[/color]

[color=#000000]    [/color][color=#000088]int[/color][color=#000000] nodex[/color][color=#666600]=[/color][color=#000000]sx[/color][color=#666600],[/color][color=#000000] nodey[/color][color=#666600]=[/color][color=#000000]sy[/color][color=#666600];[/color]
[color=#000000]    [/color][color=#000088]for[/color][color=#666600]([/color][color=#000088]int[/color][color=#000000] row[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] row[/color][color=#666600]<[/color][color=#000000]num_rows[/color][color=#666600];[/color][color=#000000] [/color][color=#666600]++[/color][color=#000000]row[/color][color=#666600])[/color]
[color=#000000]    [/color][color=#666600]{[/color]
[color=#000000]        [/color][color=#000088]if[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]row [/color][color=#666600]&[/color][color=#000000] [/color][color=#006666]1[/color][color=#666600])[/color]
[color=#000000]        [/color][color=#666600]{[/color]
[color=#000000]            [/color][color=#880000]// Odd row[/color]
[color=#000000]            rowincx[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]            rowincy[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]            drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600];[/color]
[color=#000000]        [/color][color=#666600]}[/color]
[color=#000000]        [/color][color=#000088]else[/color]
[color=#000000]        [/color][color=#666600]{[/color]
[color=#000000]            rowincx[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]            rowincy[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]            drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600]+[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]        [/color][color=#666600]}[/color]

[color=#000000]        [/color][color=#000088]for[/color][color=#666600]([/color][color=#000088]int[/color][color=#000000] node[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] node[/color][color=#666600]<[/color][color=#000000]drawnodes[/color][color=#666600];[/color][color=#000000] [/color][color=#666600]++[/color][color=#000000]node[/color][color=#666600])[/color]
[color=#000000]        [/color][color=#666600]{[/color]
[color=#000000]            [/color][color=#880000]// Calculate cell coords[/color]
[color=#000000]            [/color][color=#000088]int[/color][color=#000000] cellx[/color][color=#666600]=[/color][color=#000000]nodex[/color][color=#666600]+[/color][color=#000000]node[/color][color=#666600];[/color]
[color=#000000]            [/color][color=#000088]int[/color][color=#000000] celly[/color][color=#666600]=[/color][color=#000000]nodey[/color][color=#666600]-[/color][color=#000000]node[/color][color=#666600];[/color]
[color=#000000]            [/color][color=#000088]if[/color][color=#666600]([/color][color=#000000]cellx[/color][color=#666600]>=[/color][color=#006666]0[/color][color=#000000] [/color][color=#666600]&&[/color][color=#000000] cellx[/color][color=#666600]<[/color][color=#000000]m_width [/color][color=#666600]&&[/color][color=#000000] celly[/color][color=#666600]>=[/color][color=#006666]0[/color][color=#000000] [/color][color=#666600]&&[/color][color=#000000] celly[/color][color=#666600]<[/color][color=#000000]m_height[/color][color=#666600])[/color]
[color=#000000]            [/color][color=#666600]{[/color]
[color=#000000]                sf[/color][color=#666600]::[/color][color=#660066]Color[/color][color=#000000] color[/color][color=#666600]=[/color][color=#000000]m_lightmap[/color][color=#666600].[/color][color=#000000]getLightValue[/color][color=#666600]([/color][color=#000000]cellx[/color][color=#666600],[/color][color=#000000]celly[/color][color=#666600]);[/color]
[color=#000000]                m_nodes[/color][color=#666600][[/color][color=#000000]celly[/color][color=#666600]*[/color][color=#000000]m_width[/color][color=#666600]+[/color][color=#000000]cellx[/color][color=#666600]].[/color][color=#000000]drawFloors[/color][color=#666600]([/color][color=#000000]win[/color][color=#666600],[/color][color=#000000]color[/color][color=#666600]);[/color]
[color=#000000]            [/color][color=#666600]}[/color]
[color=#000000]        [/color][color=#666600]}[/color]

[color=#000000]        nodex[/color][color=#666600]=[/color][color=#000000]nodex[/color][color=#666600]+[/color][color=#000000]rowincx[/color][color=#666600];[/color]
[color=#000000]        nodey[/color][color=#666600]=[/color][color=#000000]nodey[/color][color=#666600]+[/color][color=#000000]rowincy[/color][color=#666600];[/color]
[color=#000000]    [/color][color=#666600]}[/color]

It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

### #2JTippetts

Posted 22 February 2012 - 09:16 PM

The heart of drawing the map in that post is this bit of code:
[color=#000088]void[/color][color=#000000] [/color][color=#660066]IsometricMap[/color][color=#666600]::[/color][color=#000000]draw[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]RenderWindow[/color][color=#000000] [/color][color=#666600]*[/color][color=#000000]win[/color][color=#666600])[/color]
[color=#666600]{[/color]
[color=#000000]	[/color][color=#880000]// Set view[/color]
[color=#000000]	sf[/color][color=#666600]::[/color][color=#660066]View[/color][color=#000000] view[/color][color=#666600]=[/color][color=#000000]win[/color][color=#666600]->[/color][color=#660066]GetView[/color][color=#666600]();[/color]
[color=#000000]	[/color][color=#880000]// Reverse project center[/color]
[color=#000000]	sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] center[/color][color=#666600]=[/color][color=#660066]WorldToScreen[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#666600]([/color][color=#000000]m_centerx[/color][color=#666600],[/color][color=#000000]m_centery[/color][color=#666600]));[/color]
[color=#000000]	view[/color][color=#666600].[/color][color=#660066]SetCenter[/color][color=#666600]([/color][color=#000000]center[/color][color=#666600]);[/color]
[color=#000000]	win[/color][color=#666600]->[/color][color=#660066]SetView[/color][color=#666600]([/color][color=#000000]view[/color][color=#666600]);[/color]

[color=#000000]	[/color][color=#880000]// Reverse-project top-left corner[/color]
[color=#000000]	sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] viewsize[/color][color=#666600]=[/color][color=#000000]view[/color][color=#666600].[/color][color=#660066]GetSize[/color][color=#666600]();[/color]
[color=#000000]	sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#000000] topleft[/color][color=#666600]=[/color][color=#660066]ScreenToWorld[/color][color=#666600]([/color][color=#000000]sf[/color][color=#666600]::[/color][color=#660066]Vector2f[/color][color=#666600]([/color][color=#000000]center[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]-[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]/[/color][color=#006666]2.0f[/color][color=#666600],[/color][color=#000000] center[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]-[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]/[/color][color=#006666]2.0f[/color][color=#666600]));[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] sx[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])([/color][color=#000000]topleft[/color][color=#666600].[/color][color=#000000]x[/color][color=#666600]/([/color][color=#000088]float[/color][color=#666600])[/color][color=#000000]m_nodesize[/color][color=#666600]);[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] sy[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])([/color][color=#000000]topleft[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]/([/color][color=#000088]float[/color][color=#666600])[/color][color=#000000]m_nodesize[/color][color=#666600]);[/color]

[color=#000000]	[/color][color=#880000]// Move start location up and left two nodes to get a little padding. (subtract 2 from sx[/color]
[color=#000000]	sx[/color][color=#666600]-=[/color][color=#006666]2[/color][color=#666600];[/color]

[color=#000000]	[/color][color=#880000]// Calculate how many nodes across to draw[/color]
[color=#000000]	[/color][color=#880000]// A node's total width on-screen is calculated as 4*nodesize[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] num_nodes_across[/color][color=#666600]=([/color][color=#000088]int[/color][color=#666600])[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]x [/color][color=#666600]/[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]m_nodesize[/color][color=#666600]*[/color][color=#006666]4[/color][color=#666600])[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] [/color][color=#006666]4[/color][color=#666600];[/color][color=#000000] [/color][color=#880000]// Pad out the end by drawing 4 extra nodes[/color]

[color=#000000]	[/color][color=#880000]// Calculate how many rows to draw[/color]
[color=#000000]	[/color][color=#880000]// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it[/color]
[color=#000000]	[/color][color=#880000]// a little bit by adding a value that approximates the maximum cell height to the size of the[/color]
[color=#000000]	[/color][color=#880000]// viewport.[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] num_rows[/color][color=#666600]=((([/color][color=#000088]int[/color][color=#666600])[/color][color=#000000]viewsize[/color][color=#666600].[/color][color=#000000]y[/color][color=#666600]+[/color][color=#006666]512[/color][color=#666600])[/color][color=#000000] [/color][color=#666600]/[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]m_nodesize[/color][color=#666600]*[/color][color=#006666]2[/color][color=#666600]))*[/color][color=#006666]2[/color][color=#666600];[/color]

[color=#000000]	[/color][color=#880000]// Update lighting[/color]
[color=#000000]	m_lightmap[/color][color=#666600].[/color][color=#000000]updateRegion[/color][color=#666600]([/color][color=#000000]sx[/color][color=#666600],[/color][color=#000000]sy[/color][color=#666600],[/color][color=#000000]num_nodes_across[/color][color=#666600],[/color][color=#000000]num_rows[/color][color=#666600]);[/color]

[color=#000000]	[/color][color=#880000]// Drawing proceeds as thus:[/color]
[color=#000000]	[/color][color=#880000]// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y[/color]
[color=#000000]	[/color][color=#880000]// to move to the next node.[/color]
[color=#000000]	[/color][color=#880000]// When a row is done, we move to the next row. This is done by:[/color]
[color=#000000]	[/color][color=#880000]// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we[/color]
[color=#000000]	[/color][color=#880000]// move to the next row by incrementing y instead.[/color]
[color=#000000]	[/color][color=#880000]// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] rowincx[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600],[/color][color=#000000] rowincy[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]	[/color][color=#000088]int[/color][color=#000000] drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600]+[/color][color=#006666]1[/color][color=#666600];[/color]

[color=#000000]	[/color][color=#000088]int[/color][color=#000000] nodex[/color][color=#666600]=[/color][color=#000000]sx[/color][color=#666600],[/color][color=#000000] nodey[/color][color=#666600]=[/color][color=#000000]sy[/color][color=#666600];[/color]
[color=#000000]	[/color][color=#000088]for[/color][color=#666600]([/color][color=#000088]int[/color][color=#000000] row[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] row[/color][color=#666600]<[/color][color=#000000]num_rows[/color][color=#666600];[/color][color=#000000] [/color][color=#666600]++[/color][color=#000000]row[/color][color=#666600])[/color]
[color=#000000]	[/color][color=#666600]{[/color]
[color=#000000]		[/color][color=#000088]if[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]row [/color][color=#666600]&[/color][color=#000000] [/color][color=#006666]1[/color][color=#666600])[/color]
[color=#000000]		[/color][color=#666600]{[/color]
[color=#000000]			[/color][color=#880000]// Odd row[/color]
[color=#000000]			rowincx[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]			rowincy[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]			drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600];[/color]
[color=#000000]		[/color][color=#666600]}[/color]
[color=#000000]		[/color][color=#000088]else[/color]
[color=#000000]		[/color][color=#666600]{[/color]
[color=#000000]			rowincx[/color][color=#666600]=[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]			rowincy[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color]
[color=#000000]			drawnodes[/color][color=#666600]=[/color][color=#000000]num_nodes_across[/color][color=#666600]+[/color][color=#006666]1[/color][color=#666600];[/color]
[color=#000000]		[/color][color=#666600]}[/color]

[color=#000000]		[/color][color=#000088]for[/color][color=#666600]([/color][color=#000088]int[/color][color=#000000] node[/color][color=#666600]=[/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] node[/color][color=#666600]<[/color][color=#000000]drawnodes[/color][color=#666600];[/color][color=#000000] [/color][color=#666600]++[/color][color=#000000]node[/color][color=#666600])[/color]
[color=#000000]		[/color][color=#666600]{[/color]
[color=#000000]			[/color][color=#880000]// Calculate cell coords[/color]
[color=#000000]			[/color][color=#000088]int[/color][color=#000000] cellx[/color][color=#666600]=[/color][color=#000000]nodex[/color][color=#666600]+[/color][color=#000000]node[/color][color=#666600];[/color]
[color=#000000]			[/color][color=#000088]int[/color][color=#000000] celly[/color][color=#666600]=[/color][color=#000000]nodey[/color][color=#666600]-[/color][color=#000000]node[/color][color=#666600];[/color]
[color=#000000]			[/color][color=#000088]if[/color][color=#666600]([/color][color=#000000]cellx[/color][color=#666600]>=[/color][color=#006666]0[/color][color=#000000] [/color][color=#666600]&&[/color][color=#000000] cellx[/color][color=#666600]<[/color][color=#000000]m_width [/color][color=#666600]&&[/color][color=#000000] celly[/color][color=#666600]>=[/color][color=#006666]0[/color][color=#000000] [/color][color=#666600]&&[/color][color=#000000] celly[/color][color=#666600]<[/color][color=#000000]m_height[/color][color=#666600])[/color]
[color=#000000]			[/color][color=#666600]{[/color]
[color=#000000]				sf[/color][color=#666600]::[/color][color=#660066]Color[/color][color=#000000] color[/color][color=#666600]=[/color][color=#000000]m_lightmap[/color][color=#666600].[/color][color=#000000]getLightValue[/color][color=#666600]([/color][color=#000000]cellx[/color][color=#666600],[/color][color=#000000]celly[/color][color=#666600]);[/color]
[color=#000000]				m_nodes[/color][color=#666600][[/color][color=#000000]celly[/color][color=#666600]*[/color][color=#000000]m_width[/color][color=#666600]+[/color][color=#000000]cellx[/color][color=#666600]].[/color][color=#000000]drawFloors[/color][color=#666600]([/color][color=#000000]win[/color][color=#666600],[/color][color=#000000]color[/color][color=#666600]);[/color]
[color=#000000]			[/color][color=#666600]}[/color]
[color=#000000]		[/color][color=#666600]}[/color]

[color=#000000]		nodex[/color][color=#666600]=[/color][color=#000000]nodex[/color][color=#666600]+[/color][color=#000000]rowincx[/color][color=#666600];[/color]
[color=#000000]		nodey[/color][color=#666600]=[/color][color=#000000]nodey[/color][color=#666600]+[/color][color=#000000]rowincy[/color][color=#666600];[/color]
[color=#000000]	[/color][color=#666600]}[/color]

It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

### #1JTippetts

Posted 22 February 2012 - 09:16 PM

The heart of drawing the map in that post is this bit of code:

void IsometricMap::draw(sf::RenderWindow *win)
{
// Set view
sf::View view=win->GetView();
// Reverse project center
sf::Vector2f center=WorldToScreen(sf::Vector2f(m_centerx,m_centery));
view.SetCenter(center);
win->SetView(view);

// Reverse-project top-left corner
sf::Vector2f viewsize=view.GetSize();
sf::Vector2f topleft=ScreenToWorld(sf::Vector2f(center.x-viewsize.x/2.0f, center.y-viewsize.y/2.0f));
int sx=(int)(topleft.x/(float)m_nodesize);
int sy=(int)(topleft.y/(float)m_nodesize);

// Move start location up and left two nodes to get a little padding. (subtract 2 from sx
sx-=2;

// Calculate how many nodes across to draw
// A node's total width on-screen is calculated as 4*nodesize
int num_nodes_across=(int)viewsize.x / (m_nodesize*4) + 4; // Pad out the end by drawing 4 extra nodes

// Calculate how many rows to draw
// A node's total height on screen is calculated as 2*nodesize. Also, need to fudge it
// a little bit by adding a value that approximates the maximum cell height to the size of the
// viewport.
int num_rows=(((int)viewsize.y+512) / (m_nodesize*2))*2;

// Update lighting
m_lightmap.updateRegion(sx,sy,num_nodes_across,num_rows);

// Drawing proceeds as thus:
// We begin at some starting node and proceed across the row. At each step, we increment x and decrement y
// to move to the next node.
// When a row is done, we move to the next row. This is done by:
// If the current row is "even", then we move to the next row by incrementing x. If the current row is odd, we
// move to the next row by incrementing y instead.
// On even rows, we draw num_nodes+1 nodes, else we draw num_nodes nodes.
int rowincx=1, rowincy=0;
int drawnodes=num_nodes_across+1;

int nodex=sx, nodey=sy;
for(int row=0; row<num_rows; ++row)
{
if (row & 1)
{
// Odd row
rowincx=0;
rowincy=1;
drawnodes=num_nodes_across;
}
else
{
rowincx=1;
rowincy=0;
drawnodes=num_nodes_across+1;
}

for(int node=0; node<drawnodes; ++node)
{
// Calculate cell coords
int cellx=nodex+node;
int celly=nodey-node;
if(cellx>=0 && cellx<m_width && celly>=0 && celly<m_height)
{
sf::Color color=m_lightmap.getLightValue(cellx,celly);
m_nodes[celly*m_width+cellx].drawFloors(win,color);
}
}

nodex=nodex+rowincx;
nodey=nodey+rowincy;
}

It's not difficult to understand. The heart of it relies on the two functions, ScreenToWorld and WorldToScreen that can convert coordinates between the two different coordinate spaces. By converting the coordinates representing the 4 corners of the screen to world coordinates the result you end up with is the box defining the visible space. This box will be oriented at 45 degrees relative to the cells. Once you have the box, you start iterating rows, starting at the top-left corner of the visible box and proceeding across and down to the bottom right corner. It's very much language and platform agnostic, meaning that the fact I used SFML to draw stuff with is very irrelevant. I do use the SFML views in there, but that is just SFML's way of specifying screen coordinate projection. Basically, a SFML View is just a rectangle in Screen Coord space that defines what sub-rectangle of Screen Coord space is visible on the screen.

PARTNERS