aboutsummaryrefslogtreecommitdiff
path: root/src/ch/epfl/xblast/server/painter/PlayerPainter.java
blob: 79b954c824ae297e89a66201635ce570e2b1e018 (plain)
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
101
102
103
104
105
package ch.epfl.xblast.server.painter;

import ch.epfl.xblast.Direction;
import ch.epfl.xblast.PlayerID;
import ch.epfl.xblast.server.Player;

/**
 * Player painter.
 *
 * @author Timothée FLOURE (257420)
 * @author Pacien TRAN-GIRARD (261948)
 */
public final class PlayerPainter {

    private static final byte DEAD_PLAYER_IMAGE_ID = 16;
    private static final byte DYING_IMAGE_ID = 12;
    private static final byte LAST_DYING_IMAGE_ID = 13;

    private static final int BLANK_PLAYER_GROUP = 4;

    private static final int PLAYER_MULTIPLIER = 20;
    private static final int DIRECTION_MULTIPLIER = 3;

    private static final int ANIMATION_TICK_LOOP = 4;

    /**
     * Computes and returns the animation frame byte for the given tick.
     *
     * @param tick the tick
     * @return the frame byte
     */
    private static byte byteForFrame(int tick) {
        int cycleTick = tick % ANIMATION_TICK_LOOP;
        return (byte) (cycleTick % 2 == 0 ? 0 : cycleTick / 2 + 1);
    }

    /**
     * Returns the byte for the given Direction.
     *
     * @param d the Direction
     * @return the directional byte
     */
    private static byte byteForDirection(Direction d) {
        return (byte) (d.ordinal() * DIRECTION_MULTIPLIER);
    }

    /**
     * Returns the player image byte for the given PlayerID.
     *
     * @param pid the PlayerID
     * @return the image byte for the player
     */
    private static byte byteForPlayerID(PlayerID pid) {
        return (byte) (pid.ordinal() * PLAYER_MULTIPLIER);
    }

    /**
     * Returns the player image byte for the blank player.
     *
     * @return the image byte for the player
     */
    private static byte byteForPlayerID() {
        return (byte) (BLANK_PLAYER_GROUP * PLAYER_MULTIPLIER);
    }

    /**
     * Returns the image ID for the dying state according to the number of remaining lives.
     *
     * @param lives the number of remaining lives
     * @return the dying image ID
     */
    private static byte byteForDyingState(int lives) {
        return lives == 1 ? LAST_DYING_IMAGE_ID : DYING_IMAGE_ID;
    }

    /**
     * Returns the byte related to the image corresponding to the actual state of the given player.
     *
     * @param player the given player
     * @param tick   the actual tick of the game
     * @return the byte related to the image of the the actual state of the player
     */
    public static byte byteForPlayer(Player player, int tick) {
        switch (player.lifeState().state()) {
            case DEAD:
                return DEAD_PLAYER_IMAGE_ID;

            case DYING:
                return (byte) (byteForPlayerID(player.id())
                        + byteForDyingState(player.lives()));

            case INVULNERABLE:
                if (tick % 2 == 1)
                    return (byte) (byteForPlayerID()
                            + byteForDirection(player.direction())
                            + byteForFrame(tick));

            default:
                return (byte) (byteForPlayerID(player.id())
                        + byteForDirection(player.direction())
                        + byteForFrame(tick));
        }
    }

}