Commit 4701811a authored by Stas Verberkt's avatar Stas Verberkt
Browse files

New renderer class to render svg theme, rebuild parts of tron code to support it.

svn path=/trunk/playground/games/ktron/; revision=822565
parent cd5bb3dd
project(ktron)
find_package(KDE4 REQUIRED)
......@@ -9,7 +8,7 @@ include(KDE4Defaults)
include(MacroLibrary)
include_directories(${CMAKE_SOURCE_DIR}/libkdegames ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
include_directories(${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${KDEGAMES_INCLUDE_DIR})
add_subdirectory(pics)
add_subdirectory(themes)
......@@ -18,6 +17,7 @@ add_subdirectory(themes)
########### next target ###############
set(ktron_SRCS
renderer.cpp
tron.cpp
player.cpp
ktron.cpp
......@@ -29,7 +29,7 @@ kde4_add_kcfg_files(ktron_SRCS settings.kcfgc)
kde4_add_executable(ktron ${ktron_SRCS})
target_link_libraries(ktron kdegames ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS})
target_link_libraries(ktron ${KDE4_KDEUI_LIBS} kdegames ${KDE4_KNOTIFYCONFIG_LIBS} ${KDE4_KNEWSTUFF2_LIBS})
install(TARGETS ktron ${INSTALL_TARGETS_DEFAULT_ARGS})
......
......@@ -81,7 +81,7 @@ KTron::KTron(QWidget *parent) : KXmlGuiWindow(parent, KDE_DEFAULT_WINDOWFLAGS) {
playerPoints[0]=playerPoints[1]=0;
tron=new Tron(this);
connect(tron,SIGNAL(gameEnds(Player)),SLOT(changeStatus(Player)));
connect(tron,SIGNAL(gameEnds(KTronEnum::Player)),SLOT(changeStatus(KTronEnum::Player)));
setCentralWidget(tron);
tron->setMinimumSize(200,180);
......@@ -188,11 +188,11 @@ void KTron::loadSettings() {
void KTron::updateStatusbar(){
for(int i=0;i<2;i++){
Player player;
player=(i==0?One:Two);
KTronEnum::Player player;
player=(i==0 ? KTronEnum::One : KTronEnum::Two);
QString name;
if(tron->isComputer(Both))
if(tron->isComputer(KTronEnum::Both))
name=i18n("Computer(%1)", (i+1));
else if(tron->isComputer(player))
name=i18n("Computer");
......@@ -203,19 +203,19 @@ void KTron::updateStatusbar(){
}
}
void KTron::changeStatus(Player player) {
void KTron::changeStatus(KTronEnum::Player player) {
// if player=Nobody, then new game
if(player==Nobody){
if(player==KTronEnum::Nobody){
playerPoints[0]=playerPoints[1]=0;
updateStatusbar();
return;
}
if(player==One)
if(player==KTronEnum::One)
playerPoints[0]++;
else if(player==Two)
else if(player==KTronEnum::Two)
playerPoints[1]++;
else if(player==Both){
else if(player==KTronEnum::Both){
playerPoints[0]++;
playerPoints[1]++;
}
......@@ -223,20 +223,20 @@ void KTron::changeStatus(Player player) {
updateStatusbar();
if(playerPoints[0]>=WINNING_DIFF && playerPoints[1] < playerPoints[0]-1)
showWinner(One);
showWinner(KTronEnum::One);
else if(playerPoints[1]>=WINNING_DIFF && playerPoints[0] < playerPoints[1]-1)
showWinner(Two);
showWinner(KTronEnum::Two);
}
void KTron::showWinner(Player winner){
if(tron->isComputer(Both) || (winner != One && winner != Two))
void KTron::showWinner(KTronEnum::Player winner){
if(tron->isComputer(KTronEnum::Both) || (winner != KTronEnum::One && winner != KTronEnum::Two))
return;
QString loserName = i18n("KTron");
int loser = Two;
if(winner == Two)
loser = One;
if(!tron->isComputer(((Player)loser)))
KTronEnum::Player loser = KTronEnum::Two;
if(winner == KTronEnum::Two)
loser = KTronEnum::One;
if(!tron->isComputer(loser))
loserName = playerName[loser];
QString winnerName = i18n("KTron");
......
......@@ -60,9 +60,9 @@ public slots:
private slots:
void loadSettings();
/** updates players points in statusbar and checks if someone has won */
void changeStatus(Player);
void changeStatus(KTronEnum::Player);
void showWinner(Player winner);
void showWinner(KTronEnum::Player winner);
void showSettings();
};
......
/* ****************************************************************************
This file is part of the game 'KTron'
Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
Copyright (C) 2005 Benjamin C. Meyer <ben at meyerhome dot net>
Copyright (C) 2008 Stas Verberkt <legolas at legolasweb dot nl>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*****************************************************************************/
#include "renderer.h"
#include "settings.h"
#include "tron.h"
#include <QPainter>
#include <QPixmap>
#include <KGameTheme>
#include <KPixmapCache>
#include <KSvgRenderer>
class RendererPrivate
{
public:
RendererPrivate();
~RendererPrivate();
QSize m_sceneSize;
QSize m_partSize;
KSvgRenderer m_renderer;
KPixmapCache m_cache;
QString m_currentTheme;
};
const QString sizeSuffix("_%1-%2");
const QString frameSuffix("-%1");
RendererPrivate::RendererPrivate()
: m_renderer()
, m_cache("ktron-cache")
{
m_cache.setCacheLimit(3 * 1024);
m_cache.discard();
}
Renderer::Renderer()
: p(new RendererPrivate)
{
loadTheme(Settings::theme());
}
Renderer::Renderer(const Renderer &)
{
}
Renderer::~Renderer()
{
}
Renderer *Renderer::self()
{
static Renderer r;
return &r;
}
bool Renderer::loadTheme(const QString &name)
{
bool discardCache = !p->m_currentTheme.isEmpty();
if (!p->m_currentTheme.isEmpty() && p->m_currentTheme == name)
return true; //requested to load the theme that is already loaded
KGameTheme theme;
//try to load theme
if (!theme.load(name))
{
if (!theme.loadDefault())
return false;
}
p->m_currentTheme = name;
//load graphics
if (!p->m_renderer.load(theme.graphics()))
return false;
//flush cache
if (discardCache)
p->m_cache.discard();
return true;
}
QString Renderer::decodePart(int type)
{
QString name;
// Player
if (type & KTronEnum::PLAYER1)
{
name = "tron1-";
}
else if (type & KTronEnum::PLAYER2)
{
name = "tron2-";
}
// Heads (or tails)
if (type & KTronEnum::HEAD)
{
if (type & (KTronEnum::TOP | KTronEnum::LEFT | KTronEnum::RIGHT))
{
name += "head-north";
}
else if (type & (KTronEnum::BOTTOM | KTronEnum::LEFT | KTronEnum::RIGHT))
{
name += "head-south";
}
else if (type & (KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::LEFT))
{
name += "head-west";
}
else if (type & (KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::RIGHT))
{
name += "head-east";
}
}
else
{
if (type & (KTronEnum::TOP | KTronEnum::LEFT | KTronEnum::RIGHT))
{
name += "tail-south";
}
else if (type & (KTronEnum::BOTTOM | KTronEnum::LEFT | KTronEnum::RIGHT))
{
name += "tail-north";
}
else if (type & (KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::LEFT))
{
name += "tail-east";
}
else if (type & (KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::RIGHT))
{
name += "tail-west";
}
}
}
QPixmap Renderer::snakePart(int part)
{
QString frameSvgName = decodePart(part);
QString framePixName = frameSvgName + sizeSuffix.arg(p->m_partSize.width()).arg(p->m_partSize.height());
QPixmap pix;
if (!p->m_cache.find(framePixName, pix))
{
pix = QPixmap(p->m_partSize);
pix.fill(Qt::transparent);
QPainter painter(&pix);
p->m_renderer.render(&painter, frameSvgName);
painter.end();
p->m_cache.insert(framePixName, pix);
}
//return the static pixmap
return pixmapFromCache(p, frameSvgName, p->m_partSize);
}
QPixmap Renderer::pixmapFromCache(RendererPrivate *p, const QString &svgName, const QSize &size)
{
if (size.isEmpty())
return QPixmap();
QPixmap pix;
QString pixName = svgName + sizeSuffix.arg(size.width()).arg(size.height());
if (!p->m_cache.find(pixName, pix))
{
pix = QPixmap(size);
pix.fill(Qt::transparent);
QPainter painter(&pix);
p->m_renderer.render(&painter, svgName);
painter.end();
p->m_cache.insert(pixName, pix);
}
return pix;
}
QPixmap Renderer::background()
{
return pixmapFromCache(p, "ktron-background", p->m_sceneSize);
}
/* ****************************************************************************
This file is part of the game 'KTron'
Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
Copyright (C) 2005 Benjamin C. Meyer <ben at meyerhome dot net>
Copyright (C) 2008 Stas Verberkt <legolas at legolasweb dot nl>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*****************************************************************************/
#ifndef KTRON_RENDERER_H
#define KTRON_RENDERER_H
#include <QString>
#include <QSize>
class QPixmap;
class RendererPrivate;
class Renderer {
private:
Renderer();
Renderer(const Renderer &);
~Renderer();
public:
static Renderer *self();
bool loadTheme(const QString &);
QPixmap snakePart(int);
QString decodePart(int);
QPixmap background();
QPixmap pixmapFromCache(RendererPrivate *p, const QString &svgName, const QSize &size);
private:
RendererPrivate *p;
};
#endif // KTRON_RENDERER_H
......@@ -38,6 +38,6 @@ Description[x-test]=xxDefault theme for KTron.xx
Description[zh_CN]=为 KTron 设计的默认主题。
Description[zh_TW]=KTron 預設主題。
FileName=default.svgz
Author=Stas Verberkt
AuthorEmail=legolas@legolasweb.nl
Author=Eugene Trounev
AuthorEmail=eugene.trounev@gmail.com
Preview=default.png
No preview for this file type
......@@ -114,8 +114,8 @@ void Tron::loadSettings(){
}
else setBackgroundPix(QPixmap());
}
setComputerplayer(One, Settings::computerplayer1());
setComputerplayer(Two, Settings::computerplayer2());
setComputerplayer(KTronEnum::One, Settings::computerplayer1());
setComputerplayer(KTronEnum::Two, Settings::computerplayer2());
}
Tron::~Tron()
......@@ -155,7 +155,7 @@ void Tron::newGame()
{
players[0].score=0;
players[1].score=0;
emit gameEnds(Nobody);
emit gameEnds(KTronEnum::Nobody);
reset();
QTimer::singleShot(15000,this,SLOT(showBeginHint()));
......@@ -175,7 +175,7 @@ void Tron::reset()
{
int i;
for(i=0;i<fieldWidth;i++)
playfield[i].fill(BACKGROUND);
playfield[i].fill(KTronEnum::BACKGROUND);
// set start coordinates
......@@ -183,9 +183,9 @@ void Tron::reset()
players[1].setCoordinates(2*fieldWidth/3, fieldHeight/2);
playfield[players[0].xCoordinate][players[0].yCoordinate]=
PLAYER1 | TOP | BOTTOM | LEFT | RIGHT;
KTronEnum::PLAYER1 | KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::LEFT | KTronEnum::RIGHT | KTronEnum::HEAD;
playfield[players[1].xCoordinate][players[1].yCoordinate]=
PLAYER2 | TOP | BOTTOM | LEFT | RIGHT;
KTronEnum::PLAYER2 | KTronEnum::TOP | KTronEnum::BOTTOM | KTronEnum::LEFT | KTronEnum::RIGHT | KTronEnum::HEAD;
updatePixmap();
update();
......@@ -198,7 +198,7 @@ void Tron::reset()
void Tron::computerStart()
{
if(isComputer(Both))
if(isComputer(KTronEnum::Both))
{
reset();
startGame();
......@@ -243,29 +243,29 @@ void Tron::togglePause() // pause or continue game
}
}
void Tron::showWinner(Player player)
void Tron::showWinner(KTronEnum::Player player)
{
int i,j;
if(player != Both && Settings::changeWinnerColor())
if(player != KTronEnum::Both && Settings::changeWinnerColor())
{
int winner;
int loser;
if(player==One)
if(player==KTronEnum::One)
{
winner=PLAYER1;
loser=PLAYER2;
winner=KTronEnum::PLAYER1;
loser=KTronEnum::PLAYER2;
}
else
{
winner=PLAYER2;
loser=PLAYER1;
winner=KTronEnum::PLAYER2;
loser=KTronEnum::PLAYER1;
}
for(i=0;i<fieldWidth;i++)
for(j=0;j<fieldHeight;j++)
{
if(playfield[i][j]!=BACKGROUND)
if(playfield[i][j]!=KTronEnum::BACKGROUND)
{
// change player
playfield[i][j] |= winner;
......@@ -280,7 +280,7 @@ void Tron::showWinner(Player player)
emit gameEnds(player);
if(isComputer(Both))
if(isComputer(KTronEnum::Both))
{
QTimer::singleShot(1000,this,SLOT(computerStart()));
}
......@@ -315,7 +315,7 @@ void Tron::updatePixmap()
{
for(j=0;j<fieldHeight;j++)
{
if(playfield[i][j]!=BACKGROUND)
if(playfield[i][j]!=KTronEnum::BACKGROUND)
{
drawRect(p,i,j);
}
......@@ -335,12 +335,12 @@ void Tron::drawRect(QPainter & p, int x, int y)
// find out which color to draw
QColor toDraw;
int player;
if(type & PLAYER1) // check player bit
if(type & KTronEnum::PLAYER1) // check player bit
{
toDraw=Settings::color_Player1();
player=0;
}
else if(type & PLAYER2)
else if(type & KTronEnum::PLAYER2)
{
toDraw=Settings::color_Player2();
player=1;
......@@ -364,20 +364,20 @@ void Tron::drawRect(QPainter & p, int x, int y)
p.setPen(toDraw);
p.drawRect(xOffset,yOffset,blockWidth,blockHeight);
p.setPen(toDraw.light());
if(type&TOP)
if(type&KTronEnum::TOP)
{
p.drawLine(xOffset,yOffset,xOffset+blockWidth-1,yOffset);
}
if(type&LEFT)
if(type&KTronEnum::LEFT)
{
p.drawLine(xOffset,yOffset,xOffset,yOffset+blockHeight-1);
}
p.setPen(toDraw.dark());
if(type&RIGHT)
if(type&KTronEnum::RIGHT)
{
p.drawLine(xOffset+blockWidth-1,yOffset,xOffset+blockWidth-1,yOffset+blockHeight-1);
}
if(type&BOTTOM)
if(type&KTronEnum::BOTTOM)
{
p.drawLine(xOffset,yOffset+blockHeight-1,xOffset+blockWidth-1,yOffset+blockHeight-1);
}
......@@ -429,23 +429,23 @@ void Tron::setVelocity(int newVel) // set new velocity
timer->start(velocity);
}
void Tron::setComputerplayer(Player player, bool flag) {
if(player==One)
void Tron::setComputerplayer(KTronEnum::Player player, bool flag) {
if(player==KTronEnum::One)
players[0].setComputer(flag);
else if(player==Two)
else if(player==KTronEnum::Two)
players[1].setComputer(flag);
if(isComputer(Both))
if(isComputer(KTronEnum::Both))
QTimer::singleShot(1000,this,SLOT(computerStart()));
}
bool Tron::isComputer(Player player)
bool Tron::isComputer(KTronEnum::Player player)
{
if(player==One)
if(player==KTronEnum::One)
return players[0].computer;
else if(player==Two)
else if(player==KTronEnum::Two)
return players[1].computer;
else if(player==Both)
else if(player==KTronEnum::Both)
{
if(players[0].computer && players[1].computer)
return true;
......@@ -466,7 +466,7 @@ bool Tron::crashed(int playerNr,int xInc, int yInc) const
if(newX<0 || newY <0 || newX>=fieldWidth || newY>=fieldHeight)
flag=true;
else if(playfield[newX][newY] != BACKGROUND)
else if(playfield[newX][newY] != KTronEnum::BACKGROUND)
flag=true;
else flag=false;
......@@ -509,21 +509,23 @@ void Tron::updateDirections(int playerNr)
// unset drawing flags in the moving direction
case Directions::Up:
{
playfield[x][y] &= (~TOP);
playfield[x][y] &= (~KTronEnum::TOP);
break;
}
case Directions::Down:
playfield[x][y] &= (~BOTTOM);
playfield[x][y] &= (~KTronEnum::BOTTOM);
break;
case Directions::Right:
playfield[x][y] &= (~RIGHT);
playfield[x][y] &= (~KTronEnum::RIGHT);
break;
case Directions::Left:
playfield[x][y] &= (~LEFT);
playfield[x][y] &= (~KTronEnum::LEFT);
break;
default:
break;
}
playfield[x][y] &= (~KTronEnum::HEAD);
players[0].last_dir = players[0].dir;
}
......@@ -538,21 +540,23 @@ void Tron::updateDirections(int playerNr)
// unset drawing flags in the moving direction
case Directions::Up:
{
playfield[x][y] &= (~TOP);
playfield[x][y] &= (~KTronEnum::TOP);
break;
}
case Directions::Down:
playfield[x][y] &= (~BOTTOM);
playfield[x][y] &= (~KTronEnum::BOTTOM);
break;
case Directions::Right:
playfield[x][y] &= (~RIGHT);
playfield[x][y] &= (~KTronEnum::RIGHT);
break;
case Directions::Left:
playfield[x][y] &= (~LEFT);
playfield[x][y] &= (~KTronEnum::LEFT);
break;
default:
break;
}
playfield[x][y] &= (~KTronEnum::HEAD);
players[1].last_dir = players[1].dir;
}
......@@ -807,11 +811,11 @@ void Tron::doMove()
int newType; // determine type of rect to set
if(i==0)
{
newType=PLAYER1;
newType=KTronEnum::PLAYER1 | KTronEnum::HEAD;