void World::moveBullets() { for (int q = 0; q < _bulletList.size(); q++) { if (_bulletList[q]->getKillAnimation() != 0) { if (_bulletList[q]->getKillAnimation() == 10) { delete _bulletList[q]; _bulletList.remove(q); } else { _bulletList[q]->animation(); } } else { QPoint pos = _bulletList[q]->getPos(); bool withTank; void *status = testCollision(_bulletList[q]->getSpeed(), _bulletList[q], false, &withTank); if (status == nullptr) { switch (_bulletList[q]->getAngle()) { case 0: { _bulletList[q]->setPos(QPoint(pos.x(), pos.y() - _bulletList[q]->getSpeed())); break; } case 1: { _bulletList[q]->setPos(QPoint(pos.x() + _bulletList[q]->getSpeed(), pos.y())); break; } case 2: { _bulletList[q]->setPos(QPoint(pos.x(), pos.y() + _bulletList[q]->getSpeed())); break; } case 3: { _bulletList[q]->setPos(QPoint(pos.x() - _bulletList[q]->getSpeed(), pos.y())); break; } } } else { if (withTank) { Tank *tank = ((Tank*)status); tank->hit(); if (tank->getHp() == 0) { tank->setSize(0); } } else { Wall *wall = ((Wall*)status); wall->hit(); if (wall->getHp() == 0) { for (int i = 0; i < _wallList.size(); i++) { if (_wallList[i] == wall) { if (_wallList[i] == _playerBase) { _playerBase = nullptr; } delete _wallList[i]; _wallList.remove(i); } } } } _bulletList[q]->animation(); } } } }
int SnakeAI::calcBoundedCount( Vec2i const& pos , DirType dir ) { Vec2i testPos; if ( !mScene.getLevel().getMapPos( pos , dir , testPos ) ) return 0; if ( sCheckCount == sCheckMap.getData( testPos.x , testPos.y ) ) return 0; sCheckMap.getData( testPos.x , testPos.y ) = sCheckCount; if ( testCollision( testPos ) ) return 0; int count = 1; if ( dir != DIR_WEST ) count += calcBoundedCount( testPos , DIR_EAST ); if ( dir != DIR_EAST ) count += calcBoundedCount( testPos , DIR_WEST ); if ( dir != DIR_SOUTH ) count += calcBoundedCount( testPos , DIR_NORTH ); if ( dir != DIR_NORTH ) count += calcBoundedCount( testPos , DIR_SOUTH ); return count; }
void BuildingInApparition::check( ) { if( !testCollision() ) { root->addChild(buildingCon); delete this; } }
bool SnakeAI::testCollision( Vec2i const& pos , DirType dir , Vec2i& resultPos ) { Level& level = mScene.getLevel(); if ( level.getMapPos( pos , dir , resultPos ) ) return true; return testCollision( resultPos ); }
void BuildingInApparition::update( double newTime ) { if( !testCollision() ) { root->addChild(buildingCon); delete this; } }
bool standardAsteroid::checkCollision(SDL_Rect rect) { if (isActive == true) { return testCollision(rect, base.movement.Gdstrect); } else { return false; } }
bool Rect::testCollisionInContext(rect_store* context, prec_t offset_x, prec_t offset_y) { for (auto iter : *context) { if (&*iter == this) continue; if (testCollision(&*iter, offset_x, offset_y)) return true; } return false; }
Rect* Rect::findCollisionInContext(rect_store* context, prec_t offset_x, prec_t offset_y) { for (auto iter : *context) { if (&*iter == this) continue; if (testCollision(&*iter, offset_x, offset_y)) return &*iter; } return nullptr; }
void Game::gameMain() { Ball ball{ windowWidth, windowHeight }; Paddle paddle{ windowWidth, windowHeight }; std::vector<Brick> bricks; for (int iX = 0; iX < countBlocksX; ++iX) for (int iY = 0; iY < countBlocksY; ++iY) bricks.emplace_back((iX + 1) * (blockWidth + 3) + 22, (iY + 2) * (blockHeight + 3)); sf::RenderWindow window{ { windowWidth, windowHeight }, "Arkanoid Clone" }; window.setFramerateLimit(60); while (true) { window.clear(sf::Color::Black); if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) break; if (!ball.update()) return; paddle.update(); testCollision(paddle, ball); for (auto& brick : bricks) testCollision(brick, ball); bricks.erase(remove_if(begin(bricks), end(bricks), [](const Brick& mBrick) { return mBrick.destroyed; }), end(bricks)); window.draw(ball.shape); window.draw(paddle.shape); for (auto& brick : bricks) window.draw(brick.shape); window.display(); } return; }
void MovableCollisionModifier::ApplyModifierStrategy(Solid* solid) { // Initialize points to be in front of all planes CudaMemset(pIntersect, true, sizeof(bool)*solid->vertexpool->size); // Test intersection with bounding volume testCollision(solid, bVolume, pIntersect); // Call constraint function constrainIntersectingPoints(solid, pIntersect); // Call constraint function moveIntersectingNodeToSurface(solid, bVolume, pIntersect); }
//对生成的道具列表进行更新管理 void ItemManager::update(float dt, cocos2d::Node *render_node, IDisplayObject *pCollisionTarget) { mDistanceVar += dt * COURCESPEED; updateItemPosition(dt); testCollision(render_node,pCollisionTarget); if (mDistanceVar >= ITEMDISTANCE) { mDistanceVar = mDistanceVar - ITEMDISTANCE; generateItem(render_node); } }
void standardAsteroid::initialize(int asteroidSize) { int dim; size = asteroidSize; if (size == asteroid_classes_::LARGE) dim = (rand() % 50) + 400; if (size == asteroid_classes_::MEDIUM) dim = (rand() % 50) + 200; if (size == asteroid_classes_::SMALL) dim = (rand() % 50) + 50; base.setup(0, 0, dim, dim, asteroidSpritesheet_texture); dim = rand() % 3 * 640; base.defFrame(dim, 0, 640, 640, ¤tSRCRECT.srcrect); base.rotate(rand() % 360); while (testCollision(base.movement.Gdstrect, asteroid_classes_::arcadeMode_domain.dstrect) == false || testCollision(base.movement.Gdstrect, mainCamera.rect) == true) { base.setXY((rand() % asteroid_classes_::arcadeMode_domain.dstrect.w) - 200, (rand() % asteroid_classes_::arcadeMode_domain.dstrect.h) - 200); } //std::cout << base.movement.Gdstrect.x << " " << base.movement.Gdstrect.y << std::endl; while (base.movement.deltaX == 0) { base.movement.deltaX = (rand() % 20) - 10; } while (base.movement.deltaY == 0) { base.movement.deltaY = (rand() % 20) - 10; } while (base.movement.deltaAngle == 0) { base.movement.deltaAngle = rand() % 3 - 1; } base.rotateRate = (rand() % 59) + 1; /*If the asteroid size is large, it gets a slower rotation speed*/ if (size == asteroid_classes_::LARGE) base.rotateRate = (rand() % 29) + 1; state = DEAD; base.rotateTimer.start(); isActive = true; isAvailable = true; }
void moves(Circle circle[], int length, int index) { int direction[] = {1, -1}; Circle c; int i; GLfloat tmp; c = circle[index]; // the current circle will have to avoid all previous considered circles for (i = 0; i < index; i++) { // they collide if (testCollision(c, circle[i]) == 1) { // 2 circles will travel in opposite directions, post-collision c.xVector = (c.x - circle[i].x) / RADIUS * (rand() % DISTANCE); c.yVector = (c.y - circle[i].y) / RADIUS * (rand() % DISTANCE); circle[i].xVector = (-1.0) * c.xVector; circle[i].yVector = (-1.0) * c.yVector; } } // the circle won't move along horizontal line while (c.xVector == 0.0) { c.xVector = (rand() % DISTANCE) * direction[rand() % 2]; } // the circle won't move along vertical line while (c.yVector == 0.0) { c.yVector = (rand() % DISTANCE) * direction[rand() % 2]; } // detect and move away from edges if (c.y + RADIUS > SCREEN_HEIGHT || c.y - RADIUS < 0) { c.yVector *= (-1); } if (c.x + RADIUS > SCREEN_WIDTH || c.x - RADIUS < 0) { c.xVector *= (-1); } // update central position c.x += c.xVector; c.y += c.yVector; // set the new altered circle to the current consider circle circle[index] = c; }
void World::updateTanks() { for (int q = 0; q < _tankList.size(); q++) { _tankList[q]->reloading(); if (_tankList[q]->getHp() == 0) { if (_tankList[q]->getKillAnimation() == 15) { if (_tankList[q] == _playerTank) { _playerTank = nullptr; } delete _tankList[q]; _tankList.remove(q); } else { _tankList[q]->animation(); } } else if (_tankList[q]->isMove()) { QPoint pos = _tankList[q]->getPos(); void *status = testCollision(_tankList[q]->getSpeed(), _tankList[q]); if (status == nullptr) { switch (_tankList[q]->getAngle()) { case 0: { _tankList[q]->setPos(QPoint(pos.x(), pos.y() - _tankList[q]->getSpeed())); break; } case 1: { _tankList[q]->setPos(QPoint(pos.x() + _tankList[q]->getSpeed(), pos.y())); break; } case 2: { _tankList[q]->setPos(QPoint(pos.x(), pos.y() + _tankList[q]->getSpeed())); break; } case 3: { _tankList[q]->setPos(QPoint(pos.x() - _tankList[q]->getSpeed(), pos.y())); break; } } } else { _tankList[q]->move(false); } } } }
int main () { Ball ball{windowWidth / 2, windowHeight /2 }; Paddle paddle {windowWidth / 2, windowHeight - 50}; std::vector<Brick> bricks; for(int iX{0}; iX < countBlocksX; ++iX) for(int iY{0}; iY < countBlocksY; ++iY) bricks.emplace_back((iX + 1) * (blockWidth + 3) +22, (iY + 2) * (blockHeight +3)); // { // Equivalente a emplace_back : C++11 // Brick umBrick{(iX + 1) * (blockWidth + 3) +22, // (iY + 2) * (blockHeight +3)}; // bricks.push_back(umBrick); // } sf::RenderWindow window({windowWidth,windowHeight}, "Arkanoid - 5"); window.setFramerateLimit(60); // Loop do jogo while (window.isOpen()) { // Monitora os eventos e reage de acordo sf::Event event; while(window.pollEvent(event)) { if(event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Escape)) { window.close(); } } // Limpa a tela window.clear(sf::Color::Black); // Renderiza os objetos na tela ball.update(); paddle.update(); // testa colisão a cada ciclo testCollision(paddle, ball); // remove blocos colididos bricks.erase( remove_if( begin(bricks), end(bricks), [](const Brick& mBrick){ return mBrick.destroyed; }), end(bricks) ); // testa colisões entre bola e blocos for(auto& brick : bricks) testCollision(brick,ball); window.draw(ball.shape); window.draw(paddle.shape); // for(int i{0}; i < bricks.size(); ++i) // Equivalente for(auto& brick : bricks) // C++11 window.draw(brick.shape); // Exibe os conteúdos da tela window.display(); } return EXIT_SUCCESS; }
TEST(Camera, frustrumCreation) { RendererImplementationMock renderer; Camera camera( "camera", renderer, Camera::PT_PERSPECTIVE ); camera.setNearPlaneDimensions(10, 10); camera.setClippingPlanes(10, 100); camera.setFOV(90); Frustum frustrum; camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, -2), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 8), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 102), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 100), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 8), 2))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 10), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-20, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(20, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, -20, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 20, 50), 1))); // camera rotated Quaternion rotY; rotY.setAxisAngle( Quad_0100, FastFloat::fromFloat( DEG2RAD( 90 ) ) ); camera.accessLocalMtx().setRotation( rotY ); camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(10, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(100, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(50, 0, 0), 1))); // camera rotated rotY.setAxisAngle( Quad_0100, FastFloat::fromFloat( DEG2RAD( -90 ) ) ); camera.accessLocalMtx().setRotation( rotY ); camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-10, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-100, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-50, 0, 0), 1))); }
void Mob::tick() { BaseClass::tick(); float MaxMobViewDistance = 1000; Player* player = getLevel()->getPlayer(); Vec2f offset = player->getPos() - getPos(); if ( offset.length2() < MaxMobViewDistance * MaxMobViewDistance && !getLevel()->getColManager().rayTerrainTest( getPos() , player->getPos() , COL_VIEW ) ) { mTarget = player; mTimeCantView = 0; mPosLastView = mTarget->getPos(); } else { mTimeCantView += TICK_TIME; if ( mTimeCantView > 3 ) mTarget = NULL; } akceleracija=1; if ( mTarget ) { Vec2f dir; dir = mPosLastView - getPos(); Math::normalize( dir ); rotation = atan2(dir.y,dir.x) + Math::toRad( 90 ); Vec2f monent; float angle = rotation - Math::toRad( 90 ); monent.x = cos( angle ) * akceleracija; monent.y = sin( angle ) * akceleracija; Vec2f off = ( mSpeed * TICK_TIME ) * dir; Vec2f offset = Vec2f( 0 , 0 ); offset.y += off.y; if( testCollision( offset ) ) offset.y = 0; offset.x += off.x; if( testCollision( offset ) ) offset.x = 0; mPos += offset; } if( punjenje < 100 ) { punjenje += brzinaPunjenja * TICK_TIME; } if( mHP<=0 ) { destroy(); } akceleracija=0; }
DirType SnakeAI::decideMoveDir() { Level& level = mScene.getLevel(); Snake::Body const& head = mInfo.snake->getHead(); DirType frontDir = head.dir; DirType leftDir = ( head.dir + 3 ) % 4; DirType rightDir = ( head.dir + 1 ) % 4; Vec2i frontPos; if ( testCollision( head.pos , frontDir , frontPos ) ) { Vec2i pos; if ( !testCollision( head.pos , leftDir , pos ) ) return leftDir; if ( !testCollision( head.pos , rightDir , pos ) ) return rightDir; } else { return frontDir; } int count[3]; unsigned testCount[3]; incTestCount(); count[0] = calcBoundedCount( head.pos , frontDir ); testCount[0] = sCheckCount; Vec2i pos; unsigned const mask = Level::eTERRAIN_MASK | Level::eTERRAIN_MASK; if ( !testCollision( head.pos , leftDir , pos ) ) { unsigned c = sCheckMap.getData( pos.x , pos.y ); if ( c == testCount[0] ) { count[1] = count[0]; } else { incTestCount(); count[1] = calcBoundedCount( head.pos , leftDir ); } testCount[1] = sCheckCount; } else { count[1] = 0; testCount[1] = 0; } if ( !testCollision( head.pos , rightDir , pos ) ) { unsigned c = sCheckMap.getData( pos.x , pos.y ); if ( c == testCount[0] ) { count[2] = count[0]; } else if ( c == testCount[1] ) { count[2] = count[1]; } else { incTestCount(); count[2] = calcBoundedCount( head.pos , leftDir ); } testCount[2] = sCheckCount; } else { count[2] = 0; testCount[2] = 0; } return 0; }
int Game::gameLoop() { Object ScoreDisplay(0,0); int displayScore = 0; int moveEnemy = 0; int movePlayer = 0; int oatpoints = oatWorth; int moveScoreUp = 0; int nextRandomMove = 0; int lastScore = 0; int nextLevel = 0; int rMove = 0; bool done = false; while(!done) { ticks = GetTickCount(); render(); if (nextRandomMove==100) { srand(ticks); for(int i = 2; i < objects; object[i++].setDirection(0)); nextRandomMove=0; } if (nextLevel > 1000) { levelUp(); nextLevel -= 1000; } // input and output of user and enemies if (movePlayer >= playerSlowD) { object[0].getInput(); movePlayer = 0; } if (moveEnemy >= enemySlowD) { for (int i = 2; i < objects; i++) { if(!tooClose(object[0], object[i])) object[i].randMove(rand()%5); } moveEnemy = 0; } for (int i = 0; i < objects; testCollision(object[i++])); for (int i = 2; i < objects && !done; done = contact(object[0],object[i++])); // check if player ate oat if (contact(object[0],object[1])) { ScoreDisplay.x() = object[1].x(); ScoreDisplay.y() = object[1].y(); randLocation(object[1]); score+=oatpoints; nextLevel += oatpoints; if (oatWorth > MAXOATWORTH) console.alarm(); lastScore = oatpoints; oatpoints = oatWorth; } // display score of oat just eaten if (lastScore > 0 && moveScoreUp < showScorexln) { if (displayScore < showScore1ln) { console.setPos(ScoreDisplay.y(), ScoreDisplay.x()); std::cout << lastScore; displayScore++; } else { ScoreDisplay.x()++; ScoreDisplay.y()--; displayScore = 0; moveScoreUp++; } } else { moveScoreUp = 0; lastScore = 0; } // change counter values if (oatpoints > 0) oatpoints--; else { randLocation(object[1]); oatpoints = oatWorth; } moveEnemy++; movePlayer++; nextRandomMove++; // regulate fps if (1000/FPS > GetTickCount()-ticks) { Sleep(1000/FPS-(GetTickCount()-ticks)); } } return score; }
int main() { std::cout << appName << " Version " << Arkanoid11_VERSION_MAJOR << "." << Arkanoid11_VERSION_MINOR << std::endl; // setup game objects Ball ball{windowWidth / 2, windowHeight / 2}; Paddle paddle{windowWidth / 2, windowHeight - paddleHeight * 2}; std::vector<Brick> bricks; bricks.reserve(countBlocksX * countBlocksY); for(int ix{0}; ix < countBlocksX; ++ix) for(int iy{0}; iy < countBlocksY; ++iy) bricks.emplace_back( (ix + 1) * (brickWidth + 4) + 20, (iy + 1) * (brickHeight + 4), brickColors[iy / 2]); sf::VideoMode vmode(windowWidth, windowHeight); sf::RenderWindow window(vmode, appName); window.setFramerateLimit(60); while(window.isOpen()) { window.clear(); if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) window.close(); sf::Event event; while(window.pollEvent(event)) { if(event.type == sf::Event::Closed) window.close(); } // update ball.update(); paddle.update(); testCollision(paddle, ball); for(auto& brick : bricks) testCollision(brick, ball); // remove all destroyed bricks bricks.erase(std::remove_if(std::begin(bricks), std::end(bricks), [](const Brick& brick) { return brick.destroyed; }), std::end(bricks)); // winning conditions bool won = std::all_of(std::begin(bricks), std::end(bricks), [](const Brick& brick) { return brick.destroyed; }); if(won) window.close(); // Draw window.draw(paddle.shape); window.draw(ball.shape); for(auto& brick : bricks) window.draw(brick.shape); window.display(); } return 0; }
void SoftwareRasterizer::clipTriangle(const Vec4* inVerts, Vec4* outVerts, U& outVertCount) const { ANKI_ASSERT(inVerts && outVerts); const Plane& plane = m_planesL[FrustumPlaneType::NEAR]; F32 clipZ = -plane.getOffset() - EPSILON; ANKI_ASSERT(clipZ < 0.0); Array<Bool, 3> vertInside; U vertInsideCount = 0; for(U i = 0; i < 3; ++i) { vertInside[i] = inVerts[i].z() < clipZ; vertInsideCount += (vertInside[i]) ? 1 : 0; } switch(vertInsideCount) { case 0: // All out outVertCount = 0; break; case 3: // All in outVertCount = 3; outVerts[0] = inVerts[0]; outVerts[1] = inVerts[1]; outVerts[2] = inVerts[2]; break; case 1: { U i, next, prev; if(vertInside[0]) { i = 0; next = 1; prev = 2; } else if(vertInside[1]) { i = 1; next = 2; prev = 0; } else { i = 2; next = 0; prev = 1; } // Find first intersection Vec4 rayOrigin = inVerts[i].xyz0(); Vec4 rayDir = (inVerts[next].xyz0() - rayOrigin).getNormalized(); Vec4 intersection0; Bool intersects = testCollision(plane, Ray(rayOrigin, rayDir), intersection0); (void)intersects; ANKI_ASSERT(intersects); // Find second intersection rayDir = (inVerts[prev].xyz0() - rayOrigin).getNormalized(); Vec4 intersection1; intersects = testCollision(plane, Ray(rayOrigin, rayDir), intersection1); (void)intersects; ANKI_ASSERT(intersects); // Finalize outVerts[0] = inVerts[i]; outVerts[1] = intersection0.xyz1(); outVerts[2] = intersection1.xyz1(); outVertCount = 3; break; } case 2: { U in0, in1, out; if(vertInside[0] && vertInside[1]) { in0 = 0; in1 = 1; out = 2; } else if(vertInside[1] && vertInside[2]) { in0 = 1; in1 = 2; out = 0; } else { ANKI_ASSERT(vertInside[2] && vertInside[0]); in0 = 2; in1 = 0; out = 1; } // Find first intersection Vec4 rayOrigin = inVerts[in1].xyz0(); Vec4 rayDir = (inVerts[out].xyz0() - rayOrigin).getNormalized(); Vec4 intersection0; Bool intersects = testCollision(plane, Ray(rayOrigin, rayDir), intersection0); (void)intersects; ANKI_ASSERT(intersects); // Find second intersection rayOrigin = inVerts[in0].xyz0(); rayDir = (inVerts[out].xyz0() - rayOrigin).getNormalized(); Vec4 intersection1; intersects = testCollision(plane, Ray(rayOrigin, rayDir), intersection1); (void)intersects; ANKI_ASSERT(intersects); // Two triangles outVerts[0] = inVerts[in1]; outVerts[1] = intersection0; outVerts[2] = intersection1; outVerts[3] = intersection1; outVerts[4] = inVerts[in0]; outVerts[5] = inVerts[in1]; outVertCount = 6; break; } } }
void World::onUpdate() { screenCenter = screen.getPosition(); const je::Input input = getGame().getInput(); if (input.isKeyHeld(sf::Keyboard::Key::Left)) { screenCenter.x += -10; } if (input.isKeyHeld(sf::Keyboard::Key::Right)) { screenCenter.x += 10; } if (input.isKeyHeld(sf::Keyboard::Key::Up)) { screenCenter.y += -10; } if (input.isKeyHeld(sf::Keyboard::Key::Down)) { screenCenter.y += 10; } if (input.isButtonPressed(sf::Mouse::Button::Right)) { switch (currentlySelectedPower) { case Power::Rain: { addEntity(new Rain(this, sf::Vector2f(getCursorPos().x, 0.f))); } break; case Power::Lightning: { // why the hell do I have to multiply getWidth() by 2?! const sf::Vector2f start(je::randomf(getWidth() * 2), 0.f); mouseClickPoint = this->getCursorPos(); const sf::Vector2f end = mouseClickPoint; addEntity(new LightningBolt(this, start, end)); } break; } } else if (input.isButtonReleased(sf::Mouse::Button::Left)) { if (input.isKeyHeld(sf::Keyboard::Key::A)) light->shine(mouseClickPoint, getCursorPos()); } if (input.isKeyPressed(sf::Keyboard::Key::Q)) { if (currentlySelectedPower == Power::Rain) { currentlySelectedPower = Power::Lightning; } else if (currentlySelectedPower == Power::Lightning) { currentlySelectedPower = Power::Rain; } } if (input.isKeyPressed(sf::Keyboard::Key::E)) { if (currentlySelectedPower == Power::Rain) { currentlySelectedPower = Power::Lightning; } else if (currentlySelectedPower == Power::Lightning) { currentlySelectedPower = Power::Rain; } } // restart if (input.isKeyPressed(sf::Keyboard::Key::R)) { getGame().setLevel(new World(&getGame())); } screen.update(screenCenter); // check for if you achieved some things int minBuildingX = getWidth(); int maxBuildingX = 0; std::map<Building::Type, int> buildingCount; for (const je::Entity *entity : entities["Building"]) { const Building& building = *static_cast<const Building*>(entity); ++buildingCount[building.getBuildingType()]; if (building.getBuildingType() != Building::Type::Bonfire) { const int minX = building.getPos().x - building.getMask().getWidth(); if (minX < minBuildingX) { minBuildingX = minX; } const int maxX = building.getPos().x + building.getMask().getWidth(); if (maxX > maxBuildingX) { maxBuildingX = maxX; } } } // spawn initial house if (entities["Building"].empty()) { if (tree->getTrunk()->getMask().getHeight() > 32) { addEntity(new Building(this, sf::Vector2f(getWidth() / 2.f - 128 + je::randomf(256), groundLevel), Building::Type::BasicHouse)); } else { tree->grow(0.5f); } } const int gnomeCount = entities["Gnome"].size(); if (gnomeCount >= 3 && buildingCount[Building::Type::Bonfire] < gnomeCount / 9) { int count = 0; int x; bool bonfireHere = false; do { x = je::random(getWidth()); ++count; Building *b = static_cast<Building*>(testCollision(sf::Rect<int>(x, groundLevel - 32, 32, 32), "Building")); bonfireHere = b && b->getBuildingType() == Building::Type::Bonfire; } while (count < 32 && bonfireHere); if (count < 32) { addEntity(new Building(this, sf::Vector2f(x, groundLevel), Building::Type::Bonfire)); } } else if (gnomeCount >= 15 && buildingCount[Building::Type::Church] < gnomeCount / 17) { const int variance = je::random(10) - 5; const int buildingX = minBuildingX - 32 < 0 ? maxBuildingX + 32 : maxBuildingX > getWidth() + 32 ? minBuildingX - 32 : je::choose({minBuildingX - 32, maxBuildingX + 32}); addEntity(new Building(this, sf::Vector2f(buildingX + variance, groundLevel), Building::Type::Church)); } else if (buildingCount[Building::Type::BasicHouse] < gnomeCount / 7) { const int variance = je::random(8) - 4; const int buildingX = minBuildingX < 0 ? maxBuildingX : (maxBuildingX > getWidth() ? minBuildingX: je::choose({minBuildingX, maxBuildingX})); addEntity(new Building(this, sf::Vector2f(buildingX + variance, groundLevel), Building::Type::BasicHouse)); } }
int GameLoop::runLevel(SDL_Surface *screen, char *levelfile, int levelnb, int pnb) { totPlayers = pnb; level = new Level("data/levels", levelnb, screen); total_levels = level->totalLevels(); player[0] = new Player("data/smalltux1.bmp", level->playerPos(X,0), level->playerPos(Y,0), RIGHT, 4, 3); if(totPlayers == TWOPLAYER) player[1] = new Player("data/smalltux2.bmp", level->playerPos(X,1), level->playerPos(Y,1), LEFT, 4, 3); totEnemies = level->totEnemies(); // grab a random image of the enemy srand(SDL_GetTicks()); int enemynb = (rand()%3)+1; // char str[26]; sprintf(str, "data/enemy%d.bmp", enemynb); for(int i = 0; i < level->totEnemies(); i++) enemy[i] = new Enemy(str, level->enemiePos(X, i), level->enemiePos(Y, i), LEFT, 2, 3); for(int i = 0; i < MAXBOBBLES; i++) // update pos, based on the keys bobble[i] = new Bobble("data/bubble.bmp", 0, 0, 0, 2, 1); level->drawArea(screen, 0, 0, SCREENWIDTH, SCREENHEIGHT); float f_diffTicks; int i_lastTick = SDL_GetTicks(); gamedone = 0; while(gamedone == 0) { /* key events */ keyEvents(); // send keys to players f_diffTicks = SDL_GetTicks() - i_lastTick; f_diffTicks /= NORMALDELAY; i_lastTick = SDL_GetTicks(); /* updating moviments */ for(int i = 0; i < totPlayers; i++) // update pos, based on the keys player[i]->update(f_diffTicks); for(int i = 0; i < totEnemies; i++) // update pos, based on the keys enemy[i]->update(f_diffTicks); for(int i = 0; i < MAXBOBBLES; i++) // update pos, based on the keys bobble[i]->update(f_diffTicks); for(int bob = 0; bob < MAXBOBBLES; bob++) // check if a bobble has an enemy { if(bobble[bob]->alive() == false && bobble[bob]->enemy() != -1) { int ene = bobble[bob]->enemy(); bobble[bob]->resetEnemy(); enemy[ene]->setPos(bobble[bob]->pos(X), X); enemy[ene]->setPos(bobble[bob]->pos(Y), Y); enemy[ene]->setAlive(true); } } /* checking collisions */ for(int i = 0; i < totPlayers; i++) checkSpritesForLevelCollisions(player[i], PLAYER); for(int i = 0; i < totEnemies; i++) checkSpritesForLevelCollisions(enemy[i], ENEMY); for(int i = 0; i < MAXBOBBLES; i++) checkSpritesForLevelCollisions(bobble[i], BOBBLE); for(int i = 0; i < totPlayers; i++) // this is only used for jump player[i]->floorColliding(level->groundCollision(player[i]->pos(X), player[i]->pos(Y)+1, player[i]->width(), player[i]->height())); for(int bob = 0; bob < MAXBOBBLES; bob++) // test collision between enimie and bobbles for(int ene = 0; ene < totEnemies; ene++) // test collision between enimie and bobbles if(bobble[bob]->alive() && enemy[ene]->alive() && bobble[bob]->enemy() == -1 && bobble[bob]->shooting()) if(testCollision(bobble[bob]->pos(X), bobble[bob]->pos(Y), bobble[bob]->width(), bobble[bob]->height(), enemy[ene]->pos(X), enemy[ene]->pos(Y), enemy[ene]->width(), enemy[ene]->height()) == true) { createBobble(enemy[ene]->pos(X), enemy[ene]->pos(Y), -1, ene); enemy[ene]->setAlive(false); bobble[bob]->setAlive(false); } for(int pla = 0; pla < totPlayers; pla++) // test collision between players and enimie for(int ene = 0; ene < totEnemies; ene++) // test collision between players and enimie if(player[pla]->alive() == true && enemy[ene]->alive() == true) if(testCollision(player[pla]->pos(X), player[pla]->pos(Y), player[pla]->width(), player[pla]->height(), enemy[ene]->pos(X), enemy[ene]->pos(Y), enemy[ene]->width(), enemy[ene]->height()) == true) player[pla]->setAlive(false); for(int bob = 0; bob < MAXBOBBLES; bob++) // test collision between players and bobbles for(int pla = 0; pla < totPlayers; pla++) if(player[pla]->alive() == true && bobble[bob]->alive() == true && bobble[bob]->shooting() == false) if(testCollision(player[pla]->pos(X), player[pla]->pos(Y), player[pla]->width(), player[pla]->height(), bobble[bob]->pos(X), bobble[bob]->pos(Y), bobble[bob]->width(), bobble[bob]->height())) { // destroy the bubble if we have "entered" in it too much. if(testCollision(player[pla]->pos(X), player[pla]->pos(Y), player[pla]->width(), player[pla]->height(), bobble[bob]->pos(X)+bobble[bob]->width()/3, bobble[bob]->pos(Y)+bobble[bob]->height()/3, (int)(bobble[bob]->width()-(2*(bobble[bob]->width()/3))), (int)(bobble[bob]->height()-(2*(bobble[bob]->height()/3))))) { // kill bubble bobble[bob]->setAlive(false); bobble[bob]->resetEnemy(); } else { int dir = splitCollision(player[pla], bobble[bob], false); if(dir == DOWN && SDL_GetKeyState(NULL)[SDLK_UP]) // hack player[pla]->jump(); // jupm over bubble else if(dir == LEFT) // push bubble bobble[bob]->setPos((int)(bobble[bob]->pos(X)+(2.5*f_diffTicks)), X); else if(dir == RIGHT) // push bubble bobble[bob]->setPos((int)(bobble[bob]->pos(X)-(2.5*f_diffTicks)), X); } } /* drawing level */ for(int i = 0; i < totPlayers; i++) // refresh last player's pos level->drawArea(screen, player[i]->oldPos(X), player[i]->oldPos(Y), player[i]->width(), player[i]->height()); for(int i = 0; i < totEnemies; i++) // refresh last player's pos level->drawArea(screen, enemy[i]->oldPos(X), enemy[i]->oldPos(Y), enemy[i]->width(), enemy[i]->height()); for(int i = 0; i < MAXBOBBLES; i++) // refresh last player's pos level->drawArea(screen, bobble[i]->oldPos(X), bobble[i]->oldPos(Y), bobble[i]->width(), bobble[i]->height()); /* drawing objects */ for(int i = 0; i < totPlayers; i++) // put player in screen player[i]->draw(screen, 0); for(int i = 0; i < totEnemies; i++) // put player in screen enemy[i]->draw(screen, 0); for(int i = 0; i < MAXBOBBLES; i++) // put player in screen bobble[i]->draw(screen, 0); /* updating screen */ SDL_UpdateRect(screen, 0, 0, SCREENWIDTH, SCREENHEIGHT); /* checking if it's time to exit level */ // see if players are all dead, and if affirmitive, goes back to the menu bool alive = false; for(int i = 0; i < totPlayers; i++) if(player[i]->alive() == true) { alive = true; break; } if(alive == false) { blinkScreen(screen, SDL_MapRGB(screen->format, 255, 0, 0)); gamedone = PREVLEVEL; } // see if enemies are all dead, and if affirmitive, continue to the next level alive = false; for(int i = 0; i < totEnemies; i++) if(enemy[i]->alive() == true) { alive = true; break; } for(int i = 0; i < MAXBOBBLES; i++) if(bobble[i]->enemy() != -1) { alive = true; break; } if(alive == false) { blinkScreen(screen, SDL_MapRGB(screen->format, 0, 255, 0)); gamedone = NEXTLEVEL; } } // now do the cleanups delete level; for(int i = 0; i < totPlayers; i++) delete player[i]; for(int i = 0; i < totEnemies; i++) delete enemy[i]; for(int i = 0; i < MAXBOBBLES; i++) delete bobble[i]; return gamedone; }