source: trunk/monsterz/piece.cpp @ 243

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

Allow to immediately grab an ungrabbed piece if it is close enough.

File size: 3.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, tmp;
34    int id;
35    float timer;
36
37    enum
38    {
39        IDLE,
40        BLINK,
41        GRAB,
42        UNGRAB,
43    }
44    state;
45};
46
47/*
48 * Public Piece class
49 */
50
51Piece::Piece(Game *game, Int2 cell, int id)
52{
53    data = new PieceData();
54    data->game = game;
55    Ticker::Ref(game);
56    data->tiler = Tiler::Register(PNG_TILES, 48, 48, 1.0f);
57    data->cell = cell;
58    data->pos = cell * 48;
59    data->id = id;
60    data->state = PieceData::IDLE;
61}
62
63int Piece::Blink()
64{
65    switch (data->state)
66    {
67    case PieceData::IDLE:
68        data->state = PieceData::BLINK;
69        data->timer = 400.0f; /* Duration of a blink */
70        return 1;
71    default:
72        return 0;
73    }
74}
75
76int Piece::Grab(Int2 dir)
77{
78    switch (data->state)
79    {
80    case PieceData::UNGRAB:
81        if ((data->cell * 48 - data->pos).sqlen() > 24 * 24)
82            return 0;
83        /* Fall through */
84    case PieceData::IDLE:
85    case PieceData::BLINK:
86    case PieceData::GRAB:
87        data->state = PieceData::GRAB;
88        data->pos = data->pos + dir;
89        return 1;
90    default:
91        return 0;
92    }
93}
94
95int Piece::Ungrab()
96{
97    switch (data->state)
98    {
99    case PieceData::GRAB:
100        data->state = PieceData::UNGRAB;
101        data->timer = 0.0f;
102        data->tmp = data->pos;
103        return 1;
104    default:
105        return 0;
106    }
107}
108
109void Piece::TickGame(float deltams)
110{
111    switch (data->state)
112    {
113    case PieceData::IDLE:
114        break;
115    case PieceData::BLINK:
116        data->timer -= deltams;
117        if (data->timer < 0.0f)
118            data->state = PieceData::IDLE;
119        break;
120    case PieceData::GRAB:
121        break;
122    case PieceData::UNGRAB:
123        data->timer += deltams;
124        Int2 trip = data->cell * 48 - data->tmp;
125        float moving_time = trip.len() / 0.8f; /* Moving speed */
126        float t = moving_time ? data->timer / moving_time : 1.0f;
127        if (t >= 1.0f)
128            t = 1.0f;
129        if (data->timer > moving_time + 200.0f)
130            data->state = PieceData::IDLE;
131        data->pos = data->tmp + (t * trip + 0.5f);
132        break;
133    }
134    Entity::TickGame(deltams);
135}
136
137void Piece::TickDraw(float deltams)
138{
139    Entity::TickDraw(deltams);
140
141    int id = data->id;
142    int x = data->pos.x + 24;
143    int y = data->pos.y + 177;
144    int z = 2;
145
146    /* Optional modifiers */
147    switch (data->state)
148    {
149    case PieceData::IDLE:
150        break;
151    case PieceData::BLINK:
152        id = data->id + 1;
153        break;
154    case PieceData::GRAB:
155        id = data->id + 1;
156        z = 4;
157        break;
158    case PieceData::UNGRAB:
159        if ((data->cell * 48 - data->tmp).sqlen() > 24 * 24)
160            id = data->id + 2;
161        z = 4;
162        break;
163    }
164
165    data->game->GetScene()->AddTile((data->tiler << 16) | id, x, y, z, 0);
166
167    if (data->state == PieceData::GRAB)
168        data->game->GetScene()->AddTile((data->tiler << 16) | 0, x, y, z, 0);
169}
170
171Piece::~Piece()
172{
173    Ticker::Unref(data->game);
174    Tiler::Deregister(data->tiler);
175    delete data;
176}
177
Note: See TracBrowser for help on using the repository browser.