📄 view.cpp
字号:
/* * KAsteroids - Copyright (c) Martin R. Jones 1997 * * Part of the KDE project */#include <stdlib.h>#include <math.h>#include <qapplication.h>#include <qkeycode.h>#include <qaccel.h>#include <qmessagebox.h>#include "view.h"#define IMG_BACKGROUND "qasteroids/bg.png"#define REFRESH_DELAY 33#define SHIP_SPEED 0.3#define MISSILE_SPEED 10.0#define SHIP_STEPS 64#define ROTATE_RATE 2#define SHIELD_ON_COST 1#define SHIELD_HIT_COST 30#define BRAKE_ON_COST 4#define MAX_ROCK_SPEED 2.5#define MAX_POWERUP_SPEED 1.5#define MAX_SHIP_SPEED 12#define MAX_BRAKES 5#define MAX_SHIELDS 5#define MAX_FIREPOWER 5#define TEXT_SPEED 4#define PI_X_2 6.283185307#ifndef M_PI#define M_PI 3.141592654#endifstruct{ int id; const char *path; int frames;}kas_animations [] ={ { ID_ROCK_LARGE, "rock1/rock1%1.png", 32 }, { ID_ROCK_MEDIUM, "rock2/rock2%1.png", 32 }, { ID_ROCK_SMALL, "rock3/rock3%1.png", 32 }, { ID_SHIP, "ship/ship%1.png", 32 }, { ID_MISSILE, "missile/missile.png", 1 }, { ID_BIT, "bits/bits%1.png", 16 }, { ID_EXHAUST, "exhaust/exhaust.png", 1 }, { ID_ENERGY_POWERUP, "powerups/energy.png", 1 },// { ID_TELEPORT_POWERUP, "powerups/teleport%1.png", 12 }, { ID_BRAKE_POWERUP, "powerups/brake.png", 1 }, { ID_SHIELD_POWERUP, "powerups/shield.png", 1 }, { ID_SHOOT_POWERUP, "powerups/shoot.png", 1 }, { ID_SHIELD, "shield/shield%1.png", 6 }, { 0, 0, 0 }};KAsteroidsView::KAsteroidsView( QWidget *parent, const char *name ) : QWidget( parent, name ), field(640, 440), view(&field,this){ view.setVScrollBarMode( QScrollView::AlwaysOff ); view.setHScrollBarMode( QScrollView::AlwaysOff ); view.viewport()->setFocusProxy( this ); rocks.setAutoDelete( TRUE ); missiles.setAutoDelete( TRUE ); bits.setAutoDelete( TRUE ); powerups.setAutoDelete( TRUE ); exhaust.setAutoDelete( TRUE ); field.setBackgroundColor( black ); QPixmap pm( IMG_BACKGROUND ); field.setBackgroundPixmap( pm ); textSprite = new QCanvasText( &field ); QFont font( "helvetica", 18 ); textSprite->setFont( font ); shield = 0; shieldOn = FALSE; refreshRate = REFRESH_DELAY; initialized = readSprites(); shieldTimer = new QTimer( this ); connect( shieldTimer, SIGNAL(timeout()), this, SLOT(hideShield()) ); mTimerId = -1; shipPower = MAX_POWER_LEVEL; vitalsChanged = TRUE; can_destroy_powerups = FALSE; mPaused = TRUE; if ( !initialized ) { textSprite->setText( tr("Error: Cannot read sprite images") ); textSprite->setColor( red ); textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2, (field.height()-textSprite->boundingRect().height()) / 2 ); textSprite->show(); }}// - - -KAsteroidsView::~KAsteroidsView(){}// - - -void KAsteroidsView::reset(){ if ( !initialized ) return; rocks.clear(); missiles.clear(); bits.clear(); powerups.clear(); exhaust.clear(); shotsFired = 0; shotsHit = 0; rockSpeed = 1.0; powerupSpeed = 1.0; mFrameNum = 0; mPaused = FALSE; ship->hide(); shield->hide();/* if ( mTimerId >= 0 ) { killTimer( mTimerId ); mTimerId = -1; }*/}// - --void KAsteroidsView::newGame(){ if ( !initialized ) return; if ( shieldOn ) { shield->hide(); shieldOn = FALSE; } reset(); if ( mTimerId < 0 ) mTimerId = startTimer( REFRESH_DELAY ); emit updateVitals();}// - - -void KAsteroidsView::endGame(){}void KAsteroidsView::pause( bool p ){ if ( !initialized ) return; if ( !mPaused && p ) { if ( mTimerId >= 0 ) { killTimer( mTimerId ); mTimerId = -1; } } else if ( mPaused && !p ) mTimerId = startTimer( REFRESH_DELAY ); mPaused = p;}// - - -void KAsteroidsView::newShip(){ if ( !initialized ) return; ship->move( width()/2, height()/2, 0 ); shield->move( width()/2, height()/2, 0 ); ship->setVelocity( 0.0, 0.0 ); shipDx = 0; shipDy = 0; shipAngle = 0; rotateL = FALSE; rotateR = FALSE; thrustShip = FALSE; shootShip = FALSE; brakeShip = FALSE; teleportShip = FALSE; shieldOn = TRUE; shootDelay = 0; shipPower = MAX_POWER_LEVEL; rotateRate = ROTATE_RATE; rotateSlow = 0; mBrakeCount = 0; mTeleportCount = 0; mShootCount = 0; ship->show(); shield->show(); mShieldCount = 1; // just in case the ship appears on a rock. shieldTimer->start( 1000, TRUE );}void KAsteroidsView::setShield( bool s ){ if ( !initialized ) return; if ( shieldTimer->isActive() && !s ) { shieldTimer->stop(); hideShield(); } else { shieldOn = s && mShieldCount; }}void KAsteroidsView::brake( bool b ){ if ( !initialized ) return; if ( mBrakeCount ) { if ( brakeShip && !b ) { rotateL = FALSE; rotateR = FALSE; thrustShip = FALSE; rotateRate = ROTATE_RATE; } brakeShip = b; }}// - - -bool KAsteroidsView::readSprites(){ QString sprites_prefix = "qasteroids/sprites/"; int i = 0; while ( kas_animations[i].id ) { QCanvasPixmapArray *anim = new QCanvasPixmapArray( sprites_prefix + kas_animations[i].path, kas_animations[i].frames ); if ( !anim->isValid() ) return FALSE; animation.insert( kas_animations[i].id, anim ); i++; } ship = new QCanvasSprite( animation[ID_SHIP], &field ); ship->hide(); shield = new KShield( animation[ID_SHIELD], &field ); shield->hide(); return (ship->image(0) && shield->image(0));}// - - -void KAsteroidsView::addRocks( int num ){ if ( !initialized ) return; for ( int i = 0; i < num; i++ ) { KRock *rock = new KRock( animation[ID_ROCK_LARGE], &field, ID_ROCK_LARGE, randInt(2), randInt(2) ? -1 : 1 ); double dx = (2.0 - randDouble()*4.0) * rockSpeed; double dy = (2.0 - randDouble()*4.0) * rockSpeed; rock->setVelocity( dx, dy ); rock->setFrame( randInt( rock->frameCount() ) ); if ( dx > 0 ) { if ( dy > 0 ) rock->move( 5, 5, 0 ); else rock->move( 5, field.height() - 25, 0 ); } else { if ( dy > 0 ) rock->move( field.width() - 25, 5, 0 ); else rock->move( field.width() - 25, field.height() - 25, 0 ); } rock->show( ); rocks.append( rock ); }}// - - -void KAsteroidsView::showText( const QString &text, const QColor &color, bool scroll ){ if ( !initialized ) return; textSprite->setText( text ); textSprite->setColor( color ); if ( scroll ) { textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2, -textSprite->boundingRect().height() ); textDy = TEXT_SPEED; } else { textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2, (field.height()-textSprite->boundingRect().height()) / 2 ); textDy = 0; } textSprite->show();}// - - -void KAsteroidsView::hideText(){ textDy = -TEXT_SPEED;}// - - -void KAsteroidsView::resizeEvent(QResizeEvent* event){ QWidget::resizeEvent(event); field.resize(width()-4, height()-4); view.resize(width(),height());}// - - -void KAsteroidsView::timerEvent( QTimerEvent * ){ field.advance(); QCanvasSprite *rock; // move rocks forward for ( rock = rocks.first(); rock; rock = rocks.next() ) { ((KRock *)rock)->nextFrame(); wrapSprite( rock ); } wrapSprite( ship ); // check for missile collision with rocks. processMissiles(); // these are generated when a ship explodes for ( KBit *bit = bits.first(); bit; bit = bits.next() ) { if ( bit->expired() ) { bits.removeRef( bit ); } else { bit->growOlder(); bit->setFrame( ( bit->frame()+1 ) % bit->frameCount() ); } } for ( KExhaust *e = exhaust.first(); e; e = exhaust.next() ) exhaust.removeRef( e ); // move / rotate ship. // check for collision with a rock. processShip(); // move powerups and check for collision with player and missiles processPowerups(); if ( textSprite->isVisible() ) { if ( textDy < 0 && textSprite->boundingRect().y() <= -textSprite->boundingRect().height() ) { textSprite->hide(); } else { textSprite->moveBy( 0, textDy ); } if ( textSprite->boundingRect().y() > (field.height()-textSprite->boundingRect().height())/2 ) textDy = 0; } if ( vitalsChanged && !(mFrameNum % 10) ) { emit updateVitals(); vitalsChanged = FALSE; } mFrameNum++;}void KAsteroidsView::wrapSprite( QCanvasItem *s ){ int x = int(s->x() + s->boundingRect().width() / 2); int y = int(s->y() + s->boundingRect().height() / 2); if ( x > field.width() ) s->move( s->x() - field.width(), s->y() ); else if ( x < 0 ) s->move( field.width() + s->x(), s->y() ); if ( y > field.height() ) s->move( s->x(), s->y() - field.height() ); else if ( y < 0 ) s->move( s->x(), field.height() + s->y() );}// - - -void KAsteroidsView::rockHit( QCanvasItem *hit ){ KPowerup *nPup = 0; int rnd = int(randDouble()*30.0) % 30; switch( rnd ) { case 4: case 5: nPup = new KPowerup( animation[ID_ENERGY_POWERUP], &field, ID_ENERGY_POWERUP ); break; case 10:// nPup = new KPowerup( animation[ID_TELEPORT_POWERUP], &field,// ID_TELEPORT_POWERUP ); break; case 15: nPup = new KPowerup( animation[ID_BRAKE_POWERUP], &field, ID_BRAKE_POWERUP ); break; case 20: nPup = new KPowerup( animation[ID_SHIELD_POWERUP], &field, ID_SHIELD_POWERUP ); break; case 24: case 25: nPup = new KPowerup( animation[ID_SHOOT_POWERUP], &field, ID_SHOOT_POWERUP );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -