source: trunk/monsterz/piece.cpp @ 261

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

Use a different speed when pieces are swapped and when they fall.

File size: 4.5 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    }
45    state;
46};
47
48/*
49 * Public Piece class
50 */
51
52Piece::Piece(Game *game, Int2 cell, int id)
53  : data(new PieceData())
54{
55    data->game = game;
56    Ticker::Ref(game);
57    data->tiler = Tiler::Register(PNG_TILES, 48, 48, 1.0f);
58    data->cell = cell;
59    data->pos = cell * 48;
60    data->id = id;
61    data->state = PieceData::IDLE;
62}
63
64void Piece::SetCell(Int2 cell)
65{
66    data->cell = cell;
67}
68
69Int2 Piece::GetPos() const
70{
71    return data->pos;
72}
73
74int Piece::GetId() const
75{
76    return data->id;
77}
78
79int Piece::Blink()
80{
81    switch (data->state)
82    {
83    case PieceData::IDLE:
84        data->state = PieceData::BLINK;
85        data->timer = 400.0f; /* Duration of a blink */
86        return 1;
87    default:
88        return 0;
89    }
90}
91
92int Piece::Pop()
93{
94    return 0;
95}
96
97int Piece::Grab(Int2 dir)
98{
99    switch (data->state)
100    {
101    case PieceData::UNGRAB:
102    case PieceData::MOVE:
103        /* Only allow swaps when piece is close enough to its target cell. */
104        if ((data->cell * 48 - data->pos).sqlen() > 24 * 24)
105            return 0;
106        /* Fall through */
107    case PieceData::IDLE:
108    case PieceData::BLINK:
109    case PieceData::GRAB:
110        data->state = PieceData::GRAB;
111        data->pos = data->pos + dir;
112        return 1;
113    default:
114        return 0;
115    }
116}
117
118int Piece::Ungrab()
119{
120    switch (data->state)
121    {
122    case PieceData::GRAB:
123        data->state = PieceData::UNGRAB;
124        data->speed = 0.3f;
125        data->timer = 0.0f;
126        data->src = data->pos;
127        data->dst = data->cell * 48;
128        return 1;
129    default:
130        return 0;
131    }
132}
133
134int Piece::Goto(Int2 pos, float speed)
135{
136    switch (data->state)
137    {
138    case PieceData::IDLE:
139    case PieceData::BLINK:
140    case PieceData::UNGRAB:
141    case PieceData::MOVE:
142        data->state = PieceData::MOVE;
143        data->timer = 0.0f;
144        data->src = data->pos;
145        data->dst = pos;
146        data->speed = speed;
147        return 1;
148    case PieceData::GRAB:
149    default:
150        return 0;
151    }
152}
153
154void Piece::TickGame(float deltams)
155{
156    switch (data->state)
157    {
158    case PieceData::IDLE:
159        break;
160    case PieceData::BLINK:
161        data->timer -= deltams;
162        if (data->timer < 0.0f)
163            data->state = PieceData::IDLE;
164        break;
165    case PieceData::GRAB:
166        break;
167    case PieceData::UNGRAB:
168    case PieceData::MOVE:
169        data->timer += deltams;
170        Int2 trip = data->dst - data->src;
171        float moving_time = trip.len() / data->speed;
172        float t = moving_time ? data->timer / moving_time : 1.0f;
173        if (t >= 1.0f)
174            t = 1.0f;
175        if (data->timer > moving_time + 200.0f)
176            data->state = PieceData::IDLE;
177        t = t * t * 3 - t * t * t * 2;
178        t = t * t * 3 - t * t * t * 2;
179        data->pos = data->src + (t * trip + 0.5f);
180        break;
181    }
182    Entity::TickGame(deltams);
183}
184
185void Piece::TickDraw(float deltams)
186{
187    Entity::TickDraw(deltams);
188
189    int id = data->id;
190    int x = data->pos.x + 24;
191    int y = data->pos.y + 177;
192    int z = 2;
193
194    /* Optional modifiers */
195    switch (data->state)
196    {
197    case PieceData::IDLE:
198        break;
199    case PieceData::BLINK:
200        id = data->id + 1;
201        break;
202    case PieceData::GRAB:
203        id = data->id + 1;
204        z = 4;
205        break;
206    case PieceData::UNGRAB:
207        if ((data->cell * 48 - data->src).sqlen() > 24 * 24)
208            id = data->id + 2;
209        z = 4;
210        break;
211    case PieceData::MOVE:
212        z = 3;
213        break;
214    }
215
216    data->game->GetScene()->AddTile((data->tiler << 16) | id, x, y, z, 0);
217
218    if (data->state == PieceData::GRAB)
219        data->game->GetScene()->AddTile((data->tiler << 16) | 0, x, y, 5, 0);
220}
221
222Piece::~Piece()
223{
224    Ticker::Unref(data->game);
225    Tiler::Deregister(data->tiler);
226    delete data;
227}
228
Note: See TracBrowser for help on using the repository browser.