summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/qasteroids/toplevel.cpp9
-rw-r--r--noncore/games/qasteroids/view.cpp14
2 files changed, 10 insertions, 13 deletions
diff --git a/noncore/games/qasteroids/toplevel.cpp b/noncore/games/qasteroids/toplevel.cpp
index 9053d3d..d1e1fac 100644
--- a/noncore/games/qasteroids/toplevel.cpp
+++ b/noncore/games/qasteroids/toplevel.cpp
@@ -1,533 +1,534 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** 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
*/
// --- toplevel.cpp ---
#include "toplevel.h"
#include "ledmeter.h"
+#include <opie2/oresource.h>
+
#include <qpe/qpeapplication.h>
-#include <qpe/resource.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qlcdnumber.h>
#include <sys/utsname.h>
#define SB_SCORE 1
#define SB_LEVEL 2
#define SB_SHIPS 3
struct SLevel
{
int nrocks;
double rockSpeed;
};
#define MAX_LEVELS 16
SLevel levels[MAX_LEVELS] =
{
{ 1, 0.4 },
{ 1, 0.6 },
{ 2, 0.5 },
{ 2, 0.7 },
{ 2, 0.8 },
{ 3, 0.6 },
{ 3, 0.7 },
{ 3, 0.8 },
{ 4, 0.6 },
{ 4, 0.7 },
{ 4, 0.8 },
{ 5, 0.7 },
{ 5, 0.8 },
{ 5, 0.9 },
{ 5, 1.0 }
};
const char *soundEvents[] =
{
"ShipDestroyed",
"RockDestroyed",
0
};
const char *soundDefaults[] =
{
"Explosion.wav",
"ploop.wav",
0
};
KAstTopLevel::KAstTopLevel( QWidget *parent, const char *_name, WFlags fl )
: QMainWindow( parent, _name, fl )
{
setCaption( tr("Asteroids") );
QPEApplication::grabKeyboard();
QWidget *border = new QWidget( this );
border->setBackgroundColor( black );
setCentralWidget( border );
QVBoxLayout *borderLayout = new QVBoxLayout( border );
QWidget *mainWin = new QWidget( border );
borderLayout->addWidget( mainWin, 2, AlignHCenter );
view = new KAsteroidsView( mainWin );
connect( view, SIGNAL( shipKilled() ), SLOT( slotShipKilled() ) );
connect( view, SIGNAL( rockHit(int) ), SLOT( slotRockHit(int) ) );
connect( view, SIGNAL( rocksRemoved() ), SLOT( slotRocksRemoved() ) );
connect( view, SIGNAL( updateVitals() ), SLOT( slotUpdateVitals() ) );
QVBoxLayout *vb = new QVBoxLayout( mainWin );
QHBoxLayout *hb = new QHBoxLayout;
QHBoxLayout *hbd = new QHBoxLayout;
vb->addLayout( hb );
QFont labelFont( "helvetica", 12 );
QColorGroup grp( darkGreen, black, QColor( 128, 128, 128 ),
QColor( 64, 64, 64 ), black, darkGreen, black );
QPalette pal( grp, grp, grp );
mainWin->setPalette( pal );
QLabel *label;
label = new QLabel( tr("Score"), mainWin );
label->setFont( labelFont );
label->setPalette( pal );
// label->setFixedWidth( label->sizeHint().width() );
hb->addWidget( label );
scoreLCD = new QLCDNumber( 5, mainWin );
scoreLCD->setFrameStyle( QFrame::NoFrame );
scoreLCD->setSegmentStyle( QLCDNumber::Flat );
scoreLCD->setFixedHeight( 16 );
scoreLCD->setPalette( pal );
hb->addWidget( scoreLCD );
hb->addStretch( 1 );
label = new QLabel( tr("Level"), mainWin );
label->setFont( labelFont );
label->setPalette( pal );
// label->setFixedWidth( label->sizeHint().width() );
hb->addWidget( label );
levelLCD = new QLCDNumber( 2, mainWin );
levelLCD->setFrameStyle( QFrame::NoFrame );
levelLCD->setSegmentStyle( QLCDNumber::Flat );
levelLCD->setFixedHeight( 16 );
levelLCD->setPalette( pal );
hb->addWidget( levelLCD );
hb->addStretch( 1 );
label = new QLabel( tr("Ships"), mainWin );
label->setFont( labelFont );
// label->setFixedWidth( label->sizeHint().width() );
label->setPalette( pal );
hb->addWidget( label );
shipsLCD = new QLCDNumber( 1, mainWin );
shipsLCD->setFrameStyle( QFrame::NoFrame );
shipsLCD->setSegmentStyle( QLCDNumber::Flat );
shipsLCD->setFixedHeight( 16 );
shipsLCD->setPalette( pal );
hb->addWidget( shipsLCD );
// hb->addStrut( 14 );
vb->addWidget( view, 10 );
// -- bottom layout:
vb->addLayout( hbd );
QFont smallFont( "helvetica", 12 );
hbd->addSpacing( 5 );
/*
label = new QLabel( tr( "T" ), mainWin );
label->setFont( smallFont );
label->setFixedWidth( label->sizeHint().width() );
label->setPalette( pal );
hbd->addWidget( label );
teleportsLCD = new QLCDNumber( 1, mainWin );
teleportsLCD->setFrameStyle( QFrame::NoFrame );
teleportsLCD->setSegmentStyle( QLCDNumber::Flat );
teleportsLCD->setPalette( pal );
teleportsLCD->setFixedHeight( 18 );
hbd->addWidget( teleportsLCD );
hbd->addSpacing( 10 );
*/
label = new QLabel( mainWin );
- label->setPixmap( Resource::loadPixmap("qasteroids/powerups/brake.png") );
+ label->setPixmap( Opie::Core::OResource::loadPixmap("qasteroids/powerups/brake.png") );
label->setFixedWidth( 16 );
label->setPalette( pal );
hbd->addWidget( label );
brakesLCD = new QLCDNumber( 1, mainWin );
brakesLCD->setFrameStyle( QFrame::NoFrame );
brakesLCD->setSegmentStyle( QLCDNumber::Flat );
brakesLCD->setPalette( pal );
brakesLCD->setFixedHeight( 16 );
hbd->addWidget( brakesLCD );
hbd->addSpacing( 5 );
label = new QLabel( mainWin );
- label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shield.png") );
+ label->setPixmap( Opie::Core::OResource::loadPixmap("qasteroids/powerups/shield.png") );
label->setFixedWidth( 16 );
label->setPalette( pal );
hbd->addWidget( label );
shieldLCD = new QLCDNumber( 1, mainWin );
shieldLCD->setFrameStyle( QFrame::NoFrame );
shieldLCD->setSegmentStyle( QLCDNumber::Flat );
shieldLCD->setPalette( pal );
shieldLCD->setFixedHeight( 16 );
hbd->addWidget( shieldLCD );
hbd->addSpacing( 5 );
label = new QLabel( mainWin );
- label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shoot.png") );
+ label->setPixmap( Opie::Core::OResource::loadPixmap("qasteroids/powerups/shoot.png") );
label->setFixedWidth( 16 );
label->setPalette( pal );
hbd->addWidget( label );
shootLCD = new QLCDNumber( 1, mainWin );
shootLCD->setFrameStyle( QFrame::NoFrame );
shootLCD->setSegmentStyle( QLCDNumber::Flat );
shootLCD->setPalette( pal );
shootLCD->setFixedHeight( 16 );
hbd->addWidget( shootLCD );
hbd->addStretch( 1 );
label = new QLabel( tr( "Fuel" ), mainWin );
label->setFont( smallFont );
label->setFixedWidth( label->sizeHint().width() + 5 );
label->setPalette( pal );
hbd->addWidget( label );
powerMeter = new KALedMeter( mainWin );
powerMeter->setFrameStyle( QFrame::Box | QFrame::Plain );
powerMeter->setRange( MAX_POWER_LEVEL );
powerMeter->addColorRange( 10, darkRed );
powerMeter->addColorRange( 20, QColor(160, 96, 0) );
powerMeter->addColorRange( 70, darkGreen );
powerMeter->setCount( 15 );
powerMeter->setPalette( pal );
powerMeter->setFixedSize( 60, 12 );
hbd->addWidget( powerMeter );
shipsRemain = 3;
showHiscores = FALSE;
actions.insert( Qt::Key_Up, Thrust );
actions.insert( Qt::Key_Left, RotateLeft );
actions.insert( Qt::Key_Right, RotateRight );
actions.insert( Qt::Key_Enter, Shoot );
actions.insert( Qt::Key_Z, Teleport );
actions.insert( Qt::Key_Down, Brake );
actions.insert( Qt::Key_P, Pause );
struct utsname name; /* check for embedix kernel running on the zaurus, if
lineo change string, this break
*/
if (uname(&name) != -1) {
QString release=name.release;
if(release.find("embedix",0,TRUE) !=-1) {
actions.insert( Key_F12, Launch );
actions.insert( Key_F11, Shield );
actions.insert( Key_F9, NewGame );
} else {
// ipaq
actions.insert( Key_F12, Shoot );
actions.insert( Key_F11, Shield );
actions.insert( Key_F10, Launch );
actions.insert( Key_F9, NewGame );
}
}
// actions.insert( Qt::Key_S, Shield );
// actions.insert( Qt::Key_X, Brake );
// actions.insert( Qt::Key_L, Launch );
actions.insert( Qt::Key_Space, Shoot );
view->showText( tr( "Press Calendar to start playing" ), yellow );
setFocusPolicy( StrongFocus );
slotNewGame();
}
KAstTopLevel::~KAstTopLevel()
{
}
void KAstTopLevel::playSound( const char * )
{
}
void KAstTopLevel::keyPressEvent( QKeyEvent *event )
{
if ( event->isAutoRepeat() || !actions.contains( event->key() ) )
{
event->ignore();
return;
}
Action a = actions[ event->key() ];
switch ( a )
{
case RotateLeft:
view->rotateLeft( TRUE );
break;
case RotateRight:
view->rotateRight( TRUE );
break;
case Thrust:
view->thrust( TRUE );
break;
case Shoot:
view->shoot( TRUE );
break;
case Shield:
view->setShield( TRUE );
break;
case Teleport:
view->teleport( TRUE );
break;
case Brake:
view->brake( TRUE );
break;
default:
event->ignore();
return;
}
event->accept();
}
void KAstTopLevel::keyReleaseEvent( QKeyEvent *event )
{
if ( event->isAutoRepeat() || !actions.contains( event->key() ) )
{
event->ignore();
return;
}
Action a = actions[ event->key() ];
switch ( a )
{
case RotateLeft:
view->rotateLeft( FALSE );
break;
case RotateRight:
view->rotateRight( FALSE );
break;
case Thrust:
view->thrust( FALSE );
break;
case Shoot:
view->shoot( FALSE );
break;
case Brake:
view->brake( FALSE );
break;
case Shield:
view->setShield( FALSE );
break;
case Teleport:
view->teleport( FALSE );
break;
case Launch:
if ( waitShip )
{
view->newShip();
waitShip = FALSE;
view->hideText();
}
else
{
event->ignore();
return;
}
break;
case NewGame:
slotNewGame();
break;
/*
case Pause:
{
view->pause( TRUE );
QMessageBox::information( this,
tr("KAsteroids is paused"),
tr("Paused") );
view->pause( FALSE );
}
break;
*/
default:
event->ignore();
return;
}
event->accept();
}
void KAstTopLevel::showEvent( QShowEvent *e )
{
QMainWindow::showEvent( e );
view->pause( FALSE );
setFocus();
}
void KAstTopLevel::hideEvent( QHideEvent *e )
{
QMainWindow::hideEvent( e );
view->pause( TRUE );
}
void KAstTopLevel::focusInEvent( QFocusEvent * )
{
view->pause( FALSE );
setFocus();
}
void KAstTopLevel::focusOutEvent( QFocusEvent * )
{
view->pause( TRUE );
}
void KAstTopLevel::slotNewGame()
{
shipsRemain = 3;
score = 0;
scoreLCD->display( 0 );
level = 0;
levelLCD->display( level+1 );
shipsLCD->display( shipsRemain-1 );
view->newGame();
view->setRockSpeed( levels[0].rockSpeed );
view->addRocks( levels[0].nrocks );
view->newShip();
waitShip = FALSE;
view->hideText();
isPaused = FALSE;
}
void KAstTopLevel::slotShipKilled()
{
shipsRemain--;
shipsLCD->display( shipsRemain-1 );
playSound( "ShipDestroyed" );
if ( shipsRemain > 0 )
{
waitShip = TRUE;
view->showText( tr( "Ship Destroyed.\nPress Contacts/Home key."), yellow );
}
else
{
view->endGame();
doStats();
}
}
void KAstTopLevel::slotRockHit( int size )
{
switch ( size )
{
case 0:
score += 10;
break;
case 1:
score += 20;
break;
default:
score += 40;
}
playSound( "RockDestroyed" );
scoreLCD->display( score );
}
void KAstTopLevel::slotRocksRemoved()
{
level++;
if ( level >= MAX_LEVELS )
level = MAX_LEVELS - 1;
view->setRockSpeed( levels[level-1].rockSpeed );
view->addRocks( levels[level-1].nrocks );
levelLCD->display( level+1 );
}
void KAstTopLevel::doStats()
{
QString r( "0.00" );
if ( view->shots() )
r = QString::number( (double)view->hits() / view->shots() * 100.0,
'g', 2 );
view->showText( tr( "Game Over.\nPress Calendar for a new game." ), yellow, FALSE );
}
void KAstTopLevel::slotUpdateVitals()
{
brakesLCD->display( view->brakeCount() );
shieldLCD->display( view->shieldCount() );
shootLCD->display( view->shootCount() );
// teleportsLCD->display( view->teleportCount() );
powerMeter->setValue( view->power() );
}
diff --git a/noncore/games/qasteroids/view.cpp b/noncore/games/qasteroids/view.cpp
index 3a4d410..6cab700 100644
--- a/noncore/games/qasteroids/view.cpp
+++ b/noncore/games/qasteroids/view.cpp
@@ -1,882 +1,878 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** 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 <qpe/resource.h>
-
+#include <opie2/oresource.h>
+#include <qpe/qpeapplication.h>
#include <stdlib.h>
#include <math.h>
-#define IMG_BACKGROUND "qasteroids/bg.png"
+#define IMG_BACKGROUND "qasteroids/bg"
#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 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
#endif
struct kas_animations_t
{
int id;
const char *path;
int frames;
};
static const kas_animations_t 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 );
+ field.setBackgroundPixmap( Opie::Core::OResource::loadPixmap(IMG_BACKGROUND) );
textSprite = new QCanvasText( &field );
QFont font( "helvetica", 14 );
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 = TRUE;
can_destroy_powerups = FALSE;
mPaused = 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()
{
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 ( !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 );
+ QString sprites_prefix = QPEApplication::qpeDir() + "pics/qasteroids";
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;
int rnd = static_cast<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 );
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->visible() )
{
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() - 5, ship->y() - 5 );
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 < 8; 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() + 10 - cosangle*11,
ship->y() + 10 - sinangle*11,
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/8;
double thrusty = sinangle/8;
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() + 10 - cosangle*10,
ship->y() + 10 - sinangle*10,
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( 11+ship->x()+cosangle*11,
11+ship->y()+sinangle*11, 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;
}