source: trunk/monsterz/board.cpp @ 248

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

Make swaps effective now, just for testing purposes.

  • Property svn:keywords set to Id
File size: 5.4 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#include <cstdlib>
18
19#include "core.h"
20#include "board.h"
21#include "piece.h"
22#include "monsterz.h"
23
24/*
25 * Board implementation class
26 */
27
28class BoardData
29{
30    friend class Board;
31
32private:
33    Game *game;
34    int screen, board, tiles;
35    Piece *pieces[8][8];
36    Piece *grabbed;
37    Int2 src_cell, dst_cell;
38
39    Int2 mouse;
40    Int3 buttons;
41    float nextblink;
42
43    enum
44    {
45        IDLE,
46        BADCLICK,
47        GRAB,
48    }
49    state;
50};
51
52/*
53 * Public Board class
54 */
55
56Board::Board(Game *game)
57{
58    data = new BoardData();
59    data->game = game;
60    Ticker::Ref(game);
61    data->screen = Tiler::Register(PNG_BACKGROUND, 640, 480, 1.0f);
62    data->board = Tiler::Register(PNG_BOARD, 384, 384, 1.0f);
63    data->tiles = Tiler::Register(PNG_TILES, 48, 48, 1.0f);
64
65    for (int j = 0; j < 8; j++)
66        for (int i = 0; i < 8; i++)
67        {
68            int id = (35 + i + (i ^ (j + 13)) * (2 * j + 711)) % 9;
69            data->pieces[i][j] = new Piece(game, Int2(i, j), 25 + 5 * id);
70            Ticker::Ref(data->pieces[i][j]);
71        }
72
73    data->nextblink = 0.0f;
74    data->state = BoardData::IDLE;
75}
76
77void Board::TickGame(float deltams)
78{
79    Entity::TickGame(deltams);
80
81    Int2 mouse = Input::GetMousePos();
82    Int3 buttons = Input::GetMouseButtons();
83
84    /* If possible, make a random monster blink */
85    if ((data->nextblink -= deltams) < 0.0f)
86    {
87        data->pieces[rand() % 8][rand() % 8]->Blink();
88        data->nextblink = (float)(200 + rand() % 500);
89    }
90
91    /* Should we start dragging something? */
92    switch (data->state)
93    {
94    case BoardData::IDLE:
95        if (buttons[0] && !data->buttons[0])
96        {
97            int x = mouse.x - 24;
98            int y = mouse.y - 72;
99            if (x >= 0 && x < 8 * 48 && y >= 0 && y < 8 * 48)
100            {
101                if (data->pieces[x / 48][y / 48]->Grab(Int2(0, 0)))
102                {
103                    data->grabbed = data->pieces[x / 48][y / 48];
104                    data->src_cell = Int2(x / 48, y / 48);
105                    data->dst_cell = Int2(-1);
106                    data->state = BoardData::GRAB;
107                }
108                else
109                    data->state = BoardData::BADCLICK;
110            }
111            else
112                data->state = BoardData::BADCLICK;
113        }
114        break;
115    case BoardData::GRAB:
116        if (mouse.x >= 0 && mouse.y >= 0)
117        {
118            data->grabbed->Grab(mouse - data->mouse);
119            Int2 cur_pos = data->grabbed->GetPos();
120            Int2 cur_cell = (cur_pos + 24) / 48;
121            if (cur_cell.i < 0 || cur_cell.i >= 8
122                 || cur_cell.j < 0 || cur_cell.j >= 8
123                 || (cur_pos - cur_cell * 48).sqlen() > 24 * 24
124                 || (cur_cell - data->src_cell).sqlen() != 1)
125                cur_cell = Int2(-1);
126            /* If potential target changed, update our cache. */
127            if (cur_cell != data->dst_cell)
128            {
129                if (data->dst_cell != Int2(-1))
130                    data->pieces[data->dst_cell.i]
131                                [data->dst_cell.j]->Goto(data->dst_cell * 48);
132                if (cur_cell != Int2(-1))
133                    data->pieces[cur_cell.i]
134                                [cur_cell.j]->Goto(data->src_cell * 48);
135                data->dst_cell = cur_cell;
136            }
137        }
138        if (!buttons[0] || mouse.x < 0 || mouse.y < 0
139             || (data->src_cell * 48
140                  - data->grabbed->GetPos()).sqlen() > 100 * 100)
141        {
142            if (data->dst_cell != Int2(-1))
143            {
144                Piece *src = data->pieces[data->src_cell.i][data->src_cell.j];
145                Piece *dst = data->pieces[data->dst_cell.i][data->dst_cell.j];
146                data->pieces[data->src_cell.i][data->src_cell.j] = dst;
147                data->pieces[data->dst_cell.i][data->dst_cell.j] = src;
148                src->SetCell(data->dst_cell);
149                src->Goto(data->dst_cell * 48);
150                dst->SetCell(data->src_cell);
151                dst->Goto(data->src_cell * 48);
152            }
153            data->grabbed->Ungrab();
154            data->state = BoardData::IDLE;
155        }
156        break;
157    case BoardData::BADCLICK:
158        if (!buttons[0])
159            data->state = BoardData::IDLE;
160        break;
161    }
162
163    data->mouse = mouse;
164    data->buttons = buttons;
165}
166
167void Board::TickDraw(float deltams)
168{
169    Entity::TickDraw(deltams);
170
171    data->game->GetScene()->AddTile((data->screen << 16) | 0, 0, 1050, 0, 0);
172    data->game->GetScene()->AddTile((data->board << 16) | 0, 24, 912, 1, 0);
173
174    if (data->mouse.x >= 0 && data->mouse.y >= 0)
175    {
176        int x = data->mouse.x - 2;
177        int y = data->mouse.y + 59;
178        data->game->GetScene()->AddTile((data->tiles << 16) | 9, x, y, 10, 0);
179    }
180}
181
182Board::~Board()
183{
184    Ticker::Unref(data->game);
185    for (int j = 0; j < 8; j++)
186        for (int i = 0; i < 8; i++)
187            Ticker::Unref(data->pieces[i][j]);
188    Tiler::Deregister(data->board);
189    Tiler::Deregister(data->screen);
190    Tiler::Deregister(data->tiles);
191    delete data;
192}
193
Note: See TracBrowser for help on using the repository browser.