📄 view.cpp
字号:
break; } if ( nPup ) { double r = 0.5 - randDouble(); nPup->move( hit->x(), hit->y(), 0 ); nPup->setVelocity( hit->xVelocity() + r, hit->yVelocity() + r ); nPup->show( ); powerups.append( nPup ); } if ( hit->rtti() == ID_ROCK_LARGE || hit->rtti() == ID_ROCK_MEDIUM ) { // break into smaller rocks double addx[4] = { 1.0, 1.0, -1.0, -1.0 }; double addy[4] = { -1.0, 1.0, -1.0, 1.0 }; double dx = hit->xVelocity(); double dy = hit->yVelocity(); double maxRockSpeed = MAX_ROCK_SPEED * rockSpeed; if ( dx > maxRockSpeed ) dx = maxRockSpeed; else if ( dx < -maxRockSpeed ) dx = -maxRockSpeed; if ( dy > maxRockSpeed ) dy = maxRockSpeed; else if ( dy < -maxRockSpeed ) dy = -maxRockSpeed; QCanvasSprite *nrock; for ( int i = 0; i < 4; i++ ) { double r = rockSpeed/2 - randDouble()*rockSpeed; if ( hit->rtti() == ID_ROCK_LARGE ) { nrock = new KRock( animation[ID_ROCK_MEDIUM], &field, ID_ROCK_MEDIUM, randInt(2), randInt(2) ? -1 : 1 ); emit rockHit( 0 ); } else { nrock = new KRock( animation[ID_ROCK_SMALL], &field, ID_ROCK_SMALL, randInt(2), randInt(2) ? -1 : 1 ); emit rockHit( 1 ); } nrock->move( hit->x(), hit->y(), 0 ); nrock->setVelocity( dx+addx[i]*rockSpeed+r, dy+addy[i]*rockSpeed+r ); nrock->setFrame( randInt( nrock->frameCount() ) ); nrock->show( ); rocks.append( nrock ); } } else if ( hit->rtti() == ID_ROCK_SMALL ) emit rockHit( 2 ); rocks.removeRef( (QCanvasSprite *)hit ); if ( rocks.count() == 0 ) emit rocksRemoved();}void KAsteroidsView::reducePower( int val ){ shipPower -= val; if ( shipPower <= 0 ) { shipPower = 0; thrustShip = FALSE; if ( shieldOn ) { shieldOn = FALSE; shield->hide(); } } vitalsChanged = TRUE;}void KAsteroidsView::addExhaust( double x, double y, double dx, double dy, int count ){ for ( int i = 0; i < count; i++ ) { KExhaust *e = new KExhaust( animation[ID_EXHAUST], &field ); e->move( x + 2 - randDouble()*4, y + 2 - randDouble()*4 ); e->setVelocity( dx, dy ); e->show( ); exhaust.append( e ); }}void KAsteroidsView::processMissiles(){ KMissile *missile; // if a missile has hit a rock, remove missile and break rock into smaller // rocks or remove completely. QPtrListIterator<KMissile> it(missiles); for ( ; it.current(); ++it ) { missile = it.current(); missile->growOlder(); if ( missile->expired() ) { missiles.removeRef( missile ); continue; } wrapSprite( missile ); QCanvasItemList hits = missile->collisions( TRUE ); QCanvasItemList::Iterator hit; for ( hit = hits.begin(); hit != hits.end(); ++hit ) { if ( (*hit)->rtti() >= ID_ROCK_LARGE && (*hit)->rtti() <= ID_ROCK_SMALL ) { shotsHit++; rockHit( *hit ); missiles.removeRef( missile ); break; } } }}// - - -void KAsteroidsView::processShip(){ if ( ship->isVisible() ) { if ( shieldOn ) { shield->show(); reducePower( SHIELD_ON_COST ); static int sf = 0; sf++; if ( sf % 2 ) shield->setFrame( (shield->frame()+1) % shield->frameCount() ); shield->move( ship->x() - 9, ship->y() - 9 ); QCanvasItemList hits = shield->collisions( TRUE ); QCanvasItemList::Iterator it; for ( it = hits.begin(); it != hits.end(); ++it ) { if ( (*it)->rtti() >= ID_ROCK_LARGE && (*it)->rtti() <= ID_ROCK_SMALL ) { int factor; switch ( (*it)->rtti() ) { case ID_ROCK_LARGE: factor = 3; break; case ID_ROCK_MEDIUM: factor = 2; break; default: factor = 1; } if ( factor > mShieldCount ) { // shield not strong enough shieldOn = FALSE; break; } rockHit( *it ); // the more shields we have the less costly reducePower( factor * (SHIELD_HIT_COST - mShieldCount*2) ); } } } if ( !shieldOn ) { shield->hide(); QCanvasItemList hits = ship->collisions( TRUE ); QCanvasItemList::Iterator it; for ( it = hits.begin(); it != hits.end(); ++it ) { if ( (*it)->rtti() >= ID_ROCK_LARGE && (*it)->rtti() <= ID_ROCK_SMALL ) { KBit *bit; for ( int i = 0; i < 12; i++ ) { bit = new KBit( animation[ID_BIT], &field ); bit->move( ship->x() + 5 - randDouble() * 10, ship->y() + 5 - randDouble() * 10, randInt(bit->frameCount()) ); bit->setVelocity( 1-randDouble()*2, 1-randDouble()*2 ); bit->setDeath( 60 + randInt(60) ); bit->show( ); bits.append( bit ); } ship->hide(); shield->hide(); emit shipKilled(); break; } } } if ( rotateSlow ) rotateSlow--; if ( rotateL ) { shipAngle -= rotateSlow ? 1 : rotateRate; if ( shipAngle < 0 ) shipAngle += SHIP_STEPS; } if ( rotateR ) { shipAngle += rotateSlow ? 1 : rotateRate; if ( shipAngle >= SHIP_STEPS ) shipAngle -= SHIP_STEPS; } double angle = shipAngle * PI_X_2 / SHIP_STEPS; double cosangle = cos( angle ); double sinangle = sin( angle ); if ( brakeShip ) { thrustShip = FALSE; rotateL = FALSE; rotateR = FALSE; rotateRate = ROTATE_RATE; if ( fabs(shipDx) < 2.5 && fabs(shipDy) < 2.5 ) { shipDx = 0.0; shipDy = 0.0; ship->setVelocity( shipDx, shipDy ); brakeShip = FALSE; } else { double motionAngle = atan2( -shipDy, -shipDx ); if ( angle > M_PI ) angle -= PI_X_2; double angleDiff = angle - motionAngle; if ( angleDiff > M_PI ) angleDiff = PI_X_2 - angleDiff; else if ( angleDiff < -M_PI ) angleDiff = PI_X_2 + angleDiff; double fdiff = fabs( angleDiff ); if ( fdiff > 0.08 ) { if ( angleDiff > 0 ) rotateL = TRUE; else if ( angleDiff < 0 ) rotateR = TRUE; if ( fdiff > 0.6 ) rotateRate = mBrakeCount + 1; else if ( fdiff > 0.4 ) rotateRate = 2; else rotateRate = 1; if ( rotateRate > 5 ) rotateRate = 5; } else if ( fabs(shipDx) > 1 || fabs(shipDy) > 1 ) { thrustShip = TRUE; // we'll make braking a bit faster shipDx += cosangle/6 * (mBrakeCount - 1); shipDy += sinangle/6 * (mBrakeCount - 1); reducePower( BRAKE_ON_COST ); addExhaust( ship->x() + 20 - cosangle*22, ship->y() + 20 - sinangle*22, shipDx-cosangle, shipDy-sinangle, mBrakeCount+1 ); } } } if ( thrustShip ) { // The ship has a terminal velocity, but trying to go faster // still uses fuel (can go faster diagonally - don't care). double thrustx = cosangle/4; double thrusty = sinangle/4; if ( fabs(shipDx + thrustx) < MAX_SHIP_SPEED ) shipDx += thrustx; if ( fabs(shipDy + thrusty) < MAX_SHIP_SPEED ) shipDy += thrusty; ship->setVelocity( shipDx, shipDy ); reducePower( 1 ); addExhaust( ship->x() + 20 - cosangle*20, ship->y() + 20 - sinangle*20, shipDx-cosangle, shipDy-sinangle, 3 ); } ship->setFrame( shipAngle >> 1 ); if ( shootShip ) { if ( !shootDelay && (int)missiles.count() < mShootCount + 2 ) { KMissile *missile = new KMissile( animation[ID_MISSILE], &field ); missile->move( 21+ship->x()+cosangle*21, 21+ship->y()+sinangle*21, 0 ); missile->setVelocity( shipDx + cosangle*MISSILE_SPEED, shipDy + sinangle*MISSILE_SPEED ); missile->show( ); missiles.append( missile ); shotsFired++; reducePower( 1 ); shootDelay = 5; } if ( shootDelay ) shootDelay--; } if ( teleportShip ) { int ra = rand() % 10; if( ra == 0 ) ra += rand() % 20; int xra = ra * 60 + ( (rand() % 20) * (rand() % 20) ); int yra = ra * 50 - ( (rand() % 20) * (rand() % 20) ); ship->move( xra, yra ); } vitalsChanged = TRUE; }}// - - -void KAsteroidsView::processPowerups(){ if ( !powerups.isEmpty() ) { // if player gets the powerup remove it from the screen, if option // "Can destroy powerups" is enabled and a missile hits the powerup // destroy it KPowerup *pup; QPtrListIterator<KPowerup> it( powerups ); for( ; it.current(); ++it ) { pup = it.current(); pup->growOlder(); if( pup->expired() ) { powerups.removeRef( pup ); continue; } wrapSprite( pup ); QCanvasItemList hits = pup->collisions( TRUE ); QCanvasItemList::Iterator it; for ( it = hits.begin(); it != hits.end(); ++it ) { if ( (*it) == ship ) { switch( pup->rtti() ) { case ID_ENERGY_POWERUP: shipPower += 150; if ( shipPower > MAX_POWER_LEVEL ) shipPower = MAX_POWER_LEVEL; break; case ID_TELEPORT_POWERUP: mTeleportCount++; break; case ID_BRAKE_POWERUP: if ( mBrakeCount < MAX_BRAKES ) mBrakeCount++; break; case ID_SHIELD_POWERUP: if ( mShieldCount < MAX_SHIELDS ) mShieldCount++; break; case ID_SHOOT_POWERUP: if ( mShootCount < MAX_FIREPOWER ) mShootCount++; break; } powerups.removeRef( pup ); vitalsChanged = TRUE; } else if ( (*it) == shield ) { powerups.removeRef( pup ); } else if ( (*it)->rtti() == ID_MISSILE ) { if ( can_destroy_powerups ) { powerups.removeRef( pup ); } } } } } // -- if( powerups.isEmpty() )}// - - -void KAsteroidsView::hideShield(){ shield->hide(); mShieldCount = 0; shieldOn = FALSE;}double KAsteroidsView::randDouble(){ int v = rand(); return (double)v / (double)RAND_MAX;}int KAsteroidsView::randInt( int range ){ return rand() % range;}void KAsteroidsView::showEvent( QShowEvent *e ){#if defined( QT_LICENSE_PROFESSIONAL ) static bool wasThere = FALSE; if ( !wasThere ) { wasThere = TRUE; QMessageBox::information( this, tr("QCanvas demo"), tr("This game has been implemented using the QCanvas class.\n" "The QCanvas class is not part of the Professional Edition. Please \n" "contact Trolltech if you want to upgrade to the Enterprise Edition.") ); }#endif QWidget::showEvent( e );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -