Commit 298954ba authored by Branan Purvine-Riley's avatar Branan Purvine-Riley
Browse files

Ported KSpaceDuel to SVG graphics. The default_theme.svgz file is usable, but...

Ported KSpaceDuel to SVG graphics. The default_theme.svgz file is usable, but not pretty. It doesn't have very many explosion frames, so there are just little blips when something blows up.

I changed the version number to 2.0 because this is such a significant change.

The sprites aren't installed with everything else, but I left them in SVN so that artists can use them as a reference. 

There were a couple of minor tweaks to the code, as well.

svn path=/trunk/KDE/kdegames/kspaceduel/; revision=634023
parent de13769f
Author of KSpaceduel:
Andreas Zehender <az@azweb.de>
Port to SVG:
Branan Riley <branan@gmail.com>
......@@ -29,6 +29,7 @@ kde4_add_executable(kspaceduel ${kspaceduel_SRCS})
target_link_libraries(kspaceduel ${KDE4_KDEUI_LIBS} kdegames)
install(TARGETS kspaceduel DESTINATION ${BIN_INSTALL_DIR} )
install(FILES default_theme.svgz DESTINATION ${DATA_INSTALL_DIR}/kspaceduel/sprites )
########### install files ###############
......
version 2.0
* [Branan Riley] Ported Renderer to SVG
version 1.0
* [Andreas Zehender] Portet to Qt-2.0
* [Andreas Zehender] Changed option dialogs
......
......@@ -2,7 +2,9 @@ todo:
-----
sounds (using Phonon)
maybe port to SVG (partially?)
[DONE]maybe port to SVG (partially?)
-- Artwork still needs work
-- Background is still a PNG
[DONE]refactoring (split up sprites.h/cpp?)
clean up
[HACK (see MyMainView::focusOutEvent)]fix bug: clicking on playfield
......
......@@ -32,21 +32,23 @@ This program is free software; you can redistribute it and/or modify
#define MV_BACKGROUND "sprites/backgr.png"
#define MV_SHIP1_PNG "sprites/ship1/ship.png"
#define MV_SHIP2_PNG "sprites/ship2/ship.png"
#define MV_SVG_FILE "sprites/default_theme.svgz"
#define MV_BULLET1_PNG "sprites/ship1/bullet.png"
#define MV_BULLET2_PNG "sprites/ship2/bullet.png"
#define MV_SHIP1 "ship_red"
#define MV_SHIP2 "ship_blue"
#define MV_MINE1_PNG "sprites/ship1/mine1.png"
#define MV_MINE2_PNG "sprites/ship2/mine1.png"
#define MV_BULLET1 "bullet_red"
#define MV_BULLET2 "bullet_blue"
#define MV_SUN_PNG "sprites/sun/sun.png"
#define MV_MINE1 "mine_red00"
#define MV_MINE2 "mine_blue00"
#define MV_POWERBULLET_PNG "sprites/powerups/pbullet.png"
#define MV_POWERMINE_PNG "sprites/powerups/pmine.png"
#define MV_POWERSHIELD_PNG "sprites/powerups/pshield.png"
#define MV_POWERENERGY_PNG "sprites/powerups/penergy.png"
#define MV_SUN "sun"
#define MV_POWERBULLET "pbullet"
#define MV_POWERMINE "pmine"
#define MV_POWERSHIELD "pshield"
#define MV_POWERENERGY "penergy"
#define DEF_WIDTH 640
#define DEF_HEIGHT 480
......
......@@ -30,7 +30,8 @@ int main(int argc,char **argv)
KAboutData aboutData( "kspaceduel", I18N_NOOP("KSpaceDuel"),
KSPACEDUEL_VERSION, description, KAboutData::License_GPL,
"(c) 1998-2001, Andreas Zehender");
aboutData.addAuthor("Andreas Zehender",0, "az@azweb.de");
aboutData.addAuthor("Andreas Zehender",I18N_NOOP("Original Program"), "az@azweb.de");
aboutData.addAuthor("Branan Riley",I18N_NOOP("SVG Renderer"), "branan@gmail.com");
KCmdLineArgs::init( argc, argv, &aboutData );
KApplication myapplication;
......
......@@ -35,6 +35,8 @@ This program is free software; you can redistribute it and/or modify
#include <ktoggleaction.h>
#include <kconfiggroup.h>
#include <KSvgRenderer>
#include "ai.h"
#include "mainview.h"
#include "options.h"
......@@ -48,10 +50,10 @@ static struct
}
kspd_animations [] =
{
{ ID_EXPLOSION, "explosion/explos%1.png"},
{ ID_MINE1, "ship1/mine%1.png"},
{ ID_MINE2, "ship2/mine%1.png"},
{ ID_MINEEXPLO, "explosion/mineex%1.png"},
{ ID_EXPLOSION, "explos%1"},
{ ID_MINE1, "mine_red%1"},
{ ID_MINE2, "mine_blue%1"},
{ ID_MINEEXPLO, "mineex%1"},
{ 0, 0}
};
......@@ -82,25 +84,22 @@ MyMainView::MyMainView(QWidget *parent)
minePut[p]=false;
}
QString tmp = KGlobal::dirs()->findResourceDir("appdata", (QString)MV_BACKGROUND);
svgrender = new KSvgRenderer(KStandardDirs::locate("appdata", MV_SVG_FILE));
sunpixmap = new QPixmap(tmp + MV_SUN_PNG);
sun=new SunSprite(sunpixmap, &field);
sun=new SunSprite(svgrender, MV_SUN);
field.addItem(sun);
sun->setPos(QPointF(width()/2-1-(sun->width()/2),
height()/2-1-(sun->height()/2)));
shippixmap[0] = new QPixmap(tmp + MV_SHIP1_PNG);
shippixmap[1] = new QPixmap(tmp + MV_SHIP2_PNG);
ship[0]=new ShipSprite(shippixmap[0],&field,0);
ship[1]=new ShipSprite(shippixmap[1],&field,1);
bulletpixmap[0] = new QPixmap(tmp + MV_BULLET1_PNG);
bulletpixmap[1] = new QPixmap(tmp + MV_BULLET2_PNG);
powerupelements[0] = MV_POWERMINE;
powerupelements[1] = MV_POWERBULLET;
powerupelements[2] = MV_POWERSHIELD;
powerupelements[3] = MV_POWERENERGY;
poweruppixmap[0] = new QPixmap( tmp + MV_POWERMINE_PNG);
poweruppixmap[1] = new QPixmap( tmp + MV_POWERBULLET_PNG);
poweruppixmap[2] = new QPixmap( tmp + MV_POWERSHIELD_PNG);
poweruppixmap[3] = new QPixmap( tmp + MV_POWERENERGY_PNG);
ship[0]=new ShipSprite(svgrender, MV_SHIP1, 0);
ship[1]=new ShipSprite(svgrender, MV_SHIP2, 1);
field.addItem(ship[0]);
field.addItem(ship[1]);
readSprites();
......@@ -123,19 +122,14 @@ MyMainView::~MyMainView()
int i;
QAbstractEventDispatcher::instance()->unregisterTimers(this);
delete sunpixmap;
for(i=0;i<2;i++)
{
delete shippixmap[i];
delete bulletpixmap[i];
delete ai[i];
qDeleteAll(*mines[i]);
delete mines[i];
qDeleteAll(*bullets[i]);
delete bullets[i];
}
for(i=0;i<4;i++)
delete poweruppixmap[i];
qDeleteAll(powerups);
powerups.clear();
......@@ -151,25 +145,30 @@ void MyMainView::setActionCollection(KActionCollection *a)
actionCollection = a;
}
/* taken from kasteroids (as the whole animation system). Thank you! */
/* Assumes that there are no gaps between animation frames. ie 1,2,3 will only have frames 1&2
recognized. It also assumes that there is at least one frame. */
// FIXME: Add Check for existence of first frame
// TODO: Add support for missing frames (ie 1,2,5)
bool MyMainView::readSprites()
{
QString sprites_prefix = KGlobal::dirs()->findResourceDir("appdata", (QString)MV_BACKGROUND) + "sprites/";
int i = 0;
while ( kspd_animations[i].id )
{
QList<QPixmap> anim;
QString wildcard = sprites_prefix + kspd_animations[i].path;
wildcard.replace("%1", "*");
QFileInfo fi(wildcard);
foreach (const QString &entry, QDir(fi.path(), fi.fileName()).entryList())
anim << QPixmap(fi.path() + '/' + entry);
QList<QString> anim;
short frame = 0;
QString element = kspd_animations[i].path;
QString elem = element.arg(frame, 2, 10, QLatin1Char('0'));
do
{
anim.append(elem);
frame++;
elem = element.arg(frame, 2, 10, QLatin1Char('0'));
} while ( svgrender->elementExists(elem) );
animation.insert( kspd_animations[i].id, anim );
i++;
}
// FixMe: perform test!
// FIXME: Perform test!
return true;
}
......@@ -476,8 +475,8 @@ void MyMainView::newRound()
my+config.startPosY-(ship[0]->height()/2)));
ship[0]->setRotation(0.0);
ship[1]->setPos(QPointF(mx-config.startPosX-(ship[1]->width()/2),
my-config.startPosY-(ship[1]->height()/2)));
ship[1]->setPos(QPointF(mx-config.startPosX+(ship[1]->width()/2),
my-config.startPosY+(ship[1]->height()/2)));
ship[1]->setRotation(M_PI);
ship[0]->setVelocity(config.startVelX,config.startVelY);
......@@ -688,8 +687,13 @@ void MyMainView::moveShips()
{
ship[i]->bullet(config.bulletReloadTime);
en-=config.shotEnergyNeed;
bullet=new BulletSprite(bulletpixmap[i],&field,i,
if(i)
bullet=new BulletSprite(svgrender, MV_BULLET2, i,
config.bulletLifeTime);
else
bullet=new BulletSprite(svgrender, MV_BULLET1, i,
config.bulletLifeTime);
field.addItem(bullet);
QPointF p;
p = ship[i]->mapToScene(ship[i]->center());
bullet->setPos(QPointF(p.x()+nx*SHOTDIST,p.y()-ny*SHOTDIST));
......@@ -712,11 +716,12 @@ void MyMainView::moveShips()
ship[i]->mine(config.mineReloadTime);
en-=config.mineEnergyNeed;
if (i==0)
mine=new MineSprite(animation[ID_MINE1],animation[ID_MINEEXPLO],&field,i,
mine=new MineSprite(svgrender,animation[ID_MINE1],animation[ID_MINEEXPLO],i,
config.mineActivateTime,config.mineFuel);
else
mine=new MineSprite(animation[ID_MINE2],animation[ID_MINEEXPLO],&field,i,
mine=new MineSprite(svgrender,animation[ID_MINE2],animation[ID_MINEEXPLO],i,
config.mineActivateTime,config.mineFuel);
field.addItem(mine);
QPointF p;
mine->setPos(ship[i]->mapToScene(ship[i]->center()));
// move mine to center
......@@ -837,8 +842,9 @@ void MyMainView::calculatePowerups()
int type,x,y;
timeToNextPowerup= random.getDouble() * config.powerupRefreshTime;
type= random.getLong(PowerupSprite::PowerupNum);
sp=new PowerupSprite(poweruppixmap[type],&field,type,
sp=new PowerupSprite(svgrender,powerupelements[type],type,
config.powerupLifeTime);
field.addItem(sp);
do
{
x = random.getLong(width()-40)+20;
......@@ -1043,7 +1049,8 @@ void MyMainView::collisions()
{
op=(pl+1)%2;
ship[pl]->setExplosion((int)(EXPLOSION_TIME/config.gamespeed));
expl = new ExplosionSprite(animation[ID_EXPLOSION],&field,ship[pl]);
expl = new ExplosionSprite(svgrender,animation[ID_EXPLOSION],ship[pl]);
field.addItem(expl);
expl->show();
explosions.append(expl);
gameEnd=Options::timeAfterKill()/config.gamespeed;
......
......@@ -23,6 +23,7 @@ This program is free software; you can redistribute it and/or modify
#include <QList>
#include <QTimerEvent>
#include <QWidget>
#include <QString>
#include <krandomsequence.h>
class KToggleAction;
......@@ -95,21 +96,17 @@ private:
double gameEnd;
double timeToNextPowerup;
// sprites
QPixmap *sunpixmap;
QPixmap *shippixmap[2];
QPixmap *bulletpixmap[2];
QPixmap *poweruppixmap[PowerupSprite::PowerupNum];
// SVG sprites
QSvgRenderer* svgrender;
// This could probably be gotten rid of, but it'll be kind of a pain
QString powerupelements[PowerupSprite::PowerupNum];
QMap<int, QList<QPixmap> > animation;
QMap<int, QList<QString> > animation;
ShipSprite *ship[2];
SunSprite *sun;
QGraphicsSimpleTextItem *textSprite;
//Q3PtrList<BulletSprite> *bullets[2];
//Q3PtrList<MineSprite> *mines[2];
//Q3PtrList<ExplosionSprite> explosions;
//Q3PtrList<PowerupSprite> powerups;
QList<BulletSprite*> *bullets[2];
QList<MineSprite*> *mines[2];
QList<ExplosionSprite*> explosions;
......
......@@ -18,27 +18,24 @@ This program is free software; you can redistribute it and/or modify
#include <math.h>
#include <QGraphicsScene>
#include <QSvgRenderer>
#include <kdebug.h>
#include "spritebase.h"
SimpleSprite::SimpleSprite(QPixmap* pixmap, QGraphicsScene* scene)
:QGraphicsPixmapItem(*pixmap, 0, scene)
{
init();
}
SimpleSprite::SimpleSprite(QGraphicsItem * parent, QGraphicsScene * scene)
:QGraphicsPixmapItem(parent, scene)
SimpleSprite::SimpleSprite(QSvgRenderer* svg, const QString& element)
:QGraphicsSvgItem(0)
{
setSharedRenderer(svg);
setElementId(element);
init();
}
void SimpleSprite::init()
{
m_width = pixmap().width();
m_height = pixmap().height();
m_width = boundingRect().width();
m_height = boundingRect().height();
m_center = QPointF(m_width/2.0f,m_height/2.0f);
}
......@@ -57,15 +54,8 @@ QPointF SimpleSprite::center()
return m_center;
}
MobileSprite::MobileSprite(QPixmap* pixmap, QGraphicsScene* scene, int pn)
:SimpleSprite(pixmap, scene)
{
stopped=false;
playerNumber=pn;
}
MobileSprite::MobileSprite(QGraphicsItem * parent, QGraphicsScene * scene, int pn)
:SimpleSprite(parent, scene)
MobileSprite::MobileSprite(QSvgRenderer* svg, const QString& element, int pn)
:SimpleSprite(svg, element)
{
stopped=false;
playerNumber=pn;
......@@ -75,7 +65,7 @@ void MobileSprite::forward(double mult, int fr)
{
if(!stopped)
{
QGraphicsPixmapItem::moveBy(xVelocity()*mult,yVelocity()*mult);
QGraphicsSvgItem::moveBy(xVelocity()*mult,yVelocity()*mult);
checkBounds();
// FIXME
//setFrame(fr);
......@@ -88,7 +78,7 @@ void MobileSprite::forward(double mult)
{
if(!stopped)
{
QGraphicsPixmapItem::moveBy(xVelocity()*mult,yVelocity()*mult);
QGraphicsSvgItem::moveBy(xVelocity()*mult,yVelocity()*mult);
checkBounds();
}
}
......@@ -140,18 +130,18 @@ void MobileSprite::calculateGravity(double gravity,double mult)
int MobileSprite::spriteFieldWidth()
{
return (int)scene()->width();
return (int)scene()->width();
}
int MobileSprite::spriteFieldHeight()
{
return (int)scene()->height();
return (int)scene()->height();
}
void MobileSprite::setVelocity(double vx, double vy)
{
xvel = vx;
yvel = vy;
xvel = vx;
yvel = vy;
}
AiSprite MobileSprite::toAiSprite()
......@@ -168,20 +158,20 @@ AiSprite MobileSprite::toAiSprite()
return as;
}
AnimatedSprite::AnimatedSprite(const QList<QPixmap> &animation,
QGraphicsScene *scene, int pn)
: MobileSprite(0, scene)
AnimatedSprite::AnimatedSprite(QSvgRenderer* svg,
const QList<QString> &animation,
int pn)
: MobileSprite(svg,animation[0],pn)
{
frames = animation;
currentFrame = 0;
setFrame(0);
frames = animation;
currentFrame = 0;
}
void AnimatedSprite::setFrame(int frame)
{
if (!frames.isEmpty()) {
currentFrame = frame % frames.size();
setPixmap(frames.at(currentFrame));
setElementId(frames.at(currentFrame));
}
}
......@@ -189,7 +179,8 @@ void AnimatedSprite::advance(int phase)
{
if (phase == 1 && !frames.isEmpty()) {
currentFrame = (currentFrame + 1) % frames.size();
setPixmap(frames.at(currentFrame));
setElementId(frames.at(currentFrame));
init();
}
}
......@@ -197,13 +188,13 @@ QPainterPath AnimatedSprite::shape() const
{
QPainterPath path;
path.addRect(0, 0,
frames.at(currentFrame).width(),
frames.at(currentFrame).height());
boundingRect().width(),
boundingRect().height());
return path;
}
void AnimatedSprite::setAnimation(const QList<QPixmap> &animation)
void AnimatedSprite::setAnimation(const QList<QString> &animation)
{
frames = animation;
setFrame(0);
frames = animation;
setFrame(0);
}
......@@ -18,34 +18,34 @@ This program is free software; you can redistribute it and/or modify
#ifndef __SPRITE_BASE_H
#define __SPRITE_BASE_H
#include <QGraphicsPixmapItem>
#include <QGraphicsSvgItem>
class QGraphicsScene;
//#include "defines.h"
#include "spritebase.h"
#include "structs.h"
class SimpleSprite: public QGraphicsPixmapItem
class SimpleSprite: public QGraphicsSvgItem
{
public:
int width();
int height();
QPointF center();
private:
protected:
void init();
private:
int m_width;
int m_height;
QPointF m_center;
protected:
SimpleSprite(QPixmap* pixmap, QGraphicsScene* scene);
SimpleSprite(QGraphicsItem* parent = 0, QGraphicsScene * scene = 0);
SimpleSprite(QSvgRenderer* svg, const QString& element);
};
class MobileSprite:public SimpleSprite
{
public:
MobileSprite(QPixmap* pixmap, QGraphicsScene* scene, int pn);
MobileSprite(QSvgRenderer* svg, const QString&, int pn);
virtual void forward(double mult,int frame);
virtual void forward(double mult);
......@@ -61,8 +61,6 @@ public:
void stop(bool s=true) {stopped=s;}
int getPlayerNumber() {return playerNumber;}
protected:
MobileSprite(QGraphicsItem* parent = 0, QGraphicsScene * scene = 0, int pn = 0);
void checkBounds();
bool stopped;
int playerNumber;
......@@ -73,23 +71,23 @@ protected:
class AnimatedSprite:public MobileSprite
{
public:
explicit AnimatedSprite(const QList<QPixmap> &animation, QGraphicsScene *scene = 0, int pn=0);
explicit AnimatedSprite(QSvgRenderer* svg, const QList<QString> &animation, int pn=0);
void setFrame(int frame);
inline int frame() const
{ return currentFrame; }
inline int frameCount() const
{ return frames.size(); }
inline QPixmap image(int frame) const
{ return frames.isEmpty() ? QPixmap() : frames.at(frame % frames.size()); }
inline QString element(int frame) const
{ return frames.isEmpty() ? QString() : frames.at(frame % frames.size()); }
QPainterPath shape() const;
void setAnimation(const QList<QPixmap> &animation);
void setAnimation(const QList<QString> &animation);
void advance(int phase);
private:
int currentFrame;
QList<QPixmap> frames;
QList<QString> frames;
};
#endif
......@@ -25,23 +25,23 @@ This program is free software; you can redistribute it and/or modify
#include "mathroutines.h"
#include "sprites.h"
SunSprite::SunSprite(QPixmap* pixmap, QGraphicsScene* scene)
:SimpleSprite(pixmap, scene)
SunSprite::SunSprite(QSvgRenderer* svg, const QString& element)
:SimpleSprite(svg, element)
{
setZValue(0);
}
PowerupSprite::PowerupSprite(QPixmap* pixmap, QGraphicsScene* scene, int t,
PowerupSprite::PowerupSprite(QSvgRenderer* svg, const QString& element, int t,
double lifetime)
:SimpleSprite(pixmap, scene)
:SimpleSprite(svg, element)
{
time=lifetime;
mtype=t;
}
ShipSprite::ShipSprite(QPixmap* pixmap, QGraphicsScene* scene, int pn)
:MobileSprite(pixmap,scene,pn)
ShipSprite::ShipSprite(QSvgRenderer* svg, const QString& element, int pn)
:MobileSprite(svg, element,pn)
{
hitpoints=MAX_HP;
energy=MAX_ENERGY;
......@@ -150,8 +150,8 @@ void ShipSprite::rotateLeft(double rotationEnergyNeed,double rotationSpeed)
}
}
BulletSprite::BulletSprite(QPixmap* pixmap, QGraphicsScene* scene, int pn,double lifetime)
:MobileSprite(pixmap,scene,pn)
BulletSprite::BulletSprite(QSvgRenderer* svg, const QString& element, int pn,double lifetime)
:MobileSprite(svg,element,pn)
{
setZValue(-10);
time=lifetime;
......@@ -169,8 +169,8 @@ void BulletSprite::forward(double mult,int fr)
time-=mult;
}
MineSprite::MineSprite(const QList<QPixmap> &animation, const QList<QPixmap> &exploanimation, QGraphicsScene* scene, int pn,double atime,double f)
:AnimatedSprite(animation,scene,pn)
MineSprite::MineSprite(QSvgRenderer* svg, const QList<QString>& animation, const QList<QString>& exploanimation, int pn,double atime,double f)
:AnimatedSprite(svg, animation,pn)
{
exploframes = exploanimation;
activateTime=atime;
......@@ -239,8 +239,8 @@ void MineSprite::calculateGravity(double gravity,double mult)
}
}
ExplosionSprite::ExplosionSprite(const QList<QPixmap> &animation, QGraphicsScene *scene, MobileSprite *sp)
:AnimatedSprite(animation, scene)
ExplosionSprite::ExplosionSprite(QSvgRenderer* svg, const QList<QString>& animation, MobileSprite *sp)
:AnimatedSprite(svg, animation)
{
over=false;
setZValue(5);
......
......@@ -30,7 +30,7 @@ class QGraphicsScene;
class SunSprite:public SimpleSprite
{
public:
SunSprite(QPixmap* pixmap, QGraphicsScene* scene);
SunSprite(QSvgRenderer* svg, const QString& element);
virtual int type() const {return S_SUN;}
};
......@@ -39,7 +39,7 @@ class PowerupSprite:public SimpleSprite
public:
enum {PowerupMine=0, PowerupBullet, PowerupShield, PowerupEnergy,
PowerupNum};
PowerupSprite(QPixmap* pixmap, QGraphicsScene* scene, int t, double lifetime);
PowerupSprite(QSvgRenderer* svg, const QString& element, int t, double lifetime);
virtual int type() const {return S_POWERUP;}
double getLifetime() {return time;}
......@@ -53,7 +53,7 @@ private:
class ShipSprite:public MobileSprite
{
public:
ShipSprite(QPixmap* pixmap, QGraphicsScene* scene, int pn);
ShipSprite(QSvgRenderer* svg, const QString& element, int pn);
virtual int type() const {return S_SHIP;}
int getHitPoints() {return hitpoints;}
void setHitPoints(int hp) {hitpoints=(hp<0?0:hp);}
......@@ -90,7 +90,7 @@ private: