📄 view.cpp
字号:
/******************************************************************************** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.**** This file is part of the example classes of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//* * KAsteroids - Copyright (c) Martin R. Jones 1997 * * Part of the KDE project */#include <stdlib.h>#include <math.h>#include <qapplication.h>#include <qnamespace.h>#include <q3accel.h>#include <qmessagebox.h>#include <q3scrollview.h>#include <qdir.h>#include <QGraphicsItem>//Added by qt3to4:#include <QTimerEvent>#include <QPixmap>#include <QResizeEvent>#include <QShowEvent>#include "view.h"#define IMG_BACKGROUND ":/trolltech/examples/graphicsview/portedasteroids/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#endifstatic struct{ 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(0, 0, 640, 440), view(&field,this){ view.setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); view.setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); view.setCacheMode(QGraphicsView::CacheBackground); view.setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); view.setOptimizationFlag(QGraphicsView::DontClipPainter); view.viewport()->setFocusProxy( this ); rocks.setAutoDelete( TRUE ); missiles.setAutoDelete( TRUE ); bits.setAutoDelete( TRUE ); powerups.setAutoDelete( TRUE ); exhaust.setAutoDelete( TRUE ); QPixmap pm( IMG_BACKGROUND ); field.setBackgroundBrush( pm ); textSprite = new QGraphicsTextItem( 0, &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->setHtml( tr("<font color=red>Error: Cannot read sprite images</font>") ); textSprite->setPos( (field.width()-textSprite->boundingRect().width()) / 2, (field.height()-textSprite->boundingRect().height()) / 2 ); }}// - - -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->setPos( width()/2, height()/2 ); ship->setFrame( 0 ); shield->setPos( width()/2, height()/2 ); shield->setFrame( 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 = ":/trolltech/examples/graphicsview/portedasteroids/sprites/"; int i = 0; while ( kas_animations[i].id ) { QList<QPixmap> anim; QString wildcard = sprites_prefix + kas_animations[i].path; wildcard.replace("%1", "*"); QFileInfo fi(wildcard); foreach (QString entry, QDir(fi.path(), fi.fileName()).entryList()) anim << QPixmap(fi.path() + "/" + entry); animation.insert( kas_animations[i].id, anim ); i++; } ship = new AnimatedPixmapItem( animation[ID_SHIP], &field ); ship->hide(); shield = new KShield( animation[ID_SHIELD], &field ); shield->hide(); return (!ship->image(0).isNull() && !shield->image(0).isNull());}// - - -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->setPos( 5, 5 ); else rock->setPos( 5, field.height() - 25 ); rock->setFrame( 0 ); } else { if ( dy > 0 ) rock->setPos( field.width() - 25, 5 ); else rock->setPos( field.width() - 25, field.height() - 25 ); rock->setFrame( 0 ); } rock->show(); rocks.append( rock ); }}// - - -void KAsteroidsView::showText( const QString &text, const QColor &color, bool scroll ){ if ( !initialized ) return; textSprite->setHtml( QString("<font color=#%1%2%3>%4</font>") .arg(color.red(), 2, 16, QLatin1Char('0')) .arg(color.green(), 2, 16, QLatin1Char('0')) .arg(color.blue(), 2, 16, QLatin1Char('0')) .arg(text) ); Q_UNUSED(color); // ### Porting: no such thing textSprite->setColor( color ); if ( scroll ) { textSprite->setPos( (field.width()-textSprite->boundingRect().width()) / 2, -textSprite->boundingRect().height() ); textDy = TEXT_SPEED; } else { textSprite->setPos( (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.setSceneRect(0, 0, width()-4, height()-4); view.resize(width(),height());}// - - -void KAsteroidsView::timerEvent( QTimerEvent * ){ field.advance(); AnimatedPixmapItem *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->sceneBoundingRect().y() > (field.height()-textSprite->boundingRect().height())/2 ) textDy = 0; } if ( vitalsChanged && !(mFrameNum % 10) ) { emit updateVitals(); vitalsChanged = FALSE; } mFrameNum++;}void KAsteroidsView::wrapSprite( QGraphicsItem *s ){ int x = int(s->x() + s->boundingRect().width() / 2); int y = int(s->y() + s->boundingRect().height() / 2); if ( x > field.width() ) s->setPos( s->x() - field.width(), s->y() ); else if ( x < 0 ) s->setPos( field.width() + s->x(), s->y() ); if ( y > field.height() ) s->setPos( s->x(), s->y() - field.height() ); else if ( y < 0 ) s->setPos( s->x(), field.height() + s->y() );}// - - -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -