Docs › game library

sprite.anchor

A sprite's handle. It picks which point of the sprite sits exactly on its x and y, and it's the point the sprite spins around when you change sprite.angle.

How to write it

sprite.anchor = (across, down)
across
How far across the sprite the handle is, from 0 (left edge) to 1 (right edge). 0.5 is the middle.
down
How far down the sprite the handle is, from 0 (top edge) to 1 (bottom edge). 0.5 is the middle.

Every sprite starts at (0.5, 0.5), the middle. A few handy ones:

  • (0.5, 1): bottom middle. The sprite stands with its feet on y.
  • (0, 0): the top-left corner.
  • (0.2, 1): the bottom edge, near the left. On a car facing right, that's just over the back wheel.

It goes hand in hand with sprite.angle, which turns the sprite by that many degrees. Bigger numbers turn it clockwise, and the anchor is the point that stays still while it turns.

A full example

Three anchors at once: a kid who stands on the grass, a hammer swinging from the end of its handle, and a car that does a wheelie on its back wheel when you hold the space bar. The hammer and the car are made of plain boxes and circles. The left and right arrows walk the kid.

import game
import math

game.window(480, 360, background="#87ceeb")
GROUND = 300
game.box(240, 330, 480, 60, "#3a7d44")      # the grass

# A kid standing ON the grass, not sunk into it
kid = game.sprite("kid", 70, GROUND, size=70)
kid.anchor = (0.5, 1)                       # feet on (x, y)

# A hammer: a handle and a head that share one pivot
handle = game.box(200, GROUND, 10, 100, "#8b5a2b")
handle.anchor = (0.5, 1)                    # swings from its bottom end
head = game.box(200, GROUND, 46, 20, "#555555")
head.anchor = (0.5, 5.5)                    # pivot 5 heads below: the handle's end

# A car that pops a wheelie: a body and two wheels sharing one pivot
car = game.box(380, GROUND - 15, 100, 30, "#e63946")
car.anchor = (0.2, 1)                       # pivot: low down, over the back wheel
back = game.circle(380, GROUND - 15, 30, color="#222222")    # right on the pivot
front = game.circle(380, GROUND - 15, 30, color="#222222")
front.anchor = (-1.5, 0.5)                  # pivot 2 wheels behind it: 60 px back

game.debug(True)                            # red boxes: what touches() checks
t = 0

while game.playing():
    t = t + 1

    if game.pressed("left"):
        kid.x = kid.x - 4
    if game.pressed("right"):
        kid.x = kid.x + 4

    swing = 70 * math.sin(t / 10)
    handle.angle = swing
    head.angle = swing

    if game.pressed("space"):
        tilt = max(car.angle - 3, -30)        # front lifts
    else:
        tilt = min(car.angle + 3, 0)          # and drops back
    car.angle = tilt
    front.angle = tilt

    game.frame()

Click the game first so it hears the keys. Then try handle.anchor = (0.5, 0.5): the handle spins around its middle like a propeller, and comes apart from its head.

How it works

  • It's where the sprite is. x and y always tell you where the anchor point is. With (0.5, 1), kid.y = GROUND puts the feet on the ground, whatever size the kid is.
  • It's what the sprite turns around. Change angle and the anchor point stays put while the rest swings around it, like a door on its hinge.
  • The collision box follows. touches() and at_mouse() use a box that moves and turns with the anchor, so a swinging hammer really hits what it looks like it hits. game.debug(True) draws those boxes in red so you can see.
  • You can go past the edges. Numbers below 0 or above 1 put the handle outside the sprite. That's the trick behind the hammer head: (0.5, 5.5) puts its pivot far below it, at the end of the handle, so the two parts swing together. The car's front wheel does the same, with its pivot back at the rear wheel. Give every part the same x, y and angle, and they move as one.

When to use it

  • Things that stand on the ground: players, plants, trees, buildings. Use (0.5, 1), then set y to the ground.
  • Things that swing or turn on a hinge: a hammer, a sword, a door, a clock hand, a flipper.
  • A sprite that plays the mouse pointer: set the anchor to its tip, so the tip is exactly where you click.

Why isn't my anchor working?

  • I get a TypeError. You can't pass it to game.sprite(). Make the sprite first, then set it on the next line: kid.anchor = (0.5, 1).
  • It went to the wrong corner. The order is across, then down, and down grows towards the bottom, the same as y on the screen. (0.5, 0) is the top middle, not the bottom.
  • The numbers are pixels. They're fractions of the sprite, not pixels. (20, 60) puts the handle 20 sprite-widths away. Use (0.2, 0.6).
  • My sprite floats a little above the ground. The anchor is measured on the sprite's whole square (size by size), and some built-in pictures don't fill their square. A wide, low one like "car" has empty space under it. Move it down a few pixels, or use game.debug(True) to see where it really is.
  • It spins around the middle anyway. Check you set anchor on the same sprite whose angle you change.