[+] Added particle drawing check

This commit is contained in:
cybermind 2013-04-22 19:40:31 +06:00
parent 4b744633a1
commit 4a37c36524
8 changed files with 101 additions and 48 deletions

View file

@ -43,17 +43,7 @@ struct CPosition {
float y;
};
class Animation
{
public:
virtual ~Animation() {}
virtual void draw(int x, int y) = 0;
virtual void update(int ticks) = 0;
virtual bool isFinished() = 0;
virtual Animation *clone() = 0;
};
class GraphicAnimation : public Animation
class GraphicAnimation
{
CGraphic *g;
int ticksPerFrame;
@ -61,24 +51,24 @@ class GraphicAnimation : public Animation
int currTicks;
public:
GraphicAnimation(CGraphic *g, int ticksPerFrame);
virtual ~GraphicAnimation() {}
~GraphicAnimation() {}
/**
** Draw the current frame of the animation.
** @param x x screen coordinate where to draw the animation.
** @param y y screen coordinate where to draw the animation.
*/
virtual void draw(int x, int y);
void draw(int x, int y);
/**
** Update the animation.
** @param ticks the number of ticks elapsed since the last call.
*/
virtual void update(int ticks);
void update(int ticks);
virtual bool isFinished();
virtual Animation *clone();
bool isFinished();
bool isVisible(const CViewport &vp, const CPosition &pos);
GraphicAnimation *clone();
};
@ -92,8 +82,9 @@ public:
{}
virtual ~CParticle() {}
virtual void draw() {}
virtual void update(int) {}
virtual bool isVisible(const CViewport &vp) const = 0;
virtual void draw() = 0;
virtual void update(int) = 0;
inline void destroy() { destroyed = true; }
inline bool isDestroyed() { return destroyed; }
@ -109,15 +100,16 @@ protected:
class StaticParticle : public CParticle
{
public:
StaticParticle(CPosition position, Animation *flame);
StaticParticle(CPosition position, GraphicAnimation *flame);
virtual ~StaticParticle();
virtual bool isVisible(const CViewport &vp) const;
virtual void draw();
virtual void update(int ticks);
virtual CParticle *clone();
protected:
Animation *animation;
GraphicAnimation *animation;
};
@ -125,12 +117,13 @@ protected:
class CChunkParticle : public CParticle
{
public:
CChunkParticle(CPosition position, Animation *smokeAnimation, Animation *debrisAnimation,
Animation *destroyAnimation,
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
GraphicAnimation *destroyAnimation,
int minVelocity = 0, int maxVelocity = 400,
int minTrajectoryAngle = 77, int maxTTL = 0);
virtual ~CChunkParticle();
virtual bool isVisible(const CViewport &vp) const;
virtual void draw();
virtual void update(int ticks);
virtual CParticle *clone();
@ -147,9 +140,9 @@ protected:
int maxVelocity;
int minTrajectoryAngle;
float height;
Animation *debrisAnimation;
Animation *smokeAnimation;
Animation *destroyAnimation;
GraphicAnimation *debrisAnimation;
GraphicAnimation *smokeAnimation;
GraphicAnimation *destroyAnimation;
struct {
float x;
@ -162,15 +155,16 @@ protected:
class CSmokeParticle : public CParticle
{
public:
CSmokeParticle(CPosition position, Animation *animation, float speedx = 0, float speedy = -22.0f);
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0f);
virtual ~CSmokeParticle();
virtual bool isVisible(const CViewport &vp) const;
virtual void draw();
virtual void update(int ticks);
virtual CParticle *clone();
protected:
Animation *puff;
GraphicAnimation *puff;
struct {
float x;
float y;
@ -180,15 +174,16 @@ protected:
class CRadialParticle : public CParticle
{
public:
CRadialParticle(CPosition position, Animation *animation, int maxSpeed);
CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed);
virtual ~CRadialParticle();
virtual bool isVisible(const CViewport &vp) const;
virtual void draw();
virtual void update(int ticks);
virtual CParticle *clone();
protected:
Animation *animation;
GraphicAnimation *animation;
float direction;
int speed;
int maxSpeed;

View file

@ -44,8 +44,8 @@ static inline float deg2rad(int degrees)
}
CChunkParticle::CChunkParticle(CPosition position, Animation *smokeAnimation, Animation *debrisAnimation,
Animation *destroyAnimation,
CChunkParticle::CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
GraphicAnimation *destroyAnimation,
int minVelocity, int maxVelocity, int minTrajectoryAngle, int maxTTL) :
CParticle(position), initialPos(position), maxTTL(maxTTL), nextSmokeTicks(0),
age(0), height(0.f)
@ -81,6 +81,12 @@ static float calculateScreenPos(float posy, float height)
return posy - height * 0.2f;
}
bool CChunkParticle::isVisible(const CViewport &vp) const
{
return debrisAnimation && debrisAnimation->isVisible(vp, pos);
}
void CChunkParticle::draw()
{
CPosition screenPos = ParticleManager.getScreenPos(pos);
@ -105,7 +111,7 @@ void CChunkParticle::update(int ticks)
if (age >= lifetime) {
if (destroyAnimation) {
CPosition p(pos.x, calculateScreenPos(pos.y, height));
Animation *destroyanimation = destroyAnimation->clone();
GraphicAnimation *destroyanimation = destroyAnimation->clone();
StaticParticle *destroy = new StaticParticle(p, destroyanimation);
ParticleManager.add(destroy);
}
@ -119,7 +125,7 @@ void CChunkParticle::update(int ticks)
if (age > nextSmokeTicks) {
CPosition p(pos.x, calculateScreenPos(pos.y, height));
Animation *smokeanimation = smokeAnimation->clone();
GraphicAnimation *smokeanimation = smokeAnimation->clone();
CSmokeParticle *smoke = new CSmokeParticle(p, smokeanimation);
ParticleManager.add(smoke);
@ -128,7 +134,7 @@ void CChunkParticle::update(int ticks)
debrisAnimation->update(ticks);
if (debrisAnimation->isFinished()) {
Animation *debrisanimation = debrisAnimation->clone();
GraphicAnimation *debrisanimation = debrisAnimation->clone();
delete debrisAnimation;
debrisAnimation = debrisanimation;
}

View file

@ -30,7 +30,12 @@
//@{
#include "stratagus.h"
#include "particle.h"
#include "map.h"
#include "player.h"
#include "ui.h"
#include "video.h"
GraphicAnimation::GraphicAnimation(CGraphic *g, int ticksPerFrame) :
@ -61,7 +66,37 @@ bool GraphicAnimation::isFinished()
return currentFrame >= g->NumFrames;
}
Animation *GraphicAnimation::clone()
bool GraphicAnimation::isVisible(const CViewport &vp, const CPosition &pos)
{
// invisible graphics always invisible
if (!g) {
return false;
}
PixelSize graphicSize(g->Width, g->Height);
PixelDiff margin(PixelTileSize.x - 1, PixelTileSize.y - 1);
PixelPos position(pos.x, pos.y);
Vec2i minPos = Map.MapPixelPosToTilePos(position);
Vec2i maxPos = Map.MapPixelPosToTilePos(position + graphicSize + margin);
Map.Clamp(minPos);
Map.Clamp(maxPos);
if (!vp.AnyMapAreaVisibleInViewport(minPos, maxPos)) {
return false;
}
Vec2i p;
for (p.x = minPos.x; p.x <= maxPos.x; ++p.x) {
for (p.y = minPos.y; p.y <= maxPos.y; ++p.y) {
if (ReplayRevealMap || Map.Field(p)->playerInfo.IsTeamVisible(*ThisPlayer)) {
return true;
}
}
}
return false;
}
GraphicAnimation *GraphicAnimation::clone()
{
return new GraphicAnimation(g, ticksPerFrame);
}

View file

@ -31,8 +31,8 @@
#include "stratagus.h"
#include "particle.h"
#include "video.h"
#include "ui.h"
#include "video.h"
CParticleManager ParticleManager;
@ -76,7 +76,9 @@ void CParticleManager::draw(const CViewport &vp)
std::vector<CParticle *>::iterator i;
for (i = particles.begin(); i != particles.end(); ++i) {
(*i)->draw();
if ((*i)->isVisible(vp)) {
(*i)->draw();
}
}
this->vp = NULL;
@ -117,4 +119,4 @@ CPosition CParticleManager::getScreenPos(const CPosition &pos) const
return CPosition(screenPixelPos.x, screenPixelPos.y);
}
//@}
//@}

View file

@ -34,7 +34,7 @@
#include "stratagus.h"
#include "particle.h"
CRadialParticle::CRadialParticle(CPosition position, Animation *animation, int maxSpeed) :
CRadialParticle::CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed) :
CParticle(position)
{
Assert(animation);
@ -52,6 +52,11 @@ CRadialParticle::~CRadialParticle()
delete animation;
}
bool CRadialParticle::isVisible(const CViewport &vp) const
{
return animation && animation->isVisible(vp, pos);
}
void CRadialParticle::draw()
{
CPosition screenPos = ParticleManager.getScreenPos(pos);

View file

@ -35,7 +35,7 @@
CSmokeParticle::CSmokeParticle(CPosition position, Animation *smoke,
CSmokeParticle::CSmokeParticle(CPosition position, GraphicAnimation *smoke,
float speedx, float speedy) :
CParticle(position)
{
@ -51,6 +51,11 @@ CSmokeParticle::~CSmokeParticle()
delete puff;
}
bool CSmokeParticle::isVisible(const CViewport &vp) const
{
return puff && puff->isVisible(vp, pos);
}
void CSmokeParticle::draw()
{
CPosition screenPos = ParticleManager.getScreenPos(pos);

View file

@ -33,7 +33,7 @@
#include "particle.h"
StaticParticle::StaticParticle(CPosition position, Animation *animation) :
StaticParticle::StaticParticle(CPosition position, GraphicAnimation *animation) :
CParticle(position)
{
Assert(animation);
@ -45,6 +45,11 @@ StaticParticle::~StaticParticle()
delete animation;
}
bool StaticParticle::isVisible(const CViewport &vp) const
{
return animation && animation->isVisible(vp, pos);
}
void StaticParticle::draw()
{
CPosition screenPos = ParticleManager.getScreenPos(pos);

View file

@ -7,10 +7,10 @@ struct CPosition
float y;
};
class GraphicAnimation : public Animation
class GraphicAnimation
{
GraphicAnimation(CGraphic *g, int ticksPerFrame);
virtual Animation * clone();
virtual GraphicAnimation * clone();
};
class CParticle
@ -21,25 +21,25 @@ class CParticle
class StaticParticle : public CParticle
{
public:
StaticParticle(CPosition position, Animation *animation);
StaticParticle(CPosition position, GraphicAnimation *animation);
};
class CChunkParticle : public CParticle
{
public:
CChunkParticle(CPosition position, Animation *smokeAnimation, Animation *debrisAnimation, Animation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0);
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation, GraphicAnimation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0);
};
class CSmokeParticle : public CParticle
{
public:
CSmokeParticle(CPosition position, Animation *animation, float speedx = 0, float speedy = -22.0);
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0);
};
class CRadialParticle : public CParticle
{
public:
CRadialParticle(CPosition position, Animation *smokeAnimation, int maxSpeed);
CRadialParticle(CPosition position, GraphicAnimation *smokeAnimation, int maxSpeed);
};
class CParticleManager