Пример #1
0
int Emitter::eventHandler( const df::Event *event ) {
	if ( event->getType( ) == df::STEP_EVENT ) {
		df::Position pos = this->getPosition( );
		switch ( this->getDirection( ) ) {
		case UP:
			pos.setY( pos.getY( ) - 1 );
			break;
		case DOWN:
			pos.setY( pos.getY( ) + 1 );
			break;
		case LEFT:
			pos.setX( pos.getX( ) - 1 );
			break;
		case RIGHT:
			pos.setX( pos.getX( ) + 1 );
			break;
		default:
			break;
		}
		Laser* laser = new Laser( this->getColor( ), this->getDirection( ) );
		laser->setPosition( pos );
		return 1;
	}
	return Component::eventHandler( event );
}
Пример #2
0
void Player::FireLaser(void )
{
    Laser *l = new Laser();
    l->Initialise(position, rotation, LASER_RADIUS, LASER_VELOCITY);

    lasers.push_back(l);
}
Пример #3
0
Laser *create_laser(complex pos, float time, float deathtime, Color *color, LaserPosRule prule, LaserLogicRule lrule, complex a0, complex a1, complex a2, complex a3) {
	Laser *l = create_element((void **)&global.lasers, sizeof(Laser));
		
	l->birthtime = global.frames;
	l->timespan = time;
	l->deathtime = deathtime;
	l->pos = pos;
	l->color = color;
	
	l->args[0] = a0;	
	l->args[1] = a1;
	l->args[2] = a2;
	l->args[3] = a3;
	
	l->prule = prule;
	l->lrule = lrule;
	
	l->shader = NULL;
	l->collision_step = 5;
	l->width = 10;
	l->speed = 1;
	l->timeshift = 0;
	
	if(l->lrule)
		l->lrule(l, EVENT_BIRTH);
	
	l->prule(l, EVENT_BIRTH);
	
	return l;
}
Пример #4
0
Player::Player() : radians(PI / 2.0f) {
	this->collisionType     = entityNS::CIRCLE;
	this->mass              = playerNS::MASS;
	this->radius            = playerNS::WIDTH / 2;
	this->spriteData.height = playerNS::HEIGHT;
	this->spriteData.scale  = 1;
	this->spriteData.width  = playerNS::WIDTH;
	this->spriteData.x      = playerNS::X;
	this->spriteData.y      = playerNS::Y;

//Calculate several values regarding the position of the turret ring
	this->mirrorRadius = playerNS::HEIGHT / 2 + 10;
	this->trueCenterX = playerNS::X + playerNS::WIDTH / 2;
	this->trueCenterY = playerNS::Y + playerNS::HEIGHT / 2;
	this->turretRadius = playerNS::HEIGHT / 2 + 6;

	for(int i = 0; i < playerNS::TOTAL_LASERS; i++)
	{
		Laser* l = new Laser(graphicsNS::BLUE);
		l->setEnemyLaser(false);
		lasers[i] = l;
		l=0;
	}
	playerHealth = gladiatorNS::NUM_HEALTH_BARS;
}
bool LaserPhysicsComponent::testIntersectionWithAsteroid(Laser &laser, Asteroid &asteroid)
{
    D3DXVECTOR3 currLaserPos = laser.getPosition(), lastLaserPos = laser.getLastPosition(), 
        laserDir = laser.getDirection(), asteroidPosition = asteroid.getPosition();
    float asteroidRadius = getAsteroidBoundingSphereRadius(asteroid);
    float asteroidPosToLaserEnd;

    //check if the laser ray intersects a rough bounding sphere of the asteroid
    if (!D3DXSphereBoundProbe(&asteroidPosition, asteroidRadius, &lastLaserPos, &laserDir)) {
        return false;
    }

    asteroidPosToLaserEnd = D3DXVec3LengthSq(&(currLaserPos - asteroidPosition));

    //if this is true then the laser's current position does not fall within the sphere, and a ray starting at the laser's
    //current point crosses the circle. A ray starting at the last point already crosses the sphere, so this means both
    //points are "before" the sphere, along the ray in the direction the laser is travelling.
    if (asteroidRadius * asteroidRadius < asteroidPosToLaserEnd && 
        D3DXSphereBoundProbe(&asteroidPosition, asteroidRadius, &currLaserPos, &laserDir)) {
        return false;
    }

    //it may have collided. Now check ray against mesh
    shared_ptr<GraphicsComponent> gfx = asteroid.getGraphicsComponent();
    AsteroidGraphicsComponent *asteroidGraphicsComponent = dynamic_cast<AsteroidGraphicsComponent*>(gfx.get());
    
    if (asteroidGraphicsComponent == NULL) {
        throw "Asteroid didn't have a valid asteroid graphics component!";
    }

    BOOL hit;
    float dist;
    D3DXVECTOR3 laserPosRelativeToAsteroid = lastLaserPos - asteroidPosition;
    D3DXVECTOR3 asteroidScale = asteroid.getScale();
    D3DXQUATERNION rotationQuat = asteroid.getRotationQuat();
    D3DXMATRIX rot, scale;
    D3DXMatrixScaling(&scale, 0.8f/asteroidScale.x, 0.8f/asteroidScale.y, 0.8f/asteroidScale.z);
    D3DXMatrixRotationQuaternion(&rot, &rotationQuat);
    D3DXVec3TransformCoord(&laserPosRelativeToAsteroid, &laserPosRelativeToAsteroid, &(scale * rot));

    D3DXIntersect(asteroidGraphicsComponent->getMesh(),
        &laserPosRelativeToAsteroid,
        &laserDir,
        &hit,
        NULL,
        NULL,
        NULL,
        &dist,
        NULL,
        NULL);

    float distTravelledSq = D3DXVec3LengthSq(&(currLaserPos - lastLaserPos));
    if (!hit || dist * dist > D3DXVec3LengthSq(&(currLaserPos - lastLaserPos))) {
        return false;
    }

    return true;
}
Пример #6
0
void _delete_laser(void **lasers, void *laser) {
	Laser *l = laser;
	
	if(l->lrule)
		l->lrule(l, EVENT_DEATH);
		
	if(l->color)
		free(l->color);
	del_ref(laser);
	delete_element(lasers, laser);
}
Пример #7
0
int Lens::eventHandler( const df::Event* evt ) {
  // Reset the output color on step
  if (evt->getType() == df::STEP_EVENT) {
    if (this->color != laser::BLACK) {
      Laser* laser = new Laser(this->color, getDirection());
      laser->setPosition(getPosition());
      this->color = laser::BLACK;
    }
    return 1;
  }
  return Component::eventHandler(evt);
}
Пример #8
0
int main()
{
    Laser<Salida> l;
    Salida s;
    cout << "Hello World 00!" << endl;
    l.setCallback(&Salida::SecondTriggered, s);
    cout << "Hello World 10!" << endl;
    l.StartLaser();
    for(int j=0;j<100000000;j++);
    cout << "Hello World 01!" << endl;

    return 0;
}
Пример #9
0
Laser* Laser::create(Type _type)
{
	Laser *laser = new Laser();
	if (laser && laser->init(_type))
	{
		laser->autorelease();
		return laser;
	}
	else
	{
		delete laser;
		laser = NULL;
		return NULL;
	}
}
Пример #10
0
void Player::fire(Laser &laser) {
	if(turret.getActive())
	{
		laser.fireRad(turret.getCenterX(), turret.getCenterY(), -this->radians + 3*PI/2);
		audio->playCue(LASER_CUE);
	}
}
Пример #11
0
bool GameManager::loadLaserState(
	TiXmlElement* element,
	Apollo::SceneObject* parent)
{
	TiXmlElement* childElem = NULL;
	TiXmlElement* spriteElem = NULL;
	Laser* laser;

	laser = this->CreateLaser();
	laser->LoadState(element, parent);
	
	childElem = element->FirstChildElement("Children");
	if (childElem)
	{
		return loadChildObjects(childElem, laser);
	}

	return true;
}
Пример #12
0
void process_lasers(void) {
	Laser *laser = global.lasers, *del = NULL;
	
	while(laser != NULL) {
		if(collision_laser_curve(laser))
			player_death(&global.plr);
		
		if(laser->lrule)
			laser->lrule(laser, global.frames - laser->birthtime);
		
		if(global.frames - laser->birthtime > laser->deathtime + laser->timespan*laser->speed) {
			del = laser;
			laser = laser->next;
			_delete_laser((void **)&global.lasers, del);
			if(laser == NULL) break;
		} else {
			laser = laser->next;
		}
	}
}
Пример #13
0
double Map::update(double x, double y, double yaw, const Laser& laser)
{
	// Handle new Obstacles
	vector<Point> obstacles;
	laser.getObstacles(x, y, yaw, obstacles);

	Point initalPoint(x, y);
	double matchPercent = handleObstacles(initalPoint, obstacles);

	return matchPercent;
}
Пример #14
0
void Player::CheckLaserAsteroidCollisions(std::list<Asteroid*>* asteroids)
{
    std::list<Asteroid*>::iterator a_iter = asteroids->begin();
    std::list<Asteroid*> a_tbd;
    std::list<Laser*> l_tbd;

    while(a_iter != asteroids->end())
    {
        Asteroid *ast = a_iter._Ptr->_Myval;
        std::list<Laser*>::iterator l_iter = lasers.begin();

        while(l_iter != lasers.end())
        {
            Laser *las = l_iter._Ptr->_Myval;

            if(ast->GetBSphere().Contains(las->GetPosition()))
            {
                //The laser is inside the asteroid bsphere
                a_tbd.push_back(ast);
                l_tbd.push_back(las);
                AddScore(ast->GetBSphere().GetRadius());
            }
            l_iter++;
        }
        a_iter++;
    }

    //Do the deletions
    std::list<Laser*>::iterator l_iter = l_tbd.begin();
    while(l_iter != l_tbd.end())
    {
        lasers.remove(l_iter._Ptr->_Myval);
        l_iter++;
    }
    a_iter = a_tbd.begin();
    while(a_iter != a_tbd.end())
    {
        asteroids->remove(a_iter._Ptr->_Myval);
        a_iter++;
    }
}
Пример #15
0
  void Laser::Init() {

    // Initialize timers for laser intensity control
    #if LASER_CONTROL == 1

      #if IS_TIMER_3_PWR
        timer3_init(LASER_PWR_PIN);
      #elif IS_TIMER_4_PWR
        timer4_init(LASER_PWR_PIN);
      #endif

    #elif LASER_CONTROL == 2

      #if IS_TIMER_3_PWM
        timer3_init(LASER_PWM_PIN);
      #elif IS_TIMER_4_PWM
        timer4_init(LASER_PWM_PIN);
      #endif

    #endif

    #if ENABLED(LASER_PERIPHERALS)
      OUT_WRITE(LASER_PERIPHERALS_PIN, HIGH);         // Laser peripherals are active LOW, so preset the pin
      OUT_WRITE(LASER_PERIPHERALS_STATUS_PIN, HIGH);  // Set the peripherals status pin to pull-up.
    #endif

    #if LASER_CONTROL == 2
      OUT_WRITE(LASER_PWR_PIN, LASER_UNARM);  // Laser FIRING is active LOW, so preset the pin
    #endif

    // initialize state to some sane defaults
    laser.intensity = 100.0;
    laser.ppm = 0.0;
    laser.duration = 0;
    laser.status = LASER_OFF;
    laser.firing = LASER_ON;
    laser.mode = CONTINUOUS;
    laser.last_firing = 0;
    laser.diagnostics = false;
    laser.time = 0;

    #if ENABLED(LASER_RASTER)
      laser.raster_aspect_ratio = LASER_RASTER_ASPECT_RATIO;
      laser.raster_mm_per_pulse = LASER_RASTER_MM_PER_PULSE;
      laser.raster_direction = 1;
    #endif // LASER_RASTER

    laser.extinguish();

  }
