# Arrows and other pointy sticky things

Attention

This tutorial is work in progress. Take a look at the arrows.py example file in Examples for fully working code for the arrows.

This tutorial will explain one way to make arrows/sticky projectiles that can stick on the target.

The tutorial is heavily inspired by the Box2d tutorial “Box2D C++ tutorials - Sticky projectiles” found here http://www.iforce2d.net/b2dtut/sticky-projectiles (but adjusted for python, pymunk and chipmunk).

## Before we start

For this tutorial you will need to know some pymunk basics. I recommend that you read the other tutorial(s) and try out easier examples first before you continue.

Except for pymunk you will also need pygame to follow this tutorial. However, it should be no problem to use another graphics and input library if you want, for example pyglet.

We will try to accomplish

- An arrow that flies believable in the air
- Figure out when the arrow hits something and should stick
- Attach the arrow to an object when hit

In the end we should have a cannon like object shooting arrows that flies in a believable way and sticks to objects if they hit hard enough.

## Basic scene

Before we start with the arrow we need a scene to contain it and a “cannon” that can aim:

    import sys

    import pygame
    from pygame.locals import *
    from pygame.color import *

    import pymunk
    from pymunk.vec2d import Vec2d
    from pymunk.pygame_draw import draw_space, from_pygame

    width = height = 600
    def main():
        ### PyGame init
        pygame.init()
        screen = pygame.display.set_mode((width,height))
        clock = pygame.time.Clock()
        running = True
        font = pygame.font.SysFont("Arial", 16)

        ### Physics stuff
        space = pymunk.Space()

        # walls - the left-top-right-bottom walls
        static_lines = [pymunk.Segment(space.static_body, (50, 50), (50, 550), 5)
                    ,pymunk.Segment(space.static_body, (50, 550), (550, 550), 5)
                    ,pymunk.Segment(space.static_body, (550, 550), (550, 50), 5)
                    ,pymunk.Segment(space.static_body, (50, 50), (550, 50), 5)
                    ]
        space.add_static(static_lines)

        ### "Cannon" that can fire arrows
        cannon_body = pymunk.Body()
        player_shape = pymunk.Circle(cannon_body, 25)
        cannon_body.position = 100,100

        space.add(player_shape)

        while running:
            for event in pygame.event.get():
                if event.type == QUIT or \
                    event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]):
                    running = False

            mpos = pygame.mouse.get_pos()
            p = from_pygame( Vec2d(mpos), screen )
            mouse_position = p
            cannon_body.angle = (mouse_position - cannon_body.position).angle

            ### Clear screen
            screen.fill(pygame.color.THECOLORS["black"])

            ### Draw stuff
            draw_space(screen, space)

            ### Update physics
            fps = 60
            dt = 1./fps
            space.step(dt)

            ### Info and flip screen
            screen.blit(font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0,0))
            screen.blit(font.render("Aim with mouse, click to fire", 1, THECOLORS["darkgrey"]), (5,height - 35))
            screen.blit(font.render("Press R to reset, ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5,height - 20))

            pygame.display.flip()
            clock.tick(fps)

    if __name__ == '__main__':
        sys.exit(main())