KAstTopLevel
package KAstTopLevel;
use strict;
use warnings;
use QtCore4;
use QtGui4;
use Qt3Support4;
use QtCore4::isa qw( Qt3::MainWindow );
use QtCore4::slots
slotNewGame => [],
slotShipKilled => [],
slotRockHit => ['int'],
slotRocksRemoved => [],
slotUpdateVitals => [];
use KAsteroidsView;
use KALedMeter;
sub view() {
return this->{view};
}
sub scoreLCD() {
return this->{scoreLCD};
}
sub levelLCD() {
return this->{levelLCD};
}
sub shipsLCD() {
return this->{shipsLCD};
}
sub teleportsLCD() {
return this->{teleportsLCD};
}
sub brakesLCD() {
return this->{brakesLCD};
}
sub shieldLCD() {
return this->{shieldLCD};
}
sub shootLCD() {
return this->{shootLCD};
}
sub powerMeter() {
return this->{powerMeter};
}
sub sound() {
return this->{sound};
}
sub soundDict() {
return this->{soundDict};
}
sub waitShip() {
# waiting for user to press Enter to launch a ship
return this->{waitShip};
}
sub isPaused() {
return this->{isPaused};
}
sub shipsRemain() {
return this->{shipsRemain};
}
sub score() {
return this->{score};
}
sub level() {
return this->{level};
}
sub showHiscores() {
return this->{showHiscores};
}
sub actions() {
return this->{actions};
}
use constant {
Launch => 1,
Thrust => 2,
RotateLeft => 3,
RotateRight => 4,
Shoot => 5,
Teleport => 6,
Brake => 7,
Shield => 8,
Pause => 9,
NewGame => 10,
SB_SCORE => 1,
SB_LEVEL => 2,
SB_SHIPS => 3,
MAX_LEVELS => 16
};
#struct SLevel
#{
#int nrocks;
#double rockSpeed;
#};
my $levels =
[
{
nrocks => 1,
rockSpeed => 0.4,
},
{
nrocks => 1,
rockSpeed => 0.6,
},
{
nrocks => 2,
rockSpeed => 0.5,
},
{
nrocks => 2,
rockSpeed => 0.7,
},
{
nrocks => 2,
rockSpeed => 0.8,
},
{
nrocks => 3,
rockSpeed => 0.6,
},
{
nrocks => 3,
rockSpeed => 0.7,
},
{
nrocks => 3,
rockSpeed => 0.8,
},
{
nrocks => 4,
rockSpeed => 0.6,
},
{
nrocks => 4,
rockSpeed => 0.7,
},
{
nrocks => 4,
rockSpeed => 0.8,
},
{
nrocks => 5,
rockSpeed => 0.7,
},
{
nrocks => 5,
rockSpeed => 0.8,
},
{
nrocks => 5,
rockSpeed => 0.9,
},
{
nrocks => 5,
rockSpeed => 1.0,
},
];
#const char *soundEvents[] =
#{
#'ShipDestroyed',
#'RockDestroyed',
#0
#};
#const char *soundDefaults[] =
#{
#'Explosion.wav',
#'ploop.wav',
#0
#};
sub NEW
{
my ( $class, $parent, $name ) = @_;
$class->SUPER::NEW( $parent, $name, 0 );
this->{actions} = [];
my $border = Qt::Widget( this );
$border->setBackgroundColor( Qt::Color(Qt::black()) );
setCentralWidget( $border );
my $borderLayout = Qt3::VBoxLayout( $border );
$borderLayout->addStretch( 1 );
my $mainWin = Qt::Widget( $border );
$mainWin->setFixedSize(640, 480);
$borderLayout->addWidget( $mainWin, 0, Qt::AlignHCenter() );
$borderLayout->addStretch( 1 );
this->{view} = KAsteroidsView( $mainWin );
view->setFocusPolicy( Qt::StrongFocus() );
this->connect( view, SIGNAL 'shipKilled()', SLOT 'slotShipKilled()' );
this->connect( view, SIGNAL 'rockHit(int)', SLOT 'slotRockHit(int)' );
this->connect( view, SIGNAL 'rocksRemoved()', SLOT 'slotRocksRemoved()' );
this->connect( view, SIGNAL 'updateVitals()', SLOT 'slotUpdateVitals()' );
my $vb = Qt3::VBoxLayout( $mainWin );
my $hb = Qt3::HBoxLayout();
my $hbd = Qt3::HBoxLayout();
$vb->addLayout( $hb );
my $labelFont = Qt::Font( 'helvetica', 24 );
my $grp = Qt::ColorGroup( Qt::Color(Qt::darkGreen()), Qt::Color(Qt::black()), Qt::Color( 128, 128, 128 ),
Qt::Color( 64, 64, 64 ), Qt::Color(Qt::black()), Qt::Color(Qt::darkGreen()), Qt::Color(Qt::black()) );
my $pal = Qt::Palette( $grp, $grp, $grp );
$mainWin->setPalette( $pal );
$hb->addSpacing( 10 );
my $label = Qt::Label( this->tr('Score'), $mainWin );
$label->setFont( $labelFont );
$label->setPalette( $pal );
$label->setFixedWidth( $label->sizeHint()->width() );
$hb->addWidget( $label );
this->{scoreLCD} = Qt::LCDNumber( 6, $mainWin );
scoreLCD->setFrameStyle( Qt3::Frame::NoFrame() );
scoreLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
scoreLCD->setFixedWidth( 150 );
scoreLCD->setPalette( $pal );
$hb->addWidget( scoreLCD );
$hb->addStretch( 10 );
$label = Qt::Label( this->tr('Level'), $mainWin );
$label->setFont( $labelFont );
$label->setPalette( $pal );
$label->setFixedWidth( $label->sizeHint()->width() );
$hb->addWidget( $label );
this->{levelLCD} = Qt::LCDNumber( 2, $mainWin );
levelLCD->setFrameStyle( Qt3::Frame::NoFrame() );
levelLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
levelLCD->setFixedWidth( 70 );
levelLCD->setPalette( $pal );
$hb->addWidget( levelLCD );
$hb->addStretch( 10 );
$label = Qt::Label( this->tr('Ships'), $mainWin );
$label->setFont( $labelFont );
$label->setFixedWidth( $label->sizeHint()->width() );
$label->setPalette( $pal );
$hb->addWidget( $label );
this->{shipsLCD} = Qt::LCDNumber( 1, $mainWin );
shipsLCD->setFrameStyle( Qt3::Frame::NoFrame() );
shipsLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
shipsLCD->setFixedWidth( 40 );
shipsLCD->setPalette( $pal );
$hb->addWidget( shipsLCD );
$hb->addStrut( 30 );
$vb->addWidget( view, 10 );
# -- bottom layout:
$vb->addLayout( $hbd );
my $smallFont = Qt::Font( 'helvetica', 14 );
$hbd->addSpacing( 10 );
my $sprites_prefix = ':/trolltech/examples/graphicsview/portedasteroids/sprites/';
#label = new Qt::Label( this->tr( 'T' ), mainWin );
#label->setFont( smallFont );
#label->setFixedWidth( label->sizeHint().width() );
#label->setPalette( pal );
#hbd->addWidget( label );
#teleportsLCD = new Qt::LCDNumber( 1, mainWin );
#teleportsLCD->setFrameStyle( Qt::Frame::NoFrame );
#teleportsLCD->setSegmentStyle( Qt::LCDNumber::Flat );
#teleportsLCD->setPalette( pal );
#teleportsLCD->setFixedHeight( 20 );
#hbd->addWidget( teleportsLCD );
#hbd->addSpacing( 10 );
my $pm = Qt::Pixmap( $sprites_prefix . 'powerups/brake.png' );
$label = Qt::Label( $mainWin );
$label->setPixmap( $pm );
$label->setFixedWidth( $label->sizeHint()->width() );
$label->setPalette( $pal );
$hbd->addWidget( $label );
this->{brakesLCD} = Qt::LCDNumber( 1, $mainWin );
brakesLCD->setFrameStyle( Qt3::Frame::NoFrame() );
brakesLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
brakesLCD->setPalette( $pal );
brakesLCD->setFixedHeight( 20 );
$hbd->addWidget( brakesLCD );
$hbd->addSpacing( 10 );
$pm->load( $sprites_prefix . 'powerups/shield.png' );
$label = Qt::Label( $mainWin );
$label->setPixmap( $pm );
$label->setFixedWidth( $label->sizeHint()->width() );
$label->setPalette( $pal );
$hbd->addWidget( $label );
this->{shieldLCD} = Qt::LCDNumber( 1, $mainWin );
shieldLCD->setFrameStyle( Qt3::Frame::NoFrame() );
shieldLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
shieldLCD->setPalette( $pal );
shieldLCD->setFixedHeight( 20 );
$hbd->addWidget( shieldLCD );
$hbd->addSpacing( 10 );
$pm->load( $sprites_prefix . 'powerups/shoot.png' );
$label = Qt::Label( $mainWin );
$label->setPixmap( $pm );
$label->setFixedWidth( $label->sizeHint()->width() );
$label->setPalette( $pal );
$hbd->addWidget( $label );
this->{shootLCD} = Qt::LCDNumber( 1, $mainWin );
shootLCD->setFrameStyle( Qt3::Frame::NoFrame() );
shootLCD->setSegmentStyle( Qt::LCDNumber::Flat() );
shootLCD->setPalette( $pal );
shootLCD->setFixedHeight( 20 );
$hbd->addWidget( shootLCD );
$hbd->addStretch( 1 );
$label = Qt::Label( this->tr( 'Fuel' ), $mainWin );
$label->setFont( $smallFont );
$label->setFixedWidth( $label->sizeHint()->width() + 10 );
$label->setPalette( $pal );
$hbd->addWidget( $label );
this->{powerMeter} = KALedMeter( $mainWin );
powerMeter->setFrameStyle( Qt3::Frame::Box() | Qt3::Frame::Plain() );
powerMeter->setRange( KAsteroidsView::MAX_POWER_LEVEL() );
powerMeter->addColorRange( 10, Qt::darkRed() );
powerMeter->addColorRange( 20, Qt::Color(160, 96, 0) );
powerMeter->addColorRange( 70, Qt::darkGreen() );
powerMeter->setCount( 40 );
powerMeter->setPalette( $pal );
powerMeter->setFixedSize( 200, 12 );
$hbd->addWidget( powerMeter );
this->{shipsRemain} = 3;
this->{showHiscores} = 0;
this->{actions} = {};
this->{actions}->{${Qt::Key_Up()}} = Thrust;
this->{actions}->{${Qt::Key_Left()}} = RotateLeft;
this->{actions}->{${Qt::Key_Right()}} = RotateRight;
this->{actions}->{${Qt::Key_Space()}} = Shoot;
this->{actions}->{${Qt::Key_Z()}} = Teleport;
this->{actions}->{${Qt::Key_X()}} = Brake;
this->{actions}->{${Qt::Key_S()}} = Shield;
this->{actions}->{${Qt::Key_P()}} = Pause;
this->{actions}->{${Qt::Key_L()}} = Launch;
this->{actions}->{${Qt::Key_N()}} = NewGame;
view->showText( this->tr( 'Press N to start playing' ), Qt::Color(Qt::yellow()) );
}
sub playSound
{
}
sub keyPressEvent
{
my ( $event ) = @_;
if ( $event->isAutoRepeat() || !defined actions->{$event->key()} )
{
$event->ignore();
return;
}
my $a = actions->{ $event->key() };
if( $a == RotateLeft ) {
view->rotateLeft( 1 );
}
elsif( $a == RotateRight ) {
view->rotateRight( 1 );
}
elsif( $a == Thrust ) {
view->thrust( 1 );
}
elsif( $a == Shoot ) {
view->shoot( 1 );
}
elsif( $a == Shield ) {
view->setShield( 1 );
}
elsif( $a == Teleport ) {
view->teleport( 1 );
}
elsif( $a == Brake ) {
view->brake( 1 );
}
else {
$event->ignore();
return;
}
$event->accept();
}
sub keyReleaseEvent
{
my ( $event ) = @_;
if ( $event->isAutoRepeat() || !defined actions->{$event->key()} )
{
$event->ignore();
return;
}
my $a = actions->{ $event->key() };
if( $a == RotateLeft ) {
view->rotateLeft( 0 );
}
elsif( $a == RotateRight ) {
view->rotateRight( 0 );
}
elsif( $a == Thrust ) {
view->thrust( 0 );
}
elsif( $a == Shoot ) {
view->shoot( 0 );
}
elsif( $a == Brake ) {
view->brake( 0 );
}
elsif( $a == Shield ) {
view->setShield( 0 );
}
elsif( $a == Teleport ) {
view->teleport( 0 );
}
elsif( $a == Launch ) {
if ( waitShip )
{
view->newShip();
this->{waitShip} = 0;
view->hideText();
}
else
{
$event->ignore();
return;
}
}
elsif( $a == NewGame ) {
slotNewGame();
}
#elsif( $a == Pause ) {
#{
#view->pause( 1 );
#Qt::MessageBox::information( this,
#this->tr('KAsteroids is paused'),
#this->tr('Paused') );
#view->pause( 0 );
#}
#}
else {
$event->ignore();
return;
}
$event->accept();
}
sub showEvent
{
my ( $e ) = @_;
this->SUPER::showEvent( $e );
view->pause( 0 );
view->setFocus();
}
sub hideEvent
{
my ( $e ) = @_;
this->SUPER::hideEvent( $e );
view->pause( 1 );
}
sub slotNewGame
{
this->{score} = 0;
this->{shipsRemain} = SB_SHIPS;
scoreLCD->display( 0 );
this->{level} = 0;
levelLCD->display( level+1 );
shipsLCD->display( shipsRemain-1 );
view->newGame();
view->setRockSpeed( $levels->[0]->{rockSpeed} );
view->addRocks( $levels->[0]->{nrocks} );
# view->showText( this->tr( 'Press L to launch.' ), yellow );
view->newShip();
this->{waitShip} = 0;
view->hideText();
this->{isPaused} = 0;
}
sub slotShipKilled
{
this->{shipsRemain}--;
shipsLCD->display( shipsRemain-1 );
playSound( 'ShipDestroyed' );
if ( shipsRemain )
{
this->{waitShip} = 1;
view->showText( this->tr( 'Ship Destroyed. Press L to launch.'), Qt::Color(Qt::yellow()) );
}
else
{
view->showText( this->tr('Game Over!'), Qt::Color(Qt::red()) );
view->endGame();
doStats();
# highscore->addEntry( score, level, showHiscores );
}
}
sub slotRockHit
{
my ( $size ) = @_;
if ( $size == 0 ) {
this->{score} += 10;
}
if ( $size == 1 ) {
this->{score} += 20;
}
else {
this->{score} += 40;
}
playSound( 'RockDestroyed' );
scoreLCD->display( score );
}
sub slotRocksRemoved
{
this->{level}++;
if ( level >= MAX_LEVELS ) {
this->{level} = MAX_LEVELS - 1;
}
view->setRockSpeed( $levels->[level-1]->{rockSpeed} );
view->addRocks( $levels->[level-1]->{nrocks} );
levelLCD->display( level+1 );
}
sub doStats
{
my $r = '0.00';
if ( view->shots() ) {
$r = sprintf '%.02f', view->hits() / view->shots() * 100.0;
}
#multi-line text broken in Qt 3
#Qt::String s = this->tr( 'Game Over\n\nShots fired:\t%1\n Hit:\t%2\n Missed:\t%3\nHit ratio:\t%4 %\n\nPress N for a new game' )
#.arg(view->shots()).arg(view->hits())
#.arg(view->shots() - view->hits())
#.arg(r);
view->showText( 'Game Over. Press N for a game.', Qt::Color(Qt::yellow()), 0 );
}
sub slotUpdateVitals
{
brakesLCD->display( view->brakeCount() );
shieldLCD->display( view->shieldCount() );
shootLCD->display( view->shootCount() );
# teleportsLCD->display( view->teleportCount() );
powerMeter->setValue( view->power() );
}
1;