diff options
Diffstat (limited to 'klines')
41 files changed, 3113 insertions, 0 deletions
diff --git a/klines/AUTHORS b/klines/AUTHORS new file mode 100644 index 00000000..99eadd5e --- /dev/null +++ b/klines/AUTHORS @@ -0,0 +1,2 @@ +Roman Merzlyakov <roman@sbrf.barrt.ru> +Roman Razilov <Roman.Razilov@gmx.de> diff --git a/klines/Makefile.am b/klines/Makefile.am new file mode 100644 index 00000000..37c8a6ec --- /dev/null +++ b/klines/Makefile.am @@ -0,0 +1,27 @@ + +INCLUDES= -I$(top_srcdir)/libkdegames -I$(top_srcdir)/libkdegames/highscore $(all_includes) +METASOURCES = AUTO + +bin_PROGRAMS = klines +klines_SOURCES = prompt.cpp mwidget.cpp linesboard.cpp field.cpp cell.cpp \ + ballpainter.cpp klines.cpp main.cpp prefs.kcfgc +klines_LDFLAGS = $(all_libraries) $(KDE_RPATH) +klines_LDADD = $(LIB_KDEGAMES) +klines_DEPENDENCIES = $(LIB_KDEGAMES_DEP) + +picsdir = $(kde_datadir)/klines/ +pics_DATA = balls.jpg field.jpg fire.jpg + +xdg_apps_DATA = klines.desktop +kde_kcfg_DATA = klines.kcfg + +EXTRA_DIST = $(pics_DATA) + +KDE_ICON = klines + +rcdir = $(kde_datadir)/klines +rc_DATA = klinesui.rc + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/klines.pot; + diff --git a/klines/ballpainter.cpp b/klines/ballpainter.cpp new file mode 100644 index 00000000..06380a6f --- /dev/null +++ b/klines/ballpainter.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#include <kapplication.h> +#include <kmessagebox.h> +//#include "shotcounter.h" +#include <qpainter.h> +#include "linesboard.h" +//#include <qcolor.h> +#include <qjpegio.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <stdlib.h> + +#include "prefs.h" + +#define PIXSIZE (CELLSIZE - 2) + +int colorLinesArr[NCOLORS] = + {0x0000ff, 0x00ff00, 0xff0000, 0x00ffff, 0xff00ff, 0xffff00, 0x005080}; + // 0x00bbggrr + // red , green , blue , yellow , violet , cyan , brown + + + +BallPainter::BallPainter() + : QObject(), backgroundPix(0) +{ + createPix(); +} + +BallPainter::~BallPainter() +{ + deletePix(); +} + +void BallPainter::deletePix() +{ + delete backgroundPix; + for(int c=0; c<NCOLORS; c++) + for(int t=0; t<PIXTIME + FIREBALLS + BOOMBALLS + 1 ; t++) + delete imgCash[c][t]; + for(int t=0; t < FIREPIX ; t++) + delete firePix[t]; +} + +void BallPainter::createPix() +{ + backgroundPix = new QPixmap( + locate( "appdata", "field.jpg" )); + QPixmap *balls = new QPixmap( + locate( "appdata", "balls.jpg" )); + QPixmap *fire = new QPixmap( + locate( "appdata", "fire.jpg" )); + if (balls->isNull() ||backgroundPix->isNull() || fire->isNull() ) { + KMessageBox::error(0, i18n("Unable to find graphics. Check your installation."), i18n("Error")); + qApp->exit(1); + return; // Error + } + + for(int c=0; c<NCOLORS; c++) + { + for(int t=0; t<PIXTIME + FIREBALLS + BOOMBALLS + 1 ; t++) + { + imgCash[c][t] = new QPixmap(CELLSIZE, CELLSIZE); + QPainter p(imgCash[c][t]); + p.drawPixmap(0,0,(*backgroundPix),0,0,CELLSIZE,CELLSIZE); + p.drawPixmap(1,1,(*balls),t*PIXSIZE,c*PIXSIZE,PIXSIZE,PIXSIZE); + if (Prefs::numberedBalls() && (t == NORMALBALL)) + { + if ((c == 2) || (c == 3) || (c == 6)) + p.setPen(Qt::black); + else + p.setPen(Qt::white); + QString tmp; + tmp.setNum(c+1); + p.drawText(QRect(0,0,CELLSIZE,CELLSIZE), Qt::AlignCenter, tmp); + } + + } + } + for(int t=0; t < FIREPIX ; t++) + { + firePix[t] = new QPixmap(CELLSIZE, CELLSIZE); + QPainter p(firePix[t]); + p.drawPixmap(0,0,(*backgroundPix),0,0,CELLSIZE,CELLSIZE); + p.drawPixmap(1,1,(*fire),t*PIXSIZE,0,PIXSIZE,PIXSIZE); + } + delete balls; + delete fire; +} + + +QPixmap BallPainter::GetBall(int color, int animstep, int panim) +{ +// return backgroundPix; + + if( (color<0) || (color>=NCOLORS) || (animstep<0) || color == NOBALL ){ + return *backgroundPix; + } + if ( panim == ANIM_JUMP ) + { + if ( ( animstep < 0 ) || ( animstep >= PIXTIME ) ) + return *backgroundPix; + else + return *imgCash[color][animstep]; + } + else if ( panim == ANIM_BURN ) + { + if ( animstep < FIREBALLS ) + return *imgCash[color][animstep + PIXTIME + BOOMBALLS + 1]; + else if ( animstep < FIREBALLS + FIREPIX ) + return *firePix[animstep - FIREBALLS]; + } + else if ( panim == ANIM_BORN ) + { + if ( animstep < BOOMBALLS ) + return *imgCash[color][animstep + PIXTIME]; + else + return *imgCash[color][NORMALBALL]; + } + // rest is not imlemented yet + return *imgCash[color][NORMALBALL]; + +} + +#include "ballpainter.moc" diff --git a/klines/ballpainter.h b/klines/ballpainter.h new file mode 100644 index 00000000..a0ad2cbb --- /dev/null +++ b/klines/ballpainter.h @@ -0,0 +1,47 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef BALLPAINTER_H +#define BALLPAINTER_H + +#include <qobject.h> +#include <qpixmap.h> +#include "cfg.h" + +#define CELLSIZE 32 + +class BallPainter : public QObject +{ + Q_OBJECT + QPixmap* imgCash[NCOLORS][PIXTIME + FIREBALLS + BOOMBALLS + 1]; + QPixmap* backgroundPix; + QPixmap* firePix[FIREPIX]; + + +public: + BallPainter(); + ~BallPainter(); + + void deletePix(); + void createPix(); + + QPixmap GetBall( int color, int animstep, int panim ); + QPixmap GetNormalBall(int color) { return GetBall(color,0,ANIM_NO); } + QPixmap GetBackgroundPix() { return GetBall(NOBALL,0,ANIM_NO); } +}; + +#endif diff --git a/klines/balls.jpg b/klines/balls.jpg Binary files differnew file mode 100644 index 00000000..67a3aaf5 --- /dev/null +++ b/klines/balls.jpg diff --git a/klines/cell.cpp b/klines/cell.cpp new file mode 100644 index 00000000..1ed40e0b --- /dev/null +++ b/klines/cell.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "cell.h" + +Cell::Cell() +{ + clear(); +} + +void Cell::clear() +{ + color = NOBALL; + anim = ANIM_NO; +} + +Cell& Cell::moveBall(Cell& cell) +{ + *this = cell; + cell.clear(); + return *this; +} +Cell& Cell::operator= (const Cell& cell) +{ + color = cell.color; + anim = cell.anim; + return *this; +} diff --git a/klines/cell.h b/klines/cell.h new file mode 100644 index 00000000..48c8eb87 --- /dev/null +++ b/klines/cell.h @@ -0,0 +1,40 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef cell_h +#define cell_h + +#include "cfg.h" + +// enum int AnimType {ANIM_NO,ANIM_BORN,ANIM_JUMP,ANIM_RUN,ANIM_BURN,ANIM_BLOCK}; + +class Cell { + int color; + int anim; +public: + Cell(); + + int getColor() {return ( color );} + int getAnim() {return ( anim );} + bool isFree() { return (( color == NOBALL )? true:false);} + + void setColor(int c) {color = c;} + void setAnim(int a) {anim = a;} + void clear(); + Cell& operator = (const Cell& c); + + Cell& moveBall(Cell& cell); +}; +#endif diff --git a/klines/cfg.h b/klines/cfg.h new file mode 100644 index 00000000..d1a4b32b --- /dev/null +++ b/klines/cfg.h @@ -0,0 +1,48 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef CFG_H +#define CFG_H 1 + +#define LINESVERSION "1.1" + +#define NCOLORS 7 +#define BALLSDROP 3 + +#define NOBALL -1 +#define PIXTIME 10 +#define FIREBALLS 4 +#define BOOMBALLS 4 +#define FIREPIX 5 +#define STEPTIME 3 +#define NORMALBALL PIXTIME + BOOMBALLS +#define TIMERCLOCK 25 +#define DEMO_LEVEL -100 +#define DEMO_SEQUENCE 42 + +enum Anim +{ + ANIM_NO, + ANIM_JUMP, + ANIM_RUN, + ANIM_BORN, + ANIM_BURN, + ANIM_YES, + ANIM_BLOCK +}; + +//#define _DBG_ + +#endif //__CFG_H diff --git a/klines/field.cpp b/klines/field.cpp new file mode 100644 index 00000000..d7be22ca --- /dev/null +++ b/klines/field.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include "cfg.h" +#include "field.moc" + +Field::Field(QWidget* parent, const char* name) + : QWidget( parent, name ) +{ + clearField(); +} + +Field::~Field() +{ +} + +void Field::clearField() +{ + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + field[y][x].clear(); +} +void Field::clearAnim() +{ + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + field[y][x].setAnim( ANIM_NO ); +} +int Field::deleteAnimatedBalls() +{ + int deleted = 0; + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + { + if ( field[y][x].getAnim() != ANIM_NO ) + { + deleted++; + field[y][x].clear(); + } + } + return deleted; +} + +bool Field::checkBounds(int x, int y) +{ + return (x>=0) && (x<NUMCELLSW) && (y>=0) && (y<NUMCELLSH); +} + +void Field::putBall(int x, int y, int color) +{ + if( checkBounds(x,y) ){ + field[y][x].setColor(color); + } +} +/* +void Field::putBall(int x, int y, char color) +{ + if( checkBounds(x,y) ){ + field[y][x].setColor(color); + erase5Balls(); + repaint(FALSE); + } +}*/ +void Field::moveBall(int xa, int ya, int xb, int yb) +{ + if( checkBounds(xa,ya) && checkBounds(xb,yb) && + field[yb][xb].isFree() && ( xa != xb || ya != yb) ) { + field[yb][xb].moveBall(field[ya][xa]); + } +} + +int Field::getBall(int x, int y) +{ + if( checkBounds(x,y) ) + return field[y][x].getColor(); + else + return NOBALL; +} +int Field::getAnim(int x, int y) +{ + if( checkBounds(x,y) ) + return field[y][x].getAnim(); + else + return NOBALL; +} +void Field::setAnim(int x, int y, int anim) +{ + if( checkBounds(x,y) ) + field[y][x].setAnim( anim ); +} + +void Field::removeBall(int x, int y ) +{ + if( checkBounds(x,y) ) field[y][x].clear(); +} + +int Field::freeSpace() +{ + int s = 0; + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + if(field[y][x].isFree()) s++; + return s; +} +void Field::saveUndo() +{ + void clearAnim(); + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + field_undo[y][x] = field[y][x]; +} +void Field::restoreUndo() +{ + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + field[y][x] = field_undo[y][x]; +} + +int Field::calcRun(int sx, int sy, int dx, int dy) +{ + int ix = sx; + int iy = sy; + int run = 0; + int score = 0; + int current_color = NOBALL; + int lpr = 0; + int lprscore = 0; + int empty = 0; + for(int i = 0; i < 9; i++, ix += dx, iy += dy) + { + if ((ix < 0) || (iy < 0) || (ix >= NUMCELLSW) || (iy >= NUMCELLSH)) + continue; + int b = field[iy][ix].getColor(); +//printf("[%d,%d]%d", ix,iy,b); + if (b == NOBALL) + { + run++; + empty++; + } + else if (b == current_color) + { + run++; + score++; + empty = 0; + } + else + { + run = empty+1; + score = 1; + current_color = b; + empty = 0; + } + if (run > lpr) + { + lpr = run; + lprscore = score; + } + } + if (lpr < 5) + lprscore = -10; + else + lprscore = lprscore*lprscore; +// printf("= %d\n", lprscore); + return lprscore; +} + +int Field::calcPosScore(int x, int y, int whatIf) +{ + int score = -10; + int color = field[y][x].getColor(); + field[y][x].setColor(whatIf); + score = QMAX(score, calcRun(x, y-4, 0, 1)); + score = QMAX(score, calcRun(x-4, y-4, 1, 1)); + score = QMAX(score, calcRun(x-4, y, 1, 0)); + score = QMAX(score, calcRun(x-4, y+4, 1, -1)); + field[y][x].setColor(color); + return score; +} + diff --git a/klines/field.h b/klines/field.h new file mode 100644 index 00000000..de9ee8ce --- /dev/null +++ b/klines/field.h @@ -0,0 +1,65 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef FIELD_H +#define FIELD_H + +#include <qobject.h> +#include <qwidget.h> +#include "cell.h" +// size of game field +#define NUMCELLSW 9 +#define NUMCELLSH 9 + +class Field: public QWidget +{ + Q_OBJECT +public: + void clearField(); + + int calcPosScore(int x, int y, int whatIf); + void saveUndo(); + +protected: + Field(QWidget* parent, const char* name); + ~Field(); + + void putBall(int x, int y, int color); + void putBallRun(int x, int y, int color); + void removeBall(int x, int y ); + int getBall(int x, int y); + int getAnim(int x, int y); + void setAnim(int x, int y, int anim ); + void clearAnim(); + int deleteAnimatedBalls(); + void moveBall(int xa, int ya, int xb, int yb); + int calcRun(int sx, int sy, int dx, int dy); + + + bool checkBounds( int x, int y ); +// virtual int erase5Balls(){ return 0;} + int freeSpace(); + void restoreUndo(); + +private: + Cell field[NUMCELLSH][NUMCELLSW]; + Cell field_undo[NUMCELLSH][NUMCELLSW]; +// void search5Balls(); + +}; + +#endif diff --git a/klines/field.jpg b/klines/field.jpg Binary files differnew file mode 100644 index 00000000..d021b6fa --- /dev/null +++ b/klines/field.jpg diff --git a/klines/fire.jpg b/klines/fire.jpg Binary files differnew file mode 100644 index 00000000..022f99ca --- /dev/null +++ b/klines/fire.jpg diff --git a/klines/hi128-app-klines.png b/klines/hi128-app-klines.png Binary files differnew file mode 100644 index 00000000..4784a9ec --- /dev/null +++ b/klines/hi128-app-klines.png diff --git a/klines/hi16-app-klines.png b/klines/hi16-app-klines.png Binary files differnew file mode 100644 index 00000000..ac3bf6b8 --- /dev/null +++ b/klines/hi16-app-klines.png diff --git a/klines/hi22-app-klines.png b/klines/hi22-app-klines.png Binary files differnew file mode 100644 index 00000000..cb456ae3 --- /dev/null +++ b/klines/hi22-app-klines.png diff --git a/klines/hi32-app-klines.png b/klines/hi32-app-klines.png Binary files differnew file mode 100644 index 00000000..e38cb1a5 --- /dev/null +++ b/klines/hi32-app-klines.png diff --git a/klines/hi48-app-klines.png b/klines/hi48-app-klines.png Binary files differnew file mode 100644 index 00000000..96b49a45 --- /dev/null +++ b/klines/hi48-app-klines.png diff --git a/klines/hi64-app-klines.png b/klines/hi64-app-klines.png Binary files differnew file mode 100644 index 00000000..0efed587 --- /dev/null +++ b/klines/hi64-app-klines.png diff --git a/klines/klines.cpp b/klines/klines.cpp new file mode 100644 index 00000000..d5f36e35 --- /dev/null +++ b/klines/klines.cpp @@ -0,0 +1,585 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/* changes +21.05.2000 Roman Razilov Menu game/Next +*/ +// +// The implementation of the KLines widget +// + +#include <qkeycode.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qstring.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> + +#include <kapplication.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kconfig.h> +#include <kmenubar.h> +#include <kpopupmenu.h> +#include <kscoredialog.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kstdgameaction.h> + +#include "cfg.h" +#include "prefs.h" +#include <kstatusbar.h> +#include "klines.moc" + +enum { Nb_Levels = 5 }; +static const char *LEVEL[Nb_Levels] = { + I18N_NOOP("Very Easy"), I18N_NOOP("Easy"), I18N_NOOP("Normal"), I18N_NOOP("Hard"), + I18N_NOOP("Very Hard") +}; + + +/* + Creates the KLines widget and sets saved options (if any). +*/ + +KLines::KLines() +{ + mwidget = new MainWidget(this); + setCentralWidget( mwidget ); + + lsb = mwidget->GetLsb(); + connect(lsb, SIGNAL(endTurn()), this, SLOT(makeTurn())); + connect(lsb, SIGNAL(eraseLine(int)), this, SLOT(addScore(int))); + connect(lsb, SIGNAL(endGame()), this, SLOT(endGame())); + connect(lsb, SIGNAL(userTurn()), this, SLOT(userTurn())); + + lPrompt = mwidget->GetPrompt(); + + score = 0; + score_undo = 0; + bDemo = false; + + statusBar()->insertItem(i18n(" Score:"), 1, 1); + statusBar()->setItemAlignment(1, AlignVCenter | AlignLeft); + statusBar()->insertItem(i18n(" Level: "), 0, 1); + statusBar()->setItemAlignment(0, AlignVCenter | AlignLeft); + + initKAction(); + + connect(&demoTimer, SIGNAL(timeout()), this, SLOT(slotDemo())); + + setFocusPolicy(StrongFocus); + setFocus(); + + startGame(); +} + +/* + Saves the options and destroys the KLines widget. +*/ +KLines::~KLines() +{ + Prefs::setLevel(levelAction->currentItem()-2); + Prefs::writeConfig(); +} + +/* + Init KAction objects (menubar, toolbar, shortcuts) +*/ +void KLines::initKAction() +{ + KStdGameAction::gameNew(this, SLOT(startGame()), actionCollection()); + act_demo = KStdGameAction::demo(this, SLOT(startDemo()), actionCollection()); + act_demo->setText(i18n("Start &Tutorial")); + KStdGameAction::highscores(this, SLOT(viewHighScore()), actionCollection()); + KStdGameAction::quit(this, SLOT(close()), actionCollection()); + endTurnAction = KStdGameAction::endTurn(this, SLOT(makeTurn()), actionCollection()); + showNextAction = new KToggleAction(i18n("&Show Next"), KShortcut(CTRL+Key_P), + this, SLOT(switchPrompt()), actionCollection(), "options_show_next"); + showNextAction->setCheckedState(i18n("Hide Next")); + showNumberedAction = new KToggleAction(i18n("&Use Numbered Balls"), KShortcut(), + this, SLOT(switchNumbered()), actionCollection(), "options_show_numbered"); + undoAction = KStdGameAction::undo(this, SLOT(undo()), actionCollection()); + + levelAction = KStdGameAction::chooseGameType(0, 0, actionCollection()); + QStringList items; + for (uint i=0; i<Nb_Levels; i++) + items.append( i18n(LEVEL[i]) ); + levelAction->setItems(items); + + levelAction->setCurrentItem(Prefs::level()+2); + showNextAction->setChecked(Prefs::showNext()); + showNumberedAction->setChecked(Prefs::numberedBalls()); + lPrompt->setPrompt(Prefs::showNext()); + + (void)new KAction(i18n("Move Left"), Key_Left, lsb, SLOT(moveLeft()), actionCollection(), "left"); + (void)new KAction(i18n("Move Right"), Key_Right, lsb, SLOT(moveRight()), actionCollection(), "right"); + (void)new KAction(i18n("Move Up"), Key_Up, lsb, SLOT(moveUp()), actionCollection(), "up"); + (void)new KAction(i18n("Move Down"), Key_Down, lsb, SLOT(moveDown()), actionCollection(), "down"); + (void)new KAction(i18n("Move Ball"), Key_Space, lsb, SLOT(placePlayerBall()), actionCollection(), "place_ball"); + + setupGUI( KMainWindow::Save | Keys | StatusBar | Create ); +} + +void KLines::startGame() +{ + score = 0; + score_undo = 0; + bUndo = true; + bNewTurn = true; + if(bDemo) + stopDemo(); + + bFirst = true; + + int level = levelAction->currentItem()-2; + setLevel(level); + + lsb->setLevel(level); + lsb->setGameOver(false); + lsb->clearField(); + generateRandomBalls(); + placeBalls(); + generateRandomBalls(); + undoAction->setEnabled(false); + endTurnAction->setEnabled(true); + updateStat(); +} + +void KLines::setLevel(int level) { + levelStr = i18n(LEVEL[level+2]); + statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); +} + +void KLines::startDemo() +{ + if (bDemo) + { + stopDemo(); + return; + } + score = 0; + score_undo = 0; + bUndo = true; + bNewTurn = true; + bDemo = true; + act_demo->setText(i18n("Stop &Tutorial")); + bFirst = true; + + levelStr = i18n("Tutorial"); + statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); + + lsb->startDemoMode(); + lsb->setGameOver(false); + lsb->clearField(); + lsb->update(); + undoAction->setEnabled(false); + endTurnAction->setEnabled(false); + generateRandomBalls(); + + demoStep = 0; + demoTimer.start(1000, true); +} + +void KLines::stopDemo() +{ + bDemo = false; + lsb->hideDemoText(); + demoTimer.stop(); + statusBar()->changeItem(i18n(" Level: %1").arg(i18n("Tutorial - Stopped")), 0); + act_demo->setText(i18n("Start &Tutorial")); +} + +void KLines::slotDemo() +{ + bool newBalls = false; + int ballColors = -1; + int clickX = 0; + int clickY = 0; + QString msg; + demoStep++; + if ((demoStep % 2) == 0) + { + lsb->hideDemoText(); + demoTimer.start(1000, true); + return; + } + if (demoStep == 1) + { + msg = i18n("The goal of the game is to put\n" + "5 balls of the same color in line."); + } + else if (demoStep == 3) + { + newBalls = true; + } + else if (demoStep == 5) + { + msg = i18n("You can make horizontal, vertical\n" + "and diagonal lines."); + } + else if (demoStep == 7) + { + newBalls = true; + } + else if (demoStep == 9) + { + msg = i18n("Each turn, three new balls are placed on the board."); + } + else if (demoStep == 11) + { + newBalls = true; + } + else if (demoStep == 13) + { + msg = i18n("Every turn, you can move one ball."); + } + else if (demoStep == 15) + { + newBalls = true; + ballColors = 56; + } + else if (demoStep == 17) + { + msg = i18n("To move a ball, click on it with the mouse,\n" + "then click where you want the ball to go."); + } + else if (demoStep == 19) + { + clickX = 6; + clickY = 6; + } + else if (demoStep == 21) + { + clickX = 6; + clickY = 9; + } + else if (demoStep == 23) + { + msg = i18n("You just moved the blue ball!"); + } + else if (demoStep == 25) + { + newBalls = true; + } + else if (demoStep == 27) + { + msg = i18n("Balls can be moved to every position on the board,\n" + "as long as there are no other balls in their way."); + } + else if (demoStep == 29) + { + clickX = 4; + clickY = 3; + demoStep++; + } + else if (demoStep == 31) + { + clickX = 7; + clickY = 9; + } + else if (demoStep == 33) + { + msg = i18n("Now we only need one more blue ball."); + } + else if (demoStep == 35) + { + newBalls = true; + } + else if (demoStep == 37) + { + msg = i18n("It seems to be our lucky day!"); + } + else if (demoStep == 39) + { + clickX = 8; + clickY = 2; + demoStep++; + } + else if (demoStep == 41) + { + clickX = 8; + clickY = 9; + } + else if (demoStep == 43) + { + msg = i18n("Hurray! And away they go!\n" + "Now lets try the green balls."); + } + else if (demoStep == 45) + { + clickX = 8; + clickY = 7; + demoStep++; + } + else if (demoStep == 47) + { + clickX = 4; + clickY = 5; + lsb->demoAdjust(42); + } + else if (demoStep == 49) + { + newBalls = true; + } + else if (demoStep == 51) + { + msg = i18n("Now you try!\n" + "Click on the green ball and move it to the others!"); + demoStep++; + } + else if (demoStep == 53) + { + lsb->hideDemoText(); + lsb->adjustDemoMode(true, false); + demoStep++; + } + else if (demoStep == 55) + { + msg = i18n("Almost, try again!"); + demoStep -= 4; + } + else if (demoStep == 57) + { + msg = i18n("Very good!"); + } + else if (demoStep == 59) + { + msg = i18n("Whenever you complete a line you get an extra turn."); + } + else if (demoStep == 61) + { + msg = i18n("This is the end of this tutorial.\n" + "Feel free to finish the game!"); + demoStep++; + } + else if (demoStep == 63) + { + lsb->hideDemoText(); + lsb->adjustDemoMode(true, true); + bDemo = false; + act_demo->setText(i18n("Start &Tutorial")); + } + + if (!msg.isEmpty()) + { + lsb->showDemoText(msg); + demoTimer.start(3500 + msg.contains("\n")*1500, true); + return; + } + if (newBalls) + { + placeBalls(); + if (ballColors == -1) + { + generateRandomBalls(); + } + else + { + for( int i = 0 ; i < BALLSDROP ; i++ ) + { + nextBalls[i] = ballColors % 10; + ballColors = ballColors / 10; + lPrompt->SetBalls(nextBalls); + } + } + + updateStat(); + demoTimer.start(1000, true); + return; + } + if (clickX) + { + lsb->demoClick(clickX-1, clickY-1); + if (hasFocus()) + demoTimer.start(1000, true); + return; + } +} + +void KLines::focusOutEvent(QFocusEvent *ev) +{ + if (bDemo) + { + lsb->hideDemoText(); + demoTimer.stop(); + statusBar()->changeItem(i18n(" Level: %1").arg(i18n("Tutorial - Paused")), 0); + } + KMainWindow::focusOutEvent(ev); +} + +void KLines::focusInEvent(QFocusEvent *ev) +{ + if (bDemo) + { + statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); + slotDemo(); + } + KMainWindow::focusInEvent(ev); +} + +void KLines::stopGame() +{ + if (!lsb->gameOver()) + endGame(); + startGame(); +} + +void KLines::searchBallsLine() +{ +} + +void KLines::generateRandomBalls() +{ + score_undo = score; + for( int i = 0 ; i < BALLSDROP ; i++ ) + { + nextBalls_undo[i] = nextBalls[i]; + nextBalls[i] = bUndo ? + lsb->random(NCOLORS) : + nextBalls_redo[i]; + } + lPrompt->SetBalls(nextBalls); +} + +void KLines::placeBalls() +{ + lsb->placeBalls(nextBalls); +} + +void KLines::undo() +{ + if (lsb->gameOver()) + return; + if (!bUndo) + return; + for( int i = 0 ; i < BALLSDROP ; i++ ) + { + nextBalls_redo[i] = nextBalls[i]; + nextBalls[i] = nextBalls_undo[i]; + } + score = score_undo; + updateStat(); + lPrompt->SetBalls(nextBalls); + lsb->undo(); + switchUndo(FALSE); +} + +void KLines::makeTurn() +{ + if (bDemo) + { + lsb->adjustDemoMode(false, false); + demoTimer.start(100, true); + } + if (lsb->gameOver()) + return; + if (!bDemo){ + placeBalls(); + if(sender() != lsb) + lsb->saveUndo(); + } + bNewTurn = true; +} + +void KLines::userTurn() +{ + if(bNewTurn) + { + bNewTurn = false; + if (!bDemo) + generateRandomBalls(); + if (!bFirst && !bDemo) + switchUndo(true); + } + bFirst = false; +} + +void KLines::addScore(int ballsErased) +{ if(ballsErased >= 5){ + score += 2*ballsErased*ballsErased - 20*ballsErased + 60 ; + if( !lPrompt->getState() ) score+= 1; + updateStat(); + }; + if (bDemo) + { + lsb->adjustDemoMode(false, false); + demoStep += 2; + if (hasFocus()) + demoTimer.start(100, true); + } +} + +void KLines::updateStat() +{ + statusBar()->changeItem(i18n(" Score: %1").arg(score), 1); +} + +void KLines::viewHighScore() +{ + KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); + d.exec(); +} + +void KLines::endGame() +{ + lsb->setGameOver(true); + lsb->repaint(false); + + if (bDemo) + return; + + KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); + KScoreDialog::FieldInfo scoreInfo; + scoreInfo.insert(KScoreDialog::Level, levelStr); + if (d.addScore(score, scoreInfo, true)) + d.exec(); +} + +void KLines::switchPrompt() +{ + Prefs::setShowNext(!Prefs::showNext()); + lPrompt->setPrompt(Prefs::showNext()); + showNextAction->setChecked(Prefs::showNext()); +} + +void KLines::switchNumbered() +{ + Prefs::setNumberedBalls(!Prefs::numberedBalls()); + lPrompt->setPrompt(Prefs::showNext()); + showNumberedAction->setChecked(Prefs::numberedBalls()); + mwidget->updatePix(); +} + +void KLines::switchUndo(bool bu) +{ + bUndo = bu; + undoAction->setEnabled(bu); +} + +void KLines::keyPressEvent(QKeyEvent *e) +{ + if (lsb->gameOver() && (e->key() == Qt::Key_Space)) + { + e->accept(); + startGame(); + return; + } + KMainWindow::keyPressEvent(e); +} diff --git a/klines/klines.desktop b/klines/klines.desktop new file mode 100644 index 00000000..dba71f39 --- /dev/null +++ b/klines/klines.desktop @@ -0,0 +1,111 @@ +# KDE Config File +[Desktop Entry] +Type=Application +Exec=klines -caption "%c" %i %m +Icon=klines +DocPath=klines/index.html +GenericName=Tactical Game +GenericName[af]=Taktiese Speletjie +GenericName[ar]=لعبة تكتيكية +GenericName[az]=Taktik oyunu +GenericName[be]=Тактычная гульня +GenericName[bg]=Тактическа игра +GenericName[bn]=কৌশলের খেলা +GenericName[br]=C'hoari a vrezelekaouriezh +GenericName[bs]=Taktička igra +GenericName[ca]=Joc de tàctica +GenericName[cs]=Taktická hra +GenericName[cy]=Gêm Dactegol +GenericName[da]=Taktisk spil +GenericName[de]=Taktikspiel +GenericName[el]=Παιχνίδι τακτικής +GenericName[eo]=Taktika ludo +GenericName[es]=Juego de táctica +GenericName[et]=Taktikamäng +GenericName[eu]=Joko taktikoa +GenericName[fa]=بازی برنامهریزیشده +GenericName[fi]=Taktiikkapeli +GenericName[fo]=Taktiskt spæl +GenericName[fr]=Jeu de tactique +GenericName[ga]=Cluiche Taicticiúil +GenericName[gl]=Xogo de Táctica +GenericName[he]=משחק טקטי +GenericName[hi]=रणनीतिक खेल +GenericName[hr]=Taktička igra +GenericName[hu]=Logikai +GenericName[id]=Permainan Taktik +GenericName[is]=Herkænskuleikur +GenericName[it]=Gioco di tattica +GenericName[ja]=戦略的ゲーム +GenericName[km]=ល្បែងក្បួនយុទ្ធសាស្ត្រ +GenericName[ko]=전략 게임 +GenericName[lt]=Taktinis žaidimas +GenericName[lv]=Taktiskā spēle +GenericName[mk]=Тактичка игра +GenericName[mt]=Logħba ta' tattika +GenericName[nb]=Taktikk-spill +GenericName[nds]=Taktikspeel +GenericName[ne]=युक्तिसंगत खेल +GenericName[nl]=Tactisch spel +GenericName[nn]=Taktisk spel +GenericName[pa]=ਟਾਕਟੀਕਲ ਖੇਡ +GenericName[pl]=Gra taktyczna +GenericName[pt]=Jogo de Estratégia +GenericName[pt_BR]=Jogo Tático +GenericName[ro]=Un joc de tactică +GenericName[ru]=Тактическая игра +GenericName[rw]=Umukino Mugambi +GenericName[se]=Taktihkkaspeallu +GenericName[sk]=Taktická hra +GenericName[sl]=Taktična igra +GenericName[sr]=Тактичка игра +GenericName[sr@Latn]=Taktička igra +GenericName[sv]=Taktikspel +GenericName[ta]=தந்திரமான விளையாட்டு +GenericName[tg]=Бозии Тактикӣ +GenericName[th]=เกมวางแผน +GenericName[tr]=Taktik oyunu +GenericName[uk]=Тактична гра +GenericName[ven]=Mutambo wa Tactical +GenericName[vi]=Trò chơi chiến thuật +GenericName[wa]=Djeu di tactike +GenericName[xh]=Umdlalo onamaqhinga +GenericName[zh_CN]=战术游戏 +GenericName[zh_TW]=戰術遊戲 +GenericName[zu]=Umdlalo wamasu +Terminal=false +Name=Kolor Lines +Name[af]=Kleur Lyne +Name[ar]=خطوط Kolor +Name[be]=Каляровыя лініі +Name[bn]=কালার লাইন্স +Name[br]=Linenn Kolor +Name[eo]=Kolorlinioj +Name[fa]=خطوط Kolor +Name[fr]=KLines +Name[hi]=कलर लाइन्स +Name[hr]=KNiz u boji +Name[hu]=Színes vonalak +Name[it]=KLines +Name[nb]=Klinjer +Name[ne]=रङ रेखा +Name[nso]=Methalo ya Mmala +Name[pa]=ਰੰਗ ਖੇਡ +Name[pl]=Kolorowe linie +Name[pt]=Linhas Coloridas +Name[pt_BR]=KLinhas de Cores +Name[ro]=Linii colorate +Name[ru]=Цветные линии +Name[sl]=Barvne črte +Name[sv]=Färglinjer +Name[ta]=வண்ணக்கோடுகள் +Name[tg]=Хатҳои Рангӣ +Name[tr]=Renkli çizgiler +Name[uk]=Кольорові лінії +Name[ven]=Mitalo ya Kolor +Name[wa]=Royes di coleur +Name[xh]=Iilayini zeKolor +Name[zh_TW]=Kolor Lines 彩色線條 +Name[zu]=Olayini bemibala +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;Game;StrategyGame; diff --git a/klines/klines.h b/klines/klines.h new file mode 100644 index 00000000..73720f03 --- /dev/null +++ b/klines/klines.h @@ -0,0 +1,93 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KLINES_H +#define KLINES_H + +#include <kmainwindow.h> + +#include "linesboard.h" +#include "mwidget.h" +#include "prompt.h" + +class KSelectAction; +class KAction; +class KToggleAction; + +class KLines : public KMainWindow +{ + Q_OBJECT +public: + KLines(); + ~KLines(); + +protected: + void keyPressEvent(QKeyEvent *e); + void initKAction(); + void setLevel(int level); + + void focusOutEvent(QFocusEvent *); + void focusInEvent(QFocusEvent *); + +public slots: + void startGame(); + void startDemo(); + void stopGame(); + void endGame(); + void makeTurn(); + void userTurn(); + void addScore(int ballsErased); + void switchPrompt(); + void switchNumbered(); + void undo(); + void slotDemo(); + +private slots: + void viewHighScore(); + +private: + LinesBoard* lsb; + MainWidget *mwidget; + LinesPrompt *lPrompt; + KAction *act_demo, *undoAction, *endTurnAction; + KSelectAction *levelAction; + KToggleAction *showNextAction; + KToggleAction *showNumberedAction; + QString levelStr; + + bool bNewTurn; + + int score; + int score_undo; + + int nextBalls[BALLSDROP]; + int nextBalls_undo[BALLSDROP]; + int nextBalls_redo[BALLSDROP]; + bool bUndo; + bool bFirst; + bool bDemo; + + int demoStep; + QTimer demoTimer; + + void searchBallsLine(); + void generateRandomBalls(); + void placeBalls(); + void updateStat(); + void switchUndo( bool bu ); + void stopDemo(); +}; + +#endif diff --git a/klines/klines.kcfg b/klines/klines.kcfg new file mode 100644 index 00000000..bc5b6f63 --- /dev/null +++ b/klines/klines.kcfg @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + <kcfgfile name="klinesrc"/> + <group name="Game"> + <entry name="Level" type="Int"> + <label>Difficulty level</label> + <default>0</default> + <min>-2</min> + <max>2</max> + </entry> + <entry name="ShowNext" type="Bool"> + <label>Whether to show the next set of balls.</label> + <default>true</default> + </entry> + <entry name="NumberedBalls" type="Bool"> + <label>Whether to use numbered balls.</label> + <default>false</default> + </entry> + </group> +</kcfg> diff --git a/klines/klinesui.rc b/klines/klinesui.rc new file mode 100644 index 00000000..13af3734 --- /dev/null +++ b/klines/klinesui.rc @@ -0,0 +1,11 @@ +<!DOCTYPE kpartgui> +<kpartgui name="klines" version="4"> + +<MenuBar> + <Menu name="settings"><text>&Settings</text> + <Action name="options_show_next" append="show_merge"/> + <Action name="options_show_numbered" append="show_merge"/> + </Menu> +</MenuBar> + +</kpartgui> diff --git a/klines/linesboard.cpp b/klines/linesboard.cpp new file mode 100644 index 00000000..5078b8f9 --- /dev/null +++ b/klines/linesboard.cpp @@ -0,0 +1,754 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <qpainter.h> +#include <qcolor.h> +#include <qcursor.h> +#include <qkeycode.h> +#include <qtooltip.h> +#include <stdlib.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> + +#include "linesboard.h" +#include "linesboard.moc" + +/* + Constructs a LinesBoard widget. +*/ + +LinesBoard::LinesBoard( BallPainter * abPainter, QWidget* parent, const char* name ) + : Field( parent, name ) +{ + demoLabel = 0; + bGameOver = false; + anim = ANIM_NO; + focusX = -1; + focusY = -1; +// waypos = 0; +// waylen = 0; +// jumpingRow = -1; +// jumpingCol = -1; + painting = 0; + way = new Waypoints[NUMCELLSW*NUMCELLSH]; + + bPainter = abPainter; + + setFocusPolicy( NoFocus ); + setBackgroundColor( gray ); + + setMouseTracking( FALSE ); + setFixedSize(wHint(), hHint()); + + timer = new QTimer(this); + connect( timer, SIGNAL(timeout()), SLOT(timerSlot()) ); + timer->start( TIMERCLOCK, FALSE ); + +} + +/* + Destructor: deallocates memory for contents +*/ + +LinesBoard::~LinesBoard() +{ + timer->stop(); + delete timer; + delete [] way; +} + +void LinesBoard::startDemoMode() +{ + level = DEMO_LEVEL; + rnd_demo = KRandomSequence(DEMO_SEQUENCE); + bAllowMove = false; +} + +void LinesBoard::adjustDemoMode(bool allowMove, bool off) +{ + bAllowMove = allowMove; + if (off) + level = -2; +} + +void LinesBoard::demoAdjust(int a) +{ + rnd_demo.modulate(a); +} + + +void LinesBoard::placeBalls(int pnextBalls[BALLSDROP]) +{ + for(int i=0; i < BALLSDROP; i++) + nextBalls[i] = pnextBalls[i]; + + nextBallToPlace = 0; + placeBall(); +} + +void LinesBoard::placeBall( ) +{ + char* xx = (char*)malloc( sizeof(char)*NUMCELLSW*NUMCELLSH ); + char* yy = (char*)malloc( sizeof(char)*NUMCELLSW*NUMCELLSH ); + int empty = 0; + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + if( getBall(x,y) == NOBALL ) + { + xx[empty] = x; + yy[empty] = y; + empty++; + }; + + if (empty) + { + int color = nextBalls[nextBallToPlace]; + int pos = 0; + if ((level == DEMO_LEVEL) || (level == 0)) + { + pos = random(empty); + } + else + { + int best_pos = 0; + int best_score = level > 0 ? 1000: -1000; + int maxtry = level > 0 ? level+1 : 1-level; + for(int i=0;i<maxtry;i++) + { + int pos = random(empty); + int score = calcPosScore(xx[pos], yy[pos], color) - calcPosScore(xx[pos], yy[pos], NOBALL); + if (((level > 0) && (score < best_score)) || + ((level < 0) && (score > best_score))) + { + best_pos = pos; + best_score = score; + } + } + pos = best_pos; + } + + putBall( xx[pos], yy[pos], color ); + clearAnim(); + setAnim( xx[pos], yy[pos], ANIM_BORN ); + nextBallToPlace++; + AnimStart(ANIM_BORN); + free(xx); + free(yy); + } + else + { + free(xx); + free(yy); + emit endGame(); + } +} + + +/*id LinesBoard::doAfterBalls() { + erase5Balls(); + repaint(FALSE); +} +*/ +/* + Sets the size of the table +*/ + +int LinesBoard::width() { return CELLSIZE * NUMCELLSW; } +int LinesBoard::height() { return CELLSIZE * NUMCELLSH; } +int LinesBoard::wHint() { return width(); } +int LinesBoard::hHint() { return height(); } + +void LinesBoard::setGameOver(bool b) +{ + bGameOver = b; + focusX = -1; + focusY = -1; +} + + +void LinesBoard::paintEvent( QPaintEvent* ) +{ + QPainter *paint; + KPixmap *pixmap = 0; + if (bGameOver) + { + pixmap = new KPixmap(); + pixmap->resize(width(), height()); + paint = new QPainter( pixmap ); + } + else + { + paint = new QPainter( this ); + } + + for( int y=0; y < NUMCELLSH; y++ ){ + for( int x=0; x < NUMCELLSW; x++ ){ + if( getBall(x,y) == NOBALL ) + { + paint->drawPixmap(x*CELLSIZE, y*CELLSIZE, bPainter->GetBackgroundPix() ); + } + else + { + paint->drawPixmap(x*CELLSIZE, y*CELLSIZE, + bPainter->GetBall(getBall(x,y),animstep,getAnim(x,y))); + } + } + } + if (bGameOver) + { + paint->end(); + + KPixmapEffect::fade(*pixmap, 0.5, Qt::black); + + QPainter p(this); + p.drawPixmap(0,0, *pixmap); + delete pixmap; + + QFont gameover_font = font(); + gameover_font.setPointSize(48); + gameover_font.setBold(true); + p.setFont(gameover_font); + p.setPen(Qt::white); + QString gameover_text = i18n("Game Over"); + p.drawText(0, 0, width(), height(), AlignCenter|Qt::WordBreak, gameover_text); + } + else + { + if ((focusX >= 0) && (focusX < NUMCELLSW) && + (focusY >= 0) && (focusY < NUMCELLSH)) + { + QRect r; + r.setX(focusX*CELLSIZE+2); + r.setY(focusY*CELLSIZE+2); + r.setWidth(CELLSIZE-4); + r.setHeight(CELLSIZE-4); + paint->setPen(QPen(Qt::DotLine)); + paint->drawRect(r); + } + } + delete paint; +} + +/* + Handles mouse press events for the LinesBoard widget. +*/ +void LinesBoard::mousePressEvent( QMouseEvent* e ) +{ + if (bGameOver) return; + if ((level == DEMO_LEVEL) && (!bAllowMove) && e->spontaneous()) return; + + int curRow = e->y() / CELLSIZE; + int curCol = e->x() / CELLSIZE; + + placePlayerBall(curCol, curRow); +} + +void LinesBoard::placePlayerBall(int curCol, int curRow) +{ + //check range + if (!checkBounds( curCol, curRow ) ) + return; +// if( running || anim != ANIM_NO ) return; + if(anim != ANIM_JUMP && anim != ANIM_NO) return; + if ( anim == ANIM_JUMP ) + { + if ( getBall(curCol,curRow) == NOBALL ) + { + if(existPath(jumpingCol, jumpingRow, curCol, curRow)) + { + saveRandomState(); + rnd.modulate(jumpingCol); + rnd.modulate(jumpingRow); + rnd.modulate(curCol); + rnd.modulate(curRow); + saveUndo(); + AnimStart(ANIM_RUN); + } + } + else + AnimJump(curCol,curRow); + } + else + AnimJump(curCol,curRow); +} + +/* + Move focus thingy +*/ +void LinesBoard::moveFocus(int dx, int dy) +{ + if (bGameOver) return; + if ((level == DEMO_LEVEL) && (!bAllowMove)) return; + if (focusX == -1) + { + focusX = 0; + focusY = 0; + } + else + { + focusX = (focusX + dx + NUMCELLSW) % NUMCELLSW; + focusY = (focusY + dy + NUMCELLSH) % NUMCELLSH; + } + repaint(FALSE); +} + +void LinesBoard::moveLeft() +{ + moveFocus(-1, 0); +} + +void LinesBoard::moveRight() +{ + moveFocus(1, 0); +} + +void LinesBoard::moveUp() +{ + moveFocus(0, -1); +} + +void LinesBoard::moveDown() +{ + moveFocus(0, 1); +} + +void LinesBoard::placePlayerBall() +{ + if (bGameOver) return; + if ((level == DEMO_LEVEL) && (!bAllowMove)) return; + placePlayerBall(focusX, focusY); +} + +void LinesBoard::AnimJump(int x, int y ) { + if ( getBall(x,y) != NOBALL ) + if (!( anim == ANIM_JUMP && jumpingCol == x && jumpingRow == y )) + if ( AnimEnd() ) + { + clearAnim(); + setAnim(x,y,ANIM_JUMP); + jumpingCol = x; + jumpingRow = y; + AnimStart(ANIM_JUMP); + } +} +void LinesBoard::AnimStart(int panim) { + if (anim != ANIM_NO) + AnimEnd(); + animstep = 0; + animdelaystart = 1; + switch(panim) { + case ANIM_NO: + break; + case ANIM_BORN: + animdelaystart=1; + animmax = BOOMBALLS; + break; + case ANIM_JUMP: + direction = -1; + animstep = 4; + animmax = PIXTIME -1; + break; + case ANIM_RUN: + animdelaystart=3; + // do first step on next timer; + animdelaycount = 0; + // animmax already set + break; + case ANIM_BURN: + animdelaystart=1; + animmax = FIREBALLS + FIREPIX - 1; + break; + default: + ; + } + anim = panim; + animdelaycount = animdelaystart; +} + +int LinesBoard::AnimEnd( ) +{ + if (anim == ANIM_NO ) return true; + int oldanim = anim; + anim = ANIM_NO; + if (oldanim == ANIM_RUN) { + if (animstep != animmax) { + moveBall(way[animstep].x,way[animstep].y,way[animmax].x,way[animmax].y); + } + if ( erase5Balls() == 0 ) { + emit endTurn(); + return true; + } + else + return false; + } + else if ( oldanim == ANIM_BURN ) + { + emit eraseLine( deleteAnimatedBalls() ); + repaint(FALSE); + if ( nextBallToPlace < BALLSDROP ) + { + placeBall(); + // continue with born + return false; + } + else + { + emit userTurn(); + return true; + } + } + else if ( oldanim == ANIM_BORN ) + { + if ( erase5Balls() == 0 ) + { + if ( freeSpace() > 0) + { + if ( nextBallToPlace < BALLSDROP ) + { + placeBall(); + return false; + } + else + { + emit userTurn(); + return true; + } + } + else + { + emit endGame(); + return false; + } + } + else + { + // wait for user input + emit userTurn(); + return true; + } + } + emit userTurn(); + return true; +} + +void LinesBoard::AnimNext() { + if ( anim != ANIM_NO ) + { + if ( anim == ANIM_JUMP ) { + if ( (direction > 0 && animstep == animmax) || ( direction < 0 && animstep == 0)) + direction = -direction; + animstep += direction; + repaint(FALSE); + } else { + if ( animstep >= animmax ) + AnimEnd(); + else { + animdelaycount--; + if (animdelaycount <= 0) { + if ( anim == ANIM_RUN ) + moveBall(way[animstep].x,way[animstep].y,way[animstep+1].x,way[animstep+1].y); + animstep++; + animdelaycount = animdelaystart; + repaint( FALSE ); + } + } + } + } +} +int LinesBoard::getAnim( int x, int y ) +{ + return (( Field::getAnim(x,y) != ANIM_NO )? anim : ANIM_NO); +} + +void LinesBoard::timerSlot() +{ + AnimNext(); +} + +int LinesBoard::erase5Balls() +{ + int nb=5; // minimum balls for erasure + + bool bit_erase[NUMCELLSH][NUMCELLSW]; //bool array for balls, that must be erased + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + bit_erase[y][x] = false; + + int color,newcolor; + int count; + //for horisontal + + for(int y=0; y<NUMCELLSH; y++) { + count = 1; + color = NOBALL; + for(int x=0; x<NUMCELLSW; x++){ + if ( (newcolor = getBall(x,y)) == color) { + if ( color != NOBALL) { + count++; + if ( count >= nb ) + if ( count == nb ) + for (int i = 0; i < nb; i++) + bit_erase[y][x-i] = true; + else bit_erase[y][x] = true; + } + } else { + color = newcolor; + count = 1; + } + } + } + + //for vertical + for(int x=0; x<NUMCELLSW; x++) { + count = 0; + color = NOBALL; + for(int y=0; y<NUMCELLSH; y++){ + if ( (newcolor = getBall(x,y)) == color) { + if ( color != NOBALL) { + count++; + if ( count >= nb ) + if ( count == nb ) + for (int i = 0; i < nb; i++) + bit_erase[y-i][x] = true; + else bit_erase[y][x] = true; + } + } else { + color = newcolor; + count = 1; + } + } + } + + + //for left-down to rigth-up diagonal + for ( int xs = NUMCELLSW-1,ys = NUMCELLSH-nb; xs >= nb-1; ) { + count = 0; + color = NOBALL; + for ( int x = xs, y = ys; x >= 0 && y < NUMCELLSH; x--, y++ ) { + if ( (newcolor = getBall(x,y)) == color) { + if ( color != NOBALL) { + count++; + if ( count >= nb ) + if ( count == nb ) + for (int i = 0; i < nb; i++) + bit_erase[y-i][x+i] = true; + else bit_erase[y][x] = true; + } + } else { + color = newcolor; + count = 1; + } + } + if ( ys > 0 ) ys--; else xs--; + } + + + //for left-up to rigth-down diagonal + for ( int xs = 0,ys = NUMCELLSH-nb; xs <= NUMCELLSW-nb; ) + { + count = 0; + color = NOBALL; + for ( int x = xs, y = ys; x < NUMCELLSW && y < NUMCELLSH; x++, y++ ) + { + if ( (newcolor = getBall(x,y)) == color) + { + if ( color != NOBALL) + { + count++; + if ( count >= nb ) + if ( count == nb ) + for (int i = 0; i < nb; i++) + bit_erase[y-i][x-i] = true; + else + bit_erase[y][x] = true; + } + } + else + { + color = newcolor; + count = 1; + } + } + if ( ys > 0 ) ys--; else xs++; + } + + //remove all lines balls, that more than nb + int cb=0; + for(int y=0; y < NUMCELLSH; y++) + for(int x=0; x < NUMCELLSW; x++) + { + if (bit_erase[y][x]) + { + setAnim(x,y,ANIM_YES); + cb++; + } + else + { + setAnim(x,y,ANIM_NO); + } + } + if ( cb > 0 ) + { + AnimStart(ANIM_BURN); + //emit eraseLine(cb); + } + + return cb; +} + + +#define GO_EMPTY 4 +#define GO_A 5 +#define GO_B 6 +#define GO_BALL 7 + +bool LinesBoard::existPath(int bx, int by, int ax, int ay) +{ + int dx[4]={1,-1, 0, 0}; + int dy[4]={0, 0, 1,-1}; + + if (getBall(ax,ay) != NOBALL) + return false; + + char pf[NUMCELLSH][NUMCELLSW]; + for(int y=0; y<NUMCELLSH; y++) + for(int x=0; x<NUMCELLSW; x++) + pf[y][x] = (getBall(x,y) == NOBALL) ? GO_EMPTY:GO_BALL; + + Waypoints lastchanged[2][NUMCELLSH*NUMCELLSW]; + + int lastChangedCount[2]; + int currentchanged = 0; + int nextchanged = 1; + lastchanged[currentchanged][0].x = ax; + lastchanged[currentchanged][0].y = ay; + lastChangedCount[currentchanged] = 1; + pf[ay][ax]=GO_A; + pf[by][bx]=GO_B; + + // int expanded; + bool B_reached = false; + + do + { + lastChangedCount[nextchanged] = 0; + for(int dir=0; dir<4; dir++) + { + for ( int i = 0 ; i < lastChangedCount[currentchanged]; i++ ) + { + int nx = lastchanged[currentchanged][i].x + dx[dir]; + int ny = lastchanged[currentchanged][i].y + dy[dir]; + if( (nx>=0) && (nx<NUMCELLSW) && (ny>=0) && (ny<NUMCELLSH) ) + { + if( pf[ny][nx]==GO_EMPTY ||( nx==bx && ny==by )) + { + pf[ny][nx] = dir; + lastchanged[nextchanged][lastChangedCount[nextchanged]].x = nx; + lastchanged[nextchanged][lastChangedCount[nextchanged]].y = ny; + lastChangedCount[nextchanged]++; + }; + if( (nx==bx) && (ny==by) ) + { + B_reached = true; + break; + } + } + } + } + nextchanged = nextchanged ^ 1; + currentchanged = nextchanged ^ 1; + // currentchanged,lastChangedCount[currentchanged]); + } while(!B_reached && lastChangedCount[currentchanged] != 0); + + if (B_reached) { + AnimStart( ANIM_BLOCK); + animmax = 0; +// waypos = 0; + int x, y,dir; + for( x = bx, y = by; (dir = pf[y][x]) != GO_A;x -=dx[dir],y -= dy[dir]) { + way[animmax].x = x; + way[animmax].y = y; + animmax++; + } + way[animmax].x = x; + way[animmax].y = y; + } + return B_reached; +} + +void LinesBoard::undo() +{ + AnimEnd(); + restoreUndo(); + restoreRandomState(); + repaint( FALSE ); +} + +void LinesBoard::showDemoText(const QString &text) +{ + if (!demoLabel) + { + demoLabel = new QLabel(0, "demoTip", WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM ); + demoLabel->setMargin(1); + demoLabel->setIndent(0); + demoLabel->setAutoMask( FALSE ); + demoLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + demoLabel->setLineWidth( 1 ); + demoLabel->setAlignment( AlignHCenter | AlignTop ); + demoLabel->setPalette(QToolTip::palette()); + demoLabel->polish(); + } + demoLabel->setText(text); + demoLabel->adjustSize(); + QSize s = demoLabel->sizeHint(); + QPoint p = QPoint(x() + (width()-s.width())/2, y() + (height()-s.height())/2); + demoLabel->move(mapToGlobal(p)); + demoLabel->show(); +} + +void LinesBoard::hideDemoText() +{ + if (demoLabel) + demoLabel->hide(); +} + +void LinesBoard::demoClick(int x, int y) +{ + QPoint lDest = QPoint(x*CELLSIZE+(CELLSIZE/2), y*CELLSIZE+(CELLSIZE/2)); + QPoint dest = mapToGlobal(lDest); + QPoint cur = QCursor::pos(); + for(int i = 0; i < 25;) + { + i++; + QPoint p = cur + i*(dest-cur) / 25; + QCursor::setPos(p); + QApplication::flushX(); + QTimer::singleShot(80, this, SLOT(demoClickStep())); + kapp->enter_loop(); + } + QCursor::setPos(dest); + QMouseEvent ev(QEvent::MouseButtonPress, lDest, dest, LeftButton, LeftButton); + mousePressEvent(&ev); +} + +void LinesBoard::demoClickStep() +{ + kapp->exit_loop(); +} diff --git a/klines/linesboard.h b/klines/linesboard.h new file mode 100644 index 00000000..044887b4 --- /dev/null +++ b/klines/linesboard.h @@ -0,0 +1,130 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef linesboard_h +#define linesboard_h + +#include <qwidget.h> +#include <qpixmap.h> +#include <qtimer.h> +#include <qlabel.h> + +#include <krandomsequence.h> + +#include "field.h" +//#include "shotcounter.h" +#include "ballpainter.h" + +class LinesBoard : public Field +{ + Q_OBJECT +public: + LinesBoard( BallPainter * abPainter, QWidget* parent=0, const char* name=0 ); + ~LinesBoard(); + + int width(); + int height(); + int wHint(); + int hHint(); +// void doAfterBalls(); + void placeBalls(int nextBalls[BALLSDROP]); + void undo(); + bool gameOver() { return bGameOver; } + void setGameOver(bool b); + int random(int max) { return (level == DEMO_LEVEL) ? rnd_demo.getLong(max) : rnd.getLong(max); } + void saveRandomState() { rnd_saved = rnd; } + void restoreRandomState() { rnd = rnd_saved; } + void setLevel(int _level) { level = _level; } + void startDemoMode(); + void adjustDemoMode(bool allowMove, bool off); + void showDemoText(const QString &); + void hideDemoText(); + void demoClick(int x, int y); + void demoAdjust(int a); + +signals: + void endTurn(); + void endGame(); + void eraseLine(int nb); + void userTurn(); + +private: + int anim; + + struct Waypoints { + int x,y; + } *way; + int nextBalls[BALLSDROP]; + + int animmax; + + //used for running and animation phase + int painting; + int animstep; + int animdelaycount; + int animdelaystart; + int direction; + + + int nextBallToPlace; + int jumpingCol; + int jumpingRow; + + int focusX; + int focusY; + + int level; + + QTimer* timer; +// ShotCounter* shCounter; + BallPainter* bPainter; + bool bGameOver; + KRandomSequence rnd; + KRandomSequence rnd_saved; + KRandomSequence rnd_demo; + + QLabel *demoLabel; + bool bAllowMove; + + void paintEvent( QPaintEvent* ); + void mousePressEvent( QMouseEvent* ); + + void AnimStart(int panim); + void AnimNext(); + int AnimEnd(); + int getAnim(int x, int y ); // returns if the specifyed cell is animated.. + void AnimJump( int col, int row ); + + int erase5Balls(); + bool existPath(int ax, int ay, int bx, int by); + void placeBall(); + void placePlayerBall(int col, int row); + void moveFocus(int dx, int dy); + +public slots: + void moveLeft(); + void moveRight(); + void moveUp(); + void moveDown(); + void placePlayerBall(); + +protected slots: + void timerSlot(); + void demoClickStep(); +}; + +#endif diff --git a/klines/main.cpp b/klines/main.cpp new file mode 100644 index 00000000..66f5959c --- /dev/null +++ b/klines/main.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + /* + * Roman Razilov 2000-05-19 debug dummmy + * Roman Razilov 2000-05-21 qimgio +*/ + + +#include <kapplication.h> +#include <klocale.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> + +#include "klines.h" + +static const char description[] = I18N_NOOP("Kolor Lines - a little game about balls and how to get rid of them"); + +// A hack to circumvent tricky i18n issue, not used later on in the code. +// Both context and contents must be exactly the same as for the entry in +// kdelibs/kdeui/ui_standards.rc +static const char dummy[] = I18N_NOOP2("Menu title", "&Move"); + +int main( int argc, char **argv ) +{ + KAboutData aboutData("klines", I18N_NOOP("Kolor Lines"), LINESVERSION, + description, KAboutData::License_GPL); + aboutData.addAuthor("Roman Merzlyakov", I18N_NOOP("Original author"), "roman@sbrf.barrt.ru"); + aboutData.addAuthor("Roman Razilov", I18N_NOOP("Rewrite and Extension"), "Roman.Razilov@gmx.de"); + KCmdLineArgs::init(argc, argv, &aboutData); + + KApplication a; + KGlobal::locale()->insertCatalogue("libkdegames"); + + if (a.isRestored()) + RESTORE(KLines) + else { + KLines *w = new KLines; + a.setMainWidget(w); + w->show(); + } + return a.exec(); +} diff --git a/klines/mwidget.cpp b/klines/mwidget.cpp new file mode 100644 index 00000000..a6555835 --- /dev/null +++ b/klines/mwidget.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "mwidget.moc" + +#include <klocale.h> + +#include <qlabel.h> +#include <qlayout.h> + +#include "ballpainter.h" + +MainWidget::MainWidget( QWidget* parent, const char* name ) + : QFrame( parent, name ) +{ + QBoxLayout *grid = new QHBoxLayout( this, 5 ); //(rows,col) + bPainter = new BallPainter(); + + lsb = new LinesBoard(bPainter, this); + grid->addWidget( lsb ); + + QBoxLayout *right = new QVBoxLayout(grid, 2); + QLabel *label = new QLabel(i18n("Next balls:"), this); + lPrompt = new LinesPrompt(bPainter, this); + connect(lPrompt, SIGNAL(PromptPressed()), parent, SLOT(switchPrompt())); + + right->addWidget( label, 0, Qt::AlignBottom | Qt::AlignHCenter ); + right->addWidget( lPrompt, 0, Qt::AlignTop | Qt::AlignHCenter ); + + grid->activate(); + grid->freeze(0,0); + +// warning("width: %i height: %i", width(), height() ); + +// warning("wh: %i hh: %i", sizeHint().width(), sizeHint().height() ); + +} + +/* + Destructor: deallocates memory for contents +*/ + +MainWidget::~MainWidget() +{ +} + +LinesBoard * MainWidget::GetLsb() +{ + return lsb; +} + +LinesPrompt * MainWidget::GetPrompt() +{ + return lPrompt; +} + +void MainWidget::updatePix() +{ + bPainter->deletePix(); + bPainter->createPix(); + lPrompt->update(); + lsb->update(); +} diff --git a/klines/mwidget.h b/klines/mwidget.h new file mode 100644 index 00000000..140ccd51 --- /dev/null +++ b/klines/mwidget.h @@ -0,0 +1,45 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef MWIDGET_H +#define MWIDGET_H + +#include <qwidget.h> +#include <qpixmap.h> +#include <qtimer.h> +#include <qframe.h> +#include "linesboard.h" +#include "prompt.h" + +class BallPainter; + +class MainWidget : public QFrame +{ + Q_OBJECT + LinesBoard * lsb; + LinesPrompt * lPrompt; + BallPainter *bPainter; + +public: + MainWidget( QWidget* parent=0, const char* name=0 ); + ~MainWidget(); + LinesBoard * GetLsb(); + LinesPrompt * GetPrompt(); + void updatePix(); +}; + +#endif diff --git a/klines/povray/ball.pov b/klines/povray/ball.pov new file mode 100644 index 00000000..16d577ed --- /dev/null +++ b/klines/povray/ball.pov @@ -0,0 +1,289 @@ +/*************************************************************************** + ball.pov - script for rendering Kolor Lines graphics + ------------------- + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#version 3.0 + +// Objectname = Main View +// Objecttype = view + +// This camera is build for ratio 451:277 +#include "colors.inc" +#include "textures.inc" +#declare BallColor = Green +#include "clr.inc" + +#declare CELLSIZE = 32 +#declare PIXTIME = 10 +#declare BALLDOWN = 3 +#declare BALLSPACE = 4 + +#warning concat("XXXX clock:",str(clock,5,2),"\n") + +#switch (clock) +// --------------------burning ball------------------- + #range (0,1.001) + + #declare explosion = 1 + #declare jump = 0 + #declare n = 0 + + #declare t0 = 0 + #declare t1 = 0.2 + #declare t2 = 0.5 + #declare t3 = 0.8 + #declare t4 = 1 + #declare tt = clock + #if ( tt = t0 ) + //turbulence + #declare tur = 0 + #declare trb = 0 + #declare trf = 0 + #declare pf = 0 + #end + #if ( tt > t0 & tt <= t1 ) + #declare tl = (tt - t0)/(t1-t0) + #declare tur = 3+(0.2-3)*tl + #declare trb = 0+(0-0)*tl + #declare trf = 1+(3-1)*tl + #declare pf = 0+(0.3-0)*t1 + #end + #if ( tt > t1 & tt <= t2 ) + #declare tl = (tt - t1)/(t2-t1) + #declare tur = 0.2+(0.5-0.1)*tl + #declare trb = 0+(1-0)*tl + #declare trf = 3+(1-3)*tl + #declare pf = 0.3+(0.2-0.3)*t1 + #end + #if ( tt > t2 & tt <= t3 ) + #declare tl = (tt - t2)/(t3-t2) + #declare tur = 0.5+(2-0.5)*tl + #declare trb = 1+(1-1)*tl + #declare trf = 1+(1-1)*tl + #declare pf = 0.2-(0.0-0.2)*t1 + #end + #if ( tt > t3 ) + #declare tl = (tt - t3)/(t4-t3) + #declare tur = 2+(5-2)*tl + #declare trb = 1+(1-1)*tl + #declare trf = 1+(0-1)*tl + #declare pf = 0.0-(0.0-0.0)*t1 + #end + // ball position / size + #declare by = 0 + #declare bh = CELLSIZE-2-BALLSPACE + #declare bw = CELLSIZE-2-BALLSPACE + #break +// ----------------borning ball---------------------- + #range (5,6.001) + + #declare explosion = 0 + #declare jump = 0 + + // fire turbulence + #declare tur = 0 + // trancperancy ball + #declare trb = 0 + // trancperancy fire + #declare trf = 0 + // lambda + #declare pf = 0 + // relative clock + #declare tt = clock - 5 + // y position + #declare by = 0 + #declare r=sqrt(tt) + #declare bh = (CELLSIZE-2-BALLSPACE)*r + #declare bw = (CELLSIZE-2-BALLSPACE)*r + // normal + #declare n = (1-tt)*r*2 + + #break + + // -------------jumping ball---------------------- + #range (10,11.001) + #declare explosion = 0 + #declare jump = 1 + #declare tur = 0 + #declare trb = 0 + #declare trf = 0 + #declare pf = 0 + #declare n = 0 + #declare tt = clock - 10 + // ball free fall: y = -(g * t^2)/2 + // ball jums on X*sin( sqrt(k)*(t0 - t1 + t ) ) + // t whole motion time + // g - gravity acceleration + // A - frei movement amplitude + // BB way with deflation + #declare A = BALLDOWN + #declare B = BALLSPACE + #declare ta = PIXTIME + #declare k = (pi + 2*sqrt( B*(A+B))/A - acos( A/(A+2*B)) )/ta + #declare k = k*k + #warning concat("XXXX k:",str(k,5,2),"\n") + #declare g = k*A*A/(2*(A+B)) + #warning concat("XXXX g:",str(g,5,2),"\n") + #declare t1 = sqrt(2*B/g) + #warning concat("XXXX t1:",str(t1,5,2),"\n") + #declare X = A*(A+2*B)/(2*(A+B)) + #warning concat("XXXX X:",str(X,5,2),"\n") + + #declare tc = PIXTIME - tt*PIXTIME + + #warning concat("XXXX tc:",str(tc,5,2),"\n") + // ball position + #if (tc < t1) + #declare by = B/2 - g*tc*tc/2 + #else + #declare by = -B/2 - g/k - X*cos( sqrt(k)*(ta-tc)) + #end + #if ( by < -2 ) + #declare bh=CELLSIZE-2+2*by + #declare bw = CELLSIZE-2-BALLSPACE+(-by-2) + #else + #declare bh = CELLSIZE-2-BALLSPACE + #declare bw = CELLSIZE-2-BALLSPACE + #end + + #break + + #else + #warning " ERROR, clock out of range !!! \n" + +#end + + +#warning concat("XXXX clock:",str(clock,5,2),"\n") + +#warning concat("XXXX tt:",str(tt,5,2),"\n") + + + + + +camera +{ + orthographic + location <0,0,-100> + look_at <0,0,0> + up (CELLSIZE-2)*y + right (CELLSIZE)*x +} + +// Global settings +global_settings +{ + ambient_light rgb<0.5,0.5,0.5> +} +light_source +{ + <-400, 600, -600> + color White + cylinder + radius 200 + falloff 1000 + tightness 1 + point_at <0,0,0> +} +// Background +background +{ + color rgb<.5,.5,.5> +} + +// fire +#if (explosion = 1) +sphere { 0, 1 + pigment { color rgbt<0,0,0,1> + } + halo { + emitting + spherical_mapping + poly + max_value 40 + exponent 0.1 + linear + turbulence tur +// phase pf + lambda 2-pf + frequency 1 + octaves 6 + color_map { + [ 0 color rgbt <1, 0, 0, 1> ] + [ 0.2 color rgbt <1, 0, 0, 1-1*trf> ] + [ 0.5 color rgbt <1, 0, 0, 1-3*trf> ] + [ 0.9 color rgbt <1, 1, 0, 1-4*trf> ] + [ 1 color rgbt <1, 1, 0.5, 1-6*trf> ] + } + samples 30 + } + hollow + scale<15,15,15> + translate <-0.5,-0.5,0> + } +#end +// Ball +#if ( trb < 1 & bh > 0 ) +sphere +{ + <0,0,0>,1 + pigment { + + wood +// agate_turb 0.5 + turbulence .1 + frequency 2 +// lambda + rotate <30,10,15> + color_map { + [0.5 BallColor transmit trb] + [0.3 BallColor*0.95 transmit trb] + [0.2 BallColor*0.9 transmit trb] + } + } + no_shadow + #if ( n > 0 ) + normal + { + //wood 0.5 + //frequency 2 + //turbulence .1 + //rotate <30,10,15> + bumps n + scale 0.3 + } + #end + finish { + ambient 0.3 + diffuse 0.8 + specular 1 + roughness 0.001 + reflection .1 + phong 0.9 * ( 1-trb) + phong_size 60 + + } + #if (trb > 0) + hollow + #end + scale <bw/2,bh/2,bw/2> + translate <-0.5,by - 0.5,0> + +#warning concat("XXXX by:",str(by,5,2),"\n") +#warning concat("XXXX bh:",str(bh,5,2),"\n") +#warning concat("XXXX bw:",str(bw,5,2),"\n") +} +#end diff --git a/klines/povray/balls.sh b/klines/povray/balls.sh new file mode 100755 index 00000000..1897afaa --- /dev/null +++ b/klines/povray/balls.sh @@ -0,0 +1,13 @@ +#!/bin/sh +echo "#declare BallColor = $2" >clr.inc +#### jumping balls +povray -w30 -h30 -V1 -P +A +KI10 +KF11 +KFF10 -Iball.pov +Oa$1.tga +#### borning balls +povray -w30 -h30 -V1 -P +A +KI5 +KF6 +KFF6 +SF2 +EF5 -Iball.pov +Ob$1.tga +#### burning balls balls +povray -w30 -h30 -V1 -P +A +KI0 +KF1 +KFF11 +SF1 +EF5 -Iball.pov +Oe$1.tga + +montage -geometry 30x30 -tile 100x1 -page 570x30 a$1??.tga b$1?.tga e$1??.tga bl_$1.tga +mogrify -crop 570x30+0+0 bl_$1.tga + + diff --git a/klines/povray/clean.sh b/klines/povray/clean.sh new file mode 100755 index 00000000..df78c905 --- /dev/null +++ b/klines/povray/clean.sh @@ -0,0 +1,2 @@ +#!/bin/sh +rm *.tga *.jpg
\ No newline at end of file diff --git a/klines/povray/field.pov b/klines/povray/field.pov new file mode 100644 index 00000000..1256c733 --- /dev/null +++ b/klines/povray/field.pov @@ -0,0 +1,31 @@ +#declare CELLSIZE = 32 +#include "colors.inc" + +camera +{ + orthographic + location <0,0,-100> + look_at <0,0,0> + up (CELLSIZE-2)*y + right (CELLSIZE)*x +} +// Global settings +global_settings +{ + ambient_light rgb<0.5,0.5,0.5> +} +light_source +{ + <-400, 600, -600> + color White + cylinder + radius 100 + falloff 1000 + tightness 1 + point_at <0,0,0> +} +background +{ + color rgb<.5,.5,.5> +} + diff --git a/klines/povray/field.sh b/klines/povray/field.sh new file mode 100755 index 00000000..f4a784d2 --- /dev/null +++ b/klines/povray/field.sh @@ -0,0 +1,5 @@ +#!/bin/sh +if (povray -w32 -h32 -V1 -P +A +K10 -Ifield.pov +Ofield.tga) +then + mogrify -raise 1x1 field.tga +fi diff --git a/klines/povray/fire.sh b/klines/povray/fire.sh new file mode 100755 index 00000000..2b6b5f9a --- /dev/null +++ b/klines/povray/fire.sh @@ -0,0 +1,9 @@ +#! /bin/sh +echo "#declare BallColor = White" >clr.inc +if (povray -w30 -h30 -V1 -P +A +KI0 +KF1 +KFF11 +SF6 +EF10 -Iball.pov \ ++Ofire.tga) +then # mogrify -raise 1x1 e$1??.tga + montage -geometry 30x30 -tile 100x1 -page 150x30 fire*.tga fire.tga + mogrify -crop 150x30+0+0 fire.tga +# animate -delay 7 $1??.tga +fi diff --git a/klines/povray/makeballs.sh b/klines/povray/makeballs.sh new file mode 100755 index 00000000..62769605 --- /dev/null +++ b/klines/povray/makeballs.sh @@ -0,0 +1,36 @@ +#! /bin/sh +#### clean + +clean.sh + +#### render + +field.sh +fire.sh +balls.sh Red "rgb<1,0,0>" +balls.sh Green "rgb<0,1,0>" +balls.sh Blue "rgb<0,0,1>" +balls.sh Yellow "rgb<1,1,0>" +balls.sh Violet "rgb<1,0,1>" +balls.sh Cyan "rgb<0,1,1>" +balls.sh Brown "rgb<1/2,1/3,0>" + +#### montage balls ( 20x7 cells each 30x30) + +montage -geometry 570x30 -tile 1x10 bl_*.tga balls.tga +mogrify -crop 570x210+0+0 balls.tga + +#### convert to jpeg + +convert -quality 95 balls.tga balls.jpg +convert -quality 95 fire.tga fire.jpg +convert -quality 95 field.tga field.jpg + + +#### copy to data + +cp *jpg ../ + +#### clean + +#clean.sh
\ No newline at end of file diff --git a/klines/povray/povray.ini b/klines/povray/povray.ini new file mode 100644 index 00000000..22ddf8ec --- /dev/null +++ b/klines/povray/povray.ini @@ -0,0 +1,59 @@ +; PERSISTENCE OF VISION RAY TRACER +; +; POV-Ray VERSION 3.0 +; +; SAMPLE POVRAY.INI FILE +; +; This file contains options which control how POV-Ray does its job. +; The file should be placed in the same directory as POVRAY.EXE and +; it will automaticaly read when POVRAY is run. +; +; The general form of the options is "Variable=value". Everything +; between the equals sign and the end of the line is considered part +; of the value. The spacing and layout is free-form but only one option +; per line is allowed. Variables and values are not case-sensitive. +; +; Note: characters after a semi-colon are treated as a comment +; +; Traditional POV-Ray switches beginning with + or - are also allowed +; and they may be given with more than one switch per line. +; +; These options have been put in this file because they will help +; you get up and running quickly. This file assumes you have installed +; the program in the /usr/local/lib directory. If you have installed +; the program on a directory you must edit the Library_Path lines below. +; See the general and Linux specific documentation for full instructions +; on how to use INI options. +; +; Add your own options at the bottom and/or edit these to suit. +; +; +; Width of image in pixels. Accepts integer values. +; +Width = 320 +; +; +; Height of image in pixels. Accepts integer values. +; +Height = 240 +; +; +; Turns pause when done feature off/on. Accepts boolean values. +; +Pause_when_Done = on +; +; +; Sets minimum number of objects before auto bounding kicks in. +; +Bounding_Threshold = 3 +; +; +; Test for user abort with any keypress every 100 pixels. +; +Test_Abort=On +Test_Abort_Count=100 +; +; Specify path to search for any files not found in current +; directory. Up to 25 such paths may be specified. +Library_Path=/usr/lib/povray3 +Library_Path=/usr/lib/povray3/include diff --git a/klines/prefs.kcfgc b/klines/prefs.kcfgc new file mode 100644 index 00000000..6ed42a2f --- /dev/null +++ b/klines/prefs.kcfgc @@ -0,0 +1,7 @@ +# Code generation options for kconfig_compiler +File=klines.kcfg +#IncludeFiles=defines.h +ClassName=Prefs +Singleton=true +#CustomAdditions=true +Mutators=true diff --git a/klines/prompt.cpp b/klines/prompt.cpp new file mode 100644 index 00000000..09c17e2a --- /dev/null +++ b/klines/prompt.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <qpainter.h> +#include "prompt.h" +#include "prompt.moc" + +LinesPrompt::LinesPrompt( BallPainter * abPainter, QWidget* parent, const char* name ) + : QWidget( parent, name ) +{ + + bPainter = abPainter; + + setFocusPolicy( NoFocus ); + setBackgroundColor( gray ); + + setMouseTracking( FALSE ); + setFixedSize(wPrompt(), hPrompt()); + + PromptEnabled = true; + cb[0]=NOBALL; + cb[1]=NOBALL; + cb[2]=NOBALL; +} + +LinesPrompt::~LinesPrompt() +{ +} + +int LinesPrompt::width() { return CELLSIZE * 3 ; } +int LinesPrompt::height() { return CELLSIZE ; } + +int LinesPrompt::wPrompt() { return CELLSIZE * 3 ; } +int LinesPrompt::hPrompt() { return CELLSIZE ; } + +void LinesPrompt::paintEvent( QPaintEvent* ) +{ + QPainter paint( this ); + if(PromptEnabled){ + paint.drawPixmap(0, 0, bPainter->GetNormalBall(cb[0]) ); + paint.drawPixmap(CELLSIZE, 0, bPainter->GetNormalBall(cb[1]) ); + paint.drawPixmap(2*CELLSIZE, 0, bPainter->GetNormalBall(cb[2]) ); + } + else{ + paint.drawPixmap(0, 0, bPainter->GetBackgroundPix() ); + paint.drawPixmap(CELLSIZE, 0, bPainter->GetBackgroundPix() ); + paint.drawPixmap(2*CELLSIZE, 0, bPainter->GetBackgroundPix() ); + } +} + +/* + Handles mouse press events for the LinesPrompt widget. +*/ +void LinesPrompt::mousePressEvent( QMouseEvent* ) +{ + emit PromptPressed(); +} + +void LinesPrompt::SetBalls( int *pcb ) +{ + for (int i = 0; i<BALLSDROP; i++) + cb[i] = pcb[i]; + + update(); +} + +bool LinesPrompt::getState() +{ + return PromptEnabled; +} +void LinesPrompt::setPrompt(bool enabled) +{ + PromptEnabled = enabled; + update(); +} diff --git a/klines/prompt.h b/klines/prompt.h new file mode 100644 index 00000000..f1e0b026 --- /dev/null +++ b/klines/prompt.h @@ -0,0 +1,53 @@ +/*************************************************************************** + begin : Fri May 19 2000 + copyright : (C) 2000 by Roman Merzlyakov + email : roman@sbrf.barrt.ru + copyright : (C) 2000 by Roman Razilov + email : Roman.Razilov@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef PROMPT_H +#define PROMPT_H + +#include <qwidget.h> +#include "ballpainter.h" + +class LinesPrompt : public QWidget +{ + Q_OBJECT + + BallPainter* bPainter; + bool PromptEnabled; + int cb[BALLSDROP]; + + void paintEvent( QPaintEvent* ); + void mousePressEvent( QMouseEvent* ); + +public: + LinesPrompt( BallPainter * abPainter, QWidget * parent=0, const char * name=0 ); + ~LinesPrompt(); + + void setPrompt(bool enabled); + bool getState(); // enabled = true + void SetBalls( int *pcb ); + + int width(); + int height(); + int wPrompt(); + int hPrompt(); + +signals: + void PromptPressed(); + +}; + +#endif diff --git a/klines/templates/cpp_template b/klines/templates/cpp_template new file mode 100644 index 00000000..6afef5d4 --- /dev/null +++ b/klines/templates/cpp_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ diff --git a/klines/templates/header_template b/klines/templates/header_template new file mode 100644 index 00000000..6afef5d4 --- /dev/null +++ b/klines/templates/header_template @@ -0,0 +1,16 @@ +/*************************************************************************** + |FILENAME| - description + ------------------- + begin : |DATE| + copyright : (C) |YEAR| by |AUTHOR| + email : |EMAIL| + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ |