source: trunk/monsterz/piece.cpp @ 245

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

Swapping animation works.

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