source: trunk/monsterz/piece.cpp @ 271

Last change on this file since 271 was 271, checked in by sam, 11 years ago

Remove stupid interpolation refining.

File size: 5.2 KB
Line 
1//
2// Monsterz
3//
4// Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdio>
16#include <cmath>
17
18#include "core.h"
19#include "piece.h"
20#include "monsterz.h"
21
22/*
23 * Piece implementation class
24 */
25
26class PieceData
27{
28    friend class Piece;
29
30private:
31    Game *game;
32    int tiler;
33    Int2 cell, pos, src, dst;
34    int id;
35    float speed, timer;
36
37    enum
38    {
39        IDLE,
40        BLINK,
41        GRAB,
42        UNGRAB,
43        MOVE,
44        POP,
45        DEAD,
46    }
47    state;
48};
49
50/*
51 * Public Piece class
52 */
53
54Piece::Piece(Game *game, Int2 cell, int id)
55  : data(new PieceData())
56{
57    data->game = game;
58    Ticker::Ref(game);
59    data->tiler = Tiler::Register(PNG_TILES, 48, 48, 1.0f);
60    data->cell = cell;
61    data->pos = cell * 48;
62    data->id = id;
63    data->state = PieceData::IDLE;
64}
65
66void Piece::SetCell(Int2 cell)
67{
68    data->cell = cell;
69}
70
71Int2 Piece::GetCell() const
72{
73    return data->cell;
74}
75
76void Piece::SetPos(Int2 pos)
77{
78    data->pos = pos;
79}
80
81Int2 Piece::GetPos() const
82{
83    return data->pos;
84}
85
86int Piece::GetId() const
87{
88    return data->id;
89}
90
91int Piece::IsDead() const
92{
93    return data->state == PieceData::DEAD;
94}
95
96int Piece::Blink()
97{
98    switch (data->state)
99    {
100    case PieceData::IDLE:
101        data->state = PieceData::BLINK;
102        data->timer = 400.0f; /* Duration of a blink */
103        return 1;
104    default:
105        return 0;
106    }
107}
108
109int Piece::Pop()
110{
111    switch (data->state)
112    {
113    case PieceData::IDLE:
114    case PieceData::BLINK:
115    case PieceData::GRAB:
116    case PieceData::UNGRAB:
117    case PieceData::MOVE:
118    case PieceData::POP:
119        data->state = PieceData::POP;
120        data->timer = 400.0f;
121        return 1;
122    default:
123        return 0;
124    }
125}
126
127int Piece::Grab(Int2 dir)
128{
129    switch (data->state)
130    {
131    case PieceData::UNGRAB:
132    case PieceData::MOVE:
133        /* Only allow swaps when piece is close enough to its target cell. */
134        if ((data->cell * 48 - data->pos).sqlen() > 24 * 24)
135            return 0;
136        /* Fall through */
137    case PieceData::IDLE:
138    case PieceData::BLINK:
139    case PieceData::GRAB:
140        data->state = PieceData::GRAB;
141        data->pos = data->pos + dir;
142        return 1;
143    default:
144        return 0;
145    }
146}
147
148int Piece::Ungrab()
149{
150    switch (data->state)
151    {
152    case PieceData::GRAB:
153        data->state = PieceData::UNGRAB;
154        data->speed = 0.3f;
155        data->timer = 0.0f;
156        data->src = data->pos;
157        data->dst = data->cell * 48;
158        return 1;
159    default:
160        return 0;
161    }
162}
163
164int Piece::Goto(Int2 pos, float speed)
165{
166    switch (data->state)
167    {
168    case PieceData::IDLE:
169    case PieceData::BLINK:
170    case PieceData::UNGRAB:
171    case PieceData::MOVE:
172        data->state = PieceData::MOVE;
173        data->timer = 0.0f;
174        data->src = data->pos;
175        data->dst = pos;
176        data->speed = speed;
177        return 1;
178    case PieceData::GRAB:
179    default:
180        return 0;
181    }
182}
183
184void Piece::TickGame(float deltams)
185{
186    switch (data->state)
187    {
188    case PieceData::IDLE:
189        break;
190    case PieceData::BLINK:
191        data->timer -= deltams;
192        if (data->timer < 0.0f)
193            data->state = PieceData::IDLE;
194        break;
195    case PieceData::GRAB:
196        break;
197    case PieceData::UNGRAB:
198    case PieceData::MOVE:
199    {
200        data->timer += deltams;
201        Int2 trip = data->dst - data->src;
202        float moving_time = trip.len() / data->speed;
203        float t = moving_time ? data->timer / moving_time : 1.0f;
204        if (t >= 1.0f)
205            t = 1.0f;
206        if (data->timer > moving_time + 200.0f)
207            data->state = PieceData::IDLE;
208        data->pos = data->src + (t * trip + 0.5f);
209        break;
210    }
211    case PieceData::POP:
212        data->timer -= deltams;
213        if (data->timer < 0.0f)
214            data->state = PieceData::DEAD;
215        break;
216    case PieceData::DEAD:
217        break;
218    }
219    Entity::TickGame(deltams);
220}
221
222void Piece::TickDraw(float deltams)
223{
224    Entity::TickDraw(deltams);
225
226    int id = data->id;
227    int x = data->pos.x + 24;
228    int y = data->pos.y + 177;
229    int z = 2;
230
231    /* Optional modifiers */
232    switch (data->state)
233    {
234    case PieceData::IDLE:
235        break;
236    case PieceData::BLINK:
237        id = data->id + 1;
238        break;
239    case PieceData::GRAB:
240        id = data->id + 1;
241        z = 4;
242        break;
243    case PieceData::UNGRAB:
244        if ((data->cell * 48 - data->src).sqlen() > 24 * 24)
245            id = data->id + 2;
246        z = 4;
247        break;
248    case PieceData::MOVE:
249        z = 3;
250        break;
251    case PieceData::POP:
252        id = data->id + 4;
253        break;
254    case PieceData::DEAD:
255        break;
256    }
257
258    if (data->state != PieceData::DEAD)
259        data->game->GetScene()->AddTile((data->tiler << 16) | id, x, y, z, 0);
260
261    if (data->state == PieceData::GRAB)
262        data->game->GetScene()->AddTile((data->tiler << 16) | 0, x, y, 5, 0);
263}
264
265Piece::~Piece()
266{
267    Ticker::Unref(data->game);
268    Tiler::Deregister(data->tiler);
269    delete data;
270}
271
Note: See TracBrowser for help on using the repository browser.