source: trunk/monsterz/piece.cpp @ 250

Last change on this file since 250 was 250, checked in by sam, 10 years ago

Minor tuning to piece behaviour and Z-index.

File size: 4.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 timer;
36
37    enum
38    {
39        IDLE,
40        BLINK,
41        GRAB,
42        UNGRAB,
43        PUSH,
44    }
45    state;
46};
47
48/*
49 * Public Piece class
50 */
51
52Piece::Piece(Game *game, Int2 cell, int id)
53{
54    data = new PieceData();
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::Blink()
75{
76    switch (data->state)
77    {
78    case PieceData::IDLE:
79        data->state = PieceData::BLINK;
80        data->timer = 400.0f; /* Duration of a blink */
81        return 1;
82    default:
83        return 0;
84    }
85}
86
87int Piece::Grab(Int2 dir)
88{
89    switch (data->state)
90    {
91    case PieceData::UNGRAB:
92    case PieceData::PUSH:
93        if ((data->cell * 48 - data->pos).sqlen() > 24 * 24)
94            return 0;
95        /* Fall through */
96    case PieceData::IDLE:
97    case PieceData::BLINK:
98    case PieceData::GRAB:
99        data->state = PieceData::GRAB;
100        data->pos = data->pos + dir;
101        return 1;
102    default:
103        return 0;
104    }
105}
106
107int Piece::Ungrab()
108{
109    switch (data->state)
110    {
111    case PieceData::GRAB:
112        data->state = PieceData::UNGRAB;
113        data->timer = 0.0f;
114        data->src = data->pos;
115        data->dst = data->cell * 48;
116        return 1;
117    default:
118        return 0;
119    }
120}
121
122int Piece::Goto(Int2 pos)
123{
124    switch (data->state)
125    {
126    case PieceData::IDLE:
127    case PieceData::BLINK:
128    case PieceData::UNGRAB:
129    case PieceData::PUSH:
130        data->state = PieceData::PUSH;
131        data->timer = 0.0f;
132        data->src = data->pos;
133        data->dst = pos;
134        return 1;
135    case PieceData::GRAB:
136    default:
137        return 0;
138    }
139}
140
141void Piece::TickGame(float deltams)
142{
143    switch (data->state)
144    {
145    case PieceData::IDLE:
146        break;
147    case PieceData::BLINK:
148        data->timer -= deltams;
149        if (data->timer < 0.0f)
150            data->state = PieceData::IDLE;
151        break;
152    case PieceData::GRAB:
153        break;
154    case PieceData::UNGRAB:
155    case PieceData::PUSH:
156        data->timer += deltams;
157        Int2 trip = data->dst - data->src;
158        float moving_time = trip.len() / 0.3f; /* Moving speed */
159        float t = moving_time ? data->timer / moving_time : 1.0f;
160        if (t >= 1.0f)
161            t = 1.0f;
162        if (data->timer > moving_time + 200.0f)
163            data->state = PieceData::IDLE;
164        t = t * t * 3 - t * t * t * 2;
165        t = t * t * 3 - t * t * t * 2;
166        data->pos = data->src + (t * trip + 0.5f);
167        break;
168    }
169    Entity::TickGame(deltams);
170}
171
172void Piece::TickDraw(float deltams)
173{
174    Entity::TickDraw(deltams);
175
176    int id = data->id;
177    int x = data->pos.x + 24;
178    int y = data->pos.y + 177;
179    int z = 2;
180
181    /* Optional modifiers */
182    switch (data->state)
183    {
184    case PieceData::IDLE:
185        break;
186    case PieceData::BLINK:
187        id = data->id + 1;
188        break;
189    case PieceData::GRAB:
190        id = data->id + 1;
191        z = 4;
192        break;
193    case PieceData::UNGRAB:
194        if ((data->cell * 48 - data->src).sqlen() > 24 * 24)
195            id = data->id + 2;
196        z = 4;
197        break;
198    case PieceData::PUSH:
199        z = 3;
200        break;
201    }
202
203    data->game->GetScene()->AddTile((data->tiler << 16) | id, x, y, z, 0);
204
205    if (data->state == PieceData::GRAB)
206        data->game->GetScene()->AddTile((data->tiler << 16) | 0, x, y, 5, 0);
207}
208
209Piece::~Piece()
210{
211    Ticker::Unref(data->game);
212    Tiler::Deregister(data->tiler);
213    delete data;
214}
215
Note: See TracBrowser for help on using the repository browser.