Changeset 9348 for code/trunk/src/modules/tetris
- Timestamp:
- Aug 30, 2012, 11:08:17 PM (12 years ago)
- Location:
- code/trunk
- Files:
-
- 9 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:ignore
-
old new 1 .project 1 2 build 2 3 codeblocks 4 dependencies 3 5 vs 4 dependencies
-
- Property svn:mergeinfo changed
- Property svn:ignore
-
code/trunk/src/modules/tetris/CMakeLists.txt
r8706 r9348 3 3 TetrisCenterpoint.cc 4 4 TetrisStone.cc 5 TetrisBrick.cc 6 TetrisScore.cc 5 7 ) 6 8 … … 10 12 LINK_LIBRARIES 11 13 orxonox 14 overlays 12 15 SOURCE_FILES ${TETRIS_SRC_FILES} 13 16 ) -
code/trunk/src/modules/tetris/Tetris.cc
r8858 r9348 23 23 * ... 24 24 * Co-authors: 25 * ... 26 * 25 * Johannes Ritz 26 * 27 * 28 * 29 * 30 *TASK c) end the game in a nicer way 31 *TASK d) save the highscore 32 *TASK e) eye candy 27 33 */ 28 34 … … 42 48 #include "TetrisCenterpoint.h" 43 49 #include "TetrisStone.h" 50 #include "TetrisBrick.h" 44 51 #include "infos/PlayerInfo.h" 45 52 … … 52 59 @brief 53 60 Constructor. Registers and initializes the object. 61 @ingroup Tetris 54 62 */ 55 63 Tetris::Tetris(BaseObject* creator) : Deathmatch(creator) … … 57 65 RegisterObject(Tetris); 58 66 59 this->active Stone_ = NULL;67 this->activeBrick_ = 0; 60 68 61 69 // Pre-set the timer, but don't start it yet. 62 this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Tetris::start Stone, this)));70 this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Tetris::startBrick, this))); 63 71 this->starttimer_.stopTimer(); 64 72 65 73 this->player_ = NULL; 74 this->setHUDTemplate("TetrisHUD"); 75 this->futureBrick_ = 0; 66 76 } 67 77 … … 82 92 void Tetris::cleanup() 83 93 { 84 94 if (this->activeBrick_) 95 { 96 this->activeBrick_->destroy(); 97 this->activeBrick_ = 0; 98 } 99 if (this->futureBrick_) 100 { 101 this->futureBrick_->destroy(); 102 this->futureBrick_ = 0; 103 } 104 105 for (std::list<SmartPtr<TetrisStone> >::iterator it = this->stones_.begin(); it != this->stones_.end(); ++it) 106 (*it)->destroy(); 107 this->stones_.clear(); 85 108 } 86 109 … … 89 112 SUPER(Tetris, tick, dt); 90 113 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(); 114 if((this->activeBrick_ != NULL)&&(!this->hasEnded())) 115 { 116 if(!this->isValidBrickPosition(this->activeBrick_)) 117 { 118 for (unsigned int i = 0; i < this->activeBrick_->getNumberOfStones(); i++) 119 this->stones_.push_back(this->activeBrick_->getStone(i)); 120 this->activeBrick_->setVelocity(Vector3::ZERO); 121 this->activeBrick_->releaseStones(this->center_); 122 this->findFullRows(); 123 this->startBrick(); 98 124 } 99 125 } … … 109 135 return false; 110 136 111 for(std::vector<TetrisStone*>::const_iterator it = this->stones_.begin(); it != this->stones_.end(); ++it) 112 { 113 if(stone == *it) 114 continue; 115 137 for(std::list<SmartPtr<TetrisStone> >::const_iterator it = this->stones_.begin(); it != this->stones_.end(); ++it) 138 { 116 139 const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone 117 140 … … 123 146 } 124 147 148 /** 149 @brief 150 Check for each stone in a brick if it is moved the right way. 151 */ 152 bool Tetris::isValidMove(TetrisBrick* brick, const Vector3& position, bool isRotation = false) 153 { 154 assert(brick); 155 156 for (unsigned int i = 0; i < brick->getNumberOfStones(); i++ ) 157 { 158 TetrisStone* stone = brick->getStone(i); 159 Vector3 stonePosition; //the current stone's offset to position 160 if(isRotation) 161 stonePosition = rotateVector(stone->getPosition(), brick->getRotationCount()+1); 162 else 163 stonePosition = rotateVector(stone->getPosition(), brick->getRotationCount()); 164 165 if(! this->isValidMove(stone, position + stonePosition )) 166 { 167 return false; 168 } 169 170 //catch illegal rotation (such that collisions with ground are not permitted) 171 if(isRotation) 172 { 173 if((position + stonePosition).y < this->center_->getStoneSize()/2.0f) //!< If the stone has reached the bottom of the level 174 { 175 return false; 176 } 177 } 178 } 179 return true; 180 181 } 182 183 184 125 185 bool Tetris::isValidStonePosition(TetrisStone* stone, const Vector3& position) 126 186 { 127 187 assert(stone); 128 188 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) 189 // check for collisions with all stones 190 for(std::list<SmartPtr<TetrisStone> >::const_iterator it = this->stones_.begin(); it != this->stones_.end(); ++it) 191 { 192 //Vector3 currentStonePosition = rotateVector((*it)->getPosition(), this->activeBrick_->getRotationCount()); 193 const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone 194 //!< Saves the position of the currentStone 195 196 //filter out cases where the falling stone is already below a steady stone 197 if(position.y < currentStonePosition.y - this->center_->getStoneSize()/2.0f) 133 198 continue; 134 135 const Vector3& currentStonePosition = (*it)->getPosition(); //!< Saves the position of the currentStone136 137 199 if((position.x == currentStonePosition.x) && (position.y < currentStonePosition.y + this->center_->getStoneSize())) 138 200 { 139 this->activeStone_->setPosition(Vector3(this->activeStone_->getPosition().x, currentStonePosition.y+this->center_->getStoneSize(), this->activeStone_->getPosition().z)); 201 float y_offset = static_cast<int>((this->activeBrick_->getPosition().y-currentStonePosition.y+10)/10)*10 + currentStonePosition.y; 202 if(y_offset < 0) //filter out extreme cases (very rare bug) 203 y_offset = 0; 204 this->activeBrick_->setPosition(Vector3(this->activeBrick_->getPosition().x, y_offset, this->activeBrick_->getPosition().z)); 140 205 return false; 141 206 }// This case applies if the stones overlap partially vertically … … 145 210 if(position.y < this->center_->getStoneSize()/2.0f) //!< If the stone has reached the bottom of the level 146 211 { 147 stone->setPosition(Vector3(stone->getPosition().x, this->center_->getStoneSize()/2.0f, stone->getPosition().z)); 212 float yOffset = stone->getPosition().y + this->center_->getStoneSize()/2.0f;//calculate offset 213 if(yOffset < 0) //catch brake-throughs 214 yOffset = 0; 215 this->activeBrick_->setPosition(Vector3(this->activeBrick_->getPosition().x, yOffset, this->activeBrick_->getPosition().z)); 148 216 return false; 149 217 } … … 151 219 return true; 152 220 } 221 /** 222 * @brief This function determines wether a brick touches another brick or the ground. 223 * 224 */ 225 bool Tetris::isValidBrickPosition(TetrisBrick* brick) 226 { 227 assert(brick); 228 229 const Vector3& brickPosition = this->activeBrick_->getPosition(); 230 231 // check all stones in the brick 232 for (unsigned int i = 0; i < brick->getNumberOfStones(); i++ ) 233 { 234 TetrisStone* stone = brick->getStone(i); 235 const Vector3& stonePosition = rotateVector(stone->getPosition(), brick->getRotationCount()); 236 if(! this->isValidStonePosition(stone, brickPosition + stonePosition) ) 237 { 238 // recurse because all stones have to checked again after the brick was re-positioned 239 this->isValidBrickPosition(brick); 240 return false; 241 } 242 } 243 return true; 244 } 245 246 /** 247 @brief 248 A Vector3 is rolled 90 * degrees * amount (anticlockwise rotation) 249 */ 250 Vector3 Tetris::rotateVector(Vector3 position, unsigned int amount) 251 { 252 float temp = 0; 253 for(unsigned int i = 0; i < amount; i++) 254 { 255 temp = position.x; 256 position.x = -position.y; 257 position.y = temp; 258 } 259 return position; 260 } 153 261 154 262 /** … … 160 268 if (this->center_ != NULL) // There needs to be a TetrisCenterpoint, i.e. the area the game takes place. 161 269 { 162 // Create the first stone.163 this->create Stone();270 // Create the first brick. 271 this->createBrick(); 164 272 } 165 273 else // If no centerpoint was specified, an error is thrown and the level is exited. … … 190 298 void Tetris::end() 191 299 { 300 this->activeBrick_->setVelocity(Vector3::ZERO); 301 if(this->activeBrick_ != NULL) 302 { 303 this->player_->stopControl(); 304 } 305 192 306 this->cleanup(); 193 307 … … 225 339 } 226 340 227 /** 228 @brief 229 Starts the first stone. 230 */ 231 void Tetris::startStone(void) 341 342 343 void Tetris::startBrick(void) 232 344 { 233 345 if(this->player_ == NULL) … … 235 347 236 348 unsigned int cameraIndex = 0; 237 if(this->active Stone_ != NULL)349 if(this->activeBrick_ != NULL) 238 350 { 239 351 // Get camera settings 240 cameraIndex = this->active Stone_->getCurrentCameraIndex();352 cameraIndex = this->activeBrick_->getCurrentCameraIndex(); 241 353 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); 354 // destroy old active brick 355 this->activeBrick_->destroy(); 356 } 357 358 // Make the last brick to be created the active brick. 359 this->activeBrick_ = this->futureBrick_; 360 this->futureBrick_ = 0; 361 362 // set its position 363 this->player_->startControl(this->activeBrick_); 267 364 float xPos = (this->center_->getWidth()/2 + ((this->center_->getWidth() % 2)*2-1)/2.0f)*this->center_->getStoneSize(); 268 365 float yPos = (this->center_->getHeight()-0.5f)*this->center_->getStoneSize(); 269 stone->setPosition(xPos, yPos, 0.0f); 270 stone->setGame(this); 271 } 366 this->activeBrick_->setPosition(xPos, yPos, 0.0f); 367 this->activeBrick_->setVelocity(0.0f, -this->center_->getStoneSpeed(), 0.0f); 368 this->activeBrick_->setCameraPosition(cameraIndex); 369 370 // create a new future brick 371 this->createBrick(); 372 373 // check if the new brick is in a valid position, otherwise end the game 374 if (!this->isValidBrickPosition(this->activeBrick_)) 375 this->end(); 376 } 377 378 void Tetris::createBrick(void) //TODO: random rotation offset between 0 and 3 (times 90°) 379 { 380 // create new futureBrick_ 381 this->futureBrick_ = new TetrisBrick(this->center_); 382 383 384 // Apply the stone template to the stone. 385 this->futureBrick_->addTemplate(this->center_->getBrickTemplate()); 386 387 // Attach the brick to the Centerpoint and set the position of the brick to be at the left side. 388 this->center_->attach(this->futureBrick_); 389 float xPos = (this->center_->getWidth()*1.6f + ((this->center_->getWidth() % 2)*2-1)/2.0f)*this->center_->getStoneSize(); 390 float yPos = (this->center_->getHeight()-5.1f)*this->center_->getStoneSize(); 391 this->futureBrick_->setPosition(xPos, yPos, 0.0f); 392 this->futureBrick_->setGame(this); 393 } 394 272 395 273 396 /** … … 282 405 } 283 406 407 /*TetrisCenterpoint* Tetris::getCenterpoint(void) const 408 { 409 return this->center_; 410 }*/ 411 284 412 /** 285 413 @brief Set the TetrisCenterpoint (the playing field). … … 291 419 } 292 420 421 /** 422 @brief Check each row if it is full. Removes all full rows. Update 423 @brief Manages score. 424 */ 425 void Tetris::findFullRows() 426 { 427 unsigned int correctPosition = 0; 428 unsigned int stonesPerRow = 0; 429 for (unsigned int row = 0; row < this->center_->getHeight(); row++) 430 { 431 stonesPerRow = 0; 432 for(std::list<SmartPtr<TetrisStone> >::iterator it = this->stones_.begin(); it != this->stones_.end(); ) 433 { 434 std::list<SmartPtr<TetrisStone> >::iterator it_temp = it++; 435 correctPosition = static_cast<unsigned int>(((*it_temp)->getPosition().y - 5)/this->center_->getStoneSize()); 436 if(correctPosition == row) 437 { 438 stonesPerRow++; 439 if(stonesPerRow == this->center_->getWidth()) 440 { 441 clearRow(row); 442 row--; //the row counter has to be decreased in order to detect multiple rows! 443 this->playerScored(this->player_);// add points 444 //increase the stone's speed 445 this->center_->setStoneSpeed(this->center_->getStoneSpeed()+1.0f); 446 } 447 } 448 } 449 } 450 } 451 452 void Tetris::clearRow(unsigned int row) 453 {// clear the full row 454 for(std::list<SmartPtr<TetrisStone> >::iterator it = this->stones_.begin(); it != this->stones_.end(); ) 455 { 456 if(static_cast<unsigned int>(((*it)->getPosition().y - 5)/this->center_->getStoneSize()) == row) 457 { 458 (*it)->destroy(); 459 this->stones_.erase(it++); 460 } 461 else 462 ++it; 463 } 464 // adjust height of stones above the deleted row //TODO: check if this could be a source of a bug. 465 for(std::list<SmartPtr<TetrisStone> >::iterator it = this->stones_.begin(); it != this->stones_.end(); ++it) 466 { 467 if(static_cast<unsigned int>(((*it)->getPosition().y - 5)/this->center_->getStoneSize()) > row) 468 (*it)->setPosition((*it)->getPosition()-Vector3(0,10,0)); 469 } 470 471 } 472 473 293 474 } -
code/trunk/src/modules/tetris/Tetris.h
r8706 r9348 56 56 public: 57 57 Tetris(BaseObject* creator); //!< Constructor. Registers and initializes the object. 58 virtual ~Tetris(); //!< Destructor. Cleans up, if initialized. 58 virtual ~Tetris(); //!< Destructor. Cleans up, if initialized. 59 59 60 60 virtual void start(void); //!< Starts the Tetris minigame. … … 68 68 69 69 PlayerInfo* getPlayer(void) const; //!< Get the player. 70 WeakPtr<TetrisCenterpoint> getCenterpoint(void) 71 { return this->center_; } 70 72 71 73 bool isValidMove(TetrisStone* stone, const Vector3& position); 74 bool isValidMove(TetrisBrick* brick, const Vector3& position, bool isRotation); 75 Vector3 rotateVector(Vector3 position, unsigned int amount); 72 76 73 77 protected: 74 78 virtual void spawnPlayersIfRequested(); //!< Spawns player. 75 79 80 76 81 private: 77 void start Stone(void); //!< Starts with the first stone.78 void create Stone(void);82 void startBrick(void); 83 void createBrick(void); 79 84 void cleanup(void); //!< Cleans up the Gametype by destroying the ball and the bats. 80 85 bool isValidStonePosition(TetrisStone* stone, const Vector3& position); 81 86 bool isValidBrickPosition(TetrisBrick* brick); 87 void findFullRows(void); 88 void clearRow(unsigned int row); 89 90 82 91 PlayerInfo* player_; 83 92 84 93 WeakPtr<TetrisCenterpoint> center_; //!< The playing field. 85 std:: vector<TetrisStone*> stones_; //!< A list of all stones in play.86 std::vector< std::vector<bool> > grid_;87 TetrisStone* activeStone_;88 94 std::list<SmartPtr<TetrisStone> > stones_; //!< A list of all stones in play. 95 WeakPtr<TetrisBrick> activeBrick_; 96 WeakPtr<TetrisBrick> futureBrick_; 97 89 98 Timer starttimer_; //!< A timer to delay the start of the game. 90 99 }; -
code/trunk/src/modules/tetris/TetrisCenterpoint.cc
r8706 r9348 30 30 @file TetrisCenterpoint.cc 31 31 @brief Implementation of the TetrisCenterpoint class. 32 @ingroup Tetris 32 33 */ 33 34 … … 55 56 this->stoneSize_ = 10.0f; 56 57 this->stoneTemplate_ = ""; 58 this->brickTemplate_ = ""; 57 59 this->stoneSpeed_ = 20.0f; 58 60 … … 69 71 70 72 XMLPortParam(TetrisCenterpoint, "width", setWidth, getWidth, xmlelement, mode); // die Breite 71 XMLPortParam(TetrisCenterpoint, "height", setHeight, setWidth, xmlelement, mode); // die Grösse73 XMLPortParam(TetrisCenterpoint, "height", setHeight, getHeight, xmlelement, mode); // die Grösse //was sollte das mit setWidth?? 72 74 XMLPortParam(TetrisCenterpoint, "stoneSize", setStoneSize, getStoneSize, xmlelement, mode); 73 75 XMLPortParam(TetrisCenterpoint, "stoneTemplate", setStoneTemplate, getStoneTemplate, xmlelement, mode); 76 XMLPortParam(TetrisCenterpoint, "brickTemplate", setBrickTemplate, getBrickTemplate, xmlelement, mode); 74 77 XMLPortParam(TetrisCenterpoint, "stoneSpeed", setStoneSpeed, getStoneSpeed, xmlelement, mode); 75 78 } -
code/trunk/src/modules/tetris/TetrisCenterpoint.h
r8706 r9348 45 45 46 46 namespace orxonox 47 { 47 {//idea: add 2 triggers to the centerpoint (one to determine when a box would go above the centerpoint; 48 //the other to find out when the lowest row is filled totally) 48 49 49 50 /** … … 118 119 119 120 /** 121 @brief Set the template for the bricks. 122 @param template The template name to be applied to each brick. 123 */ 124 void setBrickTemplate(const std::string& templateName) 125 { this->brickTemplate_ = templateName; } 126 /** 127 @brief Get the template for the bricks. 128 @return Returns the template name to be applied to each brick. 129 */ 130 const std::string& getBrickTemplate(void) const 131 { return this->brickTemplate_; } 132 133 /** 120 134 @brief Set the speed of the stones. 121 135 @param speed The speed to be set. … … 137 151 float stoneSize_; 138 152 std::string stoneTemplate_; 153 std::string brickTemplate_; 139 154 float stoneSpeed_; 140 155 -
code/trunk/src/modules/tetris/TetrisPrereqs.h
r8706 r9348 68 68 class TetrisCenterpoint; 69 69 class TetrisStone; 70 class TetrisBrick; 71 class TetrisScore; 70 72 } 71 73 -
code/trunk/src/modules/tetris/TetrisStone.cc
r8706 r9348 30 30 @file TetrisStone.cc 31 31 @brief Implementation of the TetrisStone class. 32 @ingroup Tetris 32 33 */ 33 34 … … 47 48 Constructor. Registers and initializes the object. 48 49 */ 49 TetrisStone::TetrisStone(BaseObject* creator) : ControllableEntity(creator)50 TetrisStone::TetrisStone(BaseObject* creator) : MovableEntity(creator) 50 51 { 51 52 RegisterObject(TetrisStone); 52 53 53 54 this->size_ = 10.0f; 54 55 this->delay_ = false; 55 56 this->delayTimer_.setTimer(0.2f, false, createExecutor(createFunctor(&TetrisStone::enableMovement, this))); 57 this->lockRotation_ = false; 58 56 59 } 57 60 … … 64 67 void TetrisStone::moveFrontBack(const Vector2& value) 65 68 { 66 if(value.x < 0) 69 if(value.x < 0) //speedup on key down 67 70 { 68 71 this->setVelocity(this->getVelocity()*1.1); 72 } 73 else if(!this->lockRotation_) //rotate when key up is pressed 74 { 75 this->lockRotation_ = true; // multiple calls of this function have to be filtered out. 76 this->rotationTimer_.setTimer(0.1f, false, createExecutor(createFunctor(&TetrisStone::unlockRotation, this))); 77 Quaternion q(Degree(90), Vector3::UNIT_Z); 78 this->setOrientation(this->getOrientation()*q); //rotation: roll 90° 79 69 80 } 70 81 } -
code/trunk/src/modules/tetris/TetrisStone.h
r8706 r9348 38 38 #include "tetris/TetrisPrereqs.h" 39 39 40 #include "worldentities/ ControllableEntity.h"40 #include "worldentities/MovableEntity.h" 41 41 #include "tools/Timer.h" 42 42 … … 51 51 @ingroup Tetris 52 52 */ 53 class _TetrisExport TetrisStone : public ControllableEntity53 class _TetrisExport TetrisStone : public MovableEntity 54 54 { 55 55 public: … … 81 81 void enableMovement(void) 82 82 { this->delay_ = false; } 83 83 void unlockRotation(void) 84 { this->lockRotation_ = false; } 85 84 86 float size_; //!< The dimensions a stone has in the game world. 85 87 bool delay_; 88 bool lockRotation_; 86 89 Timer delayTimer_; 90 Timer rotationTimer_; ///!< This timer is used to filter out multiple rotation inputs. 87 91 88 92 Tetris* tetris_;
Note: See TracChangeset
for help on using the changeset viewer.