Пример #16
0
//--------------------------------------------------------------------------
//Cria um novo tiro do tipo qual
void Nave::NovoTiro(int qual)
{
   if (qual == TIPO_LASER)
   {
      Laser *laser = new Laser(central, this);
      central->NovoObjeto((Objeto *) laser);
      laser->AdicionaCenario(cenario);
   }
   else if (qual == TIPO_MISSIL)
   {
      Missil *missil = new Missil(central, this);
      central->NovoObjeto((Objeto *) missil);
      missil->AdicionaCenario(cenario);
      if (Mensagem(QUEM_VOCE, NULL) == JOGADOR) missil->Mensagem(PROCURA_INIMIGO, NULL);
      else if (Mensagem(QUEM_VOCE, NULL) == INIMIGO) missil->Mensagem(PROCURA_JOGADOR, NULL);
   }
   else if (qual == TIPO_MULTIPLO)
   {
      Multiplo *multiplo = new Multiplo(central, this);
      central->NovoObjeto((Objeto *) multiplo);
      multiplo->AdicionaCenario(cenario);
   }
}
Пример #17
0
void laser_line(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t step, int8_t r, int8_t g, int8_t b) {
	int dx = x2 - x1;
	int dy = y2 - y1;
	int steps = ceil(sqrtf(dx * dx + dy * dy)*16/step);
	int x, y;
	int speed = 0;
	for(int count = 0; count <= steps; count+=speed) {
		if (count <= 136 && count < steps/2) speed++;
		if (count >= steps - 136 && count > steps/2) speed--;
		if (speed==0) speed = 1;
		x = count * (x2 - x1) / steps + x1;
		y = count * (y2 - y1) / steps + y1;
		laser.set(x, y, r, g, b);
	}
}
Пример #18
0
void GunTurret::updateLasers(float elapsedtime/*, MapLoader& m_map, Player& p*/)
{
    m_lasergentime += elapsedtime;
    m_lasersit = m_lasers.begin();
    //bool switchhit = false;
    while (m_lasersit != m_lasers.end())
    {
        //cout << "Number of lasers: " << m_lasers.size();
        Laser* l = *m_lasersit;
        Vector3 pos = l->getPosition();
        //Vector3 startpos = l->getStartPosition();
        //pos = pos - startpos;
        if (2500.0f > fabs(pos.x()))
            if(2500.0f > fabs(pos.y()))
                if (2500.0f > fabs(pos.z()))
                {
                    Vector3 planenormal;
                    //if (m_map.checkLaserCollision(l->getBbox(), l->getDirection(), switchhit, planenormal, p, false))
                    //{
                    //    if (17.5 > l->getLifeTime() && !switchhit)
                    //    {
                    //        //Create scorch mark at the spot of the laser
                    //        createScorchMark(l->getPosition(), -planenormal);
                    //    }
                    //    //Setup particle system when laser hits something
                    //    ParticleSystemManager* psm = getWriteableGameResource()->getParticleSystemManager();
                    //    ParticleEmitter* pe = psm->createEmitter(l->getPosition(), planenormal);
                    //    pe->setMaxParticles(5.0f);
                    //    pe->setEmissionRate(5.0f);
                    //    pe->setParticleStartColor(Color::red());
                    //    pe->setParticleKey1Color(Color::red());
                    //    pe->setParticleKey2Color(Color::red());
                    //    pe->setParticelEndColor(Color::red());
                    //    pe->setParticleKey1Pos(0.33f);
                    //    pe->setParticleKey2Pos(0.66f);
                    //    pe->setParticleLifetime(1.0f);
                    //    pe->setLifeTime(1.0f);
                    //    pe->setParticleSize(0.75f);
                    //    pe->setStartVelocity(7.5f);
                    //    pe->setSpreadAngle(90.0f);
                    //    pe->setAlive(true);
                    //    //MSG_TRACE_CHANNEL("", sizeof(ParticleEmitter) << endl;
                    //    eraseLaser(m_lasersit, l);
                    //    continue;
                    //}
                    //l->move(elapsedtime);
                    m_lasersit++;
                }
                else
                    eraseLaser(m_lasersit, l);
            else
                eraseLaser(m_lasersit, l);
        else
            eraseLaser(m_lasersit, l);
    }
    m_scorchit = m_scorchmarks.begin();
    while (m_scorchit != m_scorchmarks.end())
    {
        //cout << "Number of lasers: " << m_lasers.size();
        ScorchMark* sm = *m_scorchit;
        if (sm->getLifetime() < 0.0f)
        {
            delete sm;
            m_scorchit = m_scorchmarks.erase(m_scorchit);
            continue;
        }
        //sm->move(elapsedtime); update of the scorch mark takes care of this
        m_scorchit++;
    }
}
Пример #19
0
void LaserSystem::addBeams(Laser& laser, TilePosition& tilePos)
{
    // Setup everything
    currentPosition = ng::vec::cast<int>(tilePos.pos);
    currentDirection = laser.direction;

    // Current layer is the starting layer of the beam
    currentLayer = (tilePos.layer && !getLayer());

    // Simulate the laser until it hits something
    laser.beamCount = 0;
    sf::Vector2f startPoint = tileMap.getCenterPoint<float>(tilePos.pos);
    PointInfo endPoint;
    do
    {
        // Find next point that collides
        endPoint = findPoint();

        Laser::Beam* beam;
        if (laser.beamCount < laser.beams.size())
        {
            // Use an existing sprite
            beam = &(laser.beams[laser.beamCount]);
        }
        else
        {
            // Setup a new sprite with the beam texture
            laser.beams.emplace_back();
            beam = &laser.beams.back();
            ng::SpriteLoader::load(beam->sprite, textureFilename, true);
        }
        ++laser.beamCount;

        beam->sprite.setOrigin(beamWidth / 2, 0);

        // Calculate and set the beam length
        float beamLength = ng::vec::distance(startPoint, endPoint.position);
        beam->sprite.setScale(1, beamLength);

        // Set the beam's position and rotation
        beam->sprite.setPosition(startPoint);
        beam->sprite.setRotation(ng::vec::rotateAngle(laser.getAngle(currentDirection), 180.0));

        // Set the beam's layer
        beam->layer = currentLayer;

        if (endPoint.state == PointInfo::State::Redirect)
        {
            // Change the direction based on the angle of the mirror
            bool mirrorState = tileMapData(endPoint.tileId).state;
            changeDirection(mirrorState, currentDirection);
        }
        else if (endPoint.state == PointInfo::State::Activate)
        {
            // Enable the laser sensor
            es::Events::send(SwitchEvent{endPoint.tileId, SwitchEvent::On});
            laserSensorsToDisable.erase(endPoint.tileId);
        }

        startPoint = endPoint.position;
    }
    while (endPoint.state == PointInfo::State::Redirect);
}
Пример #20
0
void Engine::nextMove(int turn, Pattern patt, Graphics* graph) {
    // Big and ugly switch function, but much less work than using functors, for the same effect
    // TODO: change the values that now are magic numbers so that the destruction of the ships in a stage triggers the beginning of another one
    
    switch (patt) {
        case MAIN_STAGE:
// FIRST ENEMY
            if (turn == 0) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn < 20 ) {
                // This is an excellent porting
                graph->printOtherOnScreen(SHIP_PORTING, 60, 60, turn*18, static_cast<double>(turn)/20);
            }
            else if (turn == 20) {
                spawnEnemy(40, 40, EN_FIGHTER, 1);
            }
            else if (turn > 20 && turn < 360) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(0, 2, enemyFleet[0]);
                }
            }
            else if (turn == 360 && enemyOnScreen) {
                // Here I need not use enemy1 and so on because I'm cleaning everything
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 360 && turn < 380) {
                if (expiredEnemy0) {
                    // Maybe turning the lasers a little in the direction of movement helps
                    graph->printOtherOnScreen(SHIP_PORTING, 740, 60, turn*18, static_cast<double>(380 - turn)/20);
                }
            }
            else if (turn == 380) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
            }
            if (turn >= 31 && turn % 15 == 1 && turn < 360) {
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -4; i <= 4; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/24 + (pi*1.5), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
// SECOND ENEMY
            if (turn == 400) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 400 && turn < 420 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 740, 60, (turn-400)*18, static_cast<double>(turn - 400)/20);
            }
            else if (turn == 420) {
                spawnEnemy(720, 40, EN_FIGHTER, 1);
            }
            else if (turn > 420 && turn < 760) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(pi, 2, enemyFleet[0]);
                }
            }
            else if (turn == 760 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 760 && turn < 780) {
                if (expiredEnemy0) {
                    graph->printOtherOnScreen(SHIP_PORTING, 60, 60, turn*18, static_cast<double>(780 - turn)/20);
                }
            }
            else if (turn == 780) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
            }
            if (turn >= 431 && turn % 15 == 1 && turn < 760) {
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -4; i <= 4; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/24 + (pi*1.5), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
// THIRD AND FOURTH ENEMIES
            // They move in sinusoids
            if (turn == 800) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 800 && turn < 820 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 60, 100, (turn-800)*18, static_cast<double>(turn - 800)/20);
                graph->printOtherOnScreen(SHIP_PORTING, 760, 100, (turn-800)*18, static_cast<double>(turn - 800)/20);
            }
            else if (turn == 820) {
                // enemy1 is the one on the right
                spawnEnemy(40, 80, EN_FIGHTER, 0.4);
                spawnEnemy(740, 80, EN_FIGHTER, 0.4);
            }
            else if (turn > 820 && turn < 1160) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(0, 2, enemyFleet[0]);
                    moveEnemyOnMap(pi/2, 5*sin((turn-800)/(2*pi)), enemyFleet[0]);
                }
                if (enemyFleet[1]) {
                    moveEnemyOnMap(pi, 2, enemyFleet[1]);
                    moveEnemyOnMap(pi/2, 5*sin((turn-800)/(2*pi)), enemyFleet[1]);
                }
            }
            else if (turn == 1160 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                if (enemyFleet[1]->isAlive()) {
                    expiredEnemy1 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 1160 && turn < 1180) {
                if (expiredEnemy0 == true) {
                    graph->printOtherOnScreen(SHIP_PORTING, 738, 148, turn*18, static_cast<double>(1180 - turn)/20);
                }
                if (expiredEnemy1 == true) {
                    graph->printOtherOnScreen(SHIP_PORTING, 82, 148, turn*18, static_cast<double>(1180 - turn)/20);
                }
            }
            else if (turn == 1180) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
                expiredEnemy1 = false;
            }
            if (turn >= 831 && turn % 10 == 1 && turn < 1160) {
                bool laserPlayed = false;
                if (enemyFleet[0]->isAlive()) {
                    // Not exactly right, now i'll think
                    for (int i = -1; i<= 1; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/6 + 1.5*pi - (pi*(turn-1000)/350), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
                if (enemyFleet[1]->isAlive()) {
                    for (int i = -1; i <= 1; i++) {
                        Laser* tmp = enemyFleet[1]->shootLaser(i*pi/6 + 1.5*pi + (pi*(turn-1000)/350), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
            }
// FIFTH AND SIXTH ENEMIES
            // They move in circles
            if (turn == 1200) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 1200 && turn < 1220 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 160, 60, (turn-1200)*18, static_cast<double>(turn - 1200)/20);
                graph->printOtherOnScreen(SHIP_PORTING, 640, 60, (turn-1200)*18, static_cast<double>(turn - 1200)/20);
            }
            else if (turn == 1220) {
                // enemy1 is the one on the right
                spawnEnemy(180, 40, EN_FIGHTER, 0.8);
                spawnEnemy(580, 40, EN_FIGHTER, 0.8);
            }
            else if (turn > 1220 && turn < 1940) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(pi + (turn-1200)*pi/180, 2, enemyFleet[0]);
                }
                if (enemyFleet[1]) {
                    moveEnemyOnMap(-(turn-1200)*pi/180, 2, enemyFleet[1]);
                }
            }
            else if (turn == 1940 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                if (enemyFleet[1]->isAlive()) {
                    expiredEnemy1 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 1940 && turn < 1960) {
                if (expiredEnemy0) {
                    graph->printOtherOnScreen(SHIP_PORTING, 202, 59, turn*18, static_cast<double>(1960 - turn)/20);
                }
                if (expiredEnemy1) {
                    graph->printOtherOnScreen(SHIP_PORTING, 598, 59, turn*18, static_cast<double>(1960 - turn)/20);
                }
            }
            else if (turn == 1940) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
                expiredEnemy1 = false;
            }
            if (turn >= 1231 && turn % 12 == 1 && turn < 1940) {
                double angleToProtagonist0 = atan2( enemyFleet[0]->getY() - protagonist->getY(), -(enemyFleet[0]->getX() - protagonist->getX()));
                double angleToProtagonist1 = atan2( enemyFleet[1]->getY() - protagonist->getY(), -(enemyFleet[1]->getX() - protagonist->getX()));
                // To use as the angle of the central laser in the burst. Redirecting the lasers will require a bunch of new atan2s
                bool laserPlayed = false;
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -2; i<=2; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(angleToProtagonist0 + i*pi/50, LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
                if (enemyFleet[1]->isAlive()) {
                    for (int i = -2; i<=2; i++) {
                        Laser* tmp = enemyFleet[1]->shootLaser(angleToProtagonist1 + i*pi/50, LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
            }
// SEVENTH AND FINAL ENEMY
            if (turn == 1980) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 1980 && turn < 2000 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 400, 80, (turn-1980)*18, static_cast<double>(turn - 1980)/20);
            }
            else if (turn == 2000) {
                // enemy1 is the one on the right
                spawnEnemy(380, 60, EN_FIGHTER, 2);
            }
            if (((turn%90 == 10 && turn >= 2000) || turn == 2000) && enemyFleet[0]->isAlive()) {
                bool laserPlayed = false;
                for (int i = 0; i < 18; i++) {
                    Laser* tmp = enemyFleet[0]->shootLaser(i*pi/9, LASER_ENEMY);
                    tmp->setSpeed(4);
                    lasersOnMap.push_back(tmp);
                    if (!laserPlayed) {
                        Mix_PlayChannel(-1, graph->getZap(), 0);
                        laserPlayed = true;
                    }
                }
            }
            if (turn >= 2000 && turn%90 >= 20) {
                int directionSwitch = ((turn-2000)/90)%3;
                moveEnemyOnMap(5*pi/3 - directionSwitch*2*pi/3, 4, enemyFleet[0]);
            }
            if (turn >= 2000) {
                for (int i = 0; i<lasersOnMap.size(); i++) {
                    if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() > 16 && lasersOnMap[i]->getTurnsInLife() <= 20) {
                        lasersOnMap[i]->setSpeed(lasersOnMap[i]->getSpeed() - 1);
                    }
                    else if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() == 40) {
                        double angDest = atan2( lasersOnMap[i]->getCentergY() - protagonist->getCenterY(), -(lasersOnMap[i]->getCentergX() - protagonist->getCenterX()));
                        lasersOnMap[i]->setAngle(angDest);
                    }
                    else if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() == 50) {
                        lasersOnMap[i]->setSpeed(25);
                    }
                }
            }
            break;
            
// Formerly FLOWER
        case BOSS_STAGE:
            if (turn == 0) {
                cleanEnemyFleet();
                cleanLasers();
                floweringBoss = true;
                bossPosition = 0;
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn < 20 ) {
                // This is an excellent porting
                graph->printOtherOnScreen(SHIP_PORTING, 400, 60, turn*18, static_cast<double>(turn)/20);
            }
            else if (turn == 20) {
                if (enemyFleet.size() == 0) {
                    spawnEnemy(380, 40, EN_CORVETTE, 1);
                }
                patternTurnsHelper = 0;   // The pattern is nicer this way
            }
            else if (turn <= 30) {
                // TODO: Adjust values
                moveEnemyOnMap((pi*1.5), 10, enemyFleet[0]);
            }
            
            if (turn >= 31 && turn % 500 <= 400) {
                if (enemyFleet[0]->isAlive() && enemyFleet.size() > 0 && turn%7 == 1) {
                    
                    // When it's the Flowering Night, then time will stop on the Lunar Clock. Only she who possesses the Pocket Watch of Blood will be able to go against the flow in stillness and against the stillness in the flow. She is Sakuya Izayoi, the maid in the Scarlet Devil Mansion.
                    // On unrelated news, the patterny pattern when it's not flowering is given later by manipulating the lazerbeams
                    if (floweringBoss) {
                        for (int i = 0; i<=20; i++) {
                            Laser* tmp = enemyFleet[0]->shootLaser(i*pi/10 + patternTurnsHelper*pi/32, LASER_ENEMY);
                            tmp->setSpeed(8);
                            lasersOnMap.push_back(tmp);
                        }
                    }
                    
                    // The pattern part when you're not flowering is given by shooting harmonically
                    else {
                        for (int i = 0; i<=20; i++) {
                            Laser* tmp = enemyFleet[0]->shootLaser(i*pi/10 + (pi/8)*sin((pi/100)*(turn%500)), LASER_ENEMY);
                            tmp->setSpeed(8);
                            lasersOnMap.push_back(tmp);
                        }
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
            
            /*      Possible pattern?
             *            entry
             *              |
             *      (. . . .V. . . .)
             *      (. 4 . .0. . 2 .)
             *      (. 6 . .8. . 5 .)
             *      (. 1 . .3. . 7 .)
             *      (. . . . . . . .)
             *      (. . . . . . . .)
             */
            
            if (turn >= 31 && turn % 500 >= 400) {
                switch (bossPosition) {
                    case 0:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(-200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(160, 340);
                        }
                        break;
                    case 1:
                        if (turn%500 < 448) {
                            moveEnemyOnMap(atan2(200, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 449) {
                            enemyFleet[0]->teleport(600, 140);
                        }
                        break;
                    case 2:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(-200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(380, 340);
                        }
                        break;
                    case 3:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(160, 140);
                        }
                        break;
                    case 4:
                        if (turn%500 < 445) {
                            moveEnemyOnMap(atan2(-100, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 446) {
                            enemyFleet[0]->teleport(600, 240);
                        }
                        break;
                    case 5:
                        if (turn%500 < 444) {
                            moveEnemyOnMap(atan2(0, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 445) {
                            enemyFleet[0]->teleport(160, 240);
                        }
                        break;
                    case 6:
                        if (turn%500 < 445) {
                            moveEnemyOnMap(atan2(-100, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 446) {
                            enemyFleet[0]->teleport(600, 340);
                        }
                        break;
                    case 7:
                        if (turn%500 < 424) {
                            moveEnemyOnMap(atan2(100, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 425) {
                            enemyFleet[0]->teleport(380, 240);
                        }
                        break;
                    case 8:
                        if (turn%500 < 410) {
                            moveEnemyOnMap(atan2(100, 0), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 411) {
                            enemyFleet[0]->teleport(380, 140);
                        }
                        break;
                        
                    default:
                        break;
                }
            }
            
            // This must be synced to the rate of fire
            if (turn%7 == 1) {
                if (floweringBoss) {
                    for (int i = 0; i<lasersOnMap.size(); i++) {
                        if (lasersOnMap[i]->getTurnsInLife() == 10 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()+(pi/2));
                        }
                        if (lasersOnMap[i]->getTurnsInLife() > 10 && lasersOnMap[i]->getTurnsInLife() <= 90 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()+(pi/3));
                        }
                        if (lasersOnMap[i]->getTurnsInLife() == 100 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()-(pi/2));
                        }
                    }
                }
                patternTurnsHelper++;
            }
            if (turn%500 == 0 && turn != 0) {
                floweringBoss = !floweringBoss;
                bossPosition = (bossPosition+1)%9;
            }
            
            break;
            
        default:
            break;
    }
}
Пример #21
0
void Engine::protagonistShootsSingleLaser() {
    Laser* tmp = protagonist->shootLaser(pi/2, LASER_ALLIED);
    tmp->setSpeed(20);
    lasersOnMap.push_back(tmp);
}
Пример #22
0
int main(){

    sf::Music music;
    if(!music.openFromFile("dramaticEnding.ogg")){}
    music.play();
    music.setLoop(true);
    music.setVolume(30);

    int delayLaserMoves(5); //in mili seconds
    int pushNumber(1); //Inital

    bool isGame(1); //Two bool for 3 states
    bool hasStart(false);//look up
    int spentTime(0); // For the final string , simple init;

    int hit(0); //Not being hit twice is a nice thing;

    sf::RenderWindow window(sf::VideoMode(500,300),"Leyser");

    sf::Font captureIt;
    if(!captureIt.loadFromFile("Capture it.ttf")){}

    sf::Font hacked;
    if(!hacked.loadFromFile("HACKED.ttf")){}

    sf::Texture backgroundTexture;
    if(!backgroundTexture.loadFromFile("background.png")){}

    sf::Texture laserTexture;
    if(!laserTexture.loadFromFile("laser.png")){}

    sf::Texture characTexture;
    if(!characTexture.loadFromFile("char.png")){}

    sf::Texture shieldTexture;
    if(!shieldTexture.loadFromFile("shield.png")){}



    sf::Text gameOver = genGameOver(captureIt);

    sf::Text timeSpentText = genSpentTime(captureIt);

    sf::Text restartText = genRestart(captureIt);

    sf::Text startText = genStart(hacked);

    sf::Sprite backgroundSprite;
    backgroundSprite.setTexture(backgroundTexture);
    sf::Sprite charSprite;
    charSprite.setTexture(characTexture);
    sf::Sprite laserSprite;
    laserSprite.setTexture(laserTexture);
    sf::Sprite shieldSprite;
    shieldSprite.setTexture(shieldTexture);

    sf::Clock gameClock;

    sf::Clock laserClock;

    Charac player;

    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(1, 3);

    Laser* laser;
    laser = new Laser(dis(gen));

    while(window.isOpen()){
        sf::Event event;

        if(window.pollEvent(event)){
             if(event.type == sf::Event::Closed){
                window.close();
            }
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
                window.close();
            }
            if(event.type == sf::Event::KeyPressed){
                if(event.key.code == sf::Keyboard::Up || event.key.code == sf::Keyboard::Z){
                    player.moveLane(UP);
                }
                if(event.key.code == sf::Keyboard::Down || event.key.code == sf::Keyboard::S){
                    player.moveLane(DOWN);
                }
                if(event.key.code == sf::Keyboard::G){
                    isGame = false;
                }
                if(event.key.code == sf::Keyboard::X && !hasStart){
                    hasStart = true;
                    gameClock.restart();
                    pushNumber = 1;
                }
                if(event.key.code == sf::Keyboard::R && !isGame){
                    isGame = true; // Re-Init evrything
                    pushNumber = 1;
                    gameClock.restart();
                    laserClock.restart();
                    spentTime = 0;
                    player.setShield();
                    delete laser;
                }
            }
        }
        if(hasStart && isGame){
            if(laser->getCoord() <= 0){
                laser =  new Laser(dis(gen));
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 10){
                pushNumber = 2;
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 25){
                pushNumber = 3;
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 40){
                pushNumber = 5;
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 60){
                pushNumber = 9;
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 90){
                pushNumber = 17;
            }
            if( (int) gameClock.getElapsedTime().asSeconds() == 100){
                pushNumber = 25;
            }


            if( (int) laserClock.getElapsedTime().asMilliseconds() >= delayLaserMoves){
                laser->pushLaser(pushNumber);
                laserClock.restart();
            }
            if(laser->getCoord() <= 60 && laser->getLane() == player.getLane() && hit == 0){
                if(player.hasShield()){
                    player.removeShield();
                }
                else{
                    isGame = false;
                    spentTime = gameClock.getElapsedTime().asSeconds();
                }

                hit = 1;
            }
            if(laser->getCoord() > 60){
                hit = 0;
            }

            player.checkShield();
        }

        window.clear(sf::Color::Black);

        if(isGame && hasStart){
            drawGame(window,charSprite,shieldSprite,player,laserSprite,laser,backgroundSprite);
        }
        if(!isGame){
            drawGameOverScreen(window,gameOver,timeSpentText,restartText,spentTime);
        }
        if(!hasStart){
            window.draw(startText);
        }

        window.display();
	}
    return 0;
}
Пример #23
0
void Player::Update(const float time_step)
{
    if(Keyboard::IsKeyDown((KeyCode)left_key))
    {
        //rotate left
        rotation += (rot_accel * time_step);
    }
    if(Keyboard::IsKeyDown((KeyCode)right_key))
    {
        //rotate right
        rotation -= (rot_accel * time_step);
    }
    if(Keyboard::IsKeyDown((KeyCode)thrust_key))
    {
        //increase thrust
        thrust += thrust_accel * time_step;
    }
    else
    {
        thrust = 0;
    }

    if(thrust < 0)
    {
        thrust = 0;
    }
    else if(thrust > MAX_THRUST)
    {
        thrust = MAX_THRUST;
    }

    if(Keyboard::IsKeyDown((KeyCode)fire_key))
    {
        //fire a laser
        curr_laser_time -= time_step;
        if(curr_laser_time < 0)
        {
            FireLaser();
            curr_laser_time = LASER_RECHARGE_TIME;
        }
    }

    using RustyLib::Matrix44;

    Matrix44 *rot_mat = Matrix44::CreateRotationZ(rotation);

    acceleration = (*rot_mat * Vector3::INV_Y_AXIS());

    acceleration *= thrust;

    velocity += acceleration;

    float curr_vel = velocity.Magnitude();

    if(curr_vel > MAX_VELOCITY)
    {
        curr_vel = MAX_VELOCITY;
    }

    velocity.Normalise();

    velocity *= curr_vel;

    GameObject::Update(time_step);

    //Do some collision detection
    b_sphere.SetPosition(position);

    //First check whether player is on screen still
    if(! play_region.Contains(b_sphere) )
    {
        //Player needs moving
        Vector3 min = play_region.GetMin();
        Vector3 max = play_region.GetMax();

        if(position.x < min.x - b_sphere.GetRadius())
        {
            position.x = max.x + (b_sphere.GetRadius()-1.0f);
        }
        if(position.x > max.x + b_sphere.GetRadius())
        {
            position.x = min.x - (b_sphere.GetRadius()+1.0f);
        }
        if(position.y < min.y - b_sphere.GetRadius())
        {
            position.y = max.y + (b_sphere.GetRadius()-1.0f);
        }
        if(position.y > max.y + b_sphere.GetRadius())
        {
            position.y = min.y - (b_sphere.GetRadius()+1.0f);
        }
        b_sphere.SetPosition(position);
    }

    std::list<Laser*>::iterator iter = lasers.begin();
    std::list<Laser*> tbd;//lasers to be deleted
    int ct = 0;
    while(iter != lasers.end())
    {
        Laser* l = iter._Ptr->_Myval;
        l->Update(time_step);
        if(!play_region.Contains(l->GetPosition()))
        {
            //laser has left screen
            tbd.push_back(l);
        }
        iter++;
        ct++;
    }
    iter = tbd.begin();
    while(iter != tbd.end())
    {
        lasers.remove(iter._Ptr->_Myval);
        iter++;
    }
    tbd.clear();
}
Пример #24
0
void laser_line(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t step, int8_t r, int8_t g, int8_t b) {
	int16_t dx = abs(x2 - x1);
	int16_t dy = abs(y2 - y1);
	bool x_is_bigger = dx > dy;
	int8_t dirx = (x2 - x1) >= 0 ? 1 : -1;
	int8_t diry = (y2 - y1) >= 0 ? 1 : -1;

	int16_t steps = ceil(sqrtf((int32_t)dx * dx + (int32_t)dy * dy)/step);

	int16_t sx = floor((float)dx / steps);
	int16_t sy = floor((float)dy / steps);
	int16_t cx = dx - sx * steps;
	int16_t cy = dy - sy * steps;

	int16_t ex = 0;
	int16_t ey = 0;

	int16_t x = x1;
	int16_t y = y1;
	laser.set(x, y, r, g, b);

	bool run = true;

	while (run) {
		if (dirx > 0) {
			x += sx;
			ex += cx;
			if (ex > steps) {
				x++;
				ex -= steps;
			}
			if (x >= x2 && x_is_bigger) {
				run = false;
				x = x2;
			}
		} else {
			x -= sx;
			ex += cx;
			if (ex > steps) {
				x--;
				ex -= steps;
			}
			if (x <= x2 && x_is_bigger) {
				run = false;
				x = x2;
			}
		}
		if (diry > 0) {
			y += sy;
			ey += cy;
			if (ey > steps) {
				y++;
				ey -= steps;
			}
			if (y >= y2 && !x_is_bigger) {
				run = false;
				y = y2;
			}
		} else {
			y -= sy;
			ey += cy;
			if (ey > steps) {
				y--;
				ey -= steps;
			}
			if (y <= y2 && !x_is_bigger) {
				run = false;
				y = y2;
			}
		}
		// CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;   // LED ON
		laser.set(x, y, r, g, b);
		// CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK; // LED OFF
	}
}
Пример #25
0
void BulletArray::handle(Player *p)
{
	bool destroyBullet;
	
	// Bullets
	for(int i = 0; i < MAX_BULLET; i++)
	{
		Bullet *cb = &data[i];
		destroyBullet = false;
		if(cb->isActive())
		{
			if(cb->hurtsPlayer() && !p->isDying())
			{
				// Check collisions with player if he's not dead already
				if(cb->getPolarity() != p->getPolarity())
				{
					// the player has a 1px hitbox (for now) (but that actually seems to be enough)
					if(p->x >= cb->x - itofix(cb->img[0] / 2) && p->x < cb->x + itofix(cb->img[0] / 2)
					&& p->y >= cb->y - itofix(cb->img[1] / 2) && p->y < cb->y + itofix(cb->img[1] / 2))
					{
						p->hurt();
						destroyBullet = true;
					}
				}
				else
				{
					if(sq(fixtoi(cb->x - p->x)) + sq(fixtoi(cb->y - p->y)) < sq(19)) // sqrt(player.w/2 ^2 + player.h/2 ^2)
					{
						destroyBullet = true;
						G_score += 100;
						G_power += G_power < MAX_POWER;
					}
				}
			}
			else
			{
				// Check collisions with enemies (there are much more enemies than players)
				for(int j = 0; j < MAX_ENEMY; j++)
				{
					if(G_enemiesArray[j]->isActive())
					{
						if(cb->x - itofix(cb->img[0] / 2) <= G_enemiesArray[j]->getx() + itofix(G_enemiesArray[j]->img[0] / 2) &&
						cb->x + itofix(cb->img[0] / 2) >= G_enemiesArray[j]->getx() - itofix(G_enemiesArray[j]->img[0] / 2) &&
						cb->y - itofix(cb->img[1] / 2) <= G_enemiesArray[j]->gety() + itofix(G_enemiesArray[j]->img[1] / 2) &&
						cb->y + itofix(cb->img[1] / 2) >= G_enemiesArray[j]->gety() - itofix(G_enemiesArray[j]->img[1] / 2))
						{
							G_enemiesArray[j]->damage(p, cb->getPolarity(), 1, this);
							G_score += 20;
							if(cb->getPolarity() != G_enemiesArray[j]->getPolarity()) G_score += 20;
							destroyBullet = true;
							// The same bullet can destroy several enemies if it hits them in the same frame !
						}
					}
				}
			}
			if(destroyBullet)
				deactivate(i);
			else
			{
				if(cb->handle())
					deactivate(i);
				else if(!G_skipFrame)
					cb->draw();
			}
		}
		else break;
	}	
	
	// Power fragments
	for(int i = 0; i < MAX_FRAGMENT; i++)
	{
		PowerFragment *cf = &data_fragment[i];
		destroyBullet = false;
		if(cf->isActive())
		{
			if(cf->hurtsPlayer() && !p->isDying())
			{
				// Check collisions with player
				if(cf->getPolarity() != p->getPolarity())
				{
					// the player has a 1px hitbox (for now) (but that actually seems to be enough)
					// power fragments have a 8*8 hitbox
					if(p->x >= cf->x - itofix(4) && p->x < cf->x + itofix(4)
					&& p->y >= cf->y - itofix(4) && p->y < cf->y + itofix(4))
					{
						p->hurt();
						destroyBullet = true;
					}
				}
				else
				{
					if(sq(fixtoi(cf->x - p->x)) + sq(fixtoi(cf->y - p->y)) < sq(p->img[0][0] / 2))
					{
						destroyBullet = true;
						G_score += 100;
						G_power = min(G_power + 10, MAX_POWER);
					}
				}
			}
			else
			{
				// Check collisions with enemies
				// A power fragment can only hit its registered target
				if(cf->targetE)
				{
					if(cf->targetE->isActive())
					{
						if(cf->x - itofix(4) <= cf->targetE->getx() + itofix(cf->targetE->img[0] / 2) &&
						cf->x + itofix(4) >= cf->targetE->getx() - itofix(cf->targetE->img[0] / 2) &&
						cf->y - itofix(4) <= cf->targetE->gety() + itofix(cf->targetE->img[1] / 2) &&
						cf->y + itofix(4) >= cf->targetE->gety() - itofix(cf->targetE->img[1] / 2))
						{
							cf->targetE->damage(p, cf->getPolarity(), 10, this);
							G_score += 20;
							if(cf->getPolarity() != cf->targetE->getPolarity()) G_score += 20;
							destroyBullet = true;
						}
					}
				}
			}
			if(destroyBullet)
				deactivate_fragment(i);
			else
			{
				if(cf->handle())
					deactivate_fragment(i);
				else if(!G_skipFrame)
					cf->draw();
			}
		}
		else break;
	}
	
	// Homings
	for(int i = 0; i < MAX_HOMING; i++)
	{
		Homing* ch = &data_homing[i];
		destroyBullet = false;
		if(ch->isActive())
		{
			if(!p->isDying())
			{
				// Check collisions with player
				if(ch->getPolarity() != p->getPolarity())
				{
					// the player has a 1px hitbox (for now) (but that actually seems to be enough)
					// homings have a 16*16 hitbox
					if(p->x >= ch->x - itofix(8) && p->x < ch->x + itofix(8)
					&& p->y >= ch->y - itofix(8) && p->y < ch->y + itofix(8))
					{
						p->hurt();
						destroyBullet = true;
					}
				}
				else
				{
					if(sq(fixtoi(ch->x - p->x)) + sq(fixtoi(ch->y - p->y)) < sq(p->img[0][0] / 2))
					{
						destroyBullet = true;
						G_score += 100;
						G_power = min(G_power + 10, MAX_POWER);
					}
				}
			}
			if(destroyBullet)
				deactivate_homing(i);
			else
			{
				if(ch->handle())
					deactivate_homing(i);
				else if(!G_skipFrame)
					ch->draw();
			}
		}
		else break;
	}
	
	// Lasers
	for(int i = 0; i < MAX_LASER; i++)
	{
		Rect *r, r1, r2;
		Laser *cl = &data_laser[i];
		if(cl->isActive())
		{
			if(cl->origin->isActive())
			{
				r = cl->getVector();
				cl->getSides(&r1, &r2);
				
				if(!p->isDying())
				{
					// Uses cartesian hitbox for checking collision with player
					// First, see if the player is not too far
					if(sq(fixtoi(p->x) - r->x) + sq(fixtoi(p->y) - r->y) <= sq(cl->getAmplitude()))
					{
						// if we're not too far, carry on collision checking
						// calculate the laser's cartesian equation and apply it to each of its sides
						// ax + by + c = 0
						int a, b, c1, c2;
						a = r->h;
						b = -r->w;
						c1 = -(a * r1.x + b * r1.y);
						c2 = -(a * r2.x + b * r2.y);
						
						if(p->getPolarity() != cl->getPolarity())
						{
							int temp = a * fixtoi(p->x) + b * fixtoi(p->y);
							// Work the player's 1 px hitbox
							if(sign(temp + c1) != sign(temp + c2))
								// Hit !
								p->hurt();
						}
						else
						{
							int temp1 = a * (fixtoi(p->x) - p->img[0][0] / 2) + b * fixtoi(p->y);
							int temp2 = a * (fixtoi(p->x) + p->img[0][0] / 2) + b * fixtoi(p->y);
							
							if(sign(temp1 + c1) != sign(temp1 + c2) || sign(temp2 + c1) != sign(temp2 + c2))
							{
								// Hit, but doesn't hurt
								cl->setAmplitude((int)sqrt(sq(fixtoi(p->x) - r->x) + sq(fixtoi(p->y) - r->y)));
								// Using G_skipFrame as a delay
								if(!G_skipFrame)
								{
									G_power += G_power < MAX_POWER;
									G_score += 100;
								}
								// Lasers are powerful, so they push the player
								p->x += fixcos(cl->angle) / 2;
								p->y += fixsin(cl->angle) / 2;
								
								// Add particles ! Yeeee !
								int k = (rand() % 4) + 1;
								for(int j = 0; j < k; j++)
								{
									Fixed a = cl->angle + 128 + (rand() % 64) - 32;
									G_particles->add(p->x, p->y, fixcos(a) / 2, fixsin(a) / 2, cl->getPolarity());
								}
							}
						}
					}
				}
				
				cl->handle();
				if(!G_skipFrame) cl->draw();
			}
			else
				cl->deactivate();
		}
	}
}