Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/tetris/TetrisBrick.cc @ 9870

Last change on this file since 9870 was 9803, checked in by jo, 11 years ago

The brick falldown acceleration is increased, but the velocity is limited, such that occasional break-throughs are prevented.

File size: 8.0 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 TetrisBrick.cc
31    @brief Implementation of the TetrisBrick class.
32*/
33
34#include "TetrisBrick.h"
35
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38
39#include "TetrisCenterpoint.h"
40#include "TetrisStone.h"
41#include "Tetris.h"
42#include "util/Math.h"
43
44namespace orxonox
45{
46    RegisterClass(TetrisBrick);
47
48    /**
49    @brief
50        Constructor. Registers and initializes the object.
51    @ingroup Tetris
52    */
53    TetrisBrick::TetrisBrick(Context* context): ControllableEntity(context)
54    {
55        RegisterObject(TetrisBrick);
56        this->shapeIndex_ = 1 + static_cast<unsigned int>(rnd(6.0f)); //<! random number between 0 and 7
57        this->stonesPerBrick_ = 4; //<! most tetris bricks is formed by 4 stones
58        this->delay_ = false;
59        this->delayTimer_.setTimer(0.2f, false, createExecutor(createFunctor(&TetrisBrick::enableMovement, this)));
60        this->lockRotation_ = false;
61        this->tetris_ = this->getTetris();
62        this->size_ = 10.0f; //TODO: fix this via this->tetris_->center_->getStoneSize();
63        this->rotationCount_ = 0;
64        this->createBrick(); //<! create a whole new Brick;
65    }
66
67    /**
68    @brief
69        This function partly initializes a TetrisBrick as an array of TetrisStones
70    */
71    void TetrisBrick::createBrick(void)
72    { //Index 0 : single stone, 1 : 4 in a row; 2: 4-Block right shifted; 3: 'T' 4: 4-Block left shifted;
73      //Index 5 : 4-Block; 6 : 'L'; 7 : mirrored 'L';
74        if(this->shapeIndex_ == 0)
75            this->stonesPerBrick_ = 1;
76        for (unsigned int i = 0; i < this->stonesPerBrick_; i++)
77        {
78            // Create a new stone and add it to the brick.
79            TetrisStone* stone = new TetrisStone(this->getContext());
80            this->brickStones_.push_back(stone);
81            this->attach(stone);
82            this->formBrick(stone, i);
83            if(this->tetris_ != NULL)
84            {
85                stone->setGame(this->tetris_);
86                if(this->tetris_->getCenterpoint() != NULL)
87                    stone->addTemplate(this->tetris_->getCenterpoint()->getStoneTemplate());
88                else
89                        orxout()<< "tetris_->getCenterpoint == NULL in TetrisBrick.cc"<< endl;
90            }
91            else
92                orxout()<< "tetris_ == NULL in TetrisBrick.cc"<< endl;
93        }
94    }
95
96    /**
97    @brief
98        This function creates the shape of a TetrisBrick. ! Spaghetti-Code !
99    @param i
100        The stone's number.
101    @param stone
102        The TetrisStone that is placed relative to the brick's position.
103    */
104    void TetrisBrick::formBrick(TetrisStone* stone, unsigned int i)
105    {
106        if(i == 0) //setting the first stone as
107        {
108            stone->setPosition(0.0f, 0.0f, 0.0f);
109        }
110        else if(i == 1)
111        {
112            stone->setPosition(0.0f, size_, 0.0f);
113        }
114        else if(i == 2)
115        {
116            if(this->shapeIndex_ == 1 || this->shapeIndex_ == 6 || this->shapeIndex_ == 7)
117            {
118                stone->setPosition(0.0f, 2*size_, 0.0f);
119            }
120            else if(this->shapeIndex_ == 3 || this->shapeIndex_ == 4|| this->shapeIndex_ == 5)
121            {
122                stone->setPosition(size_, 0, 0.0f);
123            }
124            else if(this->shapeIndex_ == 2)
125            {
126                stone->setPosition(-size_, 0, 0.0f);
127            }
128        }
129        else if(i == 3)
130        {
131            if(this->shapeIndex_ == 2 || this->shapeIndex_ == 5)
132            {
133                stone->setPosition(size_, size_, 0.0f);
134            }
135            else if(this->shapeIndex_ == 1)
136            {
137                stone->setPosition(0, 3*size_, 0.0f);
138            }
139            else if(this->shapeIndex_ == 3 || this->shapeIndex_ == 7)
140            {
141                stone->setPosition(-size_, 0, 0.0f);
142            }
143            else if(this->shapeIndex_ == 4)
144            {
145                stone->setPosition(-size_, size_, 0.0f);
146            }
147            else if(this->shapeIndex_ == 6)
148            {
149                stone->setPosition(size_, 0, 0.0f);
150            }
151        }
152    }
153
154    bool TetrisBrick::isValidMove(const Vector3& position, bool isRotation = false)
155    {
156        return this->tetris_->isValidMove(this,position, isRotation);
157    }
158
159    TetrisStone* TetrisBrick::getStone(unsigned int i)
160    {
161        if(i < this->brickStones_.size())
162            return this->brickStones_[i];
163        else return NULL;
164    }
165
166
167    Tetris* TetrisBrick::getTetris()
168    {
169        if (this->getGametype() != NULL && this->getGametype()->isA(Class(Tetris)))
170        {
171            Tetris* tetrisGametype = orxonox_cast<Tetris*>(this->getGametype().get());
172            return tetrisGametype;
173        }
174        return NULL;
175    }
176
177    /**
178    @brief
179        Overloaded the function to rotate the Brick.
180    @param value
181        A vector whose first component is the angle by which to rotate.
182    */
183    void TetrisBrick::moveFrontBack(const Vector2& value)
184    {
185        if(value.x < 0) //speedup on key down
186        {
187            Vector3 v_new = this->getVelocity()*1.2;
188            if (v_new.y < -400.0f) //limiting the speed to prevent break throughs.
189                v_new.y = -400.0f;
190            this->setVelocity(v_new);
191        }
192        else if(!this->lockRotation_) //rotate when key up is pressed
193        {
194                if(!isValidMove(this->getPosition(), true)) //catch illegal rotations
195                    return;
196            this->lockRotation_ = true; // multiple calls of this function have to be filtered out.
197            this->rotationTimer_.setTimer(0.1f, false, createExecutor(createFunctor(&TetrisBrick::unlockRotation, this)));
198            Quaternion q(Degree(90), Vector3::UNIT_Z);
199            this->setOrientation(this->getOrientation()*q); //rotation: roll 90°
200            this->rotationCount_ = (this->rotationCount_ + 1) % 4;
201        }
202    }
203
204    /**
205    @brief
206        Overloaded the function to steer the Brick right and left
207    @param value
208        A vector whose first component is the direction in which we want to steer the Brick.
209    */
210    void TetrisBrick::moveRightLeft(const Vector2& value)
211    {
212        if(!this->delay_)
213        {
214            const Vector3& position = this->getPosition();
215            Vector3 newPos = Vector3(position.x+value.x/abs(value.x)*this->size_, position.y, position.z);
216            if(!this->isValidMove(newPos))
217                return;
218
219            this->setPosition(newPos);
220            this->delay_ = true;
221            this->delayTimer_.startTimer();
222        }
223    }
224
225    /**
226    @brief
227        Is called when the player changed.
228    */
229    void TetrisBrick::changedPlayer()
230    {
231        this->setVelocity(0.0f, 0.0f, 0.0f);
232    }
233
234    /**
235    @brief
236        Attaches stones to the Centerpoint.
237    */
238    void TetrisBrick::releaseStones(TetrisCenterpoint* center)
239    {
240        assert(this->tetris_);
241        for(unsigned int i = 0; i < this->brickStones_.size(); i++)
242        {
243            this->brickStones_[i]->detachFromParent();
244            this->brickStones_[i]->attachToParent(center);
245            this->brickStones_[i]->setPosition(this->getPosition()+this->tetris_->rotateVector(this->brickStones_[i]->getPosition(),this->rotationCount_ ));
246        }
247        this->brickStones_.clear();
248    }
249
250}
Note: See TracBrowser for help on using the repository browser.