summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--apps/Games/zbounce.desktop6
-rw-r--r--noncore/games/zbounce/game.cpp606
-rw-r--r--noncore/games/zbounce/game.h183
-rw-r--r--noncore/games/zbounce/kbounce.cpp302
-rw-r--r--noncore/games/zbounce/kbounce.h99
-rw-r--r--noncore/games/zbounce/main.cpp29
-rw-r--r--noncore/games/zbounce/opie-zbounce.control20
-rw-r--r--noncore/games/zbounce/zbounce.pro10
-rw-r--r--pics/zbouce/arrow0000.pngbin0 -> 244 bytes
-rw-r--r--pics/zbouce/arrow0001.pngbin0 -> 243 bytes
-rw-r--r--pics/zbouce/ball0000.pngbin0 -> 641 bytes
-rw-r--r--pics/zbouce/ball0001.pngbin0 -> 622 bytes
-rw-r--r--pics/zbouce/ball0002.pngbin0 -> 616 bytes
-rw-r--r--pics/zbouce/ball0003.pngbin0 -> 598 bytes
-rw-r--r--pics/zbouce/ball0004.pngbin0 -> 593 bytes
-rw-r--r--pics/zbouce/ball0005.pngbin0 -> 595 bytes
-rw-r--r--pics/zbouce/ball0006.pngbin0 -> 589 bytes
-rw-r--r--pics/zbouce/ball0007.pngbin0 -> 591 bytes
-rw-r--r--pics/zbouce/ball0008.pngbin0 -> 596 bytes
-rw-r--r--pics/zbouce/ball0009.pngbin0 -> 592 bytes
-rw-r--r--pics/zbouce/ball0010.pngbin0 -> 603 bytes
-rw-r--r--pics/zbouce/ball0011.pngbin0 -> 613 bytes
-rw-r--r--pics/zbouce/ball0012.pngbin0 -> 623 bytes
-rw-r--r--pics/zbouce/ball0013.pngbin0 -> 627 bytes
-rw-r--r--pics/zbouce/ball0014.pngbin0 -> 635 bytes
-rw-r--r--pics/zbouce/ball0015.pngbin0 -> 624 bytes
-rw-r--r--pics/zbouce/ball0016.pngbin0 -> 608 bytes
-rw-r--r--pics/zbouce/ball0017.pngbin0 -> 614 bytes
-rw-r--r--pics/zbouce/ball0018.pngbin0 -> 609 bytes
-rw-r--r--pics/zbouce/ball0019.pngbin0 -> 610 bytes
-rw-r--r--pics/zbouce/ball0020.pngbin0 -> 604 bytes
-rw-r--r--pics/zbouce/ball0021.pngbin0 -> 609 bytes
-rw-r--r--pics/zbouce/ball0022.pngbin0 -> 629 bytes
-rw-r--r--pics/zbouce/ball0023.pngbin0 -> 638 bytes
-rw-r--r--pics/zbouce/ball0024.pngbin0 -> 645 bytes
-rw-r--r--pics/zbouce/tiles.pngbin0 -> 654 bytes
-rw-r--r--pics/zbouce/zbounce.pngbin0 -> 863 bytes
37 files changed, 1255 insertions, 0 deletions
diff --git a/apps/Games/zbounce.desktop b/apps/Games/zbounce.desktop
new file mode 100644
index 0000000..6eb0007
--- a/dev/null
+++ b/apps/Games/zbounce.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Application
+Exec=zbounce
+Icon=zbounce/zbounce
+Comment=A JezzGame
+Name=ZBounce
diff --git a/noncore/games/zbounce/game.cpp b/noncore/games/zbounce/game.cpp
new file mode 100644
index 0000000..7a1a3cd
--- a/dev/null
+++ b/noncore/games/zbounce/game.cpp
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdlib.h>
+#include <qtimer.h>
+#include <qpe/qpeapplication.h>
+#include <qimage.h>
+
+#include "game.h"
+
+#define TILE_SIZE 9
+
+#define TILE_FIRST ((FIELD_WIDTH-2)*(FIELD_HEIGHT-2))
+#define TILE_FREE (TILE_FIRST + 0)
+#define TILE_BORDER (TILE_FIRST + 1)
+#define TILE_WALLEND (TILE_FIRST + 2)
+#define TILE_WALLUP (TILE_FIRST + 3)
+#define TILE_WALLDOWN (TILE_FIRST + 4)
+#define TILE_WALLLEFT (TILE_FIRST + 5)
+#define TILE_WALLRIGHT (TILE_FIRST + 6)
+
+#define GAME_DELAY 15
+#define BALL_ANIM_DELAY 60
+#define WALL_DELAY 100
+
+#define MS2TICKS( ms ) ((ms)/GAME_DELAY)
+
+Arrow::Arrow(QCanvasPixmapArray* array, QCanvas* canvas)
+ : QCanvasSprite( array, canvas )
+{
+ m_vertical = true;
+ move(3,3);
+}
+
+void Arrow::update()
+{
+ if ( m_vertical )
+ setFrame( 0 );
+ else
+ setFrame( 1 );
+}
+
+void Arrow::changeDirection()
+{
+ m_vertical = ! m_vertical;
+ update();
+}
+
+
+Ball::Ball(QCanvasPixmapArray* array, QCanvas* canvas)
+ : QCanvasSprite( array, canvas ), m_animDelay( 0 ), m_soundDelay( MS2TICKS(BALL_ANIM_DELAY)/2 )
+{
+}
+
+void Ball::update()
+{
+ m_animDelay--;
+ if ( m_animDelay<=0 )
+ {
+ m_animDelay = MS2TICKS(BALL_ANIM_DELAY);
+ int frameNum = frame();
+ frameNum++;
+ if ( frameNum>=frameCount() )
+ frameNum = 0;
+ setFrame( frameNum );
+ }
+}
+
+void Ball::advance(int stage)
+{
+ bool reflectX = false;
+ bool reflectY = false;
+
+ // check for collisions
+ if ( collide(xVelocity(), 0) ) reflectX = true;
+ if ( collide(0, yVelocity()) ) reflectY = true;
+ if ( !reflectX && !reflectY && collide(xVelocity(), yVelocity()) ) reflectX = reflectY = true;
+
+ // emit collision
+ QRect r = boundingRect();
+ r.moveBy( xVelocity(), yVelocity() );
+ JezzField* field = (JezzField *)canvas();
+
+ int ul = field->tile( r.left() / TILE_SIZE, r.top() / TILE_SIZE );
+ int ur = field->tile( r.right() / TILE_SIZE, r.top() / TILE_SIZE );
+ int bl = field->tile( r.left() / TILE_SIZE, r.bottom() / TILE_SIZE );
+ int br = field->tile( r.right() / TILE_SIZE, r.bottom() / TILE_SIZE );
+
+ if ( ul!=TILE_FREE ) field->emitBallCollisiton( this, r.left() / TILE_SIZE, r.top() / TILE_SIZE, ul ); else
+ if ( ur!=TILE_FREE ) field->emitBallCollisiton( this, r.right() / TILE_SIZE, r.top() / TILE_SIZE, ur ); else
+ if ( bl!=TILE_FREE ) field->emitBallCollisiton( this, r.left() / TILE_SIZE, r.bottom() / TILE_SIZE, bl ); else
+ if ( br!=TILE_FREE ) field->emitBallCollisiton( this, r.right() / TILE_SIZE, r.bottom() / TILE_SIZE, br );
+
+ // apply reflection
+ if ( reflectX ) setXVelocity( -xVelocity() );
+ if ( reflectY ) setYVelocity( -yVelocity() );
+
+ // update field
+ update();
+ QCanvasSprite::advance( stage );
+}
+
+bool Ball::collide( double dx, double dy )
+{
+ QRect r = boundingRect();
+ r.moveBy( dx, dy );
+ JezzField* field = (JezzField *)canvas();
+
+ int ul = field->tile( r.left() / TILE_SIZE, r.top() / TILE_SIZE );
+ int ur = field->tile( r.right() / TILE_SIZE, r.top() / TILE_SIZE );
+ int bl = field->tile( r.left() / TILE_SIZE, r.bottom() / TILE_SIZE );
+ int br = field->tile( r.right() / TILE_SIZE, r.bottom() / TILE_SIZE );
+
+ return ( ul!=TILE_FREE || ur!=TILE_FREE || bl!=TILE_FREE || br!=TILE_FREE );
+}
+
+/*************************************************************************/
+
+Wall::Wall( JezzField *field, int x, int y, Direction dir, int tile, QObject *parent, const char *name )
+ : QObject( parent, name ), m_dir( dir ), m_field( field ), m_startX( x ), m_startY( y ),
+ m_tile( tile ), m_delay( MS2TICKS(WALL_DELAY)/2 ), m_active( true )
+{
+ // setup position and direction
+ m_dx = 0;
+ m_dy = 0;
+ switch ( m_dir )
+ {
+ case Up: m_dy = -1; break;
+ case Down: m_dy = 1; break;
+ case Left: m_dx = -1; break;
+ case Right: m_dx = 1; break;
+ }
+
+ m_x = m_startX;
+ m_y = m_startY;
+
+ m_field->setTile( m_x, m_y, m_tile );
+}
+
+void Wall::finish()
+{
+ m_active = false;
+}
+
+bool Wall::isFree( int x, int y )
+{
+ if ( m_field->tile(x, y)==TILE_FREE )
+ {
+ // check whether there is a ball at the moment
+ QCanvasItemList cols = m_field->collisions( QRect(x*TILE_SIZE, y*TILE_SIZE,
+ TILE_SIZE, TILE_SIZE) );
+ if ( cols.count()==0 )
+ return true;
+ }
+
+ return false;
+}
+
+void Wall::update()
+{
+}
+
+void Wall::advance()
+{
+ update();
+
+ // move wall
+ if ( m_active )
+ {
+ m_delay--;
+ if ( m_delay<=0 )
+ {
+ m_delay = MS2TICKS(WALL_DELAY);
+
+ // set previous tile
+ m_field->setTile( m_x, m_y, m_tile );
+
+ // check whether next place is still free
+ if ( isFree(m_x+m_dx, m_y+m_dy) )
+ {
+ // move ball
+ m_x += m_dx;
+ m_y += m_dy;
+
+ // set tile
+ m_field->setTile( m_x, m_y, TILE_WALLEND );
+ } else
+ {
+ finish();
+ emit finished( this, m_field->tile( m_x+m_dx, m_y+m_dy ) );
+ }
+ }
+ }
+}
+
+void Wall::fill( bool black )
+{
+ if ( m_dx )
+ {
+ for ( int x=m_startX ; x!=m_x; x+=m_dx )
+ if ( m_field->tile(x, m_startY)==m_tile )
+ m_field->setGameTile( x, m_startY, black );
+
+ m_field->setGameTile( m_x, m_startY, black );
+ } else
+ {
+ for ( int y=m_startY ; y!=m_y; y+=m_dy )
+ if ( m_field->tile(m_startX, y)==m_tile )
+ m_field->setGameTile( m_startX, y, black );
+
+ m_field->setGameTile( m_startX, m_y, black );
+ }
+}
+
+/*************************************************************************/
+
+JezzField::JezzField( QPixmap tiles, QObject* parent, const char* name )
+ : QCanvas( parent, name ), m_tiles( tiles )
+{
+ setPixmaps( tiles );
+}
+
+void JezzField::setGameTile( int x, int y, bool black )
+{
+ setTile( x, y, black ? TILE_BORDER : TILE_FREE );
+}
+
+void JezzField::setPixmaps( QPixmap tiles )
+{
+ // create new tiles
+ QPixmap allTiles( TILE_SIZE*(FIELD_WIDTH-2), TILE_SIZE*(FIELD_HEIGHT-1) );
+
+ // handle default tiles
+ bitBlt( &allTiles, 0, TILE_SIZE*(FIELD_HEIGHT-2),
+ &tiles, 0, 0, tiles.width(), tiles.height() );
+
+ // load tiles into canvas
+ setTiles( allTiles, FIELD_WIDTH, FIELD_HEIGHT, TILE_SIZE, TILE_SIZE );
+}
+
+/*************************************************************************/
+
+JezzView::JezzView(QCanvas* viewing, QWidget* parent, const char* name, WFlags f)
+ : QCanvasView( viewing, parent, name, f ), m_vertical( false )
+{
+ setResizePolicy( AutoOne );
+ setHScrollBarMode( AlwaysOff );
+ setVScrollBarMode( AlwaysOff );
+
+ setCursor( sizeHorCursor );
+}
+
+void JezzView::viewportMouseReleaseEvent( QMouseEvent *ev )
+{
+ if ( ev->button() & LeftButton )
+ {
+ emit buildWall( ev->x()/TILE_SIZE, ev->y()/TILE_SIZE, m_vertical );
+ }
+}
+
+void JezzView::changeCursor()
+{
+ m_vertical = !m_vertical;
+ if ( m_vertical )
+ {
+ setCursor( sizeVerCursor );
+ }
+ else
+ {
+ setCursor( sizeHorCursor );
+ }
+}
+
+/*************************************************************************/
+
+JezzGame::JezzGame( int ballNum, QWidget *parent, const char *name )
+ : QWidget( parent, name ), m_wall1( 0 ), m_wall2( 0 ),
+ m_text( 0 ), m_running( false ), m_percent( 0 ), m_pictured( false )
+{
+ QString path = QPEApplication::qpeDir()+"pics/zbounce/";
+
+ // load gfx
+ m_ballPixmaps = new QCanvasPixmapArray( path + "ball%1.png", 25 );
+ for ( unsigned n=0; n < m_ballPixmaps->count(); n++ )
+ m_ballPixmaps->image(n)->setOffset( 0, 0 );
+
+ m_arrowPixmaps = new QCanvasPixmapArray( path + "arrow%1.png", 2 );
+ for ( unsigned n=0; n < m_arrowPixmaps->count(); n++ )
+ m_arrowPixmaps->image(n)->setOffset( 0, 0 );
+
+ QPixmap tiles( path + "tiles.png" );
+
+ // create field
+ m_field = new JezzField( tiles, this, "m_field" );
+ m_field->resize( TILE_SIZE*FIELD_WIDTH, TILE_SIZE*FIELD_HEIGHT );
+
+ for ( int x=0; x<FIELD_WIDTH; x++ )
+ m_field->setTile( x, 0, TILE_BORDER );
+ for ( int y=1; y<FIELD_HEIGHT-1; y++ )
+ {
+ m_field->setTile( 0, y, TILE_BORDER );
+ for ( int x=1; x<FIELD_WIDTH-1; x++ )
+ m_field->setTile( x, y, TILE_FREE );
+ m_field->setTile( FIELD_WIDTH-1, y, TILE_BORDER );
+ }
+ for ( int x=0; x<FIELD_WIDTH; x++ )
+ m_field->setTile( x, FIELD_HEIGHT-1, TILE_BORDER );
+
+ connect( m_field, SIGNAL(ballCollision(Ball *, int, int, int)), this, SLOT(ballCollision(Ball *, int, int, int)) );
+
+ // create view
+ m_view = new JezzView( m_field, this, "m_view" );
+ m_view->move( 0, 0 );
+ m_view->adjustSize();
+ connect( m_view, SIGNAL(buildWall(int, int, bool)), this, SLOT(buildWall(int, int, bool)) );
+
+ // create balls
+ for ( int n=0; n<ballNum; n++ )
+ {
+ Ball *ball = new Ball( m_ballPixmaps, m_field );
+ m_balls.append( ball );
+ ball->setVelocity( ((rand() & 1)*2-1)*2, ((rand() & 1)*2-1)*2 );
+ ball->setFrame( rand() % 25 );
+ ball->move( 4*TILE_SIZE + ( rand() - 50 ) % ( (FIELD_WIDTH-8)*TILE_SIZE ),
+ 4*TILE_SIZE + rand() % ( (FIELD_HEIGHT-8)*TILE_SIZE ) );
+ ball->show();
+ }
+
+ // create arrow
+ arrow = new Arrow( m_arrowPixmaps, m_field );
+ arrow->show();
+
+ // create text label
+ m_text = new QCanvasText( m_field );
+
+ // create game clock
+ m_clock = new QTimer( this );
+ connect( m_clock, SIGNAL(timeout()), this, SLOT(tick()) );
+ m_clock->start( GAME_DELAY );
+
+ // setup geometry
+ setFixedSize( m_view->size() );
+}
+
+JezzGame::~JezzGame()
+{
+ m_balls.clear();
+ delete m_view;
+ delete m_field;
+ delete m_ballPixmaps;
+}
+
+void JezzGame::display( QString text, int size )
+{
+ qDebug("This function \"display\" shouldn't be called!!!");
+ if ( !text.isEmpty() )
+ {
+ QFont font( "Helvetica", size, QFont::Bold );
+ font.setStyleHint( QFont::Helvetica );
+ m_text->setFont( font );
+ m_text->setText( text );
+
+ QRect size = m_text->boundingRect();
+ m_text->move( ( FIELD_WIDTH*TILE_SIZE - size.width() ) / 2,
+ ( FIELD_HEIGHT*TILE_SIZE - size.height() ) / 2 );
+
+ m_text->show();
+ } else
+ {
+ m_text->hide();
+ }
+}
+
+void JezzGame::start()
+{
+ m_running = true;
+}
+
+void JezzGame::stop()
+{
+ m_running = false;
+}
+
+
+void JezzGame::makeBlack()
+{
+ // copy current field into buffer
+ for ( int y=0; y<FIELD_HEIGHT; y++ )
+ for ( int x=0; x<FIELD_WIDTH; x++ )
+ m_buf[x][y] = m_field->tile( x, y );
+
+ // fill areas that contains a ball
+ for ( Ball *ball=m_balls.first(); ball!=0; ball=m_balls.next() )
+ fill( ball->x()/TILE_SIZE, ball->y()/TILE_SIZE );
+
+ // areas still free can be blacked now
+ for ( int y=0; y<FIELD_HEIGHT; y++ )
+ for ( int x=0; x<FIELD_WIDTH; x++ )
+ {
+ if ( m_buf[x][y]==TILE_FREE )
+ m_field->setGameTile( x, y, true );
+ }
+
+ m_field->update();
+ m_view->repaint();
+
+ // count percent value of occupied area
+ int p = percent();
+ if ( p!=m_percent )
+ {
+ m_percent = p;
+ emit newPercent( m_percent );
+ }
+}
+
+int JezzGame::percent()
+{
+ int notFree = 0;
+ for ( int y=1; y<FIELD_HEIGHT-1; y++ )
+ for ( int x=1; x<FIELD_WIDTH-1; x++ )
+ {
+ if ( m_field->tile(x,y)!=TILE_FREE )
+ notFree++;
+ }
+
+ return 100 * notFree / ( (FIELD_WIDTH-1) * (FIELD_HEIGHT-1) );
+}
+
+void JezzGame::fill( int x, int y )
+{
+ if ( m_buf[x][y]!=TILE_FREE) return;
+
+ // go left
+ int _x=x;
+ for ( ; m_buf[_x][y]==TILE_FREE; _x-- )
+ m_buf[_x][y] = TILE_BORDER;
+ int stopx = _x;
+
+ // fill above
+ for ( _x=x; _x>stopx; _x-- )
+ if ( m_buf[_x][y-1]==TILE_FREE ) fill( _x, y-1 );
+
+ // fill below
+ for ( _x=x; _x>stopx; _x-- )
+ if ( m_buf[_x][y+1]==TILE_FREE ) fill( _x, y+1 );
+
+ // go right
+ for ( _x=x+1; m_buf[_x][y]==TILE_FREE; _x++ )
+ m_buf[_x][y] = TILE_BORDER;
+ stopx = _x;
+
+ // fill above
+ for ( _x=x+1; _x<stopx; _x++ )
+ if ( m_buf[_x][y-1]==TILE_FREE ) fill( _x, y-1 );
+
+ // fill below;
+ for ( _x=x+1; _x<stopx; _x++ )
+ if ( m_buf[_x][y+1]==TILE_FREE ) fill( _x, y+1 );
+}
+
+void JezzGame::ballCollision( Ball*, int, int, int tile )
+{
+ if ( tile!=TILE_BORDER && tile>TILE_FREE && tile!=TILE_WALLEND )
+ {
+ // stop walls
+ if ( (tile==TILE_WALLUP || tile==TILE_WALLLEFT) && m_wall1 )
+ {
+ m_wall1->finish();
+ m_wall1->fill( false );
+ delete m_wall1;
+ m_wall1 = 0;
+ }
+
+ if ( (tile==TILE_WALLDOWN || tile==TILE_WALLRIGHT) && m_wall2 )
+ {
+ m_wall2->finish();
+ m_wall2->fill( false );
+ delete m_wall2;
+ m_wall2 = 0;
+ }
+
+ // update view
+ m_field->update();
+ m_view->repaint();
+
+ // send death msg
+ emit died();
+ }
+}
+
+void JezzGame::buildWall( int x, int y, bool vertical )
+{
+ if ( !m_running ) return;
+
+ if ( m_field->tile(x, y)==TILE_FREE )
+ {
+ // check whether there is a ball at the moment
+ QCanvasItemList cols = m_field->collisions( QRect(x*TILE_SIZE, y*TILE_SIZE, TILE_SIZE, TILE_SIZE) );
+ if ( cols.count()>0 )
+ {
+ //kdDebug() << "Direct collision" << endl;
+ emit ballCollision( (Ball*)cols.first(), x, y, TILE_WALLUP );
+ return;
+ }
+
+ // start walls
+ if ( !m_wall1 )
+ {
+ m_wall1 = new Wall( m_field, x, y,
+ vertical? Wall::Up : Wall::Left,
+ vertical? TILE_WALLUP : TILE_WALLLEFT,
+ this, "m_wall1" );
+ connect( m_wall1, SIGNAL(finished(Wall *, int)),
+ this, SLOT(wallFinished(Wall *, int)) ); }
+
+ if ( !m_wall2 )
+ {
+ m_wall2 = new Wall( m_field, x, y,
+ vertical? Wall::Down: Wall::Right,
+ vertical? TILE_WALLDOWN : TILE_WALLRIGHT,
+ this, "m_wall2" );
+ connect( m_wall2, SIGNAL(finished(Wall *, int)),
+ this, SLOT(wallFinished(Wall *, int)) );
+ }
+ }
+}
+
+void JezzGame::wallFinished( Wall *wall, int tile )
+{
+ if ( tile==TILE_WALLEND )
+ {
+ if ( m_wall1 )
+ {
+ m_wall1->fill( false );
+ delete m_wall1;
+ m_wall1 = 0;
+ }
+
+ if ( m_wall2 )
+ {
+ m_wall2->fill( false );
+ delete m_wall2;
+ m_wall2 = 0;
+ }
+ } else
+ {
+ if ( m_wall1==wall && m_wall1 )
+ {
+ m_wall1->fill( true );
+ delete m_wall1;
+ m_wall1 = 0;
+ }
+
+ if ( m_wall2==wall && m_wall2 )
+ {
+ m_wall2->fill( true );
+ delete m_wall2;
+ m_wall2 = 0;
+ }
+ }
+
+ m_field->update();
+ m_view->repaint();
+
+ makeBlack();
+}
+
+void JezzGame::tick()
+{
+ if ( m_running )
+ {
+ if ( m_field ) m_field->advance();
+ if ( m_wall1 ) m_wall1->advance();
+ if ( m_wall2 ) m_wall2->advance();
+ } else
+ {
+ for ( Ball *ball=m_balls.first(); ball!=0; ball=m_balls.next() )
+ ball->update();
+
+ if ( m_field ) m_field->update();
+ if ( m_wall1 ) m_wall1->update();
+ if ( m_wall2 ) m_wall2->update();
+ }
+}
+
+void JezzGame::changeCursor()
+{
+ arrow->changeDirection();
+ m_view->changeCursor();
+}
diff --git a/noncore/games/zbounce/game.h b/noncore/games/zbounce/game.h
new file mode 100644
index 0000000..ae0d4fa
--- a/dev/null
+++ b/noncore/games/zbounce/game.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GAME_H_INCLUDED
+#define GAME_H_INCLUDED
+
+#include <qwidget.h>
+#include <qcanvas.h>
+#include <qmemarray.h>
+
+class QTimer;
+class JezzField;
+
+#define FIELD_WIDTH 26
+#define FIELD_HEIGHT 26
+
+class Arrow : public QCanvasSprite
+{
+ public:
+ Arrow(QCanvasPixmapArray* array, QCanvas* canvas);
+
+ void update();
+ void changeDirection();
+
+ protected:
+ bool m_vertical;
+};
+
+class Ball : public QCanvasSprite
+{
+ public:
+ Ball(QCanvasPixmapArray* array, QCanvas* canvas);
+
+ void update();
+ void advance(int stage);
+ bool collide( double dx=0, double dy=0 );
+
+ protected:
+ int m_animDelay;
+ int m_soundDelay;
+};
+
+
+class Wall : public QObject
+{
+ Q_OBJECT
+public:
+ enum Direction { Up, Down, Left, Right };
+
+ Wall( JezzField *field, int x, int y, Direction dir, int tile,
+ QObject *parent=0, const char *name=0 );
+
+ void finish();
+ void fill( bool black );
+
+signals:
+ void finished( Wall *wall, int tile );
+
+public slots:
+ void advance();
+ void update();
+
+private:
+ bool isFree( int x, int y );
+
+ Direction m_dir;
+ JezzField *m_field;
+ int m_dx, m_dy;
+ int m_x, m_y;
+ int m_startX, m_startY;
+ int m_tile;
+ int m_delay;
+ bool m_active;
+};
+
+
+class JezzField : public QCanvas
+{
+ Q_OBJECT
+public:
+ JezzField( QPixmap tiles, QObject* parent = 0, const char* name = 0 );
+
+ void setGameTile( int x, int y, bool black );
+
+signals:
+ void ballCollision( Ball *ball, int x, int y, int tile );
+
+private:
+ friend class Ball;
+ QPixmap m_tiles;
+ QMemArray<QPixmap> m_backTiles;
+
+ void setPixmaps( QPixmap tiles );
+ void emitBallCollisiton( Ball *ball, int x, int y, int tile )
+ { emit ballCollision( ball, x, y, tile ); };
+
+};
+
+
+class JezzView : public QCanvasView
+{
+ Q_OBJECT
+public:
+ JezzView(QCanvas* viewing=0, QWidget* parent=0, const char* name=0, WFlags f=0);
+ void changeCursor();
+
+signals:
+ void buildWall( int x, int y, bool vertical );
+
+protected:
+ void viewportMouseReleaseEvent( QMouseEvent * );
+
+private:
+ bool m_vertical;
+};
+
+
+class JezzGame : public QWidget
+{
+ Q_OBJECT
+
+public:
+ JezzGame( int ballNum, QWidget *parent=0, const char *name=0 );
+ ~JezzGame();
+
+ int percent();
+ void display( QString text, int size=20 );
+ void changeCursor();
+
+signals:
+ void died();
+ void newPercent( int percent );
+
+public slots:
+ void start();
+ void stop();
+
+protected slots:
+ void tick();
+ void buildWall( int x, int y, bool vertical );
+ void wallFinished( Wall *wall, int tile );
+ void ballCollision( Ball *ball, int x, int y, int tile );
+
+protected:
+ void makeBlack();
+ void fill( int x, int y );
+ void fillLeft( int x, int y );
+ int m_buf[FIELD_WIDTH][FIELD_HEIGHT];
+
+ JezzField *m_field;
+ JezzView *m_view;
+
+ Wall *m_wall1, *m_wall2;
+
+ QList<Ball> m_balls;
+ QCanvasPixmapArray *m_ballPixmaps;
+ QCanvasPixmapArray *m_arrowPixmaps;
+ QCanvasText *m_text;
+ Arrow *arrow;
+
+ QTimer *m_clock;
+ bool m_running;
+ int m_percent;
+ bool m_pictured;
+
+};
+
+#endif
diff --git a/noncore/games/zbounce/kbounce.cpp b/noncore/games/zbounce/kbounce.cpp
new file mode 100644
index 0000000..c1c0f70
--- a/dev/null
+++ b/noncore/games/zbounce/kbounce.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License,Life or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qlcdnumber.h>
+#include <qmessagebox.h>
+#include <qmainwindow.h>
+#include <qpe/qpeapplication.h>
+
+#include "kbounce.h"
+#include "game.h"
+#include <qlabel.h>
+
+KJezzball::KJezzball() : QMainWindow(0), m_gameWidget( 0 )
+{
+ setCaption(tr("ZBounce"));
+ // setup variables
+ m_game.level = 1;
+ m_game.score = 0;
+ m_state = Idle;
+
+
+ menu = menuBar();
+ game = new QPopupMenu;
+ game->insertItem(tr("&New game"), this, SLOT(newGame()), Key_N );
+ game->insertItem(tr("&Pause game"), this, SLOT(pauseGame()), Key_P );
+ game->insertSeparator();
+ game->insertItem(tr("&About"), this, SLOT(about()));
+ menu->insertItem( tr("&Game"), game );
+
+ // create widgets
+ m_view = new QWidget( this, "m_view" );
+ setCentralWidget( m_view );
+
+ m_layout = new QGridLayout( m_view );
+ m_layout->setSpacing( 0 );
+ m_layout->setMargin( 0 );
+
+ ScoreLabel = new QLabel( m_view, "ScoreLabel" );
+ ScoreLabel->setText( tr( "Score: 00" ) );
+ ScoreLabel->setAlignment( int( QLabel::AlignCenter ) );
+
+ m_layout->addWidget( ScoreLabel, 1, 0 );
+
+ LivesLabel = new QLabel( m_view, "LivesLabel" );
+ LivesLabel->setText( tr( "Lives: 0%" ) );
+ LivesLabel->setAlignment( int( QLabel::AlignCenter ) );
+
+ m_layout->addWidget( LivesLabel, 1, 2 );
+
+ FilledLabel = new QLabel( m_view, "FilledLabel" );
+ FilledLabel->setText( tr( "Filled: 00%" ) );
+ FilledLabel->setAlignment( int( QLabel::AlignCenter ) );
+
+ m_layout->addWidget( FilledLabel, 1, 1 );
+
+ TimeLabel = new QLabel( m_view, "TimeLabel" );
+ TimeLabel->setText( tr( "Time: 00" ) );
+ TimeLabel->setAlignment( int( QLabel::AlignCenter ) );
+
+ m_layout->addWidget( TimeLabel, 1, 3 );
+
+ // create timers
+ m_nextLevelTimer = new QTimer( this, "m_nextLevelTimer" );
+ connect( m_nextLevelTimer, SIGNAL(timeout()), this, SLOT(switchLevel()) );
+
+ m_gameOverTimer = new QTimer( this, "m_gameOverTimer" );
+ connect( m_gameOverTimer, SIGNAL(timeout()), this, SLOT(gameOverNow()) );
+
+ m_timer = new QTimer( this, "m_timer" );
+ connect( m_timer, SIGNAL(timeout()), this, SLOT(second()) );
+
+ // create demo game
+ createLevel( 1 );
+}
+
+void KJezzball::newGame()
+{
+ // Check for running game
+ closeGame();
+ if ( m_state==Idle )
+ {
+ // update displays
+ m_game.level = 1;
+ m_game.score = 0;
+
+ setCaption(tr("ZBounce Level %1").arg(m_game.level));
+ ScoreLabel->setText( tr( "Score: %1" ).arg(m_game.score) );
+
+ // start new game
+ m_state = Running;
+
+ createLevel( m_game.level );
+ startLevel();
+ }
+}
+
+void KJezzball::about()
+{
+ QMessageBox::information( this, "About", "Written by: Stefan Schimanski\nPorted by: Martin Imobersteg\n\nThis program is distributed under\nthe terms of the GPL v2." );
+}
+
+void KJezzball::closeGame()
+{
+ if ( m_state!=Idle )
+ {
+ stopLevel();
+ m_state = Idle;
+ }
+}
+
+void KJezzball::pauseGame()
+{
+ switch ( m_state )
+ {
+ case Running:
+ m_state = Paused;
+ m_gameWidget->display( tr("Game paused.\nPress P to continue!") );
+ stopLevel();
+ break;
+
+ case Paused:
+ case Suspend:
+ m_state = Running;
+ m_gameWidget->display( QString::null );
+ startLevel();
+ break;
+
+ case Idle:
+ break;
+ }
+}
+
+void KJezzball::gameOver()
+{
+ stopLevel();
+ m_gameOverTimer->start( 100, TRUE );
+}
+
+
+void KJezzball::gameOverNow()
+{
+ m_state = Idle;
+
+ QString score;
+ score.setNum( m_game.score );
+ QMessageBox::information( this, "Game Over", tr("Game Over!\nScore: %1").arg(score) );
+}
+
+void KJezzball::focusOutEvent( QFocusEvent *ev )
+{
+ if ( m_state==Running )
+ {
+ stopLevel();
+ m_state = Suspend;
+ }
+
+ QMainWindow::focusOutEvent( ev );
+}
+
+void KJezzball::focusInEvent ( QFocusEvent *ev )
+{
+ if ( m_state==Suspend )
+ {
+ startLevel();
+ m_state = Running;
+ }
+
+ QMainWindow::focusInEvent( ev );
+}
+
+void KJezzball::second()
+{
+ m_level.time--;
+ TimeLabel->setText( tr( "Time: %1" ).arg(m_level.time) );
+ if ( m_level.time<=0 )
+ {
+ gameOver();
+ }
+}
+
+void KJezzball::died()
+{
+ m_level.lifes--;
+ LivesLabel->setText( tr( "Lives: %1" ).arg(m_level.lifes) );
+ if ( m_level.lifes==0 ) gameOver();
+}
+
+void KJezzball::newPercent( int percent )
+{
+ FilledLabel->setText( tr( "Filled: %1%" ).arg(percent) );
+ if ( percent>=75 )
+ {
+ m_level.score = m_level.lifes*15 + (percent-75)*2*(m_game.level+5);
+ nextLevel();
+ }
+}
+
+void KJezzball::createLevel( int level )
+{
+ // destroy old game
+ if ( m_gameWidget ) delete m_gameWidget;
+
+ m_gameWidget = new JezzGame( level+1, m_view, "m_gameWidget" );
+
+ m_gameWidget->show();
+ m_layout->addMultiCellWidget( m_gameWidget, 0, 0, 0, 3 );
+ connect( m_gameWidget, SIGNAL(died()), this, SLOT(died()) );
+ connect( m_gameWidget, SIGNAL(newPercent(int)), this, SLOT(newPercent(int)) );
+
+ // update displays
+ m_level.lifes = level+1;
+ LivesLabel->setText( tr( "Lives: %1" ).arg(m_level.lifes) );
+ FilledLabel->setText( tr( "Filled: 0%" ) );
+
+ m_level.time = (level+2)*30;
+ TimeLabel->setText( tr( "Time: %1" ).arg(m_level.time) );
+
+ m_level.score = 0;
+}
+
+void KJezzball::startLevel()
+{
+ if ( m_gameWidget )
+ {
+ m_timer->start( 1000 );
+ m_gameWidget->start();
+ }
+}
+
+void KJezzball::stopLevel()
+{
+ if ( m_gameWidget )
+ {
+ m_gameWidget->stop();
+ m_timer->stop();
+ }
+}
+
+void KJezzball::nextLevel()
+{
+ stopLevel();
+ m_nextLevelTimer->start( 100, TRUE );
+}
+
+void KJezzball::switchLevel()
+{
+ m_game.score += m_level.score;
+ ScoreLabel->setText( tr( "Score: %1" ).arg(m_game.score) );
+
+ QString score;
+ score.setNum( m_level.score );
+
+ QString level;
+ level.setNum( m_game.level );
+
+ QString foo = QString(
+ tr("Successfully cleared more than 75%.\n") +
+ tr("%1 points: 15 points per life\n").arg(m_level.lifes*15) +
+ tr("%1 points: Bonus\n").arg((m_gameWidget->percent()-75)*2*(m_game.level+5)) +
+ tr("%1 points: Total score\n").arg(score) +
+ tr("On to level %1.\nYou get %2 lives this time!")).arg(m_game.level+1).arg(m_game.level+2);
+
+ QMessageBox::information( this, "Success", foo );
+
+ m_game.level++;
+
+ createLevel( m_game.level );
+ startLevel();
+}
+
+void KJezzball::keyPressEvent( QKeyEvent *ev )
+{
+ if ( ev->key() == Key_Space ||
+ ev->key() == Key_Up ||
+ ev->key() == Key_Down ||
+ ev->key() == Key_Right ||
+ ev->key() == Key_Left )
+ {
+ m_gameWidget->changeCursor();
+ }
+ else
+ {
+ ev->ignore();
+ }
+}
diff --git a/noncore/games/zbounce/kbounce.h b/noncore/games/zbounce/kbounce.h
new file mode 100644
index 0000000..de41710
--- a/dev/null
+++ b/noncore/games/zbounce/kbounce.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef KJEZZBALL_H_INCLUDED
+#define KJEZZBALL_H_INCLUDED
+
+#include <qmainwindow.h>
+#include <qmenubar.h>
+#include <qlabel.h>
+
+class JezzGame;
+class QLCDNumber;
+class QGridLayout;
+
+class KJezzball : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ KJezzball();
+
+public slots:
+ void newGame();
+ void pauseGame();
+ void closeGame();
+ void about();
+
+protected slots:
+ void died();
+ void newPercent( int percent );
+ void second();
+ void switchLevel();
+ void gameOverNow();
+
+protected:
+ void createLevel( int level );
+ void startLevel();
+ void stopLevel();
+ void nextLevel();
+ void gameOver();
+ void initXMLUI();
+
+ void focusOutEvent( QFocusEvent * );
+ void focusInEvent ( QFocusEvent * );
+ void keyPressEvent( QKeyEvent *ev );
+
+ JezzGame *m_gameWidget;
+ QWidget *m_view;
+ QGridLayout *m_layout;
+ QLCDNumber *m_levelLCD;
+ QLCDNumber *m_lifesLCD;
+ QLCDNumber *m_scoreLCD;
+ QLCDNumber *m_percentLCD;
+ QLCDNumber *m_timeLCD;
+
+ QTimer *m_timer;
+ QTimer *m_nextLevelTimer;
+ QTimer *m_gameOverTimer;
+
+ enum { Idle, Running, Paused, Suspend } m_state;
+
+ struct
+ {
+ int lifes;
+ int time;
+ int score;
+ } m_level;
+
+ struct
+ {
+ int level;
+ int score;
+ } m_game;
+private:
+ QMenuBar *menu;
+ QPopupMenu *game;
+ QLabel* ScoreLabel;
+ QLabel* LivesLabel;
+ QLabel* FilledLabel;
+ QLabel* TimeLabel;
+
+};
+
+#endif
diff --git a/noncore/games/zbounce/main.cpp b/noncore/games/zbounce/main.cpp
new file mode 100644
index 0000000..a6b7c1a
--- a/dev/null
+++ b/noncore/games/zbounce/main.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2000 Stefan Schimanski <schimmi@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <qpe/qpeapplication.h>
+#include "kbounce.h"
+
+int main(int argc, char **argv)
+{
+ QPEApplication a( argc, argv );
+ KJezzball *top = new KJezzball;
+ a.showMainWidget(top);
+
+ return a.exec();
+}
diff --git a/noncore/games/zbounce/opie-zbounce.control b/noncore/games/zbounce/opie-zbounce.control
new file mode 100644
index 0000000..d419eaf
--- a/dev/null
+++ b/noncore/games/zbounce/opie-zbounce.control
@@ -0,0 +1,20 @@
+Files: bin/zbounce apps/Games/zbounce.desktop pics/zbounce/zbounce.png \
+pics/zbounce/arrow0000.png pics/zbounce/ball0008.png pics/zbounce/ball0018.png \
+pics/zbounce/arrow0001.png pics/zbounce/ball0009.png pics/zbounce/ball0019.png \
+pics/zbounce/ball0000.png pics/zbounce/ball0010.png pics/zbounce/ball0020.png \
+pics/zbounce/ball0001.png pics/zbounce/ball0011.png pics/zbounce/ball0021.png \
+pics/zbounce/ball0002.png pics/zbounce/ball0012.png pics/zbounce/ball0022.png \
+pics/zbounce/ball0003.png pics/zbounce/ball0013.png pics/zbounce/ball0023.png \
+pics/zbounce/ball0004.png pics/zbounce/ball0014.png pics/zbounce/ball0024.png \
+pics/zbounce/ball0005.png pics/zbounce/ball0015.png pics/zbounce/tiles.png \
+pics/zbounce/ball0006.png pics/zbounce/ball0016.png \
+pics/zbounce/ball0007.png pics/zbounce/ball0017.png \
+Version: 0.6
+Depends: opie-base ($QPE_VERSION)
+Priority: optional
+Section: opie/games
+Maintainer: Martin Imobersteg <imm@gmx.ch>
+Architecture: arm
+License: GPL
+Description: ZBounce
+ A JezzGame like game for Qtopia.
diff --git a/noncore/games/zbounce/zbounce.pro b/noncore/games/zbounce/zbounce.pro
new file mode 100644
index 0000000..4bf2058
--- a/dev/null
+++ b/noncore/games/zbounce/zbounce.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+HEADERS = game.h kbounce.h
+SOURCES = game.cpp kbounce.cpp main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+DESTDIR = $(OPIEDIR)/bin
+TARGET = zbounce
diff --git a/pics/zbouce/arrow0000.png b/pics/zbouce/arrow0000.png
new file mode 100644
index 0000000..0f49880
--- a/dev/null
+++ b/pics/zbouce/arrow0000.png
Binary files differ
diff --git a/pics/zbouce/arrow0001.png b/pics/zbouce/arrow0001.png
new file mode 100644
index 0000000..4daeb57
--- a/dev/null
+++ b/pics/zbouce/arrow0001.png
Binary files differ
diff --git a/pics/zbouce/ball0000.png b/pics/zbouce/ball0000.png
new file mode 100644
index 0000000..3afe8f0
--- a/dev/null
+++ b/pics/zbouce/ball0000.png
Binary files differ
diff --git a/pics/zbouce/ball0001.png b/pics/zbouce/ball0001.png
new file mode 100644
index 0000000..845c833
--- a/dev/null
+++ b/pics/zbouce/ball0001.png
Binary files differ
diff --git a/pics/zbouce/ball0002.png b/pics/zbouce/ball0002.png
new file mode 100644
index 0000000..e561860
--- a/dev/null
+++ b/pics/zbouce/ball0002.png
Binary files differ
diff --git a/pics/zbouce/ball0003.png b/pics/zbouce/ball0003.png
new file mode 100644
index 0000000..ee1bfad
--- a/dev/null
+++ b/pics/zbouce/ball0003.png
Binary files differ
diff --git a/pics/zbouce/ball0004.png b/pics/zbouce/ball0004.png
new file mode 100644
index 0000000..cc39da5
--- a/dev/null
+++ b/pics/zbouce/ball0004.png
Binary files differ
diff --git a/pics/zbouce/ball0005.png b/pics/zbouce/ball0005.png
new file mode 100644
index 0000000..a316f11
--- a/dev/null
+++ b/pics/zbouce/ball0005.png
Binary files differ
diff --git a/pics/zbouce/ball0006.png b/pics/zbouce/ball0006.png
new file mode 100644
index 0000000..c3f024a
--- a/dev/null
+++ b/pics/zbouce/ball0006.png
Binary files differ
diff --git a/pics/zbouce/ball0007.png b/pics/zbouce/ball0007.png
new file mode 100644
index 0000000..c2d4f80
--- a/dev/null
+++ b/pics/zbouce/ball0007.png
Binary files differ
diff --git a/pics/zbouce/ball0008.png b/pics/zbouce/ball0008.png
new file mode 100644
index 0000000..c0b9a07
--- a/dev/null
+++ b/pics/zbouce/ball0008.png
Binary files differ
diff --git a/pics/zbouce/ball0009.png b/pics/zbouce/ball0009.png
new file mode 100644
index 0000000..aedbd60
--- a/dev/null
+++ b/pics/zbouce/ball0009.png
Binary files differ
diff --git a/pics/zbouce/ball0010.png b/pics/zbouce/ball0010.png
new file mode 100644
index 0000000..133527d
--- a/dev/null
+++ b/pics/zbouce/ball0010.png
Binary files differ
diff --git a/pics/zbouce/ball0011.png b/pics/zbouce/ball0011.png
new file mode 100644
index 0000000..4db6a48
--- a/dev/null
+++ b/pics/zbouce/ball0011.png
Binary files differ
diff --git a/pics/zbouce/ball0012.png b/pics/zbouce/ball0012.png
new file mode 100644
index 0000000..8b2f758
--- a/dev/null
+++ b/pics/zbouce/ball0012.png
Binary files differ
diff --git a/pics/zbouce/ball0013.png b/pics/zbouce/ball0013.png
new file mode 100644
index 0000000..6d551dc
--- a/dev/null
+++ b/pics/zbouce/ball0013.png
Binary files differ
diff --git a/pics/zbouce/ball0014.png b/pics/zbouce/ball0014.png
new file mode 100644
index 0000000..851cd6c
--- a/dev/null
+++ b/pics/zbouce/ball0014.png
Binary files differ
diff --git a/pics/zbouce/ball0015.png b/pics/zbouce/ball0015.png
new file mode 100644
index 0000000..f706d72
--- a/dev/null
+++ b/pics/zbouce/ball0015.png
Binary files differ
diff --git a/pics/zbouce/ball0016.png b/pics/zbouce/ball0016.png
new file mode 100644
index 0000000..cd762eb
--- a/dev/null
+++ b/pics/zbouce/ball0016.png
Binary files differ
diff --git a/pics/zbouce/ball0017.png b/pics/zbouce/ball0017.png
new file mode 100644
index 0000000..fba0308
--- a/dev/null
+++ b/pics/zbouce/ball0017.png
Binary files differ
diff --git a/pics/zbouce/ball0018.png b/pics/zbouce/ball0018.png
new file mode 100644
index 0000000..e500118
--- a/dev/null
+++ b/pics/zbouce/ball0018.png
Binary files differ
diff --git a/pics/zbouce/ball0019.png b/pics/zbouce/ball0019.png
new file mode 100644
index 0000000..4695261
--- a/dev/null
+++ b/pics/zbouce/ball0019.png
Binary files differ
diff --git a/pics/zbouce/ball0020.png b/pics/zbouce/ball0020.png
new file mode 100644
index 0000000..70d1d65
--- a/dev/null
+++ b/pics/zbouce/ball0020.png
Binary files differ
diff --git a/pics/zbouce/ball0021.png b/pics/zbouce/ball0021.png
new file mode 100644
index 0000000..f219ffc
--- a/dev/null
+++ b/pics/zbouce/ball0021.png
Binary files differ
diff --git a/pics/zbouce/ball0022.png b/pics/zbouce/ball0022.png
new file mode 100644
index 0000000..bb4bb0a
--- a/dev/null
+++ b/pics/zbouce/ball0022.png
Binary files differ
diff --git a/pics/zbouce/ball0023.png b/pics/zbouce/ball0023.png
new file mode 100644
index 0000000..80f8d79
--- a/dev/null
+++ b/pics/zbouce/ball0023.png
Binary files differ
diff --git a/pics/zbouce/ball0024.png b/pics/zbouce/ball0024.png
new file mode 100644
index 0000000..7a6db2b
--- a/dev/null
+++ b/pics/zbouce/ball0024.png
Binary files differ
diff --git a/pics/zbouce/tiles.png b/pics/zbouce/tiles.png
new file mode 100644
index 0000000..68127e8
--- a/dev/null
+++ b/pics/zbouce/tiles.png
Binary files differ
diff --git a/pics/zbouce/zbounce.png b/pics/zbouce/zbounce.png
new file mode 100644
index 0000000..1a1168a
--- a/dev/null
+++ b/pics/zbouce/zbounce.png
Binary files differ