📄 view.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************//* * KAsteroids - Copyright (c) Martin R. Jones 1997 * * Part of the KDE project */#include "view.h"#include <qtopia/resource.h>#include <qapplication.h>#include <qkeycode.h>#include <qaccel.h>#include <stdlib.h>#include <math.h>#define IMG_BACKGROUND "qasteroids/bg"#define REFRESH_DELAY 33#define SHIP_SPEED 0.3#ifndef QTOPIA_PHONE# define MISSILE_SPEED 10.0#else# define MISSILE_SPEED 6.0#endif#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 8#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", 0 }, { ID_BIT, "bits/bits\%1.png", 16 }, { ID_EXHAUST, "exhaust/exhaust.png", 0 }, { ID_ENERGY_POWERUP, "powerups/energy.png", 0 },// { ID_TELEPORT_POWERUP, "powerups/teleport%1.png", 12 }, { ID_BRAKE_POWERUP, "powerups/brake.png", 0 }, { ID_SHIELD_POWERUP, "powerups/shield.png", 0 }, { ID_SHOOT_POWERUP, "powerups/shoot.png", 0 }, { ID_SHIELD, "shield/shield\%1.png", 6 }, { 0, 0, 0 }};KAsteroidsView::KAsteroidsView( QWidget *parent, const char *name ) : QWidget( parent, name ), field(200, 200), view(&field,this){ view.setVScrollBarMode( QScrollView::AlwaysOff ); view.setHScrollBarMode( QScrollView::AlwaysOff ); rocks.setAutoDelete( TRUE ); missiles.setAutoDelete( TRUE ); bits.setAutoDelete( TRUE ); powerups.setAutoDelete( TRUE ); exhaust.setAutoDelete( TRUE ); QPixmap pm( Resource::loadPixmap(IMG_BACKGROUND) ); field.setBackgroundPixmap( pm ); textSprite = new QCanvasText( &field ); QFont font( "helvetica", 12 ); textSprite->setFont( font ); shield = 0; shieldOn = FALSE; refreshRate = REFRESH_DELAY; readSprites(); shieldTimer = new QTimer( this ); connect( shieldTimer, SIGNAL(timeout()), this, SLOT(hideShield()) ); mTimerId = -1; shipPower = MAX_POWER_LEVEL; vitalsChanged = FALSE; can_destroy_powerups = FALSE; mPaused = TRUE; gameover = TRUE;}// - - -KAsteroidsView::~KAsteroidsView(){}// - - -void KAsteroidsView::reset(){ 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(){ gameover = FALSE; if ( shieldOn ) { shield->hide(); shieldOn = FALSE; } reset(); if ( mTimerId < 0 ) mTimerId = startTimer( REFRESH_DELAY ); emit updateVitals();}// - - -void KAsteroidsView::endGame(){ gameover = TRUE;}void KAsteroidsView::pause( bool p ){ if ( !mPaused && p ) { if ( mTimerId >= 0 ) { killTimer( mTimerId ); mTimerId = -1; } } else if ( mPaused && !p ) mTimerId = startTimer( REFRESH_DELAY ); mPaused = p;}// - - -void KAsteroidsView::newShip(){ ship->move( field.width()/2, field.height()/2, 0 ); shield->move( field.width()/2, field.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 ( shieldTimer->isActive() && !s ) { shieldTimer->stop(); hideShield(); } else { shieldOn = s && mShieldCount; }}void KAsteroidsView::brake( bool b ){ if ( mBrakeCount ) { if ( brakeShip && !b ) { rotateL = FALSE; rotateR = FALSE; thrustShip = FALSE; rotateRate = ROTATE_RATE; } brakeShip = b; }}// - - -void KAsteroidsView::readSprites(){ QString sprites_prefix = Resource::findPixmap( IMG_BACKGROUND ); int sep = sprites_prefix.findRev( "/" ); sprites_prefix.truncate( sep ); int i = 0; while ( kas_animations[i].id ) { animation.insert( kas_animations[i].id, new QCanvasPixmapArray( sprites_prefix + "/" + kas_animations[i].path, kas_animations[i].frames ) ); i++; } ship = new QCanvasSprite( animation[ID_SHIP], &field ); ship->hide(); shield = new KShield( animation[ID_SHIELD], &field ); shield->hide();}// - - -void KAsteroidsView::addRocks( int num ){ for ( int i = 0; i < num; i++ ) { KRock *rock = new KRock( animation[ID_ROCK_MEDIUM], &field, ID_ROCK_MEDIUM, 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 ){ textSprite->setTextFlags( AlignLeft | AlignVCenter); 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->visible() ) { 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;#ifdef QTOPIA_PHONE const int range = 60;#else const int range = 30;#endif int rnd = static_cast<int>(randDouble()*range) % range; 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -