Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/tetris/Tetris.cc @ 8748

Last change on this file since 8748 was 8706, checked in by dafrick, 14 years ago

Merging presentation branch back into trunk.
There are many new features and also a lot of other changes and bugfixes, if you want to know, digg through the svn log.
Not everything is yet working as it should, but it should be fairly stable. If you habe any bug reports, just send me an email.

  • Property svn:eol-style set to native
File size: 8.5 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 "infos/PlayerInfo.h"
45
46namespace orxonox
47{
48
49    CreateUnloadableFactory(Tetris);
50
51    /**
52    @brief
53        Constructor. Registers and initializes the object.
54    */
55    Tetris::Tetris(BaseObject* creator) : Deathmatch(creator)
56    {
57        RegisterObject(Tetris);
58
59        this->activeStone_ = NULL;
60
61        // Pre-set the timer, but don't start it yet.
62        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Tetris::startStone, this)));
63        this->starttimer_.stopTimer();
64
65        this->player_ = NULL;
66    }
67
68    /**
69    @brief
70        Destructor. Cleans up, if initialized.
71    */
72    Tetris::~Tetris()
73    {
74        if (this->isInitialized())
75            this->cleanup();
76    }
77
78    /**
79    @brief
80        Cleans up the Gametype.
81    */
82    void Tetris::cleanup()
83    {
84
85    }
86
87    void Tetris::tick(float dt)
88    {
89        SUPER(Tetris, tick, dt);
90
91        if(this->activeStone_ != NULL)
92        {
93            if(!this->isValidStonePosition(this->activeStone_, this->activeStone_->getPosition()))
94            {
95                this->activeStone_->setVelocity(Vector3::ZERO);
96                this->createStone();
97                this->startStone();
98            }
99        }
100    }
101
102    bool Tetris::isValidMove(TetrisStone* stone, const Vector3& position)
103    {
104        assert(stone);
105
106        if(position.x < this->center_->getStoneSize()/2.0)  //!< If the stone touches the left edge of the level
107            return false;
108        else if(position.x > (this->center_->getWidth()-0.5)*this->center_->getStoneSize()) //!< If the stone touches the right edge of the level
109            return false;
110
111        for(std::vector<TetrisStone*>::const_iterator it = this->stones_.begin(); it != this->stones_.end(); ++it)
112        {
113            if(stone == *it)
114                continue;
115
116            const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone
117
118            if((position.x == currentStonePosition.x) && abs(position.y-currentStonePosition.y) < this->center_->getStoneSize())
119                return false;
120        }
121
122        return true;
123    }
124
125    bool Tetris::isValidStonePosition(TetrisStone* stone, const Vector3& position)
126    {
127        assert(stone);
128
129        // we use a reverse iterator because we have to check for collisions with the topmost stones first
130        for(std::vector<TetrisStone*>::const_reverse_iterator it = this->stones_.rbegin(); it != this->stones_.rend(); ++it)
131        {
132            if(stone == *it)
133                continue;
134
135            const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone
136
137            if((position.x == currentStonePosition.x) && (position.y < currentStonePosition.y + this->center_->getStoneSize()))
138            {
139                this->activeStone_->setPosition(Vector3(this->activeStone_->getPosition().x, currentStonePosition.y+this->center_->getStoneSize(), this->activeStone_->getPosition().z));
140                return false;
141            }// This case applies if the stones overlap partially vertically
142        }
143
144        // after we checked for collision with all stones, we also check for collision with the bottom
145        if(position.y < this->center_->getStoneSize()/2.0f) //!< If the stone has reached the bottom of the level
146        {
147            stone->setPosition(Vector3(stone->getPosition().x, this->center_->getStoneSize()/2.0f, stone->getPosition().z));
148            return false;
149        }
150
151        return true;
152    }
153
154    /**
155    @brief
156        Starts the Tetris minigame.
157    */
158    void Tetris::start()
159    {
160        if (this->center_ != NULL) // There needs to be a TetrisCenterpoint, i.e. the area the game takes place.
161        {
162            // Create the first stone.
163            this->createStone();
164        }
165        else // If no centerpoint was specified, an error is thrown and the level is exited.
166        {
167            COUT(1) << "Error: No Centerpoint specified." << std::endl;
168            GSLevel::startMainMenu();
169            return;
170        }
171
172        // Start the timer. After it has expired the stone is started.
173        this->starttimer_.startTimer();
174
175        // Set variable to temporarily force the player to spawn.
176        bool temp = this->bForceSpawn_;
177        this->bForceSpawn_ = true;
178
179        // Call start for the parent class.
180        Deathmatch::start();
181
182        // Reset the variable.
183        this->bForceSpawn_ = temp;
184    }
185
186    /**
187    @brief
188        Ends the Tetris minigame.
189    */
190    void Tetris::end()
191    {
192        this->cleanup();
193
194        // Call end for the parent class.
195        Deathmatch::end();
196    }
197
198    /**
199    @brief
200        Spawns player.
201    */
202    void Tetris::spawnPlayersIfRequested()
203    {
204        // Spawn a human player.
205        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
206            if (it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
207                this->spawnPlayer(it->first);
208    }
209
210    /**
211    @brief
212        Spawns the input player.
213    @param player
214        The player to be spawned.
215    */
216    void Tetris::spawnPlayer(PlayerInfo* player)
217    {
218        assert(player);
219
220        if(this->player_ == NULL)
221        {
222            this->player_ = player;
223            this->players_[player].state_ = PlayerState::Alive;
224        }
225    }
226
227    /**
228    @brief
229        Starts the first stone.
230    */
231    void Tetris::startStone(void)
232    {
233        if(this->player_ == NULL)
234            return;
235
236        unsigned int cameraIndex = 0;
237        if(this->activeStone_ != NULL)
238        {
239            // Get camera settings
240            cameraIndex = this->activeStone_->getCurrentCameraIndex();
241            this->player_->stopControl();
242        }
243       
244        // Make the last stone to be created the active stone.
245        this->activeStone_ = this->stones_.back();
246       
247        this->player_->startControl(this->activeStone_);
248        this->activeStone_->setVelocity(0.0f, -this->center_->getStoneSpeed(), 0.0f);
249        this->activeStone_->setCameraPosition(cameraIndex);
250    }
251
252    /**
253    @brief
254        Creates a new stone.
255    */
256    void Tetris::createStone(void)
257    {
258        // Create a new stone and add it to the list of stones.
259        TetrisStone* stone = new TetrisStone(this->center_);
260        this->stones_.push_back(stone);
261       
262        // Apply the stone template to the stone.
263        stone->addTemplate(this->center_->getStoneTemplate());
264       
265        // Attach the stone to the Centerpoint and set the position of the stone to be at the top middle.
266        this->center_->attach(stone);
267        float xPos = (this->center_->getWidth()/2 + ((this->center_->getWidth() % 2)*2-1)/2.0f)*this->center_->getStoneSize();
268        float yPos = (this->center_->getHeight()-0.5f)*this->center_->getStoneSize();
269        stone->setPosition(xPos, yPos, 0.0f);
270        stone->setGame(this);
271    }
272
273    /**
274    @brief
275        Get the player.
276    @return
277        Returns a pointer to the player. If there is no player, NULL is returned.
278    */
279    PlayerInfo* Tetris::getPlayer(void) const
280    {
281        return this->player_;
282    }
283
284    /**
285    @brief Set the TetrisCenterpoint (the playing field).
286    @param center A pointer to the TetrisCenterpoint to be set.
287    */
288    void Tetris::setCenterpoint(TetrisCenterpoint* center)
289    {
290        this->center_ = center;
291    }
292
293}
Note: See TracBrowser for help on using the repository browser.