summaryrefslogtreecommitdiffstats
path: root/asciiquarium/src/sprite.h
blob: 927c149c094d4c59bdb0656e46f378b0a3fe4c59 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
 * Asciiquarium - Native KDE Screensaver based on the Asciiquarium program
 *    (c) Kirk Baucom <kbaucom@schizoid.com>, which you can find at
 *    http://www.robobunny.com/projects/asciiquarium/
 *
 * Ported to KDE by Maksim Orlovich <maksim@kde.org> and
 * Michael Pyne <michael.pyne@kdemail.net>.
 *
 * Copyright (c) 2003 Kirk Baucom     <kbaucom@schizoid.com>
 * Copyright (c) 2005 Maksim Orlovich <maksim@kde.org>
 * Copyright (c) 2005 Michael Pyne    <michael.pyne@kdemail.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef AA_SPRITE_H
#define AA_SPRITE_H

#include <ntqvaluevector.h>
#include "frame.h"

/**
 * This class represents a on-screen character of some sort.  These make up
 * the building blocks of the animation.
 *
 * You can use multiple frames of animation, but movement is not supported in
 * this class, try MovingSprite.  If you use multiple frames, use
 * setFrameDelay to control the interval between frames, and use
 * setDieAfterLastFrame to set whether the animation should loop or cause
 * the Sprite to go away.
 *
 * Use kill() to get rid of a Sprite, do not delete it by yourself, as Screen
 * will do that as needed.
 */
class Sprite
{
protected:
    Screen* m_screen;   ///< The Screen that we belong to.
    int m_currentFrame; ///< The current frame of animation.
    int m_x;  ///< Our current logical x position.
    int m_y;  ///< Our current logical y position.
    int m_z;  ///< Our current depth.

    TQValueVector<Frame> m_frames; ///< Array of animation frames.
    bool m_isKilled;              ///< True if we've been killed.
    bool m_killAfterLastFrame;    ///< True if we should auto-kill after the last frame.
    int  m_ticksSinceFrameChange; ///< Number of timer ticks since we last changed frame.
    int  m_frameDelay;            ///< Number of milliseconds to show a frame for.

    /**
     * Increments the animation timer.
     *
     * @return true if time has elapsed past m_frameDelay since the last frame
     * change.
     */
    bool timerTick();

public:
    /**
     * Construct a sprite without automatically adding it to \p screen.
     *
     * @param screen The Screen that the sprite belongs to.
     * @param x The x column position for the left edge of this sprite.
     * @param y The y row position for the upper line of this sprite.
     * @param z The depth of the sprite (0 is closest to screen).
     * @param frameDelay Amount of milliseconds to elapse between animation
     *                   frames.
     */
    Sprite(Screen* screen, int x, int y, int z, int frameDelay = 100);

    /**
     * Destuctor.  Does nothing at this point, present to ensure a continuous
     * line of virtual destructors.
     */
    virtual ~Sprite()
    {
    }

    /**
     * @return true if this sprite can be involved in a collision with another
     *         Sprite.  The other sprite doesn't necessarily have to have this
     *         also set to true.
     */
    virtual bool canCollide() const { return false; }

    /**
     * Called when a collision occurs with *any* Sprite on-screen if canCollide()
     * returns true.
     *
     * @param sprite The Sprite that a collision happened with.  It is safe to
     *               kill() the Sprite, move it, etc.
     */
    virtual void collision (Sprite *sprite)
    {
    }

    /**
     * Appends a frame of animation to the end of the current list.
     *
     * @param frame Frame of animation to add.  It should be the same size as
     *              the other frames already in the list.
     */
    void addFrame(const Frame& frame);

    /**
     * Sets the amount of time to show a frame for.
     *
     * @param delay The frame delay, in milliseconds of time.
     */
    void setFrameDelay(int delay)
    {
        m_frameDelay = delay;
    }

    /**
     * Sets whether this Sprite should automatically call kill() after the
     * last frame of animation has run.
     *
     * @param dieAfterLast If true, this Sprite will automatically call kill()
     *                     after its last frame has elapsed.
     */
    void setDieAfterLastFrame(bool dieAfterLast)
    {
        m_killAfterLastFrame = dieAfterLast;
    }

    /**
     * @return The Screen this Sprite belongs to.
     */
    Screen *screen() const
    {
        return m_screen;
    }

    /**
     * @return true if this Sprite is dead.  If true, it will probably soon be
     * deleted by its Screen.
     */
    bool isKilled() const
    {
        return m_isKilled;
    }

    /**
     * @return The depth of the Sprite.  0 is closest to the screen.
     */
    int depth() const
    {
        return m_z;
    }

    /**
     * @return The rectangular geometry of this object in the Pixel coordinate
     * system.
     */
    TQRect geom() const;

    /**
     * Erases this Sprite from its Screen, using the current animation frame to
     * form the clear mask.  This should be called *before* any change which
     * will change the on-screen display of the object, such as motion or
     * animation changes.
     */
    void erase();

    /**
     * Draws this Sprite onto the Screen.
     */
    void paint();

    /**
     * Kills this Sprite.  The parent Screen will delete this Sprite on the next
     * animation cycle.
     */
    virtual void kill()
    {
        m_isKilled = true;
    }

    //main animation hook. Should return true + erase if something changed
    /**
     * Called when the current frame expires.  This function needs to perform
     * any actions necessary to make sure that it is ready to be painted,
     * including calling erase().  You do not need to call paint() from this
     * function.
     *
     * @return true if the on-screen representation of this Sprite changed,
     *         false, otherwise.
     */
    virtual bool tickUpdate();
};

#endif

// vim: set et ts=8 sw=4: