Help With Diagonal Wrap

Tholish

Emperor
Joined
Jul 5, 2002
Messages
1,344
Location
Japan
I'm trying to write a civ like game from scratch, but it is to have diagonal wrap: go off the top edge and you come out at the left side the same distance from the north pole (upper left corner); go off the bottom edge and you come ouat at the right side the same distance from the south pole (lower right corner).

I've got a map generator that's pretty good, and it applies the wrap.
Run the attached program (place directly in your root C: directory and click on the executable in the folder) and you will see that land features on the top edge match up with those on the left edge for example. Rain clouds even travel on the wrap correctly during terrain generation, but I can't get the display to correctly show the edges.

All the current code is in the folder, but
here's the relevant function.


Code:
void DisplayTerrain()
{

short distance=0;
short tileX=0;
short tileY=0;
short displayX=0;
short displayY=0;

while (tileX<640)
{
	while (tileY<640)//tile  is where it comes from on the map array
	{ 
		displayX=(tileX-zoomX)*zoom;//display is where it shows on the screen
		displayY=(tileY-zoomY)*zoom;

//THIS GETS THREE EXTRA MAPS TO THE SOUTHEAST, unchanged orientation
//if (tileX<zoomX)
//		displayX=(640-(zoomX-tileX))*zoom;
//if (tileY<zoomY)
//		displayY=(640-(zoomY-tileY))*zoom;

			if (displayX>0)
				if (displayY>0)
					if (displayX<640)
						if (displayY<640)
							StandardDisplay(displayX,displayY,tileX,tileY);

//this creates a northwest corner: totally correct!
//also parts of a mirror image north and south, not right
		if (zoomX<1)
		{
			distance=0-zoomX;
			if (tileX<distance)
			{
				displayX=0-((tileX-distance)*zoom);
			};

		};

		if (zoomY<1)
		{
			distance=0-zoomY;
			if (tileY<distance)
			{
				displayY=0-((tileY-distance)*zoom);
			};
		};

			if (displayX>0)
				if (displayY>0)
					if (displayX<640)
						if (displayY<640)
							StandardDisplay(displayX,displayY,tileX,tileY);



			tileY=tileY+1;
		};
		tileY=0;
		tileX=tileX+1;
	};
}


Any advice on how to do this?
 

Attachments

Might this be better placed in the computers sub forum?
 
Make copies of the world off each edge, rotate the display when it off the edge (and move the now rotated display to the actual edge)
 
That would be the easy way. Just a duplicate map array for the near edge sections to show
that it wraps, and how. After exhaustive experimentation, I have discovered a way to mark such a mapped area by deleting every other pixel (so that nobody gets confused, thinking its the real map).

But I'm trying to create a formula.
Something like


if (zoomX<0)
{
displayX=tileY+zoomX;
displayY=-tileX+zoomY;
};
if (zoomY<0)
{
displayX=-tileY+zoomX;
displayY=tileX+zoomY;
};
if (zoomX>640)
{
displayX=-tileY+zoomX;
displayY=-640-(tileX-640)+zoomY;
};
if (zoomY>640)
{
displayX=640-(tileY-640)+zoomX;
displayY=tileX+zoomY;
};


except producing the desired result. ZoomX or ZoomY is the offset, the location of the
upper left corner of the display area relative to the square world map. TileX and TileY are the
coordinates on the world map that are being stepped through, where the data comes from.
The formula should produce a DisplayX and DisplayY, which is where the data is to be placed
on the map by another function. Zoom is an additional variable that simply multiplies all coordinates to create a sort of virtual map that the display function shows a window sized slice of.
 
When you're done with the game, show us.
 
Oh, I will.

Anyway, I finally got the top left half to work adequately.

I stick this

if (zoomX<1)
{
distance=0-zoomX;
if (tileX<distance)
displayX=0-((tileX-distance)*zoom);
};

if (zoomY<1)
{
distance=0-zoomY;
if (tileY<distance)
displayY=0-((tileY-distance)*zoom);
};

TileX=tileY;
TileY=tileX;
if (displayX>0)
if (displayY>0)
if (displayX<640)
if (displayY<640)
StandardDisplay(displayX,displayY,TileX,TileY);
//standard display just blits from the tileX tileY array value to the displayX displayY location

in between two iterations of the piece that shows the regular map:

displayX=(tileX-zoomX)*zoom;
displayY=(tileY-zoomY)*zoom;
if (displayX>0)
if (displayY>0)
if (displayX<640)
if (displayY<640)
StandardDisplay(displayX,displayY,tileX,tileY);

With only one iteration of the standard display, the edge eats the regular map as you go farther out.

Now, just to do the down and left (southwest and southeast) edges.


Admittedly a 640 by 640 map will run slow, even as a strategy game low on graphical demands.
In fact I made an earlier version that was only 400 by 400 with two levels of zoom:
the map was a 1000 by 1000 km "region" divided into 20 by 20 of "counties" that you could
click down into, each of which was made of a 20 by 20 of "square leagues." I had all kind of
resources that showed splashes and quantities when you rolled over and indicated large deposits map wide when you clicked on a marginal button. I had all this ecology going on, with hunters and gatherers and large and small game and various kinds of vegetation and predators. However, it was already turning into a good wait each turn, and I hadn't extended beyond the paleolithic. Also, my terrain art looked clunky. So, against my own better judgement, I scratched it and started over. If you look at this one see how fast it generates the terrain after the continents rise up out of the sea? That blink is all kinds of calculations with rain clouds moving and dropping loads on the hills, then that flowing down and rivers joining rivers. The main delay with the altitude
generation is that it is being displayed, which I just did for each operation so I could see if it was working (left that one in because it looked cool, though I need to change the colors).

I'm figuring if I have about 1000 resources/buildings/units etc..., with the quantity of each in each
tile (now 20 miles high and 40 wide, no sideways diagonal movement allowed) represented by a short integer (16 bits) each turn will only take a few billion operations, or a few seconds. In theory.


Anyway, getting the other sides should be a simple matter of doing some morph of the existing formula. Also, the fact that the margin map slices vanish from the pole down as you go beyond
the regular map boundaries is fine. I'll probably put in something to make zoomX and zoomY jump
if you go more than 640/(zoom+1) beyond the edge anyway.

It seems like there's maybe a natural limit based on the capabilities of computers regarding how large a map can be, but there's no reason why the amount of Library in a city has to be a bool
rather than an integer. Its only 16 times as much. I suspect its because object oriented programming is intrinsically slower than procedural. I'll be testing that. This thing will be based entirely on passing through hundreds of arrays of 409,600 integers and running small functions on each to produce and consume and transport.
 
Back
Top Bottom