16
\$\begingroup\$

Animal Crossing has a unique way of scrolling the world map: When the character moves down, the the world rolls around and over at the top, like it's stuck to a cardboard tube:

Animal Crossing's the cylinder world

This video shows how it moves.

How can I create this effect?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Doesnt look like an effect to me, it looks like a very simple 3D world that the camera is just following. \$\endgroup\$
    – James
    Sep 22, 2011 at 16:27
  • \$\begingroup\$ Hacking the game can produce a collision glitch that lets you walk into the ocean where the world ends. You can see bits of the world rendered "curved back" in the emptiness beyond the edge of the world. Video here. \$\endgroup\$
    – Anko
    Jan 29, 2015 at 15:57

3 Answers 3

6
\$\begingroup\$

Seems like it's just taking a "flat world" and mapping to cylindrical coordinates. Essentially wrapping the world on a cylinder. I did something similar with a flat world, but I wrapped it onto a sphere:

enter image description here enter image description here

The way I did it for a sphere is similar to the way you'd do it for a cylinder. Choose a suitable radius (ρ or "rho" in cylindrical coordinates) for your world. For each vertex, take the XZ coordinates of your world (assuming Y is height), then covert to cylindrical coordinates using the XZ and radius plus Y. If you don't add the Y, you'll get a flat cylinder. Then convert back to Cartesian coordinates to draw in game.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ Another thing to mention, the world's Y dimension in Animal Crossing is much larger than the circumference of the cylinder (just by eyeballing it, because the horizon line is very close). Therefore some part of the world map is cropped to only the areas closest to the character and that cropped area gets wrapped around the whole cylinder. It's similar to cropping a 2D tile-based map to only the visible parts. \$\endgroup\$
    – ChrisC
    Sep 22, 2011 at 16:58
  • \$\begingroup\$ Excellent point. I imagine that could also be used to keep the memory footprint small by loading/unloading the world as needed. \$\endgroup\$
    – House
    Sep 23, 2011 at 1:09
6
\$\begingroup\$

I was experimenting a bit after playing Deathspank, which has a similar effect. Though I never delved into it enough to see if it could be tuned to work super well, one possibility is to just modify items in your vertex shader based on depth. A function mapping cos(depth) to a Y axis modification works. You can adjust it such that the world not only drops off in the distance but also if it closer than some depth, making the world feel especially round. You can do the same for X axis value to make it seem more spherical. I'm unsure if this is how such games actually do it; my experiments gave unsatisfactory results but I didn't play with the ratios much, so it may have been as simple as changing the rate of falloff to make it better.

\$\endgroup\$
2
  • \$\begingroup\$ +1 because this is the way I would do it. However, you may want to clarify what you mean by 'depth'. It could be distance from camera, or distance from character. I think it would be good to experiment with both. \$\endgroup\$
    – DaleyPaley
    May 29, 2013 at 8:36
  • \$\begingroup\$ Sorry I'm late to the party - like 6 years late - but in the AC case the 'depth' is computed based on the distance from the camera... but as the camera position is based on the character position everything is kind of connected. \$\endgroup\$
    – lvictorino
    Aug 28, 2019 at 8:54
6
\$\begingroup\$

You want to go from a planar world, to a cylindrical one.

A rotation around the x axis (in homogeneous coordinates) looks like this:

     | 1   0   0   0 |
Rx = | 0  ca  -sa  0 |
     | 0  sa   ca  0 |
     | 0   0    0  1 |

Where:

ca = cos(angle) and sa = sin(angle)

To calculate the angle, look at the image. The pi/2 cancels out and you are left with:

angle = offset_from_character.z - radius

Also, look at the image. The angle of the projected point is dependent on the horizontal distance from character, the distance from the sphere is dependent on the vertical.

new_position = character_position - vec3(0,radius,0) + Rx * vec3(0,radius+_old_position.y,0)

be sure to cull things that are over the horizon, otherwise the whole world will wrap around.

Disclaimer: I haven't tested this and I am no mathematics expert, but the answer is something like this. Someone please correct me if I am wrong.

spherical world

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .