/* * Performs actions that should happen continuously in the background on this Screen. * * Returns: A pointer to the Screen object control should shift to after this function exits, or * NULL if control should not shift to another Screen object */ void GameScreen::doBackground() throw (QUIT, NEW_SCREEN) { // If we previously retained this and returned, stop saying to retain or we'll leak if (retain) { retain = false; } applyLayout(); draw(); clock_t curTime = clock(); /* * If we aren't initialized, initialize. We didn't initialize earlier because we don't want the * clock to start before we need it to. */ if (prevTime <= 0) { prevTime += curTime; } if (curTime > prevTime+tick) { if (field.canShiftDown(currentTetromino)) { doShiftDown(); } else if (!doJoinAndRespawn()) { doGameOver(); } prevTime = curTime; } }
/* * Joins the currentTetromino with the field and spawns a new one. * * Returns: True if a Tetromino could be successfully spawned, false otherwise */ bool GameScreen::doJoinAndRespawn() { bool couldSpawn; TetrominoBase* tmp = currentTetromino; currentTetromino = NULL; shadow->erase(); field.mergeAndDelete(tmp, scoreCallback); TetrominoShape shape = static_cast<TetrominoShape>(rand()%7); int blockType = rand(); currentTetromino = field.spawnNewTetromino(nextTetromino); if (blockType < (RAND_MAX/50)) { // 1/50 nextTetromino = new Tetromino<ExplodingBlock>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } else if (blockType < 2*(RAND_MAX/50)) { // 1/50 nextTetromino = new Tetromino<LaserBlock>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } else if (blockType < 2*(RAND_MAX/50)+(RAND_MAX/69)) { // 1/69 nextTetromino = new Tetromino<LeftMagnetBlock>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } else if (blockType < 2*(RAND_MAX/50)+2*(RAND_MAX/69)) { // 1/69 nextTetromino = new Tetromino<RightMagnetBlock>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } else if (blockType < 2*(RAND_MAX/50)+3*(RAND_MAX/69)) { // 1/69 nextTetromino = new Tetromino<GravityBlock>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } else { // ~11/12 nextTetromino = new Tetromino<Block>(0, 0, field.getBlockSize(), field.getPadding(), shape, upNextbg.getForeground()); } couldSpawn = currentTetromino; // If currentTetromino is NULL, couldSpawn becomes false if (couldSpawn) { delete shadow; shadow = new Tetromino<GhostBlock>(currentTetromino->getLocationX(), currentTetromino->getLocationY(), currentTetromino->getBlockSize(), currentTetromino->getPadding(), currentTetromino->getShape(), field.getForeground()); // Have the shadow fall while (field.canShiftDown(shadow)) { shadow->shiftDown(); } applyLayout(); draw(); // We may have waited while merging, reset the tick prevTime = clock(); } return couldSpawn; }
UIElement::UIElement(Core::Engine &engine, UIElement *parent, unsigned long id, std::string state, glm::vec2 pos, glm::vec2 size): engine_(engine), parent_(parent),localPos_(pos), allowClick_(false), bounds_{pos.x, pos.y, size.x, size.y}, minSize_(size),id_(id), state_(state){ if(parent_) { setPos(parent_->pos().x + pos.x, parent_->pos().y + pos.y); } hoveredProperty_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,false)); leftDown_ = std::unique_ptr<Property<unsigned long>>(new Property<unsigned long>(engine,0)); rightDown_ = std::unique_ptr<Property<unsigned long>>(new Property<unsigned long>(engine,0)); midDown_ = std::unique_ptr<Property<unsigned long>>(new Property<unsigned long>(engine,0)); leftPressed_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,false)); rightPressed_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,false)); midPressed_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,false)); entered_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,false)); backgroundColorProperty_ = std::unique_ptr<Property<glm::vec4>>(new Property<glm::vec4>(engine,glm::vec4(0.f))); layoutProperty_ = std::unique_ptr<Property<int>>(new Property<int>(engine,LAYOUT_ABSOLUT)); layoutProperty_->addListener([this](){this->applyLayout();}); depthProperty_ = std::unique_ptr<Property<float>>(new Property<float>(engine,41.f)); marginProperty_ = std::unique_ptr<Property<glm::vec2>>(new Property<glm::vec2>(engine,glm::vec2(0.f))); marginProperty_->addListener([this](){this->resize();this->applyLayout();}); visibleProperty_ = std::unique_ptr<Property<bool>>(new Property<bool>(engine,true)); visibleProperty_->addListener([this](){ auto mousePos = engine_.inputSystem().mousePos(); if(bounds_.intersects(mousePos) && !*visibleProperty_) engine_.inputSystem().setMouseInUI(false); }); depthProperty_->addListener([this](){ for(auto &elem : children_) { elem.second->setDepth(*depthProperty_); } }); resize(); applyLayout(); }