Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
207 KB
Referenced Files
None
Subscribers
None
diff --git a/src/ArtefactDescriptionEntity.cpp b/src/ArtefactDescriptionEntity.cpp
index 33db947..40025ad 100644
--- a/src/ArtefactDescriptionEntity.cpp
+++ b/src/ArtefactDescriptionEntity.cpp
@@ -1,101 +1,101 @@
#include "ArtefactDescriptionEntity.h"
#include "Constants.h"
#include "sfml_game/ImageManager.h"
#include "WitchBlastGame.h"
#include "Items.h"
ArtefactDescriptionEntity::ArtefactDescriptionEntity(enumItemType itemType)
: SpriteEntity (ImageManager::getImageManager()->getImage(itemType >= FirstEquipItem ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS ),
0, 0, ITEM_WIDTH, ITEM_HEIGHT)
{
this->setLifetime(6.0f);
imagesProLine = 10;
if (itemType >= FirstEquipItem)
this->setFrame(itemType - FirstEquipItem);
else
this->setFrame(itemType);
this->setType(ENTITY_ARTIFACT_DESCRIPTION);
float x0 = OFFSET_X + MAP_WIDTH * TILE_WIDTH * 0.5f - ARTEFACT_RECT_WIDTH * 0.5f;
rectangle.setSize(sf::Vector2f(ARTEFACT_RECT_WIDTH, ARTEFACT_RECT_HEIGHT));
rectangle.setPosition(sf::Vector2f(x0, ARTEFACT_POS_Y));
rectangle.setFillColor(sf::Color(20, 20, 70, 180));
rectangleBorder.setSize(sf::Vector2f(ARTEFACT_RECT_WIDTH + ARTEFACT_BORDER * 2.0f,
ARTEFACT_RECT_HEIGHT + ARTEFACT_BORDER * 2.0f));
rectangleBorder.setPosition(sf::Vector2f(x0 - ARTEFACT_BORDER, ARTEFACT_POS_Y - ARTEFACT_BORDER));
rectangleBorder.setFillColor(sf::Color(255, 255, 255, 180));
this->x = x0 + 50.0f;
this->y = 500.0f;
sprite.setScale(3.5f, 3.5f);
z = 5000.0f;
if (items[itemType].type == itemType)
{
artefactName = items[itemType].name;
artefactDescription = items[itemType].description;
}
else
{
artefactName = "Unknown";
artefactDescription = "Report to developper";
}
}
ArtefactDescriptionEntity::~ArtefactDescriptionEntity()
{
}
void ArtefactDescriptionEntity::animate(float delay)
{
if (age < ARTEFACT_ZOOM_TIME)
{
float perc = 1.0f - age / ARTEFACT_ZOOM_TIME;
sprite.setScale(3.5f + perc * 50.0f, 3.5f + perc * 50.0f);
}
else
{
sprite.setScale(3.5f, 3.5f);
}
SpriteEntity::animate(delay);
}
-void ArtefactDescriptionEntity::render(sf::RenderWindow* app)
+void ArtefactDescriptionEntity::render(sf::RenderTarget* app)
{
int nx = frame;
int ny = 0;
if (imagesProLine > 0)
{
nx = frame % imagesProLine;
ny = frame / imagesProLine;
}
sprite.setTextureRect(sf::IntRect(nx * width, ny * height, /*(nx + 1) **/ width, /*(ny + 1) */ height));
sprite.setPosition(x, y);
sprite.setRotation(angle);
if (isFading)
{
sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)(getFade() * 255)));
}
if (isShrinking)
{
sprite.setScale(getFade(), getFade());
}
app->draw(rectangleBorder);
app->draw(rectangle);
app->draw(sprite);
- game().Write(artefactName, 22, 315.0f, ARTEFACT_POS_Y + 15.0f, ALIGN_LEFT, sf::Color(255, 255, 255));
- game().Write(artefactDescription, 20, 315.0f, ARTEFACT_POS_Y + 55.0f, ALIGN_LEFT, sf::Color(255, 255, 255));
+ game().Write(artefactName, 22, 315.0f, ARTEFACT_POS_Y + 15.0f, ALIGN_LEFT, sf::Color(255, 255, 255), app);
+ game().Write(artefactDescription, 20, 315.0f, ARTEFACT_POS_Y + 55.0f, ALIGN_LEFT, sf::Color(255, 255, 255), app);
}
diff --git a/src/ArtefactDescriptionEntity.h b/src/ArtefactDescriptionEntity.h
index 7a7231a..0a85e05 100644
--- a/src/ArtefactDescriptionEntity.h
+++ b/src/ArtefactDescriptionEntity.h
@@ -1,22 +1,22 @@
#ifndef ARTEFACTDESCRIPTIONENTITY_H
#define ARTEFACTDESCRIPTIONENTITY_H
#include "sfml_game/SpriteEntity.h"
#include "ItemEntity.h"
class ArtefactDescriptionEntity : public SpriteEntity
{
public:
ArtefactDescriptionEntity(enumItemType);
~ArtefactDescriptionEntity();
virtual void animate(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
private:
sf::RectangleShape rectangle;
sf::RectangleShape rectangleBorder;
std::string artefactName;
std::string artefactDescription;
};
#endif // ARTEFACTDESCRIPTIONENTITY_H
diff --git a/src/BaseCreatureEntity.cpp b/src/BaseCreatureEntity.cpp
index 215a55b..ed3a12a 100644
--- a/src/BaseCreatureEntity.cpp
+++ b/src/BaseCreatureEntity.cpp
@@ -1,340 +1,340 @@
#include "BaseCreatureEntity.h"
#include "sfml_game/ImageManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
BaseCreatureEntity::BaseCreatureEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int spriteWidth = -1, int spriteHeight = -1)
: CollidingSpriteEntity (image, x, y, spriteWidth, spriteHeight )
{
hurting = false;
hurtingType = ShotTypeStandard;
shadowFrame = -1;
setMap(game().getCurrentMap(), TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
hpDisplay = 0;
movingStyle = movWalking;
for (int i = 0; i < NB_SPECIAL_STATES; i++)
{
specialState[i].type = (enumSpecialState)i;
specialState[i].resistance = ResistanceStandard;
specialState[i].active = false;
specialState[i].timer = 0.0f;
}
recoil.active = false;
facingDirection = 2;
}
int BaseCreatureEntity::getHp()
{
return hp;
}
int BaseCreatureEntity::getHpMax()
{
return hpMax;
}
void BaseCreatureEntity::setHp(int hp)
{
this->hp = hp;
}
void BaseCreatureEntity::setHpMax(int hpMax)
{
this->hpMax = hpMax;
}
int BaseCreatureEntity::getHpDisplay()
{
return hpDisplay;
}
IntCoord BaseCreatureEntity::getCurrentTile()
{
int xMap = (x - OFFSET_X) / TILE_WIDTH;
int yMap = (y - OFFSET_Y) / TILE_HEIGHT;
return (IntCoord(xMap, yMap));
}
BaseCreatureEntity::enumMovingStyle BaseCreatureEntity::getMovingStyle()
{
return movingStyle;
}
float BaseCreatureEntity::animateStates(float delay)
{
for (int i = 0; i < NB_SPECIAL_STATES; i++)
{
if (specialState[i].active)
{
specialState[i].timer -= delay;
if (specialState[i].timer <= 0.0f) specialState[i].active = false;
}
}
if (specialState[SpecialStateIce].active) delay *= STATUS_FROZEN_MULT;
return delay;
}
void BaseCreatureEntity::animateColors(float delay)
{
// no color
sprite.setColor(sf::Color(255, 255, 255, 255 ));
if (hurting and hp > 0)
{
hurtingDelay -= delay;
if (hurtingDelay > 0.0f)
{
int fadeColor = (sf::Uint8)((HURTING_DELAY - hurtingDelay) * 255);
if (hurtingType == ShotTypeIce)
sprite.setColor(sf::Color(fadeColor, fadeColor, 255, 255 )); // blue
else
sprite.setColor(sf::Color(255, fadeColor, fadeColor, 255 )); // red
}
else
{
hurting = false;
sprite.setColor(sf::Color(255, 255, 255, 255 ));
}
}
if (specialState[SpecialStateIce].active) sprite.setColor(sf::Color(100, 100, 255, 255 ));
}
void BaseCreatureEntity::animateRecoil(float delay)
{
// recoil
if (recoil.active)
{
recoil.velocity.x *= 0.97f;
recoil.velocity.y *= 0.97f;
recoil.timer -= delay;
if (recoil.timer <= 0.0f)
{
recoil.active = false;
computeFacingDirection();
// TODO ?
}
}
}
void BaseCreatureEntity::animatePhysics(float delay)
{
velocity.x *= viscosity;
velocity.y *= viscosity;
float velx = velocity.x;
float vely = velocity.y;
if (recoil.active)
{
if (recoil.stun)
{
velx = 0.0f;
vely = 0.0f;
}
velx += recoil.velocity.x;
vely += recoil.velocity.y;
}
spin *= viscosity;
angle += spin * delay;
if ((int)velx > 0)
{
x += velx * delay;
if (collideWithMap(DIRECTION_LEFT))
{
x = (float)((int)x);
while (collideWithMap(DIRECTION_LEFT))
x--;
collideMapRight();
}
else if (x > map->getWidth() * tileWidth + offsetX)
{
exitMap(DIRECTION_RIGHT);
}
}
else if ((int)velx < 0)
{
x += velx * delay;
if (collideWithMap(DIRECTION_RIGHT))
{
x = (float)((int)x);
while (collideWithMap(DIRECTION_RIGHT))
x++;
collideMapLeft();
}
else if (x < offsetX)
{
exitMap(DIRECTION_LEFT);
}
}
vely += weight * delay;
if ( vely > maxY) vely = maxY;
if ((int)vely > 0)
{
y += vely * delay;
if (collideWithMap(DIRECTION_BOTTOM))
{
y = (float)((int)y);
while (collideWithMap(DIRECTION_BOTTOM))
y--;
collideMapBottom();
}
}
else if ((int)vely < 0)
{
y += vely * delay;
if (collideWithMap(DIRECTION_TOP))
{
y = (float)((int)y);
while (collideWithMap(DIRECTION_TOP))
y++;
collideMapTop();
}
}
if (lifetime > 0)
{
if (age >= lifetime) isDying = true;
}
age += delay;
}
void BaseCreatureEntity::animate(float delay)
{
if (hpDisplay > hp) hpDisplay--;
else if (hpDisplay < hp) hpDisplay++;
delay = animateStates(delay);
animateColors(delay);
animateRecoil(delay);
animatePhysics(delay);
z = y + height/2;
}
-void BaseCreatureEntity::render(sf::RenderWindow* app)
+void BaseCreatureEntity::render(sf::RenderTarget* app)
{
if (!isDying && shadowFrame > -1)
{
// shadow
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
CollidingSpriteEntity::render(app);
#ifdef SHOW_BOUNDING_BOX
sf::Vertex line[] =
{
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top))
};
app->draw(line, 8, sf::Lines);
#endif
}
void BaseCreatureEntity::calculateBB()
{
}
bool BaseCreatureEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
if (movingStyle == movWalking)
{
if ( dynamic_cast<DungeonMap*>(map)->isWalkable(xTile, yTile) == false ) return true;
}
else if (movingStyle == movFlying)
{
if ( dynamic_cast<DungeonMap*>(map)->isFlyable(xTile, yTile) == false ) return true;
}
}
return false;
}
bool BaseCreatureEntity::hurt(int damages, enumShotType hurtingType)
{
hurting = true;
hurtingDelay = HURTING_DELAY;
this->hurtingType = hurtingType;
if (hurtingType == ShotTypeIce && specialState[SpecialStateIce].resistance > ResistanceImmune)
{
specialState[SpecialStateIce].active = true;
specialState[SpecialStateIce].timer = STATUS_FROZEN_DELAY;
}
hp -= damages;
if (hp <= 0)
{
hp = 0;
prepareDying();
}
return true;
}
void BaseCreatureEntity::prepareDying()
{
dying();
}
void BaseCreatureEntity::dying()
{
isDying = true;
}
void BaseCreatureEntity::computeFacingDirection()
{
if (abs((int)velocity.x) > 0 && abs((int)velocity.y) > 0)
{
if (abs((int)velocity.x) > abs((int)velocity.y))
{
if (velocity.x > 0.0f) facingDirection = 6;
else facingDirection = 4;
}
else
{
if (velocity.y > 0.0f) facingDirection = 2;
else facingDirection = 8;
}
}
}
void BaseCreatureEntity::giveRecoil(bool stun, Vector2D velocity, float timer)
{
recoil.active = true;
recoil.stun = stun;
recoil.velocity = velocity;
recoil.timer = timer;
}
void BaseCreatureEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
}
diff --git a/src/BaseCreatureEntity.h b/src/BaseCreatureEntity.h
index 06a987a..839c58e 100644
--- a/src/BaseCreatureEntity.h
+++ b/src/BaseCreatureEntity.h
@@ -1,76 +1,76 @@
#ifndef BASECREATUREENTITY_H
#define BASECREATUREENTITY_H
#include "sfml_game/CollidingSpriteEntity.h"
#include "Constants.h"
const int NB_SPECIAL_STATES = 1;
class BaseCreatureEntity : public CollidingSpriteEntity
{
public:
BaseCreatureEntity(sf::Texture* image, float x, float y, int spriteWidth, int spriteHeight);
int getHp();
int getHpMax();
void setHp(int hp);
void setHpMax(int hpMax);
int getHpDisplay();
IntCoord getCurrentTile();
virtual void animate(float delay);
virtual float animateStates(float delay);
virtual void animateColors(float delay);
virtual void animateRecoil(float delay);
virtual void animatePhysics(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void calculateBB();
virtual bool collideWithMap(int direction);
virtual bool hurt(int damages, enumShotType hurtingType);
virtual void prepareDying();
virtual void dying();
enum enumMovingStyle { movWalking, movFlying};
virtual enumMovingStyle getMovingStyle();
enum enumBloodColor { bloodRed, bloodGreen};
enum enumSpecialState
{
SpecialStateIce // = 0
};
enum enumStateResistance { ResistanceImmune, ResistanceResistant, ResistanceStandard, ResistanceLow, ResistanceVeryLow};
struct itemStuct
{
enumSpecialState type;
enumStateResistance resistance;
bool active;
float timer;
};
itemStuct specialState[NB_SPECIAL_STATES];
virtual void giveRecoil(bool stun, Vector2D velocity, float timer);
virtual void inflictsRecoilTo(BaseCreatureEntity* targetEntity);
virtual void computeFacingDirection();
protected:
int hp;
int hpMax;
int hpDisplay;
float creatureSpeed;
int shadowFrame;
int facingDirection;
bool hurting;
float hurtingDelay;
enumShotType hurtingType;
enumBloodColor bloodColor;
enumMovingStyle movingStyle;
struct recoilStruct
{
bool active;
Vector2D velocity;
bool stun;
float timer;
} recoil;
private:
};
#endif // BASECREATUREENTITY_H
diff --git a/src/Constants.h b/src/Constants.h
index 09c8f9c..d877265 100644
--- a/src/Constants.h
+++ b/src/Constants.h
@@ -1,265 +1,268 @@
/** This file is part of Witch Blast.
*
* Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
* Witch Blast 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 Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONSTANTS_H_INCLUDED
#define CONSTANTS_H_INCLUDED
// uncomment to show bounding box in the app
// #define SHOW_BOUNDING_BOX
#include <string>
const std::string APP_NAME = "Witch Blast";
const std::string APP_VERSION = "0.0.8";
// Client size
const int SCREEN_WIDTH = 970;
const int SCREEN_HEIGHT = 720;
// Tile set
const int TILE_WIDTH = 64;
const int TILE_HEIGHT = 64;
// Tile map offset
const int OFFSET_X = 5;
const int OFFSET_Y = 5;
const int MAP_WIDTH = 15;
const int MAP_HEIGHT = 9;
+const int GAME_WIDTH = MAP_WIDTH * TILE_WIDTH;
+const int GAME_HEIGHT = MAP_HEIGHT * TILE_HEIGHT;
+
const int FLOOR_WIDTH = 13;
const int FLOOR_HEIGHT = 7;
const int ITEM_WIDTH = 32;
const int ITEM_HEIGHT = 32;
const int BOLT_WIDTH = 24;
const int BOLT_HEIGHT = 24;
const int BB_LEFT = 22;
const int BB_RIGHT = 22;
const int BB_TOP = 4;
const int BB_BOTTOM = 31;
const float FADE_IN_DELAY = 1.0f;
const float FADE_OUT_DELAY = 1.0f;
enum item_images {
IMAGE_PLAYER_BASE,
IMAGE_PLAYER_EQUIP,
IMAGE_PLAYER_COLLAR,
IMAGE_BOLT,
IMAGE_TILES,
IMAGE_RAT,
IMAGE_MINIMAP,
IMAGE_DOOR,
IMAGE_ITEMS,
IMAGE_ITEMS_EQUIP,
IMAGE_CHEST,
IMAGE_BAT,
IMAGE_FLOWER,
IMAGE_SLIME,
IMAGE_KING_RAT,
IMAGE_BLOOD,
IMAGE_CORPSES,
IMAGE_CORPSES_BIG,
IMAGE_STAR,
IMAGE_STAR_2,
IMAGE_INTERFACE,
IMAGE_HUD_SHOTS,
IMAGE_PNJ,
IMAGE_FAIRY
};
enum sound_resources {
SOUND_STEP,
SOUND_BLAST_STANDARD,
SOUND_BLAST_FLOWER,
SOUND_DOOR_CLOSING,
SOUND_DOOR_OPENING,
SOUND_CHEST_OPENING,
SOUND_IMPACT,
SOUND_BONUS,
SOUND_DRINK,
SOUND_EAT,
SOUND_PLAYER_HIT,
SOUND_PLAYER_DIE,
SOUND_ENNEMY_DYING,
SOUND_COIN_PICK_UP,
SOUND_PAY,
SOUND_WALL_IMPACT,
SOUND_BIG_WALL_IMPACT,
SOUND_KING_RAT_1,
SOUND_KING_RAT_2,
SOUND_KING_RAT_DIE,
SOUND_SLIME_JUMP,
SOUND_SLIME_IMAPCT,
SOUND_SLIME_IMAPCT_WEAK,
SOUND_ICE_CHARGE,
SOUND_SHOT_SELECT,
SOUND_HEART
};
enum corpses_ressources{
FRAME_CORPSE_RAT,
FRAME_CORPSE_BAT,
FRAME_CORPSE_FLOWER,
FRAME_CORPSE_GREEN_RAT,
FRAME_CORPSE_SLIME,
FRAME_CORPSE_KING_RAT
};
// Player game play
const float INITIAL_PLAYER_SPEED = 180.0f;
const int INITIAL_PLAYER_HP = 20;
const float INITIAL_PLAYER_FIRE_DELAY = 0.7f;
const float ACQUIRE_DELAY = 2.8f;
const float UNLOCK_DELAY = 1.0f;
const float INITIAL_BOLT_LIFE = 0.4f;
const int INITIAL_BOLT_DAMAGES = 8;
const float INITIAL_BOLT_VELOCITY = 700.0f;
const float FAIRY_SPEED = 180.0f;
const float FAIRY_FIRE_DELAY = 0.8f;
const float FAIRY_BOLT_LIFE = 0.4f;
const int FAIRY_BOLT_DAMAGES = 8;
const float FAIRY_BOLT_VELOCITY = 700.0f;
enum chest_type_enum {
CHEST_BASIC,
CHEST_FAIRY
};
// Artefact Info
const float ARTEFACT_RECT_WIDTH = 600.0f;
const float ARTEFACT_RECT_HEIGHT = 100.0f;
const float ARTEFACT_POS_Y = 450.0f;
const float ARTEFACT_BORDER = 8.0f;
const float ARTEFACT_ZOOM_TIME = 0.5f;
// shot types
enum enumShotType {
ShotTypeStandard,
ShotTypeIce,
ShotTypeIllusion,
ShotTypeStone,
ShotTypeLightning
};
// status
const float STATUS_FROZEN_DELAY = 5.0f; // how long the freeze occurs
const float STATUS_FROZEN_BOLT_DELAY = 2.5f; // how long the freeze occurs
const float STATUS_FROZEN_MULT = 0.33f; // speed multiplier (= 3 times slower)
// entity type
const int ENTITY_PLAYER = 1;
const int ENTITY_FAMILIAR = 2;
const int ENTITY_DOOR = 3;
const int ENTITY_ARTIFACT_DESCRIPTION = 9;
const int ENTITY_BLOOD = 11;
const int ENTITY_CORPSE = 12;
const int ENTITY_EFFECT = 13;
const int ENTITY_BOLT = 15;
const int ENTITY_ENNEMY_BOLT = 16;
const int ENTITY_PNJ = 17;
const int ENTITY_CHEST = 18;
const int ENTITY_ITEM = 19;
const int ENTITY_ENNEMY = 21;
const int ENTITY_ENNEMY_INVOCATED = 22;
const int ENTITY_ENNEMY_BOSS = 23;
const int ENTITY_ENNEMY_MAX = 23;
// monster type
enum monster_type_enum
{
MONSTER_RAT,
MONSTER_BAT,
MONSTER_EVIL_FLOWER,
MONSTER_SLIME,
MONSTER_BLACK_RAT,
MONSTER_KING_RAT
};
const float DOOR_OPEN_TIME = 1.0f;
const float DOOR_CLOSE_TIME = 1.0f;
// Rat
const float RAT_SPEED = 160.0f;
const int RAT_HP = 24;
const int RAT_DAMAGES = 5;
const int RAT_BB_LEFT = 14;
const int RAT_BB_WIDTH_DIFF = 28;
const int RAT_BB_TOP = 22;
const int RAT_BB_HEIGHT_DIFF = 22;
// Green Rat
const float GREEN_RAT_SPEED = 170.0f;
const int GREEN_RAT_HP = 16;
const int GREEN_RAT_DAMAGES = 5;
const float GREEN_RAT_FADE = 1.0f;
// Black Rat
const float BLACK_RAT_SPEED = 160.0f;
const int BLACK_RAT_HP = 24;
const int BLACK_RAT_DAMAGES = 5;
// Bat
const float BAT_SPEED = 250.0f;
const int BAT_HP = 8;
const int BAT_DAMAGES = 5;
const int BAT_BB_LEFT = 5;
const int BAT_BB_WIDTH_DIFF = 10;
const int BAT_BB_TOP = 2;
const int BAT_BB_HEIGHT_DIFF = 32;
// Evl Flower
const int EVIL_FLOWER_HP = 16;
const int EVIL_FLOWER_MELEE_DAMAGES = 8;
const int EVIL_FLOWER_MISSILE_DAMAGES = 5;
const int EVIL_FLOWER_BB_LEFT = 14;
const int EVIL_FLOWER_BB_WIDTH_DIFF = 28;
const int EVIL_FLOWER_BB_TOP = 22;
const int EVIL_FLOWER_BB_HEIGHT_DIFF = 22;
const float EVIL_FLOWER_FIRE_DELAY = 2.7f;
const float EVIL_FLOWER_FIRE_VELOCITY = 220.0f;
// Slime
const int SLIME_HP = 16;
const int SLIME_DAMAGES = 5;
const int SLIME_BB_LEFT = 13;
const int SLIME_BB_WIDTH_DIFF = 26;
const int SLIME_BB_TOP = 38;
const int SLIME_BB_HEIGHT_DIFF = 40;
// KingRat
const float KING_RAT_SPEED = 200.0f;
const float KING_RAT_RUNNING_SPEED = 600.0f;
const float KING_RAT_BERSERK_SPEED = 250.0f;
const float KING_RAT_RUNNING_RECOIL = 750.0f;
const int KING_RAT_HP = 600;
const int KING_RAT_DAMAGES = 8;
// EFFECTS
const float HURTING_DELAY = 0.4f;
const float HEART_BEAT_DELAY = 1.2f;
#endif // CONSTANTS_H_INCLUDED
diff --git a/src/DoorEntity.cpp b/src/DoorEntity.cpp
index 81c0c3f..89e6d7a 100644
--- a/src/DoorEntity.cpp
+++ b/src/DoorEntity.cpp
@@ -1,281 +1,281 @@
#include "DoorEntity.h"
#include "Constants.h"
#include "sfml_game/ImageManager.h"
DoorEntity::DoorEntity(int direction) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_DOOR))
{
this->direction = direction;
isOpen = true;
removeCenter();
width = TILE_WIDTH;
height = TILE_HEIGHT;
z = -0.5f;
type = ENTITY_DOOR;
doorType = 0;
}
void DoorEntity::animate(float delay)
{
age += delay;
if (timer > 0.0f) timer -= delay;
}
void DoorEntity::setOpen(bool open)
{
isOpen = open;
timer = 0.0f;
}
void DoorEntity::setDoorType(int doorType)
{
this->doorType = doorType;
}
void DoorEntity::closeDoor()
{
isOpen = false;
timer = DOOR_CLOSE_TIME;
}
void DoorEntity::openDoor()
{
isOpen = true;
timer = DOOR_OPEN_TIME;
}
-void DoorEntity::render(sf::RenderWindow* app)
+void DoorEntity::render(sf::RenderTarget* app)
{
if (!isVisible) return;
float xl, yl, xr, yr;
if (direction == 8)
{
yl = OFFSET_Y;
yr = OFFSET_Y;
if (isOpen)
{
if (timer > 0.0f)
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
- 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
}
else
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH * 1.2f;
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH * 1.2f;
}
}
else
{
if (timer > 0.0f)
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
- 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
}
else
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH /2;;
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH /2;
}
}
// back
sprite.setTextureRect(sf::IntRect(3 * width, doorType * height, width * 3, height));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
app->draw(sprite);
// door
sprite.setTextureRect(sf::IntRect(0.5f * width, doorType * height, width, height));
sprite.setPosition(xl, yl);
app->draw(sprite);
sprite.setTextureRect(sf::IntRect(1.5f * width, doorType * height, width, height));
sprite.setPosition(xr, yr);
app->draw(sprite);
// front
sprite.setTextureRect(sf::IntRect(6 * width, doorType * height, width * 3, height));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
app->draw(sprite);
}
if (direction == 4)
{
xl = OFFSET_X;
xr = OFFSET_X;
if (isOpen)
{
if (timer > 0.0f)
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
- 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
}
else
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT * 1.2f;
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT * 1.2f;
}
}
else
{
if (timer > 0.0f)
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
- 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
}
else
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT /2;
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT /2;
}
}
// back
sprite.setTextureRect(sf::IntRect(width + (3 * width * doorType), 2 * height, width , height* 3));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
sprite.setPosition(OFFSET_X, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
app->draw(sprite);
// door
sprite.setTextureRect(sf::IntRect( 3 * width * doorType, 2.5 * height, width, height));
sprite.setPosition(xl, yl);
app->draw(sprite);
sprite.setTextureRect(sf::IntRect( 3 * width * doorType, 3.5 * height, width, height));
sprite.setPosition(xr, yr);
app->draw(sprite);
// front
sprite.setTextureRect(sf::IntRect(2 * width + (3 * width * doorType), 2 * height, width , height* 3));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
sprite.setPosition(OFFSET_X, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
app->draw(sprite);
}
if (direction == 2)
{
sprite.setRotation(0.0f);
yl = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1);
yr = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1);
if (isOpen)
{
if (timer > 0.0f)
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
- 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
}
else
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH * 1.2f;
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH * 1.2f;
}
}
else
{
if (timer > 0.0f)
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
- 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
}
else
{
xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH /2;;
xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH /2;
}
}
// back
sprite.setTextureRect(sf::IntRect(3 * width, (1 + doorType) * height, width * 3, -height));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, yl);
app->draw(sprite);
// door
sprite.setTextureRect(sf::IntRect(0.5f * width, (1 + doorType) * height, width, -height));
sprite.setPosition(xl, yl);
app->draw(sprite);
sprite.setTextureRect(sf::IntRect(1.5f * width, (1 + doorType) * height, width, -height));
sprite.setPosition(xr, yr);
app->draw(sprite);
// front
sprite.setTextureRect(sf::IntRect(6 * width, (1 + doorType) * height, width * 3, -height));
sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, yl);
//sprite.setRotation(angle);
app->draw(sprite);
}
if (direction == 6)
{
xl = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1);
xr = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1);
if (isOpen)
{
if (timer > 0.0f)
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
- 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
}
else
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT * 1.2f;
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT * 1.2f;
}
}
else
{
if (timer > 0.0f)
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
- 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
}
else
{
yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT /2;
yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT /2;
}
}
// back
sprite.setTextureRect(sf::IntRect(width * 2 + (3 * width * doorType), 2 * height, -width , height* 3));
sprite.setPosition(xl + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
sprite.setPosition(xl, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
app->draw(sprite);
// door
sprite.setTextureRect(sf::IntRect(1 * width + (3 * width * doorType), 2.5 * height, -width, height));
sprite.setPosition(xl, yl);
app->draw(sprite);
sprite.setTextureRect(sf::IntRect(1* width + (3 * width * doorType), 3.5 * height, -width, height));
sprite.setPosition(xr, yr);
app->draw(sprite);
// front
sprite.setTextureRect(sf::IntRect(3 * width + (3 * width * doorType), 2 * height, -width , height* 3));
sprite.setPosition(xl + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
sprite.setPosition(xl, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
app->draw(sprite);
}
}
diff --git a/src/DoorEntity.h b/src/DoorEntity.h
index 0ac6bee..239893e 100644
--- a/src/DoorEntity.h
+++ b/src/DoorEntity.h
@@ -1,24 +1,24 @@
#ifndef DOORENTITY_H
#define DOORENTITY_H
#include "sfml_game/SpriteEntity.h"
class DoorEntity : public SpriteEntity
{
public:
DoorEntity(int direction);
virtual void animate(float delay);
- void render(sf::RenderWindow* app);
+ void render(sf::RenderTarget* app);
void setOpen(bool open);
void setDoorType(int doorType);
void closeDoor();
void openDoor();
private:
int direction;
bool isOpen;
float timer;
int doorType;
};
#endif // DOORENTITY_H
diff --git a/src/EvilFlowerEntity.cpp b/src/EvilFlowerEntity.cpp
index dedf986..fe98e57 100644
--- a/src/EvilFlowerEntity.cpp
+++ b/src/EvilFlowerEntity.cpp
@@ -1,109 +1,109 @@
#include "EvilFlowerEntity.h"
#include "BoltEntity.h"
#include "EnnemyBoltEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <math.h>
EvilFlowerEntity::EvilFlowerEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_FLOWER), x, y)
{
hp = EVIL_FLOWER_HP;
meleeDamages = EVIL_FLOWER_MELEE_DAMAGES;
setSpin(50.0f);
frame = 0;
type = 23;
bloodColor = bloodGreen;
//shadowFrame = 2;
fireDelay = EVIL_FLOWER_FIRE_DELAY;
age = -1.0f + (rand() % 2500) * 0.001f;
}
void EvilFlowerEntity::animate(float delay)
{
float flowerDelay = delay;
if (specialState[SpecialStateIce].active) flowerDelay = delay * STATUS_FROZEN_MULT;
if (fireDelay < 0.7f) setSpin(500.0f);
else if (fireDelay < 1.4f) setSpin(120.0f);
else setSpin(50.0f);
EnnemyEntity::animate(delay);
angle += spin * flowerDelay;
if (age > 0.0f)
{
fireDelay -= flowerDelay;
if (fireDelay <= 0.0f)
{
fireDelay = EVIL_FLOWER_FIRE_DELAY;
fire();
}
}
}
void EvilFlowerEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + EVIL_FLOWER_BB_LEFT;
boundingBox.width = width - EVIL_FLOWER_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + EVIL_FLOWER_BB_TOP;
boundingBox.height = height - EVIL_FLOWER_BB_HEIGHT_DIFF;
}
void EvilFlowerEntity::dying()
{
isDying = true;
SpriteEntity* deadFlower = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
deadFlower->setZ(OFFSET_Y);
deadFlower->setFrame(FRAME_CORPSE_FLOWER);
deadFlower->setType(ENTITY_CORPSE);
for (int i = 0; i < 4; i++) game().generateBlood(x, y, bloodColor);
drop();
SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
}
void EvilFlowerEntity::fire()
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
EnnemyBoltEntity* bolt = new EnnemyBoltEntity
(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y + 10);
bolt->setFrame(1);
bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
float flowerFireVelocity = EVIL_FLOWER_FIRE_VELOCITY;
if (specialState[SpecialStateIce].active) flowerFireVelocity *= 0.5f;
if (game().getPlayer()->getY() > y)
bolt->setVelocity(Vector2D(sin(angle) * flowerFireVelocity,
cos(angle) * flowerFireVelocity));
else
bolt->setVelocity(Vector2D(-sin(angle) * flowerFireVelocity,
-cos(angle) * flowerFireVelocity));
}
-void EvilFlowerEntity::render(sf::RenderWindow* app)
+void EvilFlowerEntity::render(sf::RenderTarget* app)
{
sprite.setPosition(x, y);
float savedAngle = sprite.getRotation();
sprite.setRotation(0.0f);
// shadow
sprite.setTextureRect(sf::IntRect(width * 2, 0, width, height));
app->draw(sprite);
sprite.setTextureRect(sf::IntRect(width, 0, width, height));
app->draw(sprite);
sprite.setRotation(savedAngle);
EnnemyEntity::render(app);
}
diff --git a/src/EvilFlowerEntity.h b/src/EvilFlowerEntity.h
index b2419f1..6aada9b 100644
--- a/src/EvilFlowerEntity.h
+++ b/src/EvilFlowerEntity.h
@@ -1,21 +1,21 @@
#ifndef EVILFLOWER_H
#define EVILFLOWER_H
#include "EnnemyEntity.h"
#include "PlayerEntity.h"
class EvilFlowerEntity : public EnnemyEntity
{
public:
EvilFlowerEntity(float x, float y);
virtual void animate(float delay);
virtual void calculateBB();
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
void fire();
protected:
virtual void dying();
private:
float fireDelay;
};
#endif // EVILFLOWER_H
diff --git a/src/ItemEntity.cpp b/src/ItemEntity.cpp
index 0aa71ba..4e5ea34 100644
--- a/src/ItemEntity.cpp
+++ b/src/ItemEntity.cpp
@@ -1,163 +1,163 @@
#include "ItemEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/SpriteEntity.h"
#include "Constants.h"
#include "MagnetEntity.h"
#include "WitchBlastGame.h"
#include <iostream>
#include <sstream>
ItemEntity::ItemEntity(enumItemType itemType, float x, float y)
: CollidingSpriteEntity(ImageManager::getImageManager()->getImage(itemType >= FirstEquipItem ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS), x, y, ITEM_WIDTH, ITEM_HEIGHT)
{
type = ENTITY_ITEM;
this->itemType = itemType;
frame = itemType;
if (itemType >= FirstEquipItem) frame = itemType - FirstEquipItem;
isMerchandise = false;
imagesProLine = 10;
setMap(game().getCurrentMap(), TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
isBeating = false;
}
void ItemEntity::setMerchandise(bool isMerchandise)
{
this->isMerchandise = isMerchandise;
}
bool ItemEntity::getMerchandise()
{
return isMerchandise;
}
int ItemEntity::getPrice()
{
return (items[itemType].price);
}
void ItemEntity::animate(float delay)
{
z = y + height;
CollidingSpriteEntity::animate(delay);
if (age > 0.7f) testSpriteCollisions();
if (isBeating)
{
timer -= delay;
if (timer <= 0.0f)
{
timer = HEART_BEAT_DELAY;
SoundManager::getSoundManager()->playSound(SOUND_HEART);
}
float sc;
if (timer > HEART_BEAT_DELAY - 0.25f)
{
sc = timer - HEART_BEAT_DELAY + 1.25f;
}
else
sc = 1.0f;
sprite.setScale(sc, sc);
}
if (itemType == itemBossHeart && !isBeating && game().getCurrentMap()->isCleared())
{
// start beating
isBeating = true;
timer = HEART_BEAT_DELAY;
}
}
-void ItemEntity::render(sf::RenderWindow* app)
+void ItemEntity::render(sf::RenderTarget* app)
{
// shadow
sprite.setTextureRect(sf::IntRect(9 * width, height, width, height));
app->draw(sprite);
// price
if (isMerchandise)
{
std::ostringstream oss;
oss << getPrice() << " $";
- game().Write(oss.str(), 16, x, y + 18.0f, ALIGN_CENTER, sf::Color(255, 255, 255));
+ game().Write(oss.str(), 16, x, y + 18.0f, ALIGN_CENTER, sf::Color(255, 255, 255), app);
}
CollidingSpriteEntity::render(app);
}
void ItemEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - height / 2;
boundingBox.height = height;
}
void ItemEntity::dying()
{
isDying = true;
}
void ItemEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (itemType == itemBossHeart && !game().getCurrentMap()->isCleared()) return;
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
if (collideWithEntity(entity))
{
if (playerEntity != NULL && !playerEntity->isDead())
{
if (isMerchandise == false || playerEntity->getGold() >= getPrice())
{
playerEntity->acquireItem(itemType);
if (isMerchandise) playerEntity->pay(getPrice());
dying();
if (items[itemType].generatesStance)
{
game().showArtefactDescription(itemType);
SpriteEntity* spriteItem = new SpriteEntity(
image,
playerEntity->getX(), playerEntity->getY() - 60.0f, ITEM_WIDTH, ITEM_HEIGHT);
spriteItem->setFrame(frame);
spriteItem->setImagesProLine(10);
spriteItem->setZ(z);
spriteItem->setLifetime(ACQUIRE_DELAY);
SpriteEntity* spriteStar = new SpriteEntity(
ImageManager::getImageManager()->getImage(IMAGE_STAR),
playerEntity->getX(), playerEntity->getY() - 60.0f);
spriteStar->setScale(4.0f, 4.0f);
spriteStar->setZ(z-1.0f);
spriteStar->setLifetime(ACQUIRE_DELAY);
spriteStar->setSpin(50.0f);
}
else
new MagnetEntity(x, y, playerEntity, itemType);
}
}
}
}
void ItemEntity::collideMapRight()
{
velocity.x = -velocity.x * 0.66f;
}
void ItemEntity::collideMapLeft()
{
velocity.x = -velocity.x * 0.66f;
}
void ItemEntity::collideMapTop()
{
velocity.y = -velocity.y * 0.66f;
}
void ItemEntity::collideMapBottom()
{
velocity.y = -velocity.y * 0.66f;
}
diff --git a/src/ItemEntity.h b/src/ItemEntity.h
index ed7533b..183dfe9 100644
--- a/src/ItemEntity.h
+++ b/src/ItemEntity.h
@@ -1,38 +1,38 @@
#ifndef ITEMENTITY_H
#define ITEMENTITY_H
#include "sfml_game/CollidingSpriteEntity.h"
#include "Items.h"
class ItemEntity : public CollidingSpriteEntity
{
public:
ItemEntity(enumItemType itemType, float x, float y);
void setMerchandise(bool isMerchandise);
bool getMerchandise();
int getPrice();
virtual void animate(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void calculateBB();
virtual void dying();
enumItemType getItemType() { return itemType; };
protected:
enumItemType itemType;
bool isMerchandise;
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
virtual void readCollidingEntity(CollidingSpriteEntity* entity);
private:
float timer;
bool isBeating;
};
#endif // ITEMENTITY_H
diff --git a/src/KingRatEntity.cpp b/src/KingRatEntity.cpp
index 75bfb17..15a405f 100644
--- a/src/KingRatEntity.cpp
+++ b/src/KingRatEntity.cpp
@@ -1,365 +1,367 @@
#include "KingRatEntity.h"
#include "GreenRatEntity.h"
#include "BoltEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
KingRatEntity::KingRatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_KING_RAT), x, y)
{
width = 128;
height = 128;
creatureSpeed = KING_RAT_SPEED;
velocity = Vector2D(creatureSpeed);
hp = KING_RAT_HP;
hpDisplay = hp;
hpMax = KING_RAT_HP;
meleeDamages = KING_RAT_DAMAGES;
type = ENTITY_ENNEMY_BOSS;
bloodColor = bloodRed;
shadowFrame = 4;
frame = 0;
sprite.setOrigin(64.0f, 64.0f);
state = 0;
timer = 2.0f + (rand() % 40) / 10.0f;
age = 0.0f;
berserkDelay = 1.0f + rand()%5 * 0.1f;
hasBeenBerserk = false;
specialState[SpecialStateIce].resistance = ResistanceImmune;
}
void KingRatEntity::animate(float delay)
{
float timerMult = 1.0f;
if (hp <= hpMax / 4)
{
creatureSpeed = KING_RAT_SPEED * 1.4f;
timerMult = 0.7f;
}
else if (hp <= hpMax / 2)
{
creatureSpeed = KING_RAT_SPEED * 1.2f;
timerMult = 0.85f;
}
else
{
creatureSpeed = KING_RAT_SPEED;
}
if (state == 5)
{
velocity.x *= 0.965f;
velocity.y *= 0.965f;
}
else
{
if (velocity.x > 0.1f) sprite.setScale(-1.0f, 1.0f);
else if (velocity.x < -0.1f) sprite.setScale(1.0f, 1.0f);
}
timer -= delay;
if (timer <= 0.0f)
{
if (state == 0)
{
state = 1;
// generate rats
generateGreenRats();
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_1);
timer = 2.0f;
velocity.x = 0.0f;
velocity.y = 0.0f;
}
else if (state == 1) // generate rats
{
// to normal or berserk
if (hp < hpMax / 4 && !hasBeenBerserk)
{
hasBeenBerserk = true;
timer = 12.0f;
state = 6;
velocity = Vector2D(KING_RAT_BERSERK_SPEED);
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 2;
}
}
else if (state == 2) // normal -> rush
{
state = 3;
// angry
timer = 2.0f;
velocity.x = 0.0f;
velocity.y = 0.0f;
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else if (state == 3) // normal -> rush
{
state = 4;
// rush
timer = 12.0f;
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
if (game().getPlayer()->getY() > y)
setVelocity(Vector2D(sin(angle) * KING_RAT_RUNNING_SPEED,
cos(angle) * KING_RAT_RUNNING_SPEED));
else
setVelocity(Vector2D(-sin(angle) * KING_RAT_RUNNING_SPEED,
-cos(angle) * KING_RAT_RUNNING_SPEED));
}
else if (state == 5) // wall impact
{
// to normal or berserk
if (hp < hpMax / 4 && !hasBeenBerserk)
{
hasBeenBerserk = true;
timer = 12.0f;
state = 6;
velocity = Vector2D(KING_RAT_BERSERK_SPEED);
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 0;
}
}
else if (state == 6)
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 0;
}
}
if (state == 6)
{
berserkDelay -= delay;
if (berserkDelay <= 0.0f)
{
berserkDelay = 0.8f + (rand()%10) / 10.0f;
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(),KING_RAT_BERSERK_SPEED ));
}
}
frame = 0;
if (state == 1)
frame = 3;
else if (state == 3 || state == 6)
{
frame = 3; //0;
int r = ((int)(age * 10.0f)) % 2;
if (r == 0)
sprite.setScale(-1.0f, 1.0f);
else
sprite.setScale(1.0f, 1.0f);
}
else if (state == 4)
{
int r = ((int)(age * 7.5f)) % 4;
if (r == 1) frame = 1;
else if (r == 3) frame = 2;
}
else if (state == 5)
{
frame = 0;
}
else
{
int r = ((int)(age * 5.0f)) % 4;
if (r == 1) frame = 1;
else if (r == 3) frame = 2;
}
EnnemyEntity::animate(delay);
}
bool KingRatEntity::hurt(int damages)
{
hurting = true;
hurtingDelay = HURTING_DELAY;
if (state == 6)
hp -= damages / 4;
else
hp -= damages;
if (hp <= 0)
{
hp = 0;
dying();
}
return true;
}
void KingRatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + 25;
boundingBox.width = width - 50;
boundingBox.top = (int)y - height / 2 + 25;
boundingBox.height = height - 35;
}
void KingRatEntity::afterWallCollide()
{
if (state == 4)
{
state = 5;
timer = 1.4f;
velocity.x *= 0.75f;
velocity.y *= 0.75f;
SoundManager::getSoundManager()->playSound(SOUND_BIG_WALL_IMPACT);
+ game().makeShake(0.5f);
}
}
void KingRatEntity::collideMapRight()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void KingRatEntity::collideMapLeft()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void KingRatEntity::collideMapTop()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void KingRatEntity::collideMapBottom()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void KingRatEntity::dying()
{
isDying = true;
SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y, 128, 128);
deadRat->setZ(OFFSET_Y);
deadRat->setFrame(FRAME_CORPSE_KING_RAT - FRAME_CORPSE_KING_RAT);
deadRat->setType(ENTITY_CORPSE);
for (int i = 0; i < 10; i++) game().generateBlood(x, y, bloodColor);
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_DIE);
ItemEntity* newItem = new ItemEntity(itemBossHeart, x, y);
//newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
void KingRatEntity::generateGreenRats()
{
for (int i = 0; i < 5; i++)
{
float xr = x + -100 + rand() % 200;
float yr = y + -100 + rand() % 200;
if (xr > OFFSET_X + TILE_WIDTH * 1.5f && xr < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 2)
&& yr > OFFSET_Y + TILE_HEIGHT * 1.5f && yr < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 2))
{
new GreenRatEntity(xr, yr);
}
else
i--;
}
}
-void KingRatEntity::render(sf::RenderWindow* app)
+void KingRatEntity::render(sf::RenderTarget* app)
{
EnnemyEntity::render(app);
if (state == 6)
{
int r = ((int)(age *12.0f)) % 2;
if (r == 0)
sprite.setTextureRect(sf::IntRect(1 * width, 1 * height, width, height));
else
sprite.setTextureRect(sf::IntRect(2 * width, 1 * height, -width, height));
sprite.setPosition(x, y);
sprite.setColor(sf::Color(255, 255, 255, 190));
app->draw(sprite);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / KING_RAT_HP;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
game().Write( "Rat King",
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f,
ALIGN_LEFT,
- sf::Color(255, 255, 255));
+ sf::Color(255, 255, 255),
+ app);
}
void KingRatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
inflictsRecoilTo(entity);
}
}
void KingRatEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
if (state == 4 || state == 6)
{
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(targetEntity->getX(), targetEntity->getY()), KING_RAT_RUNNING_RECOIL );
targetEntity->giveRecoil(true, recoilVector, 1.0f);
}
}
diff --git a/src/KingRatEntity.h b/src/KingRatEntity.h
index c44ec51..f919856 100644
--- a/src/KingRatEntity.h
+++ b/src/KingRatEntity.h
@@ -1,34 +1,34 @@
#ifndef KINGRATSPRITE_H
#define KINGRATSPRITE_H
#include "EnnemyEntity.h"
#include "PlayerEntity.h"
class KingRatEntity : public EnnemyEntity
{
public:
KingRatEntity(float x, float y);
virtual void animate(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void calculateBB();
virtual void inflictsRecoilTo(BaseCreatureEntity* targetEntity);
protected:
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
void afterWallCollide();
virtual bool hurt(int damages);
void generateGreenRats();
virtual void collideWithEnnemy(GameEntity* collidingEntity);
virtual void dying();
private:
float timer;
float berserkDelay;
int state;
bool hasBeenBerserk;
};
#endif // KINGRATSPRITE_H
diff --git a/src/PlayerEntity.cpp b/src/PlayerEntity.cpp
index 44cfdc6..1444438 100644
--- a/src/PlayerEntity.cpp
+++ b/src/PlayerEntity.cpp
@@ -1,828 +1,828 @@
#include "PlayerEntity.h"
#include "BoltEntity.h"
#include "EnnemyBoltEntity.h"
#include "ItemEntity.h"
#include "FairyEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include "TextEntity.h"
#include <iostream>
#include <sstream>
PlayerEntity::PlayerEntity(float x, float y)
: BaseCreatureEntity (ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE), x, y, 80, 128)
{
currentFireDelay = -1.0f;
canFirePlayer = true;
type = ENTITY_PLAYER;
imagesProLine = 8;
playerStatus = playerStatusPlaying;
hp = INITIAL_PLAYER_HP;
hpDisplay = hp;
hpMax = INITIAL_PLAYER_HP;
gold = 0;
boltLifeTime = INITIAL_BOLT_LIFE;
specialBoltTimer = -1.0f;
bloodColor = bloodRed;
// init the equipment (to empty)
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++) equip[i] = false;
collidingDirection = 0;
// init the shots (to none)
for (int i = 0; i < SPECIAL_SHOT_SLOTS; i++) specialShots[i] = ShotTypeStandard;
specialShotIndex = 0;
needInitShotType = false;
computePlayer();
firingDirection = 5;
facingDirection = 2;
}
void PlayerEntity::moveTo(float newX, float newY)
{
float dx = newX - x;
float dy = newY - y;
x = newX;
y = newY;
if (equip[EQUIP_FAIRY])
{
fairy->setX(fairy->getX() + dx);
fairy->setY(fairy->getY() + dy);
}
}
int PlayerEntity::getFacingDirection()
{
return facingDirection;
}
float PlayerEntity::getPercentFireDelay()
{
if (canFirePlayer) return 1.0f;
else return (1.0f - currentFireDelay / fireDelay);
}
int PlayerEntity::getCollidingDirection()
{
return collidingDirection;
}
PlayerEntity::playerStatusEnum PlayerEntity::getPlayerStatus()
{
return playerStatus;
}
void PlayerEntity::setPlayerStatus(PlayerEntity::playerStatusEnum playerStatus)
{
this->playerStatus = playerStatus;
}
bool PlayerEntity::isDead()
{
return playerStatus==playerStatusDead;
}
void PlayerEntity::setEntering()
{
playerStatus = playerStatusEntering;
}
void PlayerEntity::setLeavingLevel()
{
playerStatus = playerStatusGoingUp;
}
void PlayerEntity::pay(int price)
{
gold -= price;
if (gold < 0) gold = 0;
SoundManager::getSoundManager()->playSound(SOUND_PAY);
}
void PlayerEntity::animate(float delay)
{
// shot timer
if (specialBoltTimer >= 0.0f)
{
specialBoltTimer -= delay;
if (specialBoltTimer <= 0.0f)
{
if (getShotType() == ShotTypeIce) SoundManager::getSoundManager()->playSound(SOUND_ICE_CHARGE);
}
}
// rate of fire
if (!canFirePlayer)
{
currentFireDelay -= delay;
canFirePlayer = (currentFireDelay <= 0.0f);
}
// acquisition animation
if (playerStatus == playerStatusAcquire)
{
acquireDelay -= delay;
if (acquireDelay <= 0.0f)
{
if (acquiredItem >= FirstEquipItem)
{
equip[acquiredItem - FirstEquipItem] = true;
if (acquiredItem == ItemFairy) //(int)EQUIP_FAIRY)
fairy = new FairyEntity(x, y - 50.0f, this);
if (items[acquiredItem].specialShot != (ShotTypeStandard))
registerSpecialShot(acquiredItem);
computePlayer();
}
else
{
if (acquiredItem == itemBossHeart)
{
int hpBonus = 2 + rand() % 4;
hpMax += hpBonus;
hp += hpBonus;
hpDisplay += hpBonus;
SoundManager::getSoundManager()->playSound(SOUND_EAT);
std::ostringstream oss;
oss << "HP Max +" << hpBonus;
TextEntity* text = new TextEntity(oss.str(), 14, x, y - 50.0f);
text->setColor(TextEntity::COLOR_GREEN);
text->setLifetime(2.0f);
text->setWeight(-100.0f);
}
}
playerStatus = playerStatusPlaying;
}
}
// unlocking animation
else if (playerStatus == playerStatusUnlocking)
{
acquireDelay -= delay;
if (acquireDelay <= 0.0f)
{
playerStatus = playerStatusPlaying;
}
}
if (playerStatus == playerStatusDead)
velocity = Vector2D(0.0f, 0.0f);
else
testSpriteCollisions();
collidingDirection = 0;
BaseCreatureEntity::animate(delay);
if (firingDirection != 5)
facingDirection = firingDirection;
firingDirection = 5;
if (isMoving())
{
frame = ((int)(age * 5.0f)) % 4;
if (frame == 3) frame = 1;
SoundManager::getSoundManager()->playSound(SOUND_STEP);
}
else if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
frame = 0;
else if (playerStatus == playerStatusDead)
frame = 0;
else // standing
{
frame = 1;
}
if (x < OFFSET_X)
game().moveToOtherMap(4);
else if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
game().moveToOtherMap(6);
else if (y < OFFSET_Y)
game().moveToOtherMap(8);
else if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 15)
game().moveToOtherMap(2);
if (playerStatus == playerStatusEntering)
{
if (boundingBox.left > OFFSET_X + TILE_WIDTH
&& (boundingBox.left + boundingBox.width) < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1)
&& boundingBox.top > OFFSET_Y + TILE_HEIGHT
&& (boundingBox.top + boundingBox.height) < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1))
{
playerStatus = playerStatusPlaying;
game().closeDoors();
}
}
if (playerStatus == playerStatusDead)
{
z = OFFSET_Y - 2;
}
}
-void PlayerEntity::renderHead(sf::RenderWindow* app)
+void PlayerEntity::renderHead(sf::RenderTarget* app)
{
if (playerStatus != playerStatusDead)
{
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, 0, width, height));
app->draw(sprite);
if (equip[EQUIP_ENCHANTER_HAT])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
sprite.setTextureRect(sf::IntRect( 0, 0, width, height));
else
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, 0, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
}
}
-void PlayerEntity::renderBody(sf::RenderWindow* app)
+void PlayerEntity::renderBody(sf::RenderTarget* app)
{
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height, width, height));
app->draw(sprite);
if (equip[EQUIP_CONCENTRATION_AMULET])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_COLLAR));
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
sprite.setTextureRect(sf::IntRect( 0, 0, width, height));
else
sprite.setTextureRect(sf::IntRect( (spriteDx / 3) * width, 0, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
if (equip[EQUIP_LEATHER_BELT])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
}
-void PlayerEntity::renderHands(sf::RenderWindow* app)
+void PlayerEntity::renderHands(sf::RenderTarget* app)
{
if (equip[EQUIP_VIBRATION_GLOVES]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height * 3, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
-void PlayerEntity::renderFeet(sf::RenderWindow* app)
+void PlayerEntity::renderFeet(sf::RenderTarget* app)
{
if (equip[EQUIP_LEATHER_BOOTS]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height * 2, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
-void PlayerEntity::renderStaff(sf::RenderWindow* app)
+void PlayerEntity::renderStaff(sf::RenderTarget* app)
{
if (equip[EQUIP_MAHOGANY_STAFF]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
int xSnake, ySnake;
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
{
sprite.setTextureRect(sf::IntRect( 12 * width, height * 4, width, height));
app->draw(sprite);
xSnake = 13 * width;
ySnake = height * 4;
}
else if (isMoving() || firingDirection != 5)
{
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, height * 4, width, height));
app->draw(sprite);
xSnake = (frame / 3 + spriteDx + 1) * width;
ySnake = height * 4;
}
else
{
sprite.setTextureRect(sf::IntRect( (spriteDx / 3 + 14) * width, height * 4, width, height));
app->draw(sprite);
xSnake = (spriteDx / 3 + 14) * width;
ySnake = 0;
}
if (equip[EQUIP_BLOOD_SNAKE])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( xSnake, ySnake, width, height));
app->draw(sprite);
}
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
-void PlayerEntity::render(sf::RenderWindow* app)
+void PlayerEntity::render(sf::RenderTarget* app)
{
sprite.setPosition(x, y);
spriteDx = 0;
if (facingDirection == 8) spriteDx = 3;
if (facingDirection == 4) spriteDx = 6;
if (facingDirection == 6) spriteDx = 9;
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking) spriteDx = 12;
if (playerStatus == playerStatusDead)
{
spriteDx = 13;
// blood
sprite.setTextureRect(sf::IntRect( width, 0, width, height));
app->draw(sprite);
}
else
{
// shadow
sprite.setTextureRect(sf::IntRect( 2 * width, 0, width, height));
app->draw(sprite);
}
if (facingDirection == 8 || facingDirection == 4)
{
renderStaff(app);
renderHead(app);
renderBody(app);
renderFeet(app);
renderHands(app);
}
else
{
renderBody(app);
renderHead(app);
renderFeet(app);
renderStaff(app);
renderHands(app);
}
// ice gem
if (getShotType() == ShotTypeIce)
{
int fade;
if (specialBoltTimer <= 0.0f) fade = 255;
else fade = ((STATUS_FROZEN_BOLT_DELAY - specialBoltTimer) / STATUS_FROZEN_BOLT_DELAY) * 128;
sprite.setTextureRect(sf::IntRect(320, 0, 20, 20));
sprite.setColor(sf::Color(255, 255, 255, fade));
if (isMoving())
{
if (facingDirection == 2 )
sprite.setPosition(x + 16, y + 36);
else if (facingDirection == 8 )
sprite.setPosition(x + 43, y + 36);
else if (facingDirection == 4 )
sprite.setPosition(x - 3 , y + 41);
else
sprite.setPosition(x + 63, y + 41);
}
else if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
{
sprite.setPosition(x + 57, y + 18);
}
else
{
if (facingDirection == 2 )
sprite.setPosition(x + 16, y + 36);
else if (facingDirection == 8 )
sprite.setPosition(x + 43, y + 29);
else if (facingDirection == 4 )
sprite.setPosition(x + 13, y + 35);
else
sprite.setPosition(x + 46, y + 35);
}
sf::RenderStates r;
r.blendMode = sf::BlendAdd;
app->draw(sprite, r);
sprite.setPosition(x, y);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
}
void PlayerEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - height / 2;
boundingBox.height = height;
boundingBox.left += 25;
boundingBox.width -= 50;
boundingBox.top += 80.0f;
boundingBox.height = boundingBox.height - 90.0f;
}
void PlayerEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (playerStatus == playerStatusDead) return;
EnnemyBoltEntity* boltEntity = dynamic_cast<EnnemyBoltEntity*>(entity);
if (collideWithEntity(entity))
{
if (boltEntity != NULL && !boltEntity->getDying())
{
boltEntity->collide();
hurt(boltEntity->getDamages(), ShotTypeStandard);
game().generateBlood(x, y, bloodColor);
}
}
}
void PlayerEntity::move(int direction)
{
if (playerStatus == playerStatusPlaying)
{
float speedx = 0.0f, speedy = 0.0f;
if (direction == 1 || direction == 4 || direction == 7)
speedx = - creatureSpeed;
else if (direction == 3 || direction == 6 || direction == 9)
speedx = creatureSpeed;
if (direction == 1 || direction == 2 || direction == 3)
speedy = creatureSpeed;
else if (direction == 7 || direction == 8 || direction == 9)
speedy = - creatureSpeed;
setVelocity(Vector2D(speedx, speedy));
{
switch (direction)
{
case 8: facingDirection = 8; break;
case 2: facingDirection = 2; break;
case 4: facingDirection = 4; break;
case 6: facingDirection = 6; break;
case 7: if (facingDirection != 4 && facingDirection != 8) facingDirection = 4; break;
case 1: if (facingDirection != 4 && facingDirection != 2) facingDirection = 4; break;
case 9: if (facingDirection != 6 && facingDirection != 8) facingDirection = 6; break;
case 3: if (facingDirection != 6 && facingDirection != 2) facingDirection = 6; break;
}
}
}
}
bool PlayerEntity::isMoving()
{
if (velocity.x < -1.0f || velocity.x > 1.0f) return true;
if (velocity.y < -1.0f || velocity.y > 1.0f) return true;
return false;
}
bool PlayerEntity::isEquiped(int eq)
{
return equip[eq];
}
void PlayerEntity::setEquiped(int item, bool eq)
{
equip[item] = eq;
if (eq && item == (int)EQUIP_FAIRY)
{
fairy = new FairyEntity(x, y - 50.0f, this);
}
computePlayer();
}
void PlayerEntity::generateBolt(float velx, float vely)
{
enumShotType boltType = ShotTypeStandard;
switch (getShotType())
{
case ShotTypeIce:
if (getShotType() == ShotTypeIce)
{
if (specialBoltTimer <= 0.0f)
{
boltType = ShotTypeIce;
needInitShotType = true;
}
else boltType = ShotTypeStandard;
}
break;
case ShotTypeStandard:
case ShotTypeIllusion:
case ShotTypeStone:
case ShotTypeLightning:
boltType = getShotType(); break;
}
BoltEntity* bolt = new BoltEntity(ImageManager::getImageManager()->getImage(1), x, y + 30, boltLifeTime, boltType);
bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
bolt->setDamages(fireDamages);
bolt->setVelocity(Vector2D(velx, vely));
}
void PlayerEntity::fire(int direction)
{
firingDirection = direction;
if (equip[EQUIP_FAIRY] && playerStatus != playerStatusDead)
fairy->fire(direction, map);
if (canFirePlayer && playerStatus != playerStatusDead)
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_STANDARD);
if (equip[EQUIP_BOOK_DUAL])
{
float shoot_angle = 0.2f;
if ((direction == 4 && velocity.x < -1.0f) || (direction == 6 && velocity.x > 1.0f)
|| (direction == 8 && velocity.y < -1.0f) || (direction == 2 && velocity.y > 1.0f))
shoot_angle = 0.1f;
else if ((direction == 6 && velocity.x < -1.0f) || (direction == 4 && velocity.x > 1.0f)
|| (direction == 2 && velocity.y < -1.0f) || (direction == 8 && velocity.y > 1.0f))
shoot_angle = 0.35f;
if (equip[EQUIP_VIBRATION_GLOVES]) shoot_angle += (1000 - rand() % 2000) * 0.0001f;
switch(direction)
{
case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
generateBolt(-fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
generateBolt(fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle));
generateBolt(-fireVelocity * sin(shoot_angle), - fireVelocity * cos(shoot_angle));break;
case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));
generateBolt(-fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));break;
}
}
else
{
if (equip[EQUIP_VIBRATION_GLOVES])
{
float shoot_angle = (1000 - rand() % 2000) * 0.0001f;
switch(direction)
{
case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle)); break;
case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle)); break;
}
}
else
{
switch(direction)
{
case 4: generateBolt(-fireVelocity, 0.0f); break;
case 6: generateBolt(fireVelocity, 0.0f); break;
case 8: generateBolt(0.0f, -fireVelocity); break;
case 2: generateBolt(0.0f, fireVelocity); break;
}
}
}
canFirePlayer = false;
currentFireDelay = fireDelay;
if (needInitShotType) initShotType();
}
}
bool PlayerEntity::canMove()
{
return (playerStatus == playerStatusPlaying);
}
bool PlayerEntity::hurt(int damages, enumShotType hurtingType)
{
if (!hurting)
{
SoundManager::getSoundManager()->playSound(SOUND_PLAYER_HIT);
BaseCreatureEntity::hurt(damages, ShotTypeStandard);
game().generateBlood(x, y, bloodColor);
game().generateBlood(x, y, bloodColor);
return true;
}
return false;
}
void PlayerEntity::loseItem(enumItemType itemType, bool isEquip)
{
CollidingSpriteEntity* itemSprite
= new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(isEquip ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS), x, y, 32, 32);
itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
itemSprite->setZ(OFFSET_Y - 1);
itemSprite->setFrame(itemType);
itemSprite->setImagesProLine(10);
itemSprite->setType(ENTITY_BLOOD);
itemSprite->setVelocity(Vector2D(rand()%450));
itemSprite->setViscosity(0.95f);
itemSprite->setSpin( (rand() % 700) - 350.0f);
}
void PlayerEntity::dying()
{
playerStatus = playerStatusDead;
hp = 0;
SoundManager::getSoundManager()->playSound(SOUND_PLAYER_DIE);
setVelocity(Vector2D(0.0f, 0.0f));
int i;
for (i = 0; i < gold; i++) loseItem(ItemCopperCoin, false);
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
if (equip[i]) loseItem(enumItemType(i), true);
for (i = 0; i < 8; i++) game().generateBlood(x, y, bloodColor);
CollidingSpriteEntity* itemSprite
= new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE), x, y, 80, 120);
itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
itemSprite->setZ(OFFSET_Y - 1);
itemSprite->setImagesProLine(14);
itemSprite->setFrame(13);
itemSprite->setType(ENTITY_BLOOD);
itemSprite->setVelocity(Vector2D(rand()%450));
itemSprite->setViscosity(0.95f);
itemSprite->setSpin( (rand() % 700) - 350.0f);
}
void PlayerEntity::acquireItem(enumItemType type)
{
if (items[type].generatesStance) acquireStance(type);
else switch (type)
{
case ItemCopperCoin: gold++;
SoundManager::getSoundManager()->playSound(SOUND_COIN_PICK_UP);
break;
case ItemSilverCoin: gold = gold + 5; break;
case ItemGoldCoin: gold = gold + 10; break;
case itemHealth: hp += 15;
SoundManager::getSoundManager()->playSound(SOUND_DRINK);
if (hp > hpMax) hp = hpMax; break;
default: break;
}
}
void PlayerEntity::computePlayer()
{
float boltLifeTimeBonus = 1.0f;
float fireDelayBonus = 1.0f;
float creatureSpeedBonus = 1.0f;
float fireVelocityBonus = 1.0f;
float fireDamagesBonus = 1.0f;
if (equip[EQUIP_VIBRATION_GLOVES]) fireDelayBonus -= 0.10f;
if (equip[EQUIP_ENCHANTER_HAT]) fireDelayBonus -= 0.2f;
if (equip[EQUIP_LEATHER_BELT]) fireDelayBonus -= 0.15f;
if (equip[EQUIP_LEATHER_BOOTS]) creatureSpeedBonus += 0.15f;
if (equip[EQUIP_BOOK_DUAL]) fireDelayBonus += 0.6f;
if (equip[EQUIP_CONCENTRATION_AMULET]) boltLifeTimeBonus += 0.5f;
if (equip[EQUIP_MAHOGANY_STAFF])
{
fireVelocityBonus += 0.15f;
fireDamagesBonus += 0.5f;
}
if (equip[EQUIP_BLOOD_SNAKE]) fireDamagesBonus += 1.0f;
//if (getShotType()) boltType = BoltIce;
fireDelay = INITIAL_PLAYER_FIRE_DELAY * fireDelayBonus;
creatureSpeed = INITIAL_PLAYER_SPEED * creatureSpeedBonus;
fireVelocity = INITIAL_BOLT_VELOCITY * fireVelocityBonus;
fireDamages = INITIAL_BOLT_DAMAGES * fireDamagesBonus;
boltLifeTime = INITIAL_BOLT_LIFE * boltLifeTimeBonus;
// gems
if (getShotType() == ShotTypeIllusion) fireDamages *= 0.8f;
}
void PlayerEntity::acquireStance(enumItemType type)
{
velocity.x = 0.0f;
velocity.y = 0.0f;
playerStatus = playerStatusAcquire;
acquireDelay = ACQUIRE_DELAY;
acquiredItem = (enumItemType)(type);
SoundManager::getSoundManager()->playSound(SOUND_BONUS);
}
void PlayerEntity::collideMapRight()
{
collidingDirection = 6;
}
void PlayerEntity::collideMapLeft()
{
collidingDirection = 4;
}
void PlayerEntity::collideMapTop()
{
collidingDirection = 8;
}
void PlayerEntity::collideMapBottom()
{
collidingDirection = 2;
}
void PlayerEntity::useBossKey()
{
velocity.x = 0.0f;
velocity.y = 0.0f;
playerStatus = playerStatusUnlocking;
acquireDelay = UNLOCK_DELAY;
acquiredItem = (enumItemType)(type - FirstEquipItem);
SoundManager::getSoundManager()->playSound(SOUND_BONUS);
equip[EQUIP_BOSS_KEY] = false;
SpriteEntity* spriteItem = new SpriteEntity(
ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP),
x, y - 60.0f, ITEM_WIDTH, ITEM_HEIGHT);
spriteItem->setFrame(EQUIP_BOSS_KEY);
spriteItem->setZ(z);
spriteItem->setLifetime(UNLOCK_DELAY);
}
enumShotType PlayerEntity::getShotType()
{
return specialShots[specialShotIndex];
}
int PlayerEntity::getShotIndex()
{
return specialShotIndex;
}
void PlayerEntity::setShotIndex(int index)
{
specialShotIndex = index;
}
enumShotType PlayerEntity::getShotType(int slot)
{
return specialShots[slot];
}
void PlayerEntity::setShotType(int slot, enumShotType shotType)
{
specialShots[slot] = shotType;
}
void PlayerEntity::registerSpecialShot(int item)
{
bool found = false;
int index = 1;
while (index < SPECIAL_SHOT_SLOTS && !found)
{
found = specialShots[index] == ShotTypeStandard;
if (!found) index++;
}
if (found)
{
this->specialShots[index] = items[item].specialShot;
specialShotIndex = index;
initShotType();
}
}
void PlayerEntity::selectNextShotType()
{
int index = specialShotIndex + 1;
bool found = false;
while (index < SPECIAL_SHOT_SLOTS && !found)
{
if (specialShots[index] == ShotTypeStandard) index++;
else found = true;
}
if (found)
{
specialShotIndex = index;
initShotType();
}
else
specialShotIndex = 0;
SoundManager::getSoundManager()->playSound(SOUND_SHOT_SELECT);
computePlayer();
}
void PlayerEntity::initShotType()
{
specialBoltTimer = STATUS_FROZEN_BOLT_DELAY;
needInitShotType = false;
}
diff --git a/src/PlayerEntity.h b/src/PlayerEntity.h
index 9ebf876..b8ae01e 100644
--- a/src/PlayerEntity.h
+++ b/src/PlayerEntity.h
@@ -1,409 +1,409 @@
#ifndef PLAYERSPRITE_H
#define PLAYERSPRITE_H
#include "BaseCreatureEntity.h"
#include "ItemEntity.h"
#include "Constants.h"
class FairyEntity;
/*! \class PlayerEntity
* \brief Class for the player
*
* It contains the game logic of the player and the rendering.
*/
class PlayerEntity : public BaseCreatureEntity
{
public:
/*!
* \brief Constructor
*
* Constructor of the PlayerEntity class.
*
* \param x : x position of the player
* \param y : y position of the player
*/
PlayerEntity(float x, float y);
/*!
* \brief updates the player
*
* Updates the player.
* Called in the game loop.
*
* \param delay : elapsed time since the last call
*/
virtual void animate(float delay);
/*!
* \brief render the player
*
* Render the player.
* Called in the game loop.
*
* \param app : Rendering target
*/
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
/*!
* \brief Moves the player to another place
*
* Moves the player to another place.
* Called when changing room, the "familiers" will move too.
*
* \param newX : target x position of the player
* \param newY : target y position of the player
*/
void moveTo(float newX, float newY);
/*!
* \brief returns the direction the player is facing
*
* Return the direction the player is facing.
* Use to know in which direction he has to fire with the "one button" gameplay.
*
* \return : the facing direction. 4 = left, 8 = north, 6 = right, 2 = south
*/
int getFacingDirection();
/*!
* \brief update the bounding box
*
* Update the bounding box of the player.
* Used before testing collision.
*/
virtual void calculateBB();
/*!
* \brief Moves the player in the given direction
*
* Moves the player in the given direction.
*
* \param direction : direction of the new map. Numeric pad, diagonals included : 4 = left, 8 = north, 7 = north-west...
*/
void move(int direction);
/*!
* \brief Fires in the given direction
*
* Fires the player in the given direction.
*
* \param direction : direction of the new map. 4 = left, 8 = north, 6 = right, 2 = south
*/
void fire(int direction);
/*!
* \brief returns if the player is moving or not
*
* Returns if the player is moving or not.
*
* \return : True if the player is moving
*/
bool isMoving();
/*!
* \brief returns if an item is equipped or not
*
* Returns if an item is equipped or not.
*
* \param eq : the equip item ID
* \return : True if the item is in possession of the player
*/
bool isEquiped(int eq);
/*!
* \brief updates the equipment of the player
*
* Updates the equipment of the player.
*
* \param item : the equip item ID
* \param eq : True if the item has to be equipped
*/
void setEquiped(int item, bool eq);
/*!
* \brief updates the entering status of the player
*
* Updates the entering status of the player.
* Used when the player is entering in a not yet cleared room.
*/
void setEntering();
/*!
* \brief updates the status of the player to going up
*
* Updates the status of the player to going up.
* Used when the player is leaving a level.
*/
void setLeavingLevel();
/*!
* \brief returns if the player can move or not
*
* Returns if the player can move or not.
*
* \return : True if the player can move
*/
bool canMove();
/*!
* \brief called when the player is dying
*
* Called when the player is dying (HP <= 0).
*/
virtual void dying();
/*!
* \brief hurts the player
*
* Hurts the player.
* Calld when the player is hurt, usually when colliding with a monster or a missile.
*
* \param damages : the inflicted damages
* \param hurtingType : damages type
* \return : True if the player has been hurt
*/
virtual bool hurt(int damages, enumShotType hurtingType);
/*!
* \brief returns if the player is dead or not
*
* Returns if the player is dead or not.
*
* \return : True if the player is dead
*/
bool isDead();
/*!
* \brief returns the fire delay percentage
*
* Returns the fire delay percentage.
* Used (currently) when displaying the blue bar in the HUD.
*
* \return : the percentage (between 0.0f for empty to 1.0 for full)
*/
float getPercentFireDelay();
/*!
* \brief called when the player get an item
*
* Called when the player get an item.
* When the item is an equip item, he starts an "acquiring stance".
*
* \param type : item ID
*/
void acquireItem(enumItemType type);
/*!
* \brief makes the player drop an item
*
* Makes the player drop an item.
* Called when the player dies.
*
* \param itemType : item ID
* \param isEquip : True if it's an equip item (not the same texture)
*/
void loseItem(enumItemType itemType, bool isEquip);
/*!
* \brief starts the acquire stance
*
* Starts the acquire stance.
* Called when the player get an equip object. The item is "highlighted" and a description is displayed.
*
* \param type : item ID
*/
void acquireStance(enumItemType type);
/*!
* \brief starts the opening stance
*
* Starts the boss door opening animation.
* Remove the key from the inventory.
*/
void useBossKey();
/*!
* \brief accessor on the gold
*
* Accessor on the gold.
*
* \return : the gold
*/
int getGold() {return gold; }
/*!
* \brief mutator on the gold
*
* Mutator on the gold.
*
* \param gold : the new gold value
*/
void setGold(int gold) { this->gold = gold; }
/*!
* \brief pay some gold
*
* Pay some gold. Usually in shops.
*
* \param gold : the price to pay
*/
void pay(int price);
/** Player status enum
* The different player states.
*/
enum playerStatusEnum
{
playerStatusPlaying, /**< Player is playing "normally" */
playerStatusEntering, /**< Player is entering a not yet cleared room (walking is forced) */
playerStatusAcquire, /**< Player is under acquiring stance */
playerStatusUnlocking, /**< Player is under unlocking stance */
playerStatusGoingUp, /**< Player goes to next level */
playerStatusDead /**< Player RIP */
};
/*!
* \brief accessor on the player status
*
* Accessor on the player status.
*
* \return : the player status
*/
playerStatusEnum getPlayerStatus();
/*!
* \brief mutator on the player status
*
* Mutator on the player status.
*
* \param player status : the new player status value
*/
void setPlayerStatus(playerStatusEnum playerStatus);
/*!
* \brief accessor on the colliding direction
*
* Accessor on the colliding direction.
*
* \return : the colliding direction
*/
int getCollidingDirection();
/*!
* \brief register a new special shot and select it
*
* Register a new special shot and select it.
*
* \param item : Item which provides the shot
*/
void registerSpecialShot(int item);
/*!
* \brief accessor on current shot type
*
* Accessor on the current shot type.
*
* \return : the current shot type
*/
enumShotType getShotType();
/*!
* \brief accessor on current shot index
*
* Accessor on the current shot index.
*
* \return : the current shot index
*/
int getShotIndex();
/*!
* \brief mutator on the shot index
*
* Mutator on the shot index.
*
* \param index : the new shot index
*/
void setShotIndex(int index);
/*!
* \brief accessor on current shot type of a slot
*
* Accessor on the current shot type of a slot.
*
* \param slot : The slot number
* \return : the current shot type
*/
enumShotType getShotType(int slot);
/*!
* \brief mutator on a shot slot
*
* Mutator on a shot slot.
*
* \param index : the shot index
* \param shotType : the shot type to set
*/
void setShotType(int slot, enumShotType shotType);
/*!
* \brief select the next shot type
*
* Select the next shot type.
*/
void selectNextShotType();
protected:
void computePlayer();
virtual void readCollidingEntity(CollidingSpriteEntity* entity);
void generateBolt(float velx, float vely);
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
private:
int fireDamages;
float fireVelocity;
float fireDelay;
float currentFireDelay;
float boltLifeTime;
int gold;
bool canFirePlayer;
playerStatusEnum playerStatus;
float acquireDelay;
enumItemType acquiredItem;
bool equip[NUMBER_EQUIP_ITEMS];
float specialBoltTimer;
enumShotType specialShots[SPECIAL_SHOT_SLOTS];
int specialShotIndex;
bool needInitShotType;
int collidingDirection; /*!< Colliding direction (4, 8, 6, 2) to detect collision with closed doors */
int firingDirection;
FairyEntity* fairy;
int spriteDx;
- void renderHead(sf::RenderWindow* app);
- void renderBody(sf::RenderWindow* app);
- void renderHands(sf::RenderWindow* app);
- void renderFeet(sf::RenderWindow* app);
- void renderStaff(sf::RenderWindow* app);
+ void renderHead(sf::RenderTarget* app);
+ void renderBody(sf::RenderTarget* app);
+ void renderHands(sf::RenderTarget* app);
+ void renderFeet(sf::RenderTarget* app);
+ void renderStaff(sf::RenderTarget* app);
/*!
* \brief init the current shot type.
*
* Init the current shot type.
* Called when the player get a new shot, or after a switch.
*/
void initShotType();
};
#endif // PLAYERSPRITE_H
diff --git a/src/PnjEntity.cpp b/src/PnjEntity.cpp
index fe9b94d..fd2ca43 100644
--- a/src/PnjEntity.cpp
+++ b/src/PnjEntity.cpp
@@ -1,102 +1,102 @@
#include "PnjEntity.h"
#include "Constants.h"
//#include "StaticTextEntity.h"
#include "WitchBlastGame.h"
#include "sfml_game/ImageManager.h"
PnjEntity::PnjEntity(float x, float y, int pnjType) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_PNJ), x, y, 64, 96)
{
this->x = x;
this->y = y;
x0 = x;
y0 = y;
pnjVelocity = 140.0f;
xGoal = x0 + 180.0f;
direction = 6;
velocity.x = pnjVelocity;
isSpeaking = false;
speechTimer = 2.5f + 0.1f * (rand() % 50);
headFrame = 2;
type = ENTITY_PNJ;
}
void PnjEntity::animate(float delay)
{
if (direction == 6 && x >= xGoal)
{
direction = 4;
velocity.x = -pnjVelocity;
xGoal = x0 - 180.0f;
}
else if (direction == 4 && x <= xGoal)
{
direction = 6;
velocity.x = pnjVelocity;
xGoal = x0 + 180.0f;
}
speechTimer -= delay;
if (speechTimer <= 0.0f)
{
if (isSpeaking)
{
isSpeaking = false;
speechTimer = 3.0f + 0.1f * (rand() % 65);
velocity.x = (direction == 6) ? pnjVelocity : -pnjVelocity;
}
else
{
isSpeaking = true;
speechTimer = 5.0f;
velocity.x = 0.0f;
int r = rand() % 3;
switch (r)
{
case 0: speech = "Best price in entire dungeon !"; break;
case 1: speech = "Welcome in deep deep stores !"; break;
case 2: speech = "Have look to our merchandise !"; break;
}
}
}
if (isSpeaking)
{
headFrame = 2 + (int)(4 * age) % 2;
}
else
{
frame = 0 + (int)(4 * age) % 2;
headFrame = 2;
}
z = y + height / 2;
SpriteEntity::animate(delay);
}
-void PnjEntity::render(sf::RenderWindow* app)
+void PnjEntity::render(sf::RenderTarget* app)
{
sprite.setPosition(x, y);
// shadow
sprite.setTextureRect(sf::IntRect(4 * width, 0, width, height));
app->draw(sprite);
// body
sprite.setTextureRect(sf::IntRect(frame * width, 0, width, height));
app->draw(sprite);
// head
sprite.setTextureRect(sf::IntRect(headFrame * width, 0, width, height));
app->draw(sprite);
if (isSpeaking)
{
- game().Write(speech, 20, x0, y0 - 72.0f, ALIGN_CENTER, sf::Color(255, 255, 255));
+ game().Write(speech, 20, x0, y0 - 72.0f, ALIGN_CENTER, sf::Color(255, 255, 255), app);
}
}
diff --git a/src/PnjEntity.h b/src/PnjEntity.h
index 36418eb..9154cd8 100644
--- a/src/PnjEntity.h
+++ b/src/PnjEntity.h
@@ -1,26 +1,26 @@
#ifndef PNJENTITY_H
#define PNJENTITY_H
#include "sfml_game/SpriteEntity.h"
class PnjEntity : public SpriteEntity
{
public:
PnjEntity(float x, float y, int pnjType );
virtual void animate(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
protected:
float x0, y0;
float xGoal;
int direction;
float pnjVelocity;
float speechTimer;
bool isSpeaking;
std::string speech;
int headFrame;
private:
};
#endif // PNJENTITY_H
diff --git a/src/SlimeEntity.cpp b/src/SlimeEntity.cpp
index c33008e..94286f2 100644
--- a/src/SlimeEntity.cpp
+++ b/src/SlimeEntity.cpp
@@ -1,246 +1,246 @@
#include "SlimeEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
SlimeEntity::SlimeEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_SLIME), x, y)
{
creatureSpeed = 0.0f;
velocity = Vector2D(0.0f, 0.0f);
hp = SLIME_HP;
meleeDamages = SLIME_DAMAGES;
type = ENTITY_ENNEMY;
bloodColor = bloodGreen;
jumpingDelay = 2.0f;
shadowFrame = 3;
isJumping = false;
h = 0.0f;
viscosity = 0.98f;
frame = 0;
jumpingDelay = 0.6f + 0.1f * (rand() % 20);
}
void SlimeEntity::animate(float delay)
{
float slimeDelay = delay;
if (specialState[SpecialStateIce].active) slimeDelay = delay * STATUS_FROZEN_MULT;
if (isJumping)
{
hVelocity -= 700.0f * slimeDelay;
h += hVelocity * slimeDelay;
if (h <= 0.0f)
{
if (hp <= 0)
dying();
else
{
h = 0.0f;
if (isFirstJumping)
{
isFirstJumping = false;
hVelocity = 160.0f;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT);
}
else
{
jumpingDelay = 0.4f + 0.1f * (rand() % 20);
isJumping = false;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT_WEAK);
}
}
}
if (hVelocity > 0.0f) frame = 2;
else frame = 0;
}
else
{
jumpingDelay -= slimeDelay;
if (jumpingDelay < 0.0f)
{
SoundManager::getSoundManager()->playSound(SOUND_SLIME_JUMP);
hVelocity = 350.0f + rand() % 300;
isJumping = true;
isFirstJumping = true;
float randVel = 250.0f + rand() % 250;
if (rand() % 2 == 0)
{
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
if (game().getPlayer()->getY() > y)
setVelocity(Vector2D(sin(angle) * randVel,
cos(angle) * randVel));
else
setVelocity(Vector2D(-sin(angle) * randVel,
-cos(angle) * randVel));
}
else
velocity = Vector2D(randVel);
}
else if (jumpingDelay < 0.25f)
frame = 1;
else frame = 0;
}
EnnemyEntity::animate(delay);
}
-void SlimeEntity::render(sf::RenderWindow* app)
+void SlimeEntity::render(sf::RenderTarget* app)
{
if (!isDying && shadowFrame > -1)
{
// shadow
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(frame * width, 0, width, height));
app->draw(sprite);
#ifdef SHOW_BOUNDING_BOX
sf::Vertex line[] =
{
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top))
};
app->draw(line, 8, sf::Lines);
#endif
}
void SlimeEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + SLIME_BB_LEFT;
boundingBox.width = width - SLIME_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + SLIME_BB_TOP;
boundingBox.height = height - SLIME_BB_HEIGHT_DIFF;
}
void SlimeEntity::collideMapRight()
{
// if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapLeft()
{
// if (x < OFFSET_X + MAP_WIDTH )
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapTop()
{
// if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT)
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideMapBottom()
{
// if (y < OFFSET_Y + MAP_HEIGHT )
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
if (recoil.active && recoil.stun) return;
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
computeFacingDirection();
}
}
bool SlimeEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
if (xTile == 0 || xTile == MAP_WIDTH - 1 || yTile == 0 || yTile == MAP_HEIGHT - 1)
{
switch (direction)
{
case DIRECTION_LEFT:
if (map->isLeftBlocking(xTile, yTile)) return true;
break;
case DIRECTION_RIGHT:
if (map->isRightBlocking(xTile, yTile)) return true;
break;
case DIRECTION_TOP:
if (map->isUpBlocking(xTile, yTile)) return true;
break;
case DIRECTION_BOTTOM:
if (map->isDownBlocking(xTile, yTile)) return true;
break;
}
}
}
return false;
}
void SlimeEntity::dying()
{
isDying = true;
SpriteEntity* deadSlime = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
deadSlime->setZ(OFFSET_Y);
deadSlime->setFrame(FRAME_CORPSE_SLIME);
deadSlime->setType(ENTITY_CORPSE);
for (int i = 0; i < 4; i++) game().generateBlood(x, y, bloodColor);
drop();
SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
}
void SlimeEntity::prepareDying()
{
if (!isJumping)
dying();
}
bool SlimeEntity::canCollide()
{
return h <= 70.0f;
}
BaseCreatureEntity::enumMovingStyle SlimeEntity::getMovingStyle()
{
if (h <= 70.0f)
return movWalking;
else
return movFlying;
}
diff --git a/src/SlimeEntity.h b/src/SlimeEntity.h
index a20bb92..2e8db1a 100644
--- a/src/SlimeEntity.h
+++ b/src/SlimeEntity.h
@@ -1,38 +1,38 @@
#ifndef SLIMESPRITE_H
#define SLIMESPRITE_H
#include "EnnemyEntity.h"
#include "PlayerEntity.h"
class SlimeEntity : public EnnemyEntity
{
public:
SlimeEntity(float x, float y);
virtual void animate(float delay);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void calculateBB();
protected:
virtual bool collideWithMap(int direction);
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
virtual void collideWithEnnemy(GameEntity* collidingEntity);
virtual void dying();
virtual void prepareDying();
virtual bool canCollide();
virtual enumMovingStyle getMovingStyle();
private:
float jumpingDelay;
float h;
float hVelocity;
bool isJumping;
bool isFirstJumping;
};
#endif // SLIMESPRITE_H
diff --git a/src/TextEntity.cpp b/src/TextEntity.cpp
index b44de1f..6ba8949 100644
--- a/src/TextEntity.cpp
+++ b/src/TextEntity.cpp
@@ -1,71 +1,71 @@
/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sstream>
#include <iostream>
#include "TextEntity.h"
#include "WitchBlastGame.h"
TextEntity::TextEntity(std::string text, int size, float x, float y) : GameEntity(x, y)
{
this->text = text;
this->size = size;
alignment = ALIGN_LEFT;
colorType = COLOR_WHITE;
color = sf::Color(255, 255, 255);
}
-void TextEntity::render(sf::RenderWindow* app)
+void TextEntity::render(sf::RenderTarget* app)
{
- game().Write(text, size, x, y, alignment, color);
+ game().Write(text, size, x, y, alignment, color, app);
}
void TextEntity::animate(float delay)
{
GameEntity::animate(delay);
// TODO : other colorType
if (colorType == COLOR_FADING_WHITE)
{
int alpha = 255 * (lifetime - age) / lifetime;
if (alpha > 255) alpha = 255;
else if (alpha < 0) alpha = 0;
color = sf::Color(255, 255, 255, alpha );
}
}
void TextEntity::setText(std::string text)
{
this->text = text;
}
void TextEntity::setColor(int colorType)
{
// TODO : other colorType
this->colorType = colorType;
if (colorType == COLOR_WHITE || colorType == COLOR_FADING_WHITE)
color = sf::Color(255, 255, 255);
else if (colorType == COLOR_GREEN)
color = sf::Color(0, 255, 0);
}
void TextEntity::setAlignment(int alignment)
{
this->alignment = alignment;
}
diff --git a/src/TextEntity.h b/src/TextEntity.h
index e2035b0..babf650 100644
--- a/src/TextEntity.h
+++ b/src/TextEntity.h
@@ -1,52 +1,52 @@
/** This file is part of Witch Blast.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TEXTENTITY_H_INCLUDED
#define TEXTENTITY_H_INCLUDED
#include "sfml_game/GameEntity.h"
// Basis class for text
class TextEntity : public GameEntity
{
public:
TextEntity(std::string text, int size, float x = 0.0f, float y = 0.0f);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
virtual void setText(std::string text);
void setAlignment(int alignment);
void setColor(int colorType);
enum alignmentEnum { ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER };
enum colorTypeEnum { COLOR_WHITE,
COLOR_BLUE,
COLOR_RED,
COLOR_GREEN,
COLOR_FADING_WHITE,
COLOR_FADING_BLUE,
COLOR_BLINKING_WHITE };
protected:
std::string text;
int size;
int alignment;
int colorType;
sf::Color color;
};
#endif // TEXTENTITY_H_INCLUDED
diff --git a/src/WitchBlastGame.cpp b/src/WitchBlastGame.cpp
index 1d4af21..a9cf1e6 100644
--- a/src/WitchBlastGame.cpp
+++ b/src/WitchBlastGame.cpp
@@ -1,1457 +1,1482 @@
#include "WitchBlastGame.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/TileMapEntity.h"
#include "DungeonMap.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/EntityManager.h"
#include "Constants.h"
#include "RatEntity.h"
#include "BlackRatEntity.h"
#include "GreenRatEntity.h"
#include "KingRatEntity.h"
#include "BatEntity.h"
#include "SlimeEntity.h"
#include "ChestEntity.h"
#include "EvilFlowerEntity.h"
#include "ItemEntity.h"
#include "ArtefactDescriptionEntity.h"
#include "PnjEntity.h"
#include "TextEntity.h"
#include <iostream>
#include <sstream>
#include <fstream>
namespace {
WitchBlastGame* gameptr;
}
WitchBlastGame::WitchBlastGame(): Game(SCREEN_WIDTH, SCREEN_HEIGHT)
{
gameptr = this;
app->setTitle(APP_NAME + " V" + APP_VERSION);
// loading resources
ImageManager::getImageManager()->addImage((char*)"media/player_base.png");
ImageManager::getImageManager()->addImage((char*)"media/player_equip.png");
ImageManager::getImageManager()->addImage((char*)"media/player_collar.png");
ImageManager::getImageManager()->addImage((char*)"media/bolt.png");
ImageManager::getImageManager()->addImage((char*)"media/tiles.png");
ImageManager::getImageManager()->addImage((char*)"media/rat.png");
ImageManager::getImageManager()->addImage((char*)"media/minimap.png");
ImageManager::getImageManager()->addImage((char*)"media/doors.png");
ImageManager::getImageManager()->addImage((char*)"media/items.png");
ImageManager::getImageManager()->addImage((char*)"media/items_equip.png");
ImageManager::getImageManager()->addImage((char*)"media/chest.png");
ImageManager::getImageManager()->addImage((char*)"media/bat.png");
ImageManager::getImageManager()->addImage((char*)"media/evil_flower.png");
ImageManager::getImageManager()->addImage((char*)"media/slime.png");
ImageManager::getImageManager()->addImage((char*)"media/king_rat.png");
ImageManager::getImageManager()->addImage((char*)"media/blood.png");
ImageManager::getImageManager()->addImage((char*)"media/corpses.png");
ImageManager::getImageManager()->addImage((char*)"media/corpses_big.png");
ImageManager::getImageManager()->addImage((char*)"media/star.png");
ImageManager::getImageManager()->addImage((char*)"media/star2.png");
ImageManager::getImageManager()->addImage((char*)"media/interface.png");
ImageManager::getImageManager()->addImage((char*)"media/hud_shots.png");
ImageManager::getImageManager()->addImage((char*)"media/pnj.png");
ImageManager::getImageManager()->addImage((char*)"media/fairy.png");
SoundManager::getSoundManager()->addSound((char*)"media/sound/step.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/blast00.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/blast01.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/door_closing.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/door_opening.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/chest_opening.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/bonus.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/drink.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/eat.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/player_hit.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/player_die.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/ennemy_dying.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/coin.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/pay.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/wall_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/big_wall_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_1.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_2.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_die.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_jump.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_impact_weak.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/ice_charge.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/select.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/heart.ogg");
if (font.loadFromFile("media/DejaVuSans-Bold.ttf"))
{
myText.setFont(font);
}
miniMap = NULL;
currentMap = NULL;
currentFloor = NULL;
xGameState = xGameStateNone;
isPausing = false;
+ if (!mainTexture.create(GAME_WIDTH + OFFSET_X, GAME_HEIGHT + OFFSET_Y) )
+ {
+ // error
+ }
+
+ mainSprite.setTexture(mainTexture.getTexture());
+ mainSprite.setTextureRect(sf::IntRect(0, GAME_HEIGHT + OFFSET_Y, GAME_WIDTH + OFFSET_X, -GAME_HEIGHT - OFFSET_Y));
+
shotsSprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_HUD_SHOTS));
input[KeyUp] = sf::Keyboard::Z;
input[KeyDown] = sf::Keyboard::S;
input[KeyLeft] = sf::Keyboard::Q;
input[KeyRight] = sf::Keyboard::D;
input[KeyFireUp] = sf::Keyboard::Up;
input[KeyFireDown] = sf::Keyboard::Down;
input[KeyFireLeft] = sf::Keyboard::Left;
input[KeyFireRight] = sf::Keyboard::Right;
}
WitchBlastGame::~WitchBlastGame()
{
// cleaning all entities
EntityManager::getEntityManager()->clean();
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
}
DungeonMap* WitchBlastGame::getCurrentMap()
{
return currentMap;
}
PlayerEntity* WitchBlastGame::getPlayer()
{
return player;
}
Vector2D WitchBlastGame::getPlayerPosition()
{
return Vector2D(player->getX(), player->getY());
}
int WitchBlastGame::getLevel()
{
return level;
}
void WitchBlastGame::onUpdate()
{
float delta = getAbsolutTime() - lastTime;
lastTime = getAbsolutTime();
if (!isPausing)
{
EntityManager::getEntityManager()->animate(delta);
if (xGameState != xGameStateNone)
{
xGameTimer -= delta;
if (xGameTimer <= 0.0f)
{
if (xGameState == xGameStateFadeOut)
{
if (player->getPlayerStatus() == PlayerEntity::playerStatusGoingUp)
{
level++;
startNewLevel();
}
else
startNewGame(false);
}
else
xGameState = xGameStateNone;
}
}
if (isPlayerAlive)
{
if (player->getHp() <= 0)
{
isPlayerAlive = false;
playMusic(MusicEnding);
}
}
}
}
void WitchBlastGame::startNewGame(bool fromSaveFile)
{
gameState = gameStateInit;
level = 1;
// cleaning all entities
EntityManager::getEntityManager()->clean();
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
miniMap = NULL;
currentFloor = NULL;
// current map (tiles)
currentTileMap = new TileMapEntity(ImageManager::getImageManager()->getImage(IMAGE_TILES), currentMap, 64, 64, 10);
currentTileMap->setX(OFFSET_X);
currentTileMap->setY(OFFSET_Y);
// the interface
SpriteEntity* interface = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_INTERFACE));
interface->setZ(10000.0f);
interface->removeCenter();
interface->setType(0);
// key symbol on the interface
keySprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP));
keySprite.setTextureRect(sf::IntRect(ITEM_WIDTH * EQUIP_BOSS_KEY, 0, ITEM_WIDTH, ITEM_HEIGHT));
keySprite.setPosition(326, 616);
miniMap = new GameMap(FLOOR_WIDTH, FLOOR_HEIGHT);
// minimap on the interface
TileMapEntity* miniMapEntity = new TileMapEntity(ImageManager::getImageManager()->getImage(IMAGE_MINIMAP), miniMap, 15, 11, 10);
miniMapEntity->setTileBox(16, 12);
miniMapEntity->setX(407);
miniMapEntity->setY(614);
miniMapEntity->setZ(10001.0f);
// doors
doorEntity[0] = new DoorEntity(8);
doorEntity[1] = new DoorEntity(4);
doorEntity[2] = new DoorEntity(2);
doorEntity[3] = new DoorEntity(6);
if (fromSaveFile)
{
if (!loadGame())
fromSaveFile = false;
else
playLevel();
}
if (!fromSaveFile)
{
// the player
player = new PlayerEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
startNewLevel();
}
}
void WitchBlastGame::startNewLevel()
{
// create the new level
if (currentFloor != NULL) delete currentFloor;
currentFloor = new GameFloor(level);
currentFloor->createFloor();
// center it
floorX = FLOOR_WIDTH / 2;
floorY = FLOOR_HEIGHT / 2;
// move the player
if (level == 1)
player->moveTo(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
else
player->moveTo(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT - 3 * TILE_HEIGHT));
// the boss room is closed
bossRoomOpened = false;
playLevel();
}
void WitchBlastGame::playLevel()
{
isPlayerAlive = true;
player->setVelocity(Vector2D(0.0f, 0.0f));
player->setPlayerStatus(PlayerEntity::playerStatusPlaying);
// generate the map
refreshMap();
// items from save
currentMap->restoreMapObjects();
// first map is open
roomClosed = false;
// game time counter an state
lastTime = getAbsolutTime();
gameState = gameStatePlaying;
playMusic(MusicDungeon);
// fade in
xGameState = xGameStateFadeIn;
xGameTimer = FADE_IN_DELAY;
float x0 = OFFSET_X + MAP_WIDTH * 0.5f * TILE_WIDTH;
float y0 = OFFSET_Y + MAP_HEIGHT * 0.5f * TILE_HEIGHT + 40.0f;
std::ostringstream oss;
oss << "Level " << level;
TextEntity* text = new TextEntity(oss.str(), 30, x0, y0);
text->setAlignment(ALIGN_CENTER);
text->setLifetime(2.5f);
text->setWeight(-36.0f);
text->setZ(1000);
text->setColor(TextEntity::COLOR_FADING_WHITE);
}
void WitchBlastGame::startGame()
{
startNewGame(true);
// Start game loop
while (app->isOpen())
{
// Process events
sf::Event event;
while (app->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
if (gameState == gameStatePlaying && !player->isDead() && currentMap->isCleared()) saveGame();
app->close();
}
if (event.type == sf::Event::MouseWheelMoved)
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
if (gameState == gameStatePlaying && !isPausing) isPausing = true;
else if (gameState == gameStatePlaying && isPausing) isPausing = false;
}
if (event.key.code == sf::Keyboard::Tab)
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.key.code == sf::Keyboard::Space)
{
if (gameState == gameStatePlaying && !isPausing) firingDirection = player->getFacingDirection();
}
if (event.key.code == sf::Keyboard::X)
{
startNewGame(false);
}
if (event.key.code == sf::Keyboard::C)
{
startNewLevel();
}
}
if (event.type == sf::Event::LostFocus)
isPausing = true;
}
if (gameState == gameStatePlaying && !isPausing)
{
if (player->canMove()) player->setVelocity(Vector2D(0.0f, 0.0f));
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) || sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
player->move(7);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
player->move(1);
else
player->move(4);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
player->move(9);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
player->move(3);
else
player->move(6);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
player->move(8);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
player->move(2);
}
// normal 4 directions gameplay
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
player->fire(4);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
player->fire(6);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
player->fire(8);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
player->fire(2);
// alternative "one button" gameplay
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
player->fire(firingDirection);
}
// alternative "firing with the mouse" gameplay
else if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(*app);
int xm = mousePosition.x - player->getX();
int ym = mousePosition.y - player->getY();
if (abs(xm) >= abs(ym))
{
if (xm > 0) player->fire(6);
else player->fire(4);
}
else
{
if (ym > 0) player->fire(2);
else player->fire(8);
}
}
if (player->isDead() && xGameState == xGameStateNone && sf::Keyboard::isKeyPressed(sf::Keyboard::Return))
{
xGameState = xGameStateFadeOut;
xGameTimer = FADE_OUT_DELAY;
}
}
onUpdate();
EntityManager::getEntityManager()->sortByZ();
onRender();
verifyDoorUnlocking();
if (roomClosed)
{
if (getEnnemyCount() == 0)
{
currentMap->setCleared(true);
openDoors();
if (currentMap->getRoomType() == roomTypeBoss)
playMusic(MusicDungeon);
}
}
}
quitGame();
}
void WitchBlastGame::createFloor()
{
// TODO : extracts from createNewGame
}
void WitchBlastGame::closeDoors()
{
if (!currentMap->isCleared())
{
int i;
for(i = 0; i < MAP_WIDTH; i++)
{
if (currentMap->getTile(i, 0) < 4) currentMap->setTile(i, 0, MAP_DOOR);
if (currentMap->getTile(i, MAP_HEIGHT - 1) < 4) currentMap->setTile(i, MAP_HEIGHT - 1, MAP_DOOR);
}
for(i = 0; i < MAP_HEIGHT; i++)
{
if (currentMap->getTile(0, i) < 4) currentMap->setTile(0, i, MAP_DOOR);
if (currentMap->getTile(MAP_WIDTH - 1, i) < 4) currentMap->setTile(MAP_WIDTH - 1, i, MAP_DOOR);
}
roomClosed = true;
}
}
void WitchBlastGame::openDoors()
{
int i, j;
for(i = 0; i < MAP_WIDTH; i++)
for(j = 0; j < MAP_WIDTH; j++)
if (currentMap->getTile(i, j) == MAP_DOOR) currentMap->setTile(i, j, 0);
roomClosed = false;
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
else
doorEntity[0]->openDoor();
if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[1]->openDoor();
if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, MAP_DOOR);
else
doorEntity[2]->openDoor();
if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[3]->openDoor();
}
int WitchBlastGame::getEnnemyCount()
{
int n=0;
EntityManager::EntityList* entityList =EntityManager::getEntityManager()->getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
if (e->getType() >= 20)
{
n++;
} // endif
} // end for
return n;
}
void WitchBlastGame::refreshMap()
{
// clean the sprites from old map
EntityManager::getEntityManager()->partialClean(10);
// if new map, it has to be randomized
bool generateMap = !(currentFloor->getMap(floorX, floorY)->isVisited());
currentMap = currentFloor->getAndVisitMap(floorX, floorY);
// load the map
currentTileMap->setMap(currentMap);
player->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
refreshMinimap();
if(generateMap)
this->generateMap();
else
{
if (currentMap->getRoomType() == roomTypeMerchant)
new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
0);
}
// for testing purpose (new stuff)
if (player->getAge() <2.0f)
{
/*ItemEntity* book = new ItemEntity(ItemEntity::itemHealth, player->getX(), player->getY()- 180);
book->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
book->setMerchandise(true);*/
/*int bonusType = getRandomEquipItem(true);
ItemEntity* boots = new ItemEntity((enumItemType)(itemMagicianHat + bonusType), player->getX(), player->getY()+ 180);
boots->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);*/
//ChestEntity* chest = new ChestEntity(player->getX() + 100, player->getY()+ 150, CHEST_FAIRY, false);
//chest->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
}
// check doors
doorEntity[0]->setVisible(currentMap->hasNeighbourUp() > 0);
if (currentMap->hasNeighbourUp() == 1) doorEntity[0]->setDoorType(0);
if (currentMap->hasNeighbourUp() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[0]->setDoorType(1);
if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
{
doorEntity[0]->setOpen(false);
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
}
else
doorEntity[0]->setOpen(true);
doorEntity[3]->setVisible(currentMap->hasNeighbourRight() > 0);
if (currentMap->hasNeighbourRight() == 1) doorEntity[3]->setDoorType(0);
if (currentMap->hasNeighbourRight() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[3]->setDoorType(1);
if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
{
doorEntity[3]->setOpen(false);
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
}
else
doorEntity[3]->setOpen(true);
doorEntity[2]->setVisible(currentMap->hasNeighbourDown() > 0);
if (currentMap->hasNeighbourDown() == 1) doorEntity[2]->setDoorType(0);
if (currentMap->hasNeighbourDown() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[2]->setDoorType(1);
if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
{
doorEntity[2]->setOpen(false);
currentMap->setTile(MAP_WIDTH/2, MAP_HEIGHT - 1, MAP_DOOR);
}
else
doorEntity[2]->setOpen(true);
doorEntity[1]->setVisible(currentMap->hasNeighbourLeft() > 0);
if (currentMap->hasNeighbourLeft() == 1) doorEntity[1]->setDoorType(0);
if (currentMap->hasNeighbourLeft() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[1]->setDoorType(1);
if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
{
doorEntity[1]->setOpen(false);
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
}
else
doorEntity[1]->setOpen(true);
}
void WitchBlastGame::refreshMinimap()
{
for (int j=0; j < FLOOR_HEIGHT; j++)
for (int i=0; i < FLOOR_WIDTH; i++)
{
int n = currentFloor->getRoom(i, j);
if (n > 0 && currentFloor->getMap(i, j)->isVisited())
{
if (currentFloor->getRoom(i, j) == roomTypeStarting
|| currentFloor->getRoom(i, j) == roomTypeBonus
|| currentFloor->getRoom(i, j) == roomTypeKey)
miniMap->setTile(i, j, roomTypeStandard);
else
miniMap->setTile(i, j, currentFloor->getRoom(i, j));
}
else if (n > 0 && currentFloor->getMap(i, j)->isKnown())
{
if (currentFloor->getRoom(i, j) == roomTypeBoss)
miniMap->setTile(i, j, 7);
else
miniMap->setTile(i, j, 9);
}
else
miniMap->setTile(i, j, 0);
}
miniMap->setTile(floorX, floorY, 8);
}
void WitchBlastGame::checkEntering()
{
if (!currentMap->isCleared())
{
player->setEntering();
SoundManager::getSoundManager()->playSound(SOUND_DOOR_CLOSING);
for (int i=0; i<4; i++)
doorEntity[i]->closeDoor();
}
}
void WitchBlastGame::saveMapItems()
{
EntityManager::EntityList* entityList = EntityManager::getEntityManager()->getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity* e = *it;
it++;
ItemEntity* itemEntity = dynamic_cast<ItemEntity*>(e);
ChestEntity* chestEntity = dynamic_cast<ChestEntity*>(e);
if (itemEntity != NULL)
{
currentMap->addItem(itemEntity->getItemType(), itemEntity->getX(), itemEntity->getY(), itemEntity->getMerchandise());
} // endif
else if (chestEntity != NULL)
{
currentMap->addChest(chestEntity->getChestType(), chestEntity->getOpened(), chestEntity->getX(), chestEntity->getY());
} // endif
else
{
SpriteEntity* spriteEntity = dynamic_cast<SpriteEntity*>(e);
if (spriteEntity != NULL && (e->getType() == ENTITY_BLOOD || e->getType() == ENTITY_CORPSE ) )
{
int spriteFrame = spriteEntity->getFrame();
if (spriteEntity->getWidth() == 128) spriteFrame += FRAME_CORPSE_KING_RAT;
currentMap->addSprite(e->getType(), spriteFrame, e->getX(), e->getY(), spriteEntity->getScaleX());
}
}
} // end for
}
void WitchBlastGame::moveToOtherMap(int direction)
{
// stairs to next level
if (direction == 8 && currentMap->getRoomType() == roomTypeExit)
{
if (player->getPlayerStatus() != PlayerEntity::playerStatusGoingUp)
{
player->setLeavingLevel();
xGameState = xGameStateFadeOut;
xGameTimer = FADE_OUT_DELAY;
player->setVelocity(Vector2D(0.0f, - INITIAL_PLAYER_SPEED / 2));
}
}
// go to another room
else
{
saveMapItems();
switch (direction)
{
case (4): floorX--; player->moveTo((OFFSET_X + MAP_WIDTH * TILE_WIDTH), player->getY()); player->move(4); break;
case (6): floorX++; player->moveTo(OFFSET_X, player->getY()); player->move(6); break;
case (8): floorY--; player->moveTo(player->getX(), OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 20); player->move(8); break;
case (2): floorY++; player->moveTo(player->getX(), OFFSET_Y); break;
}
refreshMap();
checkEntering();
currentMap->restoreMapObjects();
}
}
void WitchBlastGame::onRender()
{
// clear the view
app->clear(sf::Color(32, 32, 32));
- // render the game objects
- EntityManager::getEntityManager()->render(app);
+ if (xGameState == xGameStateShake)
+ {
+ mainTexture.clear();
+ EntityManager::getEntityManager()->renderUnder(&mainTexture, 5000);
+ mainSprite.setPosition(-3 + rand() % 7, -3 + rand() % 7);
+ app->draw(mainSprite);
+ EntityManager::getEntityManager()->renderAfter(app, 5000);
+ }
+ else
+ {
+ // render the game objects
+ EntityManager::getEntityManager()->render(app);
+ }
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(18);
std::ostringstream oss;
oss << player->getGold();
myText.setString(oss.str());
myText.setPosition(690, 612);
app->draw(myText);
myText.setColor(sf::Color(0, 0, 0, 255));
myText.setCharacterSize(16);
oss.str("");
oss << "Level " << level;
myText.setString(oss.str());
myText.setPosition(410, 692);
app->draw(myText);
sf::RectangleShape rectangle(sf::Vector2f(200, 25));
// life
if (gameState == gameStatePlaying)
{
// life and mana
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(90, 622));
rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 25));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(255, 190, 190));
rectangle.setPosition(sf::Vector2f(90, 625));
rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 2));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(20, 20, 190));
rectangle.setPosition(sf::Vector2f(90, 658));
rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 25));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(190, 190, 255));
rectangle.setPosition(sf::Vector2f(90, 661));
rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 2));
app->draw(rectangle);
// drawing the key on the interface
if (player->isEquiped(EQUIP_BOSS_KEY)) app->draw(keySprite);
// render the shots
renderHudShots(app);
if (isPausing)
{
rectangle.setFillColor(sf::Color(0, 0, 0, 160));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH, MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
int fade = 50 + 205 * (1.0f + cos(3.0f * getAbsolutTime())) * 0.5f;
myText.setColor(sf::Color(255, 255, 255, fade));
myText.setCharacterSize(40);
myText.setString("PAUSE");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 300);
app->draw(myText);
}
if (player->isDead())
{
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
int fade = 255 * (1.0f + cos(2.0f * getAbsolutTime())) * 0.5f;
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(25);
myText.setString("GAME OVER");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 400);
app->draw(myText);
myText.setColor(sf::Color(255, 255, 255, fade));
myText.setCharacterSize(20);
myText.setString("Press [ENTER] to play again !");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 440);
app->draw(myText);
}
else if (currentMap->getRoomType() == roomTypeExit)
{
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(25);
myText.setString("CONGRATULATIONS !\nYou've challenged this demo and\nmanaged to kill the boss !\nSee you soon for new adventures !");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 220);
app->draw(myText);
}
if (xGameState == xGameStateFadeIn)
{
// fade in
rectangle.setFillColor(sf::Color(0, 0, 0, 255 - ((FADE_IN_DELAY - xGameTimer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
else if (xGameState == xGameStateFadeOut)
{
// fade out
rectangle.setFillColor(sf::Color(0, 0, 0, ((FADE_IN_DELAY - xGameTimer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
}
app->display();
}
-void WitchBlastGame::renderHudShots(sf::RenderWindow* app)
+void WitchBlastGame::renderHudShots(sf::RenderTarget* app)
{
int xHud = 640;
int yHud = 650;
int index = 0;
for (int i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
if (i == 0 || player->getShotType(i) != ShotTypeStandard)
{
int type_shot = player->getShotType(i);
shotsSprite.setPosition(xHud + 48 * index, yHud);
if (index == player->getShotIndex())
{
shotsSprite.setTextureRect(sf::IntRect(0, 0, 48, 48));
app->draw(shotsSprite);
}
shotsSprite.setTextureRect(sf::IntRect(48 * ( 1 + type_shot), 0, 48, 48));
app->draw(shotsSprite);
index++;
}
}
}
void WitchBlastGame::generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor)
{
// double blood if the "Blood Snake3 object is equipped
int nbIt;
if (player->isEquiped(EQUIP_BLOOD_SNAKE))
nbIt = 2;
else
nbIt = 1;
for (int i=0; i < nbIt; i++)
{
SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
blood->setZ(OFFSET_Y - 1);
int b0 = 0;
if (bloodColor == BaseCreatureEntity::bloodGreen) b0 += 6;
blood->setFrame(b0 + rand()%6);
blood->setType(ENTITY_BLOOD);
blood->setVelocity(Vector2D(rand()%250));
blood->setViscosity(0.95f);
float bloodScale = 1.0f + (rand() % 10) * 0.1f;
blood->setScale(bloodScale, bloodScale);
}
}
void WitchBlastGame::showArtefactDescription(enumItemType itemType)
{
new ArtefactDescriptionEntity(itemType); //, &font);
}
void WitchBlastGame::generateMap()
{
if (currentMap->getRoomType() == roomTypeStandard)
generateStandardMap();
else if (currentMap->getRoomType() == roomTypeBonus)
{
currentMap->setCleared(true);
Vector2D v = currentMap->generateBonusRoom();
int bonusType = getRandomEquipItem(false);
if (bonusType == EQUIP_FAIRY)
{
new ChestEntity(v.x, v.y, CHEST_FAIRY, false);
}
else
{
new ItemEntity( (enumItemType)(FirstEquipItem + bonusType), v.x ,v.y);
}
}
else if (currentMap->getRoomType() == roomTypeKey)
{
Vector2D v = currentMap->generateKeyRoom();
new ItemEntity( (enumItemType)(ItemBossKey), v.x ,v.y);
initMonsterArray();
int x0 = MAP_WIDTH / 2;
int y0 = MAP_HEIGHT / 2;
monsterArray[x0][y0] = true;
findPlaceMonsters(MONSTER_RAT, 5);
findPlaceMonsters(MONSTER_BAT, 5);
}
else if (currentMap->getRoomType() == roomTypeMerchant)
{
currentMap->generateMerchantRoom();
ItemEntity* item1 = new ItemEntity(
itemHealth,
OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
item1->setMerchandise(true);
int bonusType = getRandomEquipItem(true);
ItemEntity* item2 = new ItemEntity(
(enumItemType)(FirstEquipItem + bonusType),
OFFSET_X + (MAP_WIDTH / 2 + 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
item2->setMerchandise(true);
new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
0);
currentMap->setCleared(true);
}
else if (currentMap->getRoomType() == roomTypeBoss)
{
currentMap->generateRoom(0);
new KingRatEntity(OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
playMusic(MusicBoss);
}
else if (currentMap->getRoomType() == roomTypeStarting)
{
currentMap->generateRoom(0);
currentMap->setCleared(true);
int bonusType = getRandomEquipItem(false);
if (level == 1)
{
if (bonusType == EQUIP_FAIRY)
{
new ChestEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + 120.0f + (TILE_HEIGHT * MAP_HEIGHT * 0.5f),
CHEST_FAIRY, false);
}
else
{
new ItemEntity( (enumItemType)(FirstEquipItem + bonusType),
OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + 120.0f + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
}
}
}
else if (currentMap->getRoomType() == roomTypeExit)
{
currentMap->generateExitRoom();
currentMap->setCleared(true);
}
else
currentMap->randomize(currentMap->getRoomType());
}
-void WitchBlastGame::Write(std::string str, int size, float x, float y, int align, sf::Color color)
+void WitchBlastGame::Write(std::string str, int size, float x, float y, int align, sf::Color color, sf::RenderTarget* app)
{
myText.setString(str);
myText.setCharacterSize(size);
myText.setColor(color);
if (align == ALIGN_CENTER)
myText.setPosition(x - myText.getLocalBounds().width / 2, y);
else
myText.setPosition(x, y);
app->draw(myText);
}
void WitchBlastGame::initMonsterArray()
{
for (int i = 0; i < MAP_WIDTH; i++)
for (int j = 0; j < MAP_HEIGHT; j++)
monsterArray[i][j] = false;
}
void WitchBlastGame::addMonster(monster_type_enum monsterType, float xm, float ym)
{
switch (monsterType)
{
case MONSTER_RAT: new RatEntity(xm, ym - 2); break;
case MONSTER_BLACK_RAT: new BlackRatEntity(xm, ym - 5); break;
case MONSTER_BAT: new BatEntity(xm, ym); break;
case MONSTER_EVIL_FLOWER: new EvilFlowerEntity(xm, ym - 2); break;
case MONSTER_SLIME: new SlimeEntity(xm, ym); break;
case MONSTER_KING_RAT: new KingRatEntity(xm, ym); break;
}
}
void WitchBlastGame::findPlaceMonsters(monster_type_enum monsterType, int amount)
{
// find a suitable place
bool isMonsterFlying = monsterType == MONSTER_BAT;
bool bOk;
int xm, ym;
float xMonster, yMonster;
for (int index = 0; index < amount; index++)
{
bOk = false;
while (!bOk)
{
bOk = true;
xm = 1 +rand() % (MAP_WIDTH - 3);
ym = 1 +rand() % (MAP_HEIGHT - 3);
if (monsterArray[xm][ym])
{
bOk = false;
}
if (bOk && !isMonsterFlying && !currentMap->isWalkable(xm, ym))
{
bOk = false;
}
if (bOk)
{
xMonster = OFFSET_X + xm * TILE_WIDTH + TILE_WIDTH * 0.5f;
yMonster = OFFSET_Y + ym * TILE_HEIGHT+ TILE_HEIGHT * 0.5f;
float dist2 = (xMonster - player->getX())*(xMonster - player->getX()) + (yMonster - player->getY())*(yMonster - player->getY());
if ( dist2 < 75000.0f)
{
bOk = false;
}
else
{
addMonster(monsterType, xMonster, yMonster);
monsterArray[xm][ym] = true;
}
}
}
}
}
void WitchBlastGame::generateStandardMap()
{
initMonsterArray();
int random = rand() % (level == 1 ? 95 : 110);
if (random < 16)
{
currentMap->generateRoom(rand()%4);
findPlaceMonsters(MONSTER_RAT,4);
}
else if (random < 32)
{
currentMap->generateRoom(rand()%5);
findPlaceMonsters(MONSTER_BAT,4);
}
else if (random < 48)
{
currentMap->generateRoom(rand()%5);
findPlaceMonsters(MONSTER_EVIL_FLOWER,4);
}
else if (random < 64)
{
Vector2D v = currentMap->generateBonusRoom();
new ChestEntity(v.x, v.y, CHEST_BASIC, false);
currentMap->setCleared(true);
}
else if (random < 80)
{
currentMap->generateRoom(rand()%4);
findPlaceMonsters(MONSTER_RAT,3);
findPlaceMonsters(MONSTER_BAT,3);
}
else if (random < 95)
{
currentMap->generateRoom(4);
findPlaceMonsters(MONSTER_BLACK_RAT,6);
}
else
{
currentMap->generateRoom(rand()%4);
findPlaceMonsters(MONSTER_SLIME,8 + rand() % 5);
}
}
item_equip_enum WitchBlastGame::getRandomEquipItem(bool toSale = false)
{
std::vector<int> bonusSet;
int setSize = 0;
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool itemOk = true;
int eq = i + FirstEquipItem;
if (player->isEquiped(i)) itemOk = false;
// TODO item already in floor
if (itemOk && toSale && !items[eq].canBeSold) itemOk = false;
if (itemOk && !toSale && !items[eq].canBeFound) itemOk = false;
if (itemOk && items[eq].level > level) itemOk = false;
if (itemOk && items[eq].requirement >= FirstEquipItem
&& !player->isEquiped(i)) itemOk = false;
if (itemOk && player->getShotType(SPECIAL_SHOT_SLOTS_STANDARD) != ShotTypeStandard
&& (items[eq].specialShot != ShotTypeStandard && items[eq].level < 4))
itemOk = false;
if (itemOk)
{
bonusSet.push_back(i);
setSize++;
}
}
int bonusType = 0;
if (setSize > 0) bonusType = bonusSet[rand() % setSize];
return (item_equip_enum) bonusType;
}
void WitchBlastGame::verifyDoorUnlocking()
{
int collidingDirection = (player->getCollidingDirection());
if (collidingDirection > 0 && currentMap->isCleared() && !bossRoomOpened && player->isEquiped(EQUIP_BOSS_KEY))
{
int xt = (player->getX() - OFFSET_X) / TILE_WIDTH;
int yt = (player->getY() - OFFSET_Y) / TILE_HEIGHT;
if (yt <= 1 && xt >= MAP_WIDTH / 2 - 1 && xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourUp() == 2)
{
doorEntity[0]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, 0, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (yt >= MAP_HEIGHT - 2 && xt >= MAP_WIDTH / 2 - 1 &&xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourDown() == 2)
{
doorEntity[2]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt <= 1 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourLeft() == 2)
{
doorEntity[1]->openDoor();
currentMap->setTile(0, MAP_HEIGHT / 2, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt >= MAP_WIDTH - 2 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourRight() == 2)
{
doorEntity[3]->openDoor();
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
}
}
void WitchBlastGame::playMusic(musicEnum musicChoice)
{
music.stop();
music.setLoop(true);
bool ok = false;
switch (musicChoice)
{
case MusicDungeon:
ok = music.openFromFile("media/sound/track00.ogg");
music.setVolume(75);
break;
case MusicEnding:
ok = music.openFromFile("media/sound/track_ending.ogg");
music.setVolume(35);
break;
case MusicBoss:
ok = music.openFromFile("media/sound/track_boss.ogg");
music.setVolume(90);
break;
}
if (ok)
music.play();
}
+void WitchBlastGame::makeShake(float duration)
+{
+ xGameState = xGameStateShake;
+ xGameTimer = duration;
+}
+
void WitchBlastGame::saveGame()
{
ofstream file("game.sav", ios::out | ios::trunc);
int i, j, k, l;
if (file)
{
// floor
file << level << std::endl;
int nbRooms = 0;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
file << currentFloor->getRoom(i,j) << " ";
if (currentFloor->getRoom(i,j) > 0) nbRooms++;
}
file << std::endl;
}
// maps
saveMapItems();
file << nbRooms << std::endl;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
if (currentFloor->getRoom(i,j) > 0)
{
file << i << " " << j << " "
<< currentFloor->getMap(i, j)->getRoomType() << " "
<< currentFloor->getMap(i, j)->isKnown() << " "
<< currentFloor->getMap(i, j)->isVisited() << " "
<< currentFloor->getMap(i, j)->isCleared() << std::endl;
if (currentFloor->getMap(i, j)->isVisited())
{
for (l = 0; l < MAP_HEIGHT; l++)
{
for (k = 0; k < MAP_WIDTH; k++)
{
file << currentFloor->getMap(i, j)->getTile(k, l) << " ";
}
file << std::endl;
}
// items, etc...
std::list<DungeonMap::itemListElement> itemList = currentFloor->getMap(i, j)->getItemList();
file << itemList.size() << std::endl;
std::list<DungeonMap::itemListElement>::iterator it;
for (it = itemList.begin (); it != itemList.end ();)
{
DungeonMap::itemListElement ilm = *it;
it++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.merch << std::endl;
}
// chests
std::list<DungeonMap::chestListElement> chestList = currentFloor->getMap(i, j)->getChestList();
file << chestList.size() << std::endl;
std::list<DungeonMap::chestListElement>::iterator itc;
for (itc = chestList.begin (); itc != chestList.end ();)
{
DungeonMap::chestListElement ilm = *itc;
itc++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.state << std::endl;
}
// sprites
std::list<DungeonMap::spriteListElement> spriteList = currentFloor->getMap(i, j)->getSpriteList();
file << spriteList.size() << std::endl;
std::list<DungeonMap::spriteListElement>::iterator its;
for (its = spriteList.begin (); its != spriteList.end ();)
{
DungeonMap::spriteListElement ilm = *its;
its++;
file << ilm.type << " " << ilm.frame << " " << ilm.x << " " << ilm.y << " " << ilm.scale << std::endl;
}
}
}
}
file << std::endl;
}
// game
file << floorX << " " << floorY << std::endl;
file << bossRoomOpened << std::endl;
// boss door !
// player
file << player->getHp() << " " << player->getHpMax() << " " << player->getGold() << std::endl;
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++) file << player->isEquiped(i) << " ";
file << std::endl;
file << player->getX() << " " << player->getY() << std::endl;
file << player->getShotIndex();
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++) file << " " << player->getShotType(i);
file.close();
}
else
{
cerr << "[ERROR] Saving the game..." << endl;
}
}
bool WitchBlastGame::loadGame()
{
ifstream file("game.sav", ios::in);
if (file)
{
int i, j, k, n;
// floor
file >> level;
currentFloor = new GameFloor(level);
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
int n;
file >> n;
currentFloor->setRoom(i, j, n);
}
}
// maps
int nbRooms;
file >> nbRooms;
for (k = 0; k < nbRooms; k++)
{
file >> i;
file >> j;
file >> n;
DungeonMap* iMap = new DungeonMap(currentFloor, i, j);
currentFloor->setMap(i, j, iMap);
iMap->setRoomType((roomTypeEnum)n);
bool flag;
file >> flag;
iMap->setKnown(flag);
file >> flag;
iMap->setVisited(flag);
file >> flag;
iMap->setCleared(flag);
if (iMap->isVisited())
{
for (j = 0; j < MAP_HEIGHT; j++)
{
for (i = 0; i < MAP_WIDTH; i++)
{
file >> n;
iMap->setTile(i, j, n);
}
}
// items int the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool merc;
file >> t >> x >> y >> merc;
iMap->addItem(t, x, y, merc);
}
// chests in the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool state;
file >> t >> x >> y >> state;
iMap->addChest(t, state, x, y);
}
// sprites in the map
file >> n;
for (i = 0; i < n; i++)
{
int t, f;
float x, y, scale;
file >> t >> f >> x >> y >> scale;
iMap->addSprite(t, f, x, y, scale);
}
}
}
// game
file >> floorX >> floorY;
currentMap = currentFloor->getMap(floorX, floorY);
file >> bossRoomOpened;
// player
int hp, hpMax, gold;
file >> hp >> hpMax >> gold;
player = new PlayerEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
player->setHp(hp);
player->setHpMax(hpMax);
player->setGold(gold);
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool eq;
file >> eq;
player->setEquiped(i, eq);
}
float x, y;
file >> x >> y;
player->moveTo(x, y);
file >> n;
player->setShotIndex(n);
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
file >> n;
player->setShotType(i, (enumShotType)n);
}
file.close();
remove("game.sav");
}
else
{
return false;
}
return true;
}
WitchBlastGame &game()
{
return *gameptr;
}
diff --git a/src/WitchBlastGame.h b/src/WitchBlastGame.h
index 57322b2..11be0ca 100644
--- a/src/WitchBlastGame.h
+++ b/src/WitchBlastGame.h
@@ -1,409 +1,418 @@
#ifndef WITCH_BLAST_GAME_H
#define WITCH_BLAST_GAME_H
#include "sfml_game/Game.h"
#include "sfml_game/TileMapEntity.h"
#include "PlayerEntity.h"
#include "EnnemyEntity.h"
#include "DoorEntity.h"
#include "GameFloor.h"
const int ALIGN_LEFT = 0; /*!< Text alignment left */
const int ALIGN_RIGHT = 1; /*!< Text alignment right */
const int ALIGN_CENTER = 2; /*!< Text alignment centered */
/*! \class WitchBlastGame
* \brief Main class of the game
*
* WitchBlastGame load the game ressources and do a large part of the game logic (game loop...),
* watches the input, manages the game states, ...
*/
class WitchBlastGame : public Game
{
public:
/*!
* \brief Constructor
*
* Constructor of the WitchBlastGame class.
*/
WitchBlastGame();
/*!
* \brief Destructor
*
* Destructor of the WitchBlastGame class.
*/
virtual ~WitchBlastGame();
/*!
* \brief Accessor on the current dungeon map
*
* Accessor on the current dungeon map (room).
*
* \return a pointer to the current dungeon map
*/
DungeonMap* getCurrentMap();
/*!
* \brief Accessor on the player
*
* Accessor on the player.
*
* \return a pointer to the player
*/
PlayerEntity* getPlayer();
/*!
* \brief Accessor on the player's position
*
* Accessor on the player's position.
*
* \return a Vector2D of the player's position
*/
Vector2D getPlayerPosition();
/*!
* \brief accessor on the level
*
* Accessor on the level.
*
* \return : the level
*/
int getLevel();
/*!
* \brief Start the game and the game loop
*
* This method starts the game and the game loop.
* The game loop watches the events, the inputs, update and draw the game elements.
*/
virtual void startGame();
/*!
* \brief Move the player to another map (room)
*
* Moves the player to another room of the dungeon.
* It's called when a player walk through an opened door.
*
* \param direction : direction of the new map. 4 = left, 8 = north, 6 = right, 2 = south
*/
void moveToOtherMap(int direction);
/*!
* \brief Closes the doors of the room
*
* Closes the doors of the room.
* It's called when the player enter in an area with monsters.
*/
void closeDoors();
/*!
* \brief Opens the doors of the room
*
* Opens the doors of the room.
* It's called when the player destroy the last monster of a room.
*/
void openDoors();
/*!
* \brief Count the enemies in the room
*
* Count the enemies in the room.
* It's called when the room is closed : 0 enemy = room is cleared and doors shall open.
*
* \return amount of enemies
*/
int getEnnemyCount();
/*!
* \brief Generates blood
*
* Generates blood, it's called when someone is hurt or dies.
*
* \param x : x position of the blood
* \param y : y position of the blood
* \param bloodColor : color of the blood (red; green, ...)
*/
void generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor);
/*!
* \brief Show a "popup" with artefact's description
*
* Show a "popup" with artefact's description.
* Artefact's description consists of zoomed picture of the item, name and description.
* It's called when a player get an equipment item.
*
* \param itemType : item identifier
*/
void showArtefactDescription(enumItemType itemType);
- void Write(std::string str, int size, float x, float y, int align, sf::Color color);
+ /*!
+ * \brief Make a "shake" effet
+ * \param duration : duration of the effect
+ */
+ void makeShake(float duration);
+
+ void Write(std::string str, int size, float x, float y, int align, sf::Color color, sf::RenderTarget* app);
/*!
* \brief Save the game
*
* Save the game to file : complete floor and maps, items and blood position, player current equipment and stats....
*/
void saveGame();
/*!
* \brief Load the game
*
* Load the game from file. After restoring the game, the file is destroy.
*
* \return true if succeeded
*/
bool loadGame();
protected:
/*!
* \brief Rendering method
*
* Render all the game objects to the screen.
* Called in the game loop.
*/
virtual void onRender();
/*!
* \brief Update method
*
* Update all the game objects to the screen.
* Called in the game loop.
*/
virtual void onUpdate();
/*!
* \brief render the HUD for shot types
*
* Render the HUD for shot types.
* Display the available shot types and highlight the current one.
*
* \param app : Rendering target
*/
- void renderHudShots(sf::RenderWindow* app);
+ void renderHudShots(sf::RenderTarget* app);
private:
// game logic / data
GameMap* miniMap; /*!< Pointer to the logical minimap */
DungeonMap* currentMap; /*!< Pointer to the logical current map */
GameFloor* currentFloor; /*!< Pointer to the logical floor (level) */
// game play
int level; /*!< Level (floor) */
int floorX; /*!< X position of the room in the level */
int floorY; /*!< Y position of the room in the level */
bool roomClosed; /*!< True if the room is closed */
bool bossRoomOpened; /*!< True if the boss gate has been opened in this level */
bool isPausing; /*!< True if the game is currently pausing */
int firingDirection; /*!< Save the firing direction - for the "one button" gameplay */
bool isPlayerAlive; /*!< Dying sets this bool to false (trigger the ending music) */
bool monsterArray[MAP_WIDTH][MAP_HEIGHT]; /*!< use to remember if a case has a monster in monster spawn */
// game objects
PlayerEntity* player; /*!< Pointer to the player entity */
TileMapEntity* currentTileMap; /*!< TileMap of the room (main game board) */
// displaying objects
DoorEntity* doorEntity[4]; /*!< Pointers to the door graphical entity */
sf::Sprite keySprite; /*!< A simple sprite with the boss key (displayed on the HUD) */
sf::Sprite shotsSprite; /*!< A simple sprite for the available shot types (displayed on the HUD) */
sf::Font font; /*!< The font used for displaying text */
sf::Text myText; /*!< The text to be displayed */
+ sf::RenderTexture mainTexture; /*!< The main game in a texture */
+ sf::Sprite mainSprite; /*!< The main game in a sprite */
sf::Music music; /*!< Current game music */
/** Music enum
* Identify the various music tracks of the game.
*/
enum musicEnum
{
MusicDungeon, /**< Main game music - played when playing the game */
MusicEnding, /**< Ending music - played when the player has died */
MusicBoss /**< Boss music - for epic fights ! */
};
/** Game states enum
* Used for the different game states
*/
enum gameStateEnum
{
gameStateInit, /**< Game initialization */
gameStatePlaying, /**< Playing */
gameStateKeyConfig /**< Key config */
};
gameStateEnum gameState; /*!< Store the game state */
/** Special game states enum
* Used for effects such as fade in...
*/
enum xGameStateEnum
{
xGameStateNone, /**< No effect */
xGameStateFadeIn, /**< Fade in effect - usually when starting a level */
- xGameStateFadeOut /**< Fade out effect - usually when leaving a level */
+ xGameStateFadeOut, /**< Fade out effect - usually when leaving a level */
+ xGameStateShake /**< Shake effect */
};
xGameStateEnum xGameState; /*!< Store the effect game state */
float xGameTimer; /*!< Effect game timer */
/** Input Keys enum
* Used for the input binding
*/
enum inputKeyEnum
{
KeyUp,
KeyDown,
KeyLeft,
KeyRight,
KeyFireUp,
KeyFireDown,
KeyFireLeft,
KeyFireRight
};
sf::Keyboard::Key input[8]; /*!< Input key aray */
/*!
* \brief Starts the game
*
* Start a new game or load it from file.
*
* \param fromSaveFile : true if we want to try to load the game from a file
*/
void startNewGame(bool fromSaveFile);
/*!
* \brief Starts a new level
*
* Start a new level.
* Called for each level of the game.
*/
void startNewLevel();
/*!
* \brief Starts the level
*
* Starts the level.
* Called after loading the game or creating a new level.
*/
void playLevel();
/*!
* \brief Creates a level
*
* Creates a random level (a level is a floor that consists of rooms).
*/
void createFloor();
/*!
* \brief Create or refresh the room
*
* Create a room (if this is a new one) or refresh it.
* Called when the player changes room.
* Checks the visibility of the doors and close it if there are monsters.
* Loads the mas items and sprites.
*/
void refreshMap();
/*!
* \brief Refreshes the minimap
*
* Refresh the minimap.
* Called when the player changes room.
*/
void refreshMinimap();
/*!
* \brief Generates a room
*
* Generates a room.
* Called when the player moves to a room for the first time.
*/
void generateMap();
/*!
* \brief Generates a standard room
*
* Generates a standard room with monsters.
* Called during the generation when the map has no particular type.
*/
void generateStandardMap();
/*!
* \brief Checks if the room will be closed
*
* Checks if the room will be closed.
* Called when entering a room. If the room is not clear, closes the doors.
*/
void checkEntering();
/*!
* \brief Saves the map items
*
* Saves the map objects such as items, corpses, blood, chest.
* Called when leaving the door.
*/
void saveMapItems();
/*!
* \brief Initializes the monster array
*
* Initializes the monster array (to empty).
*/
void initMonsterArray();
/*!
* \brief Adds a monster
*
* Adds a monster to the room.
* \param monsterType : monster type
* \param xm : x position of the monster
* \param ym : y position of the monster
*/
void addMonster(monster_type_enum monsterType, float xm, float ym);
/*!
* \brief Adds monsters
*
* Adds monsters to the room in suitable places.
* \param monsterType : monster type
* \param amount : amount of monsters
*/
void findPlaceMonsters(monster_type_enum monsterType, int amount);
/*!
* \brief Returns a random equip object
*
* Returns a random equip object (not an object the player already possesses) .
* \param toSale : true if it's an item for sale
*
* \return the equipment item ID
*/
item_equip_enum getRandomEquipItem(bool toSale);
/*!
* \brief Checks if player opens a door
*
* Checks if player opens a door (collide with the door and gets the key).
* If positive, opens the door.
*/
void verifyDoorUnlocking();
/*!
* \brief Plays a music
*
* Plays a music.
*
* \param musicChoice : music track ID
*/
void playMusic(musicEnum musicChoice);
};
/*!
* \brief Returns the game reference
*
* Returns the game reference.
*
* \return a reference to the game
*/
WitchBlastGame& game();
#endif // WITCH_BLAST_GAME_H
diff --git a/src/sfml_game/CollidingSpriteEntity.cpp b/src/sfml_game/CollidingSpriteEntity.cpp
index c73b9d1..a021279 100644
--- a/src/sfml_game/CollidingSpriteEntity.cpp
+++ b/src/sfml_game/CollidingSpriteEntity.cpp
@@ -1,280 +1,280 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CollidingSpriteEntity.h"
CollidingSpriteEntity::CollidingSpriteEntity(sf::Texture* image, float x, float y, int width, int height)
: SpriteEntity(image, x, y, width, height)
{
maxY = 1000.0f;
}
CollidingSpriteEntity::~CollidingSpriteEntity()
{
}
GameMap* CollidingSpriteEntity::getMap()
{
return map;
}
void CollidingSpriteEntity::setMap(GameMap* map, int tileWidth, int tileHeight, int offsetX, int offsetY)
{
this->map = map;
setTileDimensions(tileWidth, tileHeight);
this->offsetX = offsetX;
this->offsetY = offsetY;
}
void CollidingSpriteEntity::setTileDimensions(int width, int height)
{
tileWidth = width;
tileHeight = height;
}
-void CollidingSpriteEntity::render(sf::RenderWindow* app)
+void CollidingSpriteEntity::render(sf::RenderTarget* app)
{
SpriteEntity::render(app);
}
void CollidingSpriteEntity::animate(float delay)
{
velocity.x *= viscosity;
velocity.y *= viscosity;
spin *= viscosity;
angle += spin * delay;
velocity.y += weight * delay;
if ((int)velocity.x > 0)
{
x += velocity.x * delay;
if (collideWithMap(DIRECTION_LEFT))
{
x = (float)((int)x);
while (collideWithMap(DIRECTION_LEFT))
x--;
collideMapRight();
}
else if (x > map->getWidth() * tileWidth + offsetX)
{
exitMap(DIRECTION_RIGHT);
}
}
else if ((int)velocity.x < 0)
{
x += velocity.x * delay;
if (collideWithMap(DIRECTION_RIGHT))
{
x = (float)((int)x);
while (collideWithMap(DIRECTION_RIGHT))
x++;
collideMapLeft();
}
else if (x < offsetX)
{
exitMap(DIRECTION_LEFT);
}
}
velocity.y += weight * delay;
if ( velocity.y > maxY) velocity.y = maxY;
if ((int)velocity.y > 0)
{
y += velocity.y * delay;
if (collideWithMap(DIRECTION_BOTTOM))
{
y = (float)((int)y);
while (collideWithMap(DIRECTION_BOTTOM))
y--;
collideMapBottom();
}
}
else if ((int)velocity.y < 0)
{
y += velocity.y * delay;
//calculateBB();
if (collideWithMap(DIRECTION_TOP))
{
y = (float)((int)y);
while (collideWithMap(DIRECTION_TOP))
y++;
collideMapTop();
}
}
// for platforming
/* if ((int)weight == 0)
{
if (!(isOnGround()))
{
makeFall();
}
}*/
if (lifetime > 0)
{
if (age >= lifetime) isDying = true;
}
age += delay;
}
void CollidingSpriteEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - height / 2;
boundingBox.height = height;
}
void CollidingSpriteEntity::makeFall()
{
weight = normalWeight;
}
bool CollidingSpriteEntity::isOnGround()
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile = (boundingBox.top + boundingBox.height + 1 - offsetY) / tileHeight;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
{
if (map->isDownBlocking(xTile, yTile)) return true;
}
return false;
}
void CollidingSpriteEntity::exitMap(int direction)
{
if (direction == 0) {}
}
void CollidingSpriteEntity::collideMapRight()
{
velocity.x = 0.0f;
}
void CollidingSpriteEntity::collideMapLeft()
{
velocity.x = 0.0f;
}
void CollidingSpriteEntity::collideMapTop()
{
velocity.y = 0.0f;
}
void CollidingSpriteEntity::collideMapBottom()
{
velocity.y = 0.0f;
}
bool CollidingSpriteEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
switch (direction)
{
case DIRECTION_LEFT:
if (map->isLeftBlocking(xTile, yTile)) return true;
break;
case DIRECTION_RIGHT:
if (map->isRightBlocking(xTile, yTile)) return true;
break;
case DIRECTION_TOP:
if (map->isUpBlocking(xTile, yTile)) return true;
break;
case DIRECTION_BOTTOM:
if (map->isDownBlocking(xTile, yTile)) return true;
break;
}
}
return false;
}
bool CollidingSpriteEntity::collideWithEntity(CollidingSpriteEntity* entity)
{
calculateBB();
entity->calculateBB();
return boundingBox.intersects(entity->boundingBox);
/*if (boundingBox.left > entity->boundingBox.left + entity->boundingBox.width) return false;
if (boundingBox.Right < entity->boundingBox.Left) return false;
if (boundingBox.Top > entity->boundingBox.Bottom) return false;
if (boundingBox.Bottom < entity->boundingBox.Top) return false;*/
return true;
}
void CollidingSpriteEntity::testSpriteCollisions()
{
EntityManager::EntityList* entityList = EntityManager::getEntityManager()->getList();
EntityManager::EntityList::iterator it;
EntityManager::EntityList::iterator oldit = entityList->begin ();
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity* entity = *it;
CollidingSpriteEntity* collidingEntity = dynamic_cast<CollidingSpriteEntity*>(entity);
if (collidingEntity != NULL)
{
readCollidingEntity(collidingEntity);
}
oldit = it;
it++;
} // end for*/
}
void CollidingSpriteEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (entity == NULL) return;
}
void CollidingSpriteEntity::collideEntity(CollidingSpriteEntity* entity)
{
if (entity == NULL) return;
}
diff --git a/src/sfml_game/CollidingSpriteEntity.h b/src/sfml_game/CollidingSpriteEntity.h
index e06f294..1cb4f3a 100644
--- a/src/sfml_game/CollidingSpriteEntity.h
+++ b/src/sfml_game/CollidingSpriteEntity.h
@@ -1,76 +1,76 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COLLIDINGSPRITEENTITY_H_INCLUDED
#define COLLIDINGSPRITEENTITY_H_INCLUDED
#include "SpriteEntity.h"
#include "GameMap.h"
// Basis class for Jouster
class CollidingSpriteEntity : public SpriteEntity
{
public:
CollidingSpriteEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int width = -1, int height = -1);
~CollidingSpriteEntity();
GameMap* getMap();
void setMap(GameMap* map, int tileWidth, int tileHeight, int offsetX, int offsetY);
void setTileDimensions(int width, int height);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
virtual void calculateBB();
virtual void makeFall();
virtual bool collideWithMap(int direction);
virtual bool collideWithEntity(CollidingSpriteEntity* entity);
enum directionEnum
{
DIRECTION_RIGHT,
DIRECTION_LEFT,
DIRECTION_TOP,
DIRECTION_BOTTOM
};
bool isOnGround();
protected:
GameMap* map; // map to test collisions with
sf::IntRect boundingBox; // BoundingBox
int tileWidth;
int tileHeight;
int offsetX;
int offsetY;
float normalWeight;
float maxY;
virtual void exitMap(int direction);
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
virtual void collideEntity(CollidingSpriteEntity* entity);
virtual void testSpriteCollisions();
virtual void readCollidingEntity(CollidingSpriteEntity* entity);
};
#endif // COLLIDINGSPRITEENTITY_H_INCLUDED
diff --git a/src/sfml_game/EntityManager.cpp b/src/sfml_game/EntityManager.cpp
index 9f69fdc..a77e9e1 100644
--- a/src/sfml_game/EntityManager.cpp
+++ b/src/sfml_game/EntityManager.cpp
@@ -1,197 +1,231 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "EntityManager.h"
#include <stdlib.h>
#include <iostream>
#include "GuiEntity.h"
EntityManager::EntityManager()
{
initIterator();
mItems = 0;
}
EntityManager* EntityManager::getEntityManager()
{
static EntityManager singleton;
return &singleton;
}
void EntityManager::add(GameEntity* g)
{
entityList.push_back(g);
mItems++;
}
void EntityManager::initIterator()
{
mIterator = entityList.begin ();
}
GameEntity* EntityManager::nextItem()
{
if (mIterator == entityList.end ()) return NULL;
GameEntity *e = *mIterator;
mIterator++;
return e;
}
void EntityManager::animate (float delay)
{
if (!isEmpty())
{
EntityList::iterator it;
EntityList::iterator oldit = entityList.begin ();
//bool isBegin = false;
for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
{
GameEntity *e = *it;
oldit = it;
it++;
if (e->getDying())
{
entityList.erase(oldit);
e->onDying();
delete e;
//e == NULL;
mItems--;
} // endif
else
e->animate(delay);
} // end for
}
}
-void EntityManager::render(sf::RenderWindow* app)
+void EntityManager::render(sf::RenderTarget* app)
{
if (!isEmpty())
{
EntityList::iterator it;
EntityList::iterator oldit = entityList.begin ();
- //bool isBegin = false;
+
for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
{
GameEntity* e = *it;
oldit = it;
e->render(app);
it++;
} // end for
}
}
+void EntityManager::renderUnder(sf::RenderTarget* app, int n)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GameEntity* e = *it;
+ oldit = it;
+ if (e->getZ() < n) e->render(app);
+ it++;
+ } // end for
+ }
+}
+
+void EntityManager::renderAfter(sf::RenderTarget* app, int n)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GameEntity* e = *it;
+ oldit = it;
+ if (e->getZ() >= n) e->render(app);
+ it++;
+ } // end for
+ }
+}
+
void EntityManager::onEvent(sf::Event event)
{
if (!isEmpty())
{
EntityList::iterator it;
EntityList::iterator oldit = entityList.begin ();
for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
{
GuiEntity* guiEntity = dynamic_cast<GuiEntity*>(*it);
if (guiEntity != NULL)
{
guiEntity->onEvent(event);
}
oldit = it;
it++;
} // end for
}
}
void EntityManager::clean ()
{
if (!isEmpty())
{
EntityList::iterator it;
EntityList::iterator oldit = entityList.begin ();
//bool isBegin = false;
//EL.clear();
for (it = entityList.begin (); it != entityList.end ();)
{
GameEntity *e = *it;
oldit = it;
it++;
entityList.erase(oldit);
//e->onDying();
delete e;
//e == NULL;
} // end for*/
mItems = 0;
}
}
void EntityManager::displayToConsole()
{
std::cout << "{ ";
if (!isEmpty())
{
EntityList::iterator it;
//bool isBegin = false;
//EL.clear();
for (it = entityList.begin (); it != entityList.end ();)
{
GameEntity *e = *it;
it++;
std::cout << e->getType() << ", ";
//e == NULL;
} // end for*/
}
std::cout << " }" << std::endl;
}
void EntityManager::partialClean (int n)
{
if (!isEmpty())
{
EntityList::iterator it;
//bool isBegin = false;
for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
{
GameEntity *e = *it;
it++;
if (e->getType() >= n)
{
e->setDying(true);
} // endif
} // end for
}
}
EntityManager::EntityList* EntityManager::getList()
{
return &entityList;
}
bool compareZ(GameEntity* g1, GameEntity* g2)
{
return g1->getZ() < g2->getZ();
}
void EntityManager::sortByZ()
{
entityList.sort(compareZ);
}
diff --git a/src/sfml_game/EntityManager.h b/src/sfml_game/EntityManager.h
index 656977d..6b751ba 100644
--- a/src/sfml_game/EntityManager.h
+++ b/src/sfml_game/EntityManager.h
@@ -1,66 +1,68 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ENTITYMANAGER
#define __ENTITYMANAGER
#include <list>
class GameEntity;
#include "GameEntity.h"
class EntityManager
{
public:
static EntityManager* getEntityManager();
void initIterator();
void add(GameEntity* g);
void animate (float delay);
- void render (sf::RenderWindow* app);
+ void render (sf::RenderTarget* app);
+ void renderAfter (sf::RenderTarget* app, int n);
+ void renderUnder (sf::RenderTarget* app, int n);
void onEvent(sf::Event event);
void displayToConsole();
typedef std::list<GameEntity*> EntityList;
EntityList* getList();
void clean();
void partialClean(int n);
void sortByZ();
protected:
EntityManager();
~EntityManager() { clean(); }; // TODO !
GameEntity* nextItem();
bool isEmpty() { return mItems == 0; };
int count() { return mItems; }
void saveIterator() { mSavedIterator = mIterator; }
void restoreIterator() { mIterator = mSavedIterator; }
private:
EntityList entityList;
EntityList::iterator mIterator, mSavedIterator;
int mItems;
};
#endif
diff --git a/src/sfml_game/Game.h b/src/sfml_game/Game.h
index a64ed92..12e70a2 100644
--- a/src/sfml_game/Game.h
+++ b/src/sfml_game/Game.h
@@ -1,51 +1,51 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * sfmlGame is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * sfmlGame is distributed in the hope that it will be useful,
+ * Witch Blast 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 sfmlGame. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <stdio.h>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
//#include "Entity/EntityManager.h"
class Game
{
public:
Game(int screenWidth, int screenHeight, std::string windowsTitle = "Generic sfmlGame", bool fullScreen = false);
virtual ~Game();
virtual void startGame();
virtual void quitGame();
static float getAbsolutTime();
protected:
virtual void onRender(); // screen and game items rendering
virtual void onUpdate();
int screenWidth;
int screenHeight;
float lastTime;
sf::RenderWindow* app;
};
#endif // GAME_H_INCLUDED
diff --git a/src/sfml_game/GameEntity.cpp b/src/sfml_game/GameEntity.cpp
index f8db7d7..49eb109 100644
--- a/src/sfml_game/GameEntity.cpp
+++ b/src/sfml_game/GameEntity.cpp
@@ -1,123 +1,123 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GameEntity.h"
#include <stdlib.h>
GameEntity::GameEntity()
{
GameEntity(0.0f, 0.0f);
type = 0;
}
bool GameEntity::operator < (const GameEntity& rhs)
{
return z > rhs.z;
}
GameEntity::GameEntity(float m_x, float m_y)
{
x = m_x;
y = m_y;
bbox.x = 0.0f; bbox.y = 0.0f;
bbox.width = 0.0f; bbox.height = 0.0f;
age = 0;
lifetime = -1;
visible = true;
isDying = false;
viscosity = 1.0f;
weight = 0.0f;
velocity.x = 0.0f;
velocity.y = 0.0f;
angle = 0.0f;
spin = 0.0f;
EntityManager::getEntityManager()->add(this);
}
GameEntity::~GameEntity()
{
}
bool GameEntity::getDying() { return isDying; }
float GameEntity::getX() { return x; }
float GameEntity::getY() { return y; }
float GameEntity::getZ() { return z; }
float GameEntity::getAge() { return age; }
int GameEntity::getType() { return type; }
Vector2D GameEntity::getVelocity() { return Vector2D(velocity.x, velocity.y); }
void GameEntity::setX(float x) { this->x = x; }
void GameEntity::setY(float y) { this->y = y; }
void GameEntity::setZ(float z) { this->z = z; }
void GameEntity::setAngle(float angle) { this->angle = angle; }
void GameEntity::setWeight(float weight) { this->weight = weight; }
void GameEntity::setSpin(float spin) { this->spin = spin; }
void GameEntity::setAge(float age) { this->age = age; }
void GameEntity::setLifetime(float lifetime) { this->lifetime = lifetime; }
void GameEntity::setVelocity(Vector2D velocity)
{
this->velocity.x = velocity.x;
this->velocity.y = velocity.y;
}
void GameEntity::setDying(bool dying) { isDying = dying; }
void GameEntity::setType(int type) { this->type = type; }
void GameEntity::setViscosity(float viscosity) { this->viscosity = viscosity; }
void GameEntity::animate(float delay)
{
velocity.x *= viscosity;
velocity.y *= viscosity;
spin *= viscosity;
angle += spin * delay;
velocity.y += weight * delay;
x += velocity.x * delay;
y += velocity.y * delay;
age += delay;
if (lifetime > 0)
{
if (age >= lifetime) isDying = true;
}
}
-void GameEntity::render(sf::RenderWindow* app)
+void GameEntity::render(sf::RenderTarget* app)
{
if (app == NULL) return;
}
void GameEntity::onDying()
{
}
float GameEntity::getFade()
{
if (lifetime > 0)
{
float f= 1.0f - (float)age/lifetime;
if (f < 0.0f) f=0.0f;
if (f > 1.0f) f=1.0f;
return f;
}
else return 1.0f;
}
diff --git a/src/sfml_game/GameEntity.h b/src/sfml_game/GameEntity.h
index 0abfdbe..1b60bf7 100644
--- a/src/sfml_game/GameEntity.h
+++ b/src/sfml_game/GameEntity.h
@@ -1,102 +1,102 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GAMEENTITY
#define __GAMEENTITY
#include <SFML/Graphics.hpp>
#include "MyTools.h"
#include "EntityManager.h"
#include "Game.h"
class EntityManager;
/** Objects to be displayed during the game.
* A basic physics has been implemented.
* The EntityManager will destroy the GameEntity when dying. */
class GameEntity
{
public:
struct bboxStruct
{
float x, y, width, height;
} bbox;
GameEntity();
GameEntity(float m_x, float m_y);
//GameEntity(float m_x = 0.0f, float m_y = 0.0f, m_type = TypePart02 );
virtual ~GameEntity();
bool operator < (const GameEntity& rhs);
// accesors
bool getDying();
float getX();
float getY();
float getZ();
Vector2D getVelocity();
float getAge();
int getType();
// mutators
void setX(float x);
void setY(float y);
void setZ(float z);
void setAngle(float angle);
void setWeight(float weight);
void setVelocity(Vector2D velocity);
void setSpin(float spin);
void setAge(float age);
void setLifetime(float lifetime);
void setDying(bool dying);
void setType(int type);
void setViscosity(float viscosity);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
virtual void onDying();
float getFade();
protected:
// position and physics (geometry)
float x, y, z;
float angle;
float spin;
Vector2D velocity;
Vector2D acceleration;
float weight;
float viscosity;
// visibility
bool visible;
// life_time
float age, lifetime;
bool isDying;
int type;
};
#endif
diff --git a/src/sfml_game/GameMap.h b/src/sfml_game/GameMap.h
index 36cf90b..8b0f690 100644
--- a/src/sfml_game/GameMap.h
+++ b/src/sfml_game/GameMap.h
@@ -1,52 +1,51 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
-
#ifndef GAMEMAP_H_INCLUDED
#define GAMEMAP_H_INCLUDED
#include <string>
using namespace std ;
class GameMap
{
public:
GameMap(int width, int height);
virtual ~GameMap();
int getWidth();
int getHeight();
int getTile(int x, int y);
bool getChanged();
virtual bool isDownBlocking(int x, int y);
virtual bool isUpBlocking(int x, int y);
virtual bool isLeftBlocking(int x, int y);
virtual bool isRightBlocking(int x, int y);
bool inMap(int x, int y);
void setTile(int x, int y, int n);
virtual void randomize(int n);
virtual void loadFromFile(const char* fileName);
protected:
int width;
int height;
int** map;
bool hasChanged;
};
#endif // GAMEMAP_H_INCLUDED
diff --git a/src/sfml_game/GuiEntity.cpp b/src/sfml_game/GuiEntity.cpp
index cc270bf..1016afd 100644
--- a/src/sfml_game/GuiEntity.cpp
+++ b/src/sfml_game/GuiEntity.cpp
@@ -1,41 +1,41 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GuiEntity.h"
GuiEntity::GuiEntity(float x, float y) : GameEntity(x, y)
{
isActive = true;
}
bool GuiEntity::getActive() { return isActive; }
void GuiEntity::setActive(bool active) { isActive = active; }
-void GuiEntity::render(sf::RenderWindow* app)
+void GuiEntity::render(sf::RenderTarget* app)
{
if (app == NULL) return;
}
void GuiEntity::animate(float delay)
{
GameEntity::animate(delay);
}
void GuiEntity::onEvent(sf::Event event)
{
if (event.type == sf::Event::Closed) return;
}
diff --git a/src/sfml_game/GuiEntity.h b/src/sfml_game/GuiEntity.h
index 506e75b..31dfae0 100644
--- a/src/sfml_game/GuiEntity.h
+++ b/src/sfml_game/GuiEntity.h
@@ -1,41 +1,41 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GUIENTITY_H_INCLUDED
#define GUIENTITY_H_INCLUDED
#include "GameEntity.h"
// Basis class for GUI
class GuiEntity : public GameEntity
{
public:
GuiEntity(float x = 0.0f, float y = 0.0f);
bool getActive();
void setActive(bool active);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
virtual void onEvent(sf::Event event);
protected:
bool isActive;
};
#endif // GUIENTITY_H_INCLUDED
diff --git a/src/sfml_game/ImageManager.h b/src/sfml_game/ImageManager.h
index 8ed2dd2..39fb120 100644
--- a/src/sfml_game/ImageManager.h
+++ b/src/sfml_game/ImageManager.h
@@ -1,37 +1,37 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IMAGEMANAGER_H_INCLUDED
#define IMAGEMANAGER_H_INCLUDED
#include <SFML/Graphics.hpp>
class ImageManager
{
public:
static ImageManager* getImageManager();
void addImage(char* fileName);
bool reloadImage(int n, const char* fileName);
sf::Texture* getImage(int n);
private:
ImageManager();
~ImageManager();
std::vector<sf::Texture*> imageArray;
};
#endif // IMAGEMANAGER_H_INCLUDED
diff --git a/src/sfml_game/MyTools.h b/src/sfml_game/MyTools.h
index 181bf61..93a897d 100644
--- a/src/sfml_game/MyTools.h
+++ b/src/sfml_game/MyTools.h
@@ -1,91 +1,91 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __MYTOOLS
#define __MYTOOLS
#include <stdlib.h>
#include <math.h>
/** Vector utility, used in physics
** Default constructor creates a random Vector */
class Vector2D
{
public:
float x, y;
Vector2D(float amplitude = 1.0f)
{
float v = (float)rand() / (float)RAND_MAX;
v *= 6.283f;
x = cosf(v) * amplitude;
y = sinf(v) * amplitude;
}
Vector2D(float m_x, float m_y) { x = m_x; y = m_y; }
float distance2(Vector2D vector)
{
return ( (vector.x - x) * (vector.x - x) + (vector.y - y) * (vector.y - y) );
}
float distance2(Vector2D vector, float repeatZone)
{
float result = (vector.x - x) * (vector.x - x) + (vector.y - y) * (vector.y - y);
float d2 = (vector.x - ( x + repeatZone) ) * (vector.x - ( x + repeatZone)) + (vector.y - y) * (vector.y - y);
if (d2 < result) result = d2;
d2 = ( (vector.x + repeatZone) - x) * ((vector.x + repeatZone) - x) + (vector.y - y) * (vector.y - y);
if (d2 < result) result = d2;
return result;
}
float angleTo(Vector2D vector)
{
float tan = (vector.x - x) / (vector.y - y);
float angle = atan(tan);
return angle;
}
Vector2D vectorTo(Vector2D vector, float amplitude)
{
float angle = angleTo(vector);
Vector2D result;
if (vector.y > y)
{
result.x = sin(angle) * amplitude;
result.y = cos(angle) * amplitude;
}
else
{
result.x = -sin(angle) * amplitude;
result.y = -cos(angle) * amplitude;
}
return result;
}
};
class IntCoord
{
public:
int x, y;
IntCoord(int x, int y) { this->x = x; this->y = y; }
};
#endif
diff --git a/src/sfml_game/SoundManager.h b/src/sfml_game/SoundManager.h
index 19ae4c6..e6e9977 100644
--- a/src/sfml_game/SoundManager.h
+++ b/src/sfml_game/SoundManager.h
@@ -1,38 +1,38 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SOUNDMANAGER_H_INCLUDED
#define SOUNDMANAGER_H_INCLUDED
#include <SFML/Audio.hpp>
class SoundManager
{
public:
static SoundManager* getSoundManager();
void addSound(char* fileName);
void playSound(int n);
void stopSound(int n);
private:
SoundManager();
~SoundManager();
std::vector<sf::SoundBuffer*> soundBufferArray;
std::vector<sf::Sound*> soundArray;
};
#endif // SOUNDMANAGER_H_INCLUDED
diff --git a/src/sfml_game/SpriteEntity.cpp b/src/sfml_game/SpriteEntity.cpp
index 80fd27a..1189189 100644
--- a/src/sfml_game/SpriteEntity.cpp
+++ b/src/sfml_game/SpriteEntity.cpp
@@ -1,123 +1,123 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SpriteEntity.h"
SpriteEntity::SpriteEntity(sf::Texture* image, float x, float y, int width, int height, int imagesProLine) : GameEntity(x, y)
{
frame = 0;
isFading = false;
isShrinking = false;
isVisible = true;
isMirroring = false;
this->image = image;
sprite.setTexture(*image);
this->width = width <= 0 ? image->getSize().x : width;
this->height = height <= 0 ? image->getSize().y : height;
//sprite.SetSubRect(sf::IntRect(0, 0, this->width, this->height));
sprite.setOrigin((float)(this->width / 2), (float)(this->height / 2));
this->imagesProLine = imagesProLine;
}
int SpriteEntity::getFrame() { return frame; }
int SpriteEntity::getWidth() { return width; }
float SpriteEntity::getScaleX()
{
return sprite.getScale().x;
}
void SpriteEntity::setFading(bool isFading)
{
this->isFading = isFading;
}
void SpriteEntity::setShrinking(bool isShrinking)
{
//this->isShrinking = isShrinking;
setShrinking(isShrinking, 1.0f, 1.0f);
}
void SpriteEntity::setShrinking(bool isShrinking, float initialScaleX, float initialScaleY)
{
this->isShrinking = isShrinking;
this->initialScaleX = initialScaleX;
this->initialScaleY = initialScaleY;
}
void SpriteEntity::setVisible(bool isVisible)
{
this->isVisible = isVisible;
}
void SpriteEntity::setFrame(int frame) { this->frame = frame; }
void SpriteEntity::setScale(float scx, float scy)
{
sprite.setScale(scx, scy);
}
void SpriteEntity::setImagesProLine(int n)
{
imagesProLine = n;
}
void SpriteEntity::removeCenter()
{
sprite.setOrigin(0.0f, 0.0f);
}
-void SpriteEntity::render(sf::RenderWindow* app)
+void SpriteEntity::render(sf::RenderTarget* app)
{
if (isVisible)
{
int nx = frame;
int ny = 0;
if (imagesProLine > 0)
{
nx = frame % imagesProLine;
ny = frame / imagesProLine;
}
if (isMirroring)
sprite.setTextureRect(sf::IntRect((nx + 1) * width, ny * height, -width, height));
else
sprite.setTextureRect(sf::IntRect(nx * width, ny * height, width, height));
sprite.setPosition(x, y);
sprite.setRotation(angle);
if (isFading)
{
sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)(getFade() * 255)));
}
if (isShrinking)
{
sprite.setScale(initialScaleX * getFade(),
initialScaleY * getFade());
}
app->draw(sprite);
}
}
void SpriteEntity::animate(float delay)
{
GameEntity::animate(delay);
}
diff --git a/src/sfml_game/SpriteEntity.h b/src/sfml_game/SpriteEntity.h
index b5659f1..3639a8c 100644
--- a/src/sfml_game/SpriteEntity.h
+++ b/src/sfml_game/SpriteEntity.h
@@ -1,63 +1,63 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SPRITEENTITY_H_INCLUDED
#define SPRITEENTITY_H_INCLUDED
#include "GameEntity.h"
// Basis class for sprite
class SpriteEntity : public GameEntity
{
public:
// create a sprite with the entire image
SpriteEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int width = -1, int height = -1, int imagesProLine = 0);
int getFrame();
float getScaleX();
int getWidth();
void setFading(bool isFading);
void setShrinking(bool isShrinking);
void setShrinking(bool isShrinking, float initialScaleX, float initialScaleY);
void setVisible(bool isVisible);
void setFrame(int frame);
void setImagesProLine(int n);
void setScale(float scx, float scy);
void removeCenter();
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
protected:
sf::Sprite sprite;
sf::Texture* image;
int width;
int height;
int frame;
int imagesProLine;
// for shrinking
float initialScaleX, initialScaleY;
bool isFading;
bool isShrinking;
bool isVisible;
bool isMirroring;
};
#endif // SPRITEENTITY_H_INCLUDED
diff --git a/src/sfml_game/TileMapEntity.cpp b/src/sfml_game/TileMapEntity.cpp
index cf00f35..ac1da31 100644
--- a/src/sfml_game/TileMapEntity.cpp
+++ b/src/sfml_game/TileMapEntity.cpp
@@ -1,98 +1,98 @@
/** This file is part of sfmlGame.
*
* FreeTumble 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 3 of the License, or
* (at your option) any later version.
*
* FreeTumble 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TileMapEntity.h"
TileMapEntity::TileMapEntity(sf::Texture* image, GameMap* gameMap, int tileWidth, int tileHeight, int tilesProLine)
: GameEntity(0.0f, 0.0f)
{
this->image = image;
this->tileWidth = tileWidth;
this->tileHeight = tileHeight;
tileBoxWidth = tileWidth;
tileBoxHeight = tileHeight;
this->tilesProLine = tilesProLine;
this->gameMap = gameMap;
this->z = -1.0f;
type = 0;
hasChanged = true;
}
TileMapEntity::~TileMapEntity()
{
}
void TileMapEntity::setMap(GameMap* gameMap)
{
this->gameMap = gameMap;
hasChanged = true;
}
void TileMapEntity::setTileBox(int tileBoxWidth, int tileBoxHeight)
{
this->tileBoxWidth = tileBoxWidth;
this->tileBoxHeight = tileBoxHeight;
}
int TileMapEntity::getTilesProLine()
{
return tilesProLine;
}
bool TileMapEntity::getChanged()
{
bool result = hasChanged;
hasChanged = false;
return result;
}
void TileMapEntity::computeVertices()
{
vertices.setPrimitiveType(sf::Quads);
vertices.resize(gameMap->getWidth() * gameMap->getHeight() * 4);
for (int i = 0; i < gameMap->getWidth(); i++)
for (int j = 0; j < gameMap->getHeight(); j++)
{
int nx = gameMap->getTile(i, j) % tilesProLine;
int ny = gameMap->getTile(i, j) / tilesProLine;
sf::Vertex* quad = &vertices[(i + j * gameMap->getWidth()) * 4];
quad[0].position = sf::Vector2f(x + i * tileWidth, y + j * tileHeight);
quad[1].position = sf::Vector2f(x + (i + 1) * tileWidth + (tileBoxWidth -tileWidth), y + j * tileHeight);
quad[2].position = sf::Vector2f(x + (i + 1) * tileWidth + (tileBoxWidth -tileWidth), y + (j + 1) * tileHeight + (tileBoxHeight - tileHeight));
quad[3].position = sf::Vector2f(x + i * tileWidth, y + (j + 1) * tileHeight + (tileBoxHeight - tileHeight));
quad[0].texCoords = sf::Vector2f(nx * tileBoxWidth, ny * tileBoxHeight);
quad[1].texCoords = sf::Vector2f((nx + 1) * tileBoxWidth, ny * tileBoxHeight);
quad[2].texCoords = sf::Vector2f((nx + 1) * tileBoxWidth, (ny + 1) * tileBoxHeight);
quad[3].texCoords = sf::Vector2f(nx * tileBoxWidth, (ny + 1) * tileBoxHeight);
}
}
-void TileMapEntity::render(sf::RenderWindow* app)
+void TileMapEntity::render(sf::RenderTarget* app)
{
app->draw(vertices, image);
}
void TileMapEntity::animate(float delay)
{
age += delay;
bool needCompute = getChanged() || gameMap->getChanged();
if (needCompute) computeVertices();
}
diff --git a/src/sfml_game/TileMapEntity.h b/src/sfml_game/TileMapEntity.h
index b685b18..9c33cc9 100644
--- a/src/sfml_game/TileMapEntity.h
+++ b/src/sfml_game/TileMapEntity.h
@@ -1,56 +1,56 @@
-/** This file is part of sfmlGame.
+/** This file is part of Witch Blast.
*
- * FreeTumble is free software: you can redistribute it and/or modify
+ * Witch Blast 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 3 of the License, or
* (at your option) any later version.
*
- * FreeTumble is distributed in the hope that it will be useful,
+ * Witch Blast 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 FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ * along with Witch Blast. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TILEMAPENTITY_H_INCLUDED
#define TILEMAPENTITY_H_INCLUDED
#include "GameEntity.h"
#include "GameMap.h"
// Basis class for TileMap
class TileMapEntity : public GameEntity
{
public:
TileMapEntity(sf::Texture* image, GameMap* gameMap, int tileWidth, int tileHeight, int tilesProLine);
~TileMapEntity();
int getTilesProLine();
void setTileBox(int tileBoxWidth, int tileBoxHeight);
void setMap(GameMap* gameMap);
- virtual void render(sf::RenderWindow* app);
+ virtual void render(sf::RenderTarget* app);
virtual void animate(float delay);
virtual void computeVertices();
protected:
int width;
int height;
int tileWidth;
int tileHeight;
int tileBoxWidth;
int tileBoxHeight;
int tilesProLine;
sf::Texture* image;
GameMap* gameMap;
sf::VertexArray vertices;
bool hasChanged;
bool getChanged();
};
#endif // TILEMAPENTITY_H_INCLUDED

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:14 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68682
Default Alt Text
(207 KB)

Event Timeline