shake it baby ( camera shake effects )

Camera shake effects can be added via xml skill definitions.
This commit is contained in:
titiger 2014-02-01 23:15:44 +01:00
parent 20789087d9
commit 98234228d9
5 changed files with 174 additions and 3 deletions

View File

@ -19,6 +19,7 @@
#include "conversion.h"
#include "platform_common.h"
#include "leak_dumper.h"
#include "randomgen.h"
using namespace Shared::Graphics;
@ -41,6 +42,7 @@ const float GameCamera::vTransitionMult= 0.125f;
const float GameCamera::hTransitionMult= 0.125f;
const float GameCamera::defaultHeight= 20.f;
const float GameCamera::centerOffsetZ= 8.0f;
const float GameCamera::shakeDist= 50.f;
// ================= Constructor =================
@ -69,6 +71,9 @@ GameCamera::GameCamera() : pos(0.f, defaultHeight, 0.f),
move= Vec3f(0.f);
shakeDecrement=0.f;
currentShakeIntensity=0;
//maxRenderDistance = Config::getInstance().getFloat("RenderDistanceMax","64");
maxHeight = Config::getInstance().getFloat("CameraMaxDistance","20");
minHeight = Config::getInstance().getFloat("CameraMinDistance","7");
@ -133,8 +138,48 @@ void GameCamera::setPos(Vec3f pos){
destPos.z = pos.z;
}
void GameCamera::update(){
void GameCamera::shake(int shakeDuration, int shakeStartIntensity , bool cameraDistanceAffected, Vec3f unitVector) {
float currentDurationLeft=0;
float incomingShakeIntensity=((float) shakeStartIntensity)/1000;
// calculate the shake duration which is left
if(this->currentShakeIntensity > 0.f && this->shakeDecrement != 0.f){
currentDurationLeft=this->currentShakeIntensity / this->shakeDecrement;
}
// reduce new shake effect camera distance related
if (cameraDistanceAffected) {
incomingShakeIntensity=incomingShakeIntensity*(1.f-unitVector.dist(getPos())/GameCamera::shakeDist);
}
// add camera shake effect to current one ( if exsists ).
if(this->currentShakeIntensity>0){
this->currentShakeIntensity = this->currentShakeIntensity+incomingShakeIntensity ;
}
else {
this->currentShakeIntensity = incomingShakeIntensity ;
}
// use bigger shakeDuration to calculate new shakeDecrement
if(currentDurationLeft < shakeDuration){
this->shakeDecrement = currentShakeIntensity / ((float) shakeDuration);
}
else if(currentDurationLeft!=0.0f)
{
this->shakeDecrement = currentShakeIntensity / ((float) currentDurationLeft);
}
}
void GameCamera::shakeCamera(){
//RandomGen random;
if(currentShakeIntensity > 0.f) {
pos.x += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity;
pos.z += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity;
currentShakeIntensity -= shakeDecrement;
}
}
void GameCamera::update(){
//move XZ
if(move.z){
moveForwardH(speed * move.z, 0.9f);
@ -186,8 +231,8 @@ void GameCamera::update(){
if(abs(destPos.z - pos.z) > 0.01f) {
pos.z += (destPos.z - pos.z) / 32.0f;
}
clampAng();
shakeCamera();
if(clampDisable == false && clampBounds){
clampPosXYZ(0.0f, (float)limitX, minHeight, maxHeight, 0.0f, (float)limitY);

View File

@ -50,6 +50,7 @@ public:
static const float hTransitionMult;
static const float defaultHeight;
static const float centerOffsetZ;
static const float shakeDist;
public:
enum State{
@ -72,6 +73,8 @@ private:
Vec3f move;
float shakeDecrement;
float currentShakeIntensity;
State state;
int limitX;
@ -115,6 +118,8 @@ public:
void setPos(Vec2f pos);
void setPos(Vec3f pos);
void shake(int shakeDuration, int shakeStartIntensity , bool cameraDistanceAffected, Vec3f unitVector);
void setMoveX(float f) {this->move.x= f;}
void setMoveY(float f) {this->move.y= f;}
void setMoveZ(float f) {this->move.z= f;}
@ -177,7 +182,7 @@ private:
void clampAng();
void moveUp(float dist);
void rotateHV(float h, float v);
void shakeCamera();
};
}} //end namespace

View File

@ -528,6 +528,54 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
const XmlNode *attackBoostNode = sn->getChild("attack-boost");
loadAttackBoost(attackBoostsNode, attackBoostNode, ft, parentLoader, dir, currentPath, loadedFileList, tt);
}
shake=false;
shakeIntensity=50;
shakeDuration=300;
shakeStartTime=0.0f;
shakeSelfEnabled=false;
shakeSelfVisible=true;
shakeSelfInCameraView=false;
shakeSelfCameraAffected=false;
shakeTeamEnabled=false;
shakeTeamVisible=true;
shakeTeamInCameraView=false;
shakeTeamCameraAffected=false;
shakeEnemyEnabled=false;
shakeEnemyVisible=true;
shakeEnemyInCameraView=false;
shakeEnemyCameraAffected=false;
if (sn->hasChild("shake")) {
XmlNode *shakeNode=sn->getChild("shake");
shake= shakeNode->getAttribute("enabled")->getBoolValue();
shakeIntensity= shakeNode->getAttribute("intensity")->getIntValue();
shakeDuration= shakeNode->getAttribute("duration")->getIntValue();
if (shakeNode->hasAttribute("start-time")) {
shakeStartTime= shakeNode->getAttribute("start-time")->getFloatValue();
}
if (shakeNode->hasChild("self")) {
shakeSelfEnabled= shakeNode->getChild("enemy")->getAttribute("enabled")->getBoolValue();
shakeSelfVisible= shakeNode->getChild("self")->getAttribute("visible")->getBoolValue();
shakeSelfInCameraView= shakeNode->getChild("self")->getAttribute("in-camera-view")->getBoolValue();
shakeSelfCameraAffected= shakeNode->getChild("self")->getAttribute("camera-distance-affected")->getBoolValue();
}
if (shakeNode->hasChild("team")) {
shakeTeamEnabled= shakeNode->getChild("enemy")->getAttribute("enabled")->getBoolValue();
shakeTeamVisible= shakeNode->getChild("team")->getAttribute("visible")->getBoolValue();
shakeTeamInCameraView= shakeNode->getChild("team")->getAttribute("in-camera-view")->getBoolValue();
shakeTeamCameraAffected= shakeNode->getChild("team")->getAttribute("camera-distance-affected")->getBoolValue();
}
if (shakeNode->hasChild("enemy")) {
shakeEnemyEnabled= shakeNode->getChild("enemy")->getAttribute("enabled")->getBoolValue();
shakeEnemyVisible= shakeNode->getChild("enemy")->getAttribute("visible")->getBoolValue();
shakeEnemyInCameraView= shakeNode->getChild("enemy")->getAttribute("in-camera-view")->getBoolValue();
shakeEnemyCameraAffected= shakeNode->getChild("enemy")->getAttribute("camera-distance-affected")->getBoolValue();
}
//visible-for (team, self,all, team-and-visible, self-and-visible, all-and-visible )
}
}
bool SkillType::CanCycleNextRandomAnimation(const int *animationRandomCycleCount) const {

View File

@ -133,6 +133,24 @@ protected:
int speed;
int animSpeed;
bool shake;
int shakeIntensity;
int shakeDuration;
float shakeStartTime;
bool shakeSelfEnabled;
bool shakeSelfVisible;
bool shakeSelfInCameraView;
bool shakeSelfCameraAffected;
bool shakeTeamEnabled;
bool shakeTeamVisible;
bool shakeTeamInCameraView;
bool shakeTeamCameraAffected;
bool shakeEnemyEnabled;
bool shakeEnemyVisible;
bool shakeEnemyInCameraView;
bool shakeEnemyCameraAffected;
int animationRandomCycleMaxcount;
vector<Model *> animations;
vector<AnimationAttributes> animationAttributes;
@ -179,6 +197,25 @@ public:
Model *getAnimation(float animProgress=0, const Unit *unit=NULL, int *lastAnimationIndex=NULL, int *animationRandomCycleCount=NULL) const;
StaticSound *getSound() const {return sounds.getRandSound();}
float getSoundStartTime() const {return soundStartTime;}
float getShakeStartTime() const {return shakeStartTime;}
bool getShake() const {return shake;}
int getShakeIntensity() const {return shakeIntensity;}
int getShakeDuration() const {return shakeDuration;}
bool getShakeSelfEnabled() const {return shakeSelfEnabled;}
bool getShakeSelfVisible() const {return shakeSelfVisible;}
bool getShakeSelfInCameraView() const {return shakeSelfInCameraView;}
bool getShakeSelfCameraAffected() const {return shakeSelfCameraAffected;}
bool getShakeTeamEnabled() const {return shakeTeamEnabled;}
bool getShakeTeamVisible() const {return shakeTeamVisible;}
bool getShakeTeamInCameraView() const {return shakeTeamInCameraView;}
bool getShakeTeamCameraAffected() const {return shakeTeamCameraAffected;}
bool getShakeEnemyEnabled() const {return shakeEnemyEnabled;}
bool getShakeEnemyVisible() const {return shakeEnemyVisible;}
bool getShakeEnemyInCameraView() const {return shakeEnemyInCameraView;}
bool getShakeEnemyCameraAffected() const {return shakeEnemyCameraAffected;}
bool isAttackBoostEnabled() const { return attackBoost.enabled; }
const AttackBoost * getAttackBoost() const { return &attackBoost; }

View File

@ -137,6 +137,42 @@ bool UnitUpdater::updateUnit(Unit *unit) {
}
}
if (currSkill->getShake()) {
float shakeStartTime = currSkill->getShakeStartTime();
if (shakeStartTime >= unit->getLastAnimProgressAsFloat()
&& shakeStartTime < unit->getAnimProgressAsFloat()) {
bool visibleAffected=false;
bool cameraViewAffected=false;
bool cameraDistanceAffected=false;
bool enabled=false;
if (game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) {
visibleAffected=currSkill->getShakeSelfVisible();
cameraViewAffected=currSkill->getShakeSelfInCameraView();
cameraDistanceAffected=currSkill->getShakeSelfCameraAffected();
enabled=currSkill->getShakeSelfEnabled();
} else if (unit->getTeam() == world->getThisTeamIndex()) {
visibleAffected=currSkill->getShakeTeamVisible();
cameraViewAffected=currSkill->getShakeTeamInCameraView();
cameraDistanceAffected=currSkill->getShakeTeamCameraAffected();
enabled=currSkill->getShakeTeamEnabled();
} else {
visibleAffected=currSkill->getShakeEnemyVisible();
cameraViewAffected=currSkill->getShakeEnemyInCameraView();
cameraDistanceAffected=currSkill->getShakeEnemyCameraAffected();
enabled=currSkill->getShakeEnemyEnabled();
}
bool visibility=(!visibleAffected)||(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) ||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true));
bool cameraAffected=(!cameraViewAffected) || unit->getVisible();
if(visibility && cameraAffected && enabled) {
game->getGameCameraPtr()->shake( currSkill->getShakeDuration(), currSkill->getShakeIntensity(),cameraDistanceAffected,unit->getCurrVector());
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
unit->updateTimedParticles();