Let’s start with this 2000 pixel wide platformer-style game world:

We don’t normally show the entire game world to the player. Instead, we display a “window” into the game world. Drag the world left/right to see how we want to display 600 pixels of the game world at a time:

How would we convert world to screen coordinates for drawing? In this simple case, we can *subtract* the left side of the window. {arrow here, point to the left side}. For example, if the object in the world is at x=300, and the left side of the screen is at x=200, then we will draw that object at 300-200 = 100.

The key idea is that there can be than one coordinate system in a game. There are *world* x-coordinates in blue (measured in ~~tiles~~ pixels) and *screen* x-coordinates in red (measured in pixels).

For drawing, we converted world coordinates to screen coordinates. For mouse clicks, we want to do the opposite.

{demo}In general, whatever steps we take to turn world coordinates into screen coordinates, we’ll reverse them to turn screen coordinates into world coordinates.

The size of the world map doesn’t have to be expressed in terms of pixels. It might be meters, tiles, or some other unit. Here’s the same map measured in tiles:

{same viz but different units}If the world map size and the screen size aren’t expressed in the same units, we need to convert the number to a different scale. We can use this useful mathematical function called `rescale`

or `remap`

:

function rescale(value, from_begin, from_end, to_begin, to_end) { var t = (value - from_begin) / (from_end - from_begin); return to_begin + t * (to_end - to_begin); }

For any position `world.x`

in the world we can calculate the position on the screen by rescaling `rescale(world.x, view_left, view_right, 0, 600)`

{how to explain this??}

For mouse clicks, fortunately the `rescale`

operation can work in reverse. Instead of `rescale(world.x, world_begin, world_end, screen_begin, screen_end)`

we’ll call `rescale(screen.x, screen_begin, screen_end, world_begin, world_end)`

and it will return x in world coordinates.

Above I’ve assumed we already know where to scroll the window. In some games the player can scroll around manually. In other games the camera follows the player.

How does a *camera* work?

A camera has a position in the game world. We then want to make sure the camera’s position is in the *center* of the window.

*transforms*.

transform via camera → shift the center of the window

{...}The math works the same as before. Where we worked with just x, now we work with both x and y, independently.

THIS SECTION will go at the very end of the page

motivation: pattern for all of the transformations; introduce: matrixMatrices aren’t transforms. Matrices are *representations* of transforms.

Matrices allow you to optimize a bit. A chain of transforms might be q = f(g(h(p))). In math we can “compose” functions. We can combine f, g, h ahead of time into q = (f o g o h)(p). We don’t have a way to compose functions at run time in most programming languages we use.

All of our transforms happen to be representable as matrix multiplies, q = F * G * H * p. Matrix multiply is associative so F * (G * (H * p)) = ((F * G) * H) * p. By representing our functions as matrix operations, we can compose them ahead of time. Instead of applying a long chain of 8 operations to every point p, we can first combine those 8 operations into 1, and then apply that to p. This is common in 3D programming, and there is both CPU and GPU acceleration for 4x4 matrix operations.

u,v vectors; show how they are transformed; show how they are in the matrix; show a unit circle tooMore reading on matrices:

- http://ncase.me/matrix/
- http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/
- http://maxgoldste.in/invitation-to-another-dimension/