~game-hackers/game/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# -*- test-case-name: game.test.test_controller -*-

"""
Input handling.
"""

from pygame import (
    K_LEFT, K_RIGHT, K_UP, K_DOWN,
    K_w, K_a, K_s, K_d
)

from game.direction import (
    FORWARD, BACKWARD, LEFT, RIGHT,
    FORWARD_ZERO, SIDEWAYS_ZERO)


KEYS_TO_DIRECTIONS = {
    K_LEFT: LEFT,
    K_RIGHT: RIGHT,
    K_UP: FORWARD,
    K_DOWN: BACKWARD,
    K_w: FORWARD,
    K_a: LEFT,
    K_s: BACKWARD,
    K_d: RIGHT,
    }


class PlayerController(object):
    """
    Input handler for L{game.player.Player} objects.

    @ivar player: The player being controlled.
    @ivar downDirections: List of currently held arrow keys.

    @ivar mouseSensitivity: A multipler for how much rotation each unit of
        relative mouse movement should result in.
    """

    mouseSensitivity = 0.25

    def __init__(self, player):
        self.player = player
        self.downDirections = []


    def keyDown(self, key):
        """
        Set C{self.player} into motion in response to arrow keys being pressed.

        @type key: L{game} key identifier.
        @param key: The key which is being pressed.
        """
        if key in KEYS_TO_DIRECTIONS:
            self.downDirections.append(key)
            self.player.setDirection(
                self.calculateDirection(self.downDirections))

    def keyUp(self, key):
        """
        Set C{self.player} into motion (or lack of it) in response to
        arrow keys being released.

        @type key: L{game} key identifier.
        @param key: The key which is being released.
        """
        if key in KEYS_TO_DIRECTIONS:
            try:
                self.downDirections.remove(key)
            except ValueError:
                pass
            else:
                self.player.setDirection(
                    self.calculateDirection(self.downDirections))


    def mouseMotion(self, position, (x, y), buttons):
        """
        Handle mouse motion to change the orientation of the player.
        """
        self.player.turn(
            y * self.mouseSensitivity, x * self.mouseSensitivity)


    def calculateDirection(self, pressedKeys):
        """
        Given a list of keys (sorted by their press-time), calculate
        the direction that the player should be moving in.
        """
        forwardDir = FORWARD_ZERO
        sidewaysDir = SIDEWAYS_ZERO

        if pressedKeys:
            for key in pressedKeys:
                direction = KEYS_TO_DIRECTIONS[key]
                if direction in (FORWARD, BACKWARD):
                    forwardDir = direction
                if direction in (LEFT, RIGHT):
                    sidewaysDir = direction
            return forwardDir + sidewaysDir