Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pCuts/src/modules/tetris/Tetris.cc @ 9082

Last change on this file since 9082 was 9082, checked in by jo, 12 years ago

Trying to create tetris bricks. Rough implementation done. Still having a nasty camera bug. (see the debug output concerning the cameraIndex)

  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      ...
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file Tetris.cc
31    @brief Implementation of the Tetris class.
32*/
33
34#include "Tetris.h"
35
36#include "core/CoreIncludes.h"
37#include "core/EventIncludes.h"
38#include "core/command/Executor.h"
39
40#include "gamestates/GSLevel.h"
41
42#include "TetrisCenterpoint.h"
43#include "TetrisStone.h"
44#include "TetrisBrick.h"
45#include "infos/PlayerInfo.h"
46
47namespace orxonox
48{
49
50    CreateUnloadableFactory(Tetris);
51
52    /**
53    @brief
54        Constructor. Registers and initializes the object.
55    */
56    Tetris::Tetris(BaseObject* creator) : Deathmatch(creator)
57    {
58        RegisterObject(Tetris);
59
60        this->activeBrick_ = NULL;
61
62        // Pre-set the timer, but don't start it yet.
63        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Tetris::startBrick, this)));
64        this->starttimer_.stopTimer();
65
66        this->player_ = NULL;
67    }
68
69    /**
70    @brief
71        Destructor. Cleans up, if initialized.
72    */
73    Tetris::~Tetris()
74    {
75        if (this->isInitialized())
76            this->cleanup();
77    }
78
79    /**
80    @brief
81        Cleans up the Gametype.
82    */
83    void Tetris::cleanup()
84    {
85        /*for(int i = 0;i < this->stones_.size(); i++) //TODO: Why isn't there any code like this
86        {                                              // compensating the 'new' statement?
87            delete this->stones_[i];
88        }//*/
89
90    }
91
92    void Tetris::tick(float dt)
93    {
94        SUPER(Tetris, tick, dt);
95
96        if(this->activeBrick_ != NULL)
97        {
98            if(!this->isValidBrickPosition(this->activeBrick_, this->activeBrick_->getPosition()))
99            {
100                this->activeBrick_->setVelocity(Vector3::ZERO);
101                this->createBrick();
102                this->startBrick();
103            }
104        }
105    }
106
107    bool Tetris::isValidMove(TetrisStone* stone, const Vector3& position)
108    {
109        assert(stone);
110
111        if(position.x < this->center_->getStoneSize()/2.0)  //!< If the stone touches the left edge of the level
112            return false;
113        else if(position.x > (this->center_->getWidth()-0.5)*this->center_->getStoneSize()) //!< If the stone touches the right edge of the level
114            return false;
115
116        for(std::vector<TetrisStone*>::const_iterator it = this->stones_.begin(); it != this->stones_.end(); ++it)
117        {
118            if(stone == *it)
119                continue;
120
121            const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone
122
123            if((position.x == currentStonePosition.x) && abs(position.y-currentStonePosition.y) < this->center_->getStoneSize())
124                return false;
125        }
126
127        return true;
128    }
129
130    /**
131    @brief
132        Check for each stone in a brick wether it is moved the right way.
133    */
134    bool Tetris::isValidMove(TetrisBrick* brick, const Vector3& position)
135    {
136        assert(brick);
137
138        for (unsigned int i = 0; i < brick->getNumberOfStones(); i++ )
139        {
140            TetrisStone* stone = brick->getStone(i);
141            if(! this->isValidMove(stone, position + stone->getPosition())) // wrong position??
142                return false;
143            orxout()<< "stoneRelativePoistion: " << stone->getPosition() << endl;
144            orxout()<< "stoneTotalPoistion: " << position + stone->getPosition() << endl;
145        }
146        return true;
147
148    }
149
150
151
152    bool Tetris::isValidStonePosition(TetrisStone* stone, const Vector3& position)
153    {
154        assert(stone);
155
156        // we use a reverse iterator because we have to check for collisions with the topmost stones first
157        for(std::vector<TetrisStone*>::const_reverse_iterator it = this->stones_.rbegin(); it != this->stones_.rend(); ++it)
158        {
159            if(this->activeBrick_->contains(*it))
160                continue;
161
162            const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone
163
164            if((position.x == currentStonePosition.x) && (position.y < currentStonePosition.y + this->center_->getStoneSize()))
165            {
166                this->activeBrick_->setPosition(Vector3(this->activeBrick_->getPosition().x, currentStonePosition.y+this->center_->getStoneSize(), this->activeBrick_->getPosition().z));
167                return false;
168            }// This case applies if the stones overlap partially vertically
169        }
170
171        // after we checked for collision with all stones, we also check for collision with the bottom
172        if(position.y < this->center_->getStoneSize()/2.0f) //!< If the stone has reached the bottom of the level
173        {//TODO: correct positioning !!
174                this->activeBrick_->setPosition(Vector3(this->activeBrick_->getPosition().x, this->center_->getStoneSize()/2.0f, this->activeBrick_->getPosition().z));
175            return false;
176        }
177
178        return true;
179    }
180
181    bool Tetris::isValidBrickPosition(TetrisBrick* brick, const Vector3& position)
182    {
183        assert(brick);
184
185        for (unsigned int i = 0; i < brick->getNumberOfStones(); i++ )
186        {
187            TetrisStone* stone = brick->getStone(i);
188            if(! this->isValidStonePosition(stone, position + stone->getPosition()) ) // wrong position??
189                return false;
190        }
191        return true;
192
193    }
194
195    /**
196    @brief
197        Starts the Tetris minigame.
198    */
199    void Tetris::start()
200    {
201        if (this->center_ != NULL) // There needs to be a TetrisCenterpoint, i.e. the area the game takes place.
202        {
203            // Create the first stone.
204            this->createBrick();
205        }
206        else // If no centerpoint was specified, an error is thrown and the level is exited.
207        {
208            orxout(internal_error) << "Tetris: No Centerpoint specified." << endl;
209            GSLevel::startMainMenu();
210            return;
211        }
212
213        // Start the timer. After it has expired the stone is started.
214        this->starttimer_.startTimer();
215
216        // Set variable to temporarily force the player to spawn.
217        bool temp = this->bForceSpawn_;
218        this->bForceSpawn_ = true;
219
220        // Call start for the parent class.
221        Deathmatch::start();
222
223        // Reset the variable.
224        this->bForceSpawn_ = temp;
225    }
226
227    /**
228    @brief
229        Ends the Tetris minigame.
230    */
231    void Tetris::end()
232    {
233        this->cleanup();
234
235        // Call end for the parent class.
236        Deathmatch::end();
237    }
238
239    /**
240    @brief
241        Spawns player.
242    */
243    void Tetris::spawnPlayersIfRequested()
244    {
245        // Spawn a human player.
246        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
247            if (it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
248                this->spawnPlayer(it->first);
249    }
250
251    /**
252    @brief
253        Spawns the input player.
254    @param player
255        The player to be spawned.
256    */
257    void Tetris::spawnPlayer(PlayerInfo* player)
258    {
259        assert(player);
260
261        if(this->player_ == NULL)
262        {
263            this->player_ = player;
264            this->players_[player].state_ = PlayerState::Alive;
265        }
266    }
267
268
269
270    void Tetris::startBrick(void)
271    {
272        if(this->player_ == NULL)
273            return;
274
275        unsigned int cameraIndex = 0;
276        if(this->activeBrick_ != NULL)
277        {
278            // Get camera settings
279            cameraIndex = this->activeBrick_->getCurrentCameraIndex();
280            orxout() << "cameraIndex: " << this->activeBrick_->getCurrentCameraIndex() << endl;
281            this->player_->stopControl();
282        }
283
284        // Make the last brick to be created the active brick.
285        this->activeBrick_ = this->bricks_.back();
286
287        this->player_->startControl(this->activeBrick_);
288        this->activeBrick_->setVelocity(0.0f, -this->center_->getStoneSpeed(), 0.0f);
289        orxout() << "velocity: " << this->center_->getStoneSpeed() << endl;
290        this->activeBrick_->setCameraPosition(cameraIndex);
291    }
292
293    void Tetris::createBrick(void)             //TODO: random rotation offset between 0 and 3 (times 90°)
294    {
295        // Create a new brick and add it to the list of bricks && to the list of stones.
296        TetrisBrick* brick = new TetrisBrick(this->center_);
297        this->bricks_.push_back(brick);
298        for (unsigned int i = 0; i < brick->getNumberOfStones(); i++)
299        {
300            this->stones_.push_back(brick->getStone(i));
301        }
302
303        // Apply the stone template to the stone.
304        brick->addTemplate(this->center_->getStoneTemplate()); // TODO: find error concerning the cameras
305
306        // Attach the brick to the Centerpoint and set the position of the brick to be at the top middle.
307        this->center_->attach(brick);
308        float xPos = (this->center_->getWidth()/2 + ((this->center_->getWidth() % 2)*2-1)/2.0f)*this->center_->getStoneSize();
309        float yPos = (this->center_->getHeight()-0.5f)*this->center_->getStoneSize();
310        brick->setPosition(xPos, yPos, 0.0f);
311        brick->setGame(this);
312    }
313
314
315    /**
316    @brief
317        Get the player.
318    @return
319        Returns a pointer to the player. If there is no player, NULL is returned.
320    */
321    PlayerInfo* Tetris::getPlayer(void) const
322    {
323        return this->player_;
324    }
325
326    /*TetrisCenterpoint* Tetris::getCenterpoint(void) const
327    {
328        return this->center_;
329    }*/
330
331    /**
332    @brief Set the TetrisCenterpoint (the playing field).
333    @param center A pointer to the TetrisCenterpoint to be set.
334    */
335    void Tetris::setCenterpoint(TetrisCenterpoint* center)
336    {
337        this->center_ = center;
338    }
339
340}
Note: See TracBrowser for help on using the repository browser.