ACADEMIC RESEARCH AND PUBLICATIONS
during Graduate and Undergraduate Studies
ACADEMIC RESEARCH AND PUBLICATIONS
during Graduate and Undergraduate Studies
Doctoral Candidate in Computer Science
Visual Computing Division, Digital Production Arts
Clemson University | School of Computing
THEFT OF THE REWOLF FLOWERS:
A C++/SDL2 VIDEO GAME
#include "Player.h"
#include "gamedata.h"
#include "renderContext.h"
Player::Player(const std::string &name, int lev, int maxBarks) :
Drawable( name,
Vector2f( Gamedata::getInstance().getXmlInt(name+"/startLoc/x"),
Gamedata::getInstance().getXmlInt(name+"/startLoc/y") ),
Vector2f(0, 0), //Initialize velocity to 0.
lev, 1.0
),
frames( RenderContext::getInstance()->getFrames(name) ),
currentFrame(0),
numberOfFrames( Gamedata::getInstance().getXmlInt(name+"/frames") ),
frameInterval( Gamedata::getInstance().getXmlInt(name+"/frameInterval") ),
timeSinceLastFrame(0),
worldWidth( Gamedata::getInstance().getXmlInt("world/width") ),
worldHeight( Gamedata::getInstance().getXmlInt("world/height") ),
frameWidth( frames[0]->getWidth() ),
frameHeight( frames[0]->getHeight() ),
origVelX( Gamedata::getInstance().getXmlInt(getName()+"/speedX") ),
origVelY( Gamedata::getInstance().getXmlInt(getName()+"/speedY") ),
flip(false),
left(false),
right(false),
up(false),
down(false),
bark(false),
barkPool( BarkPool(maxBarks, origVelX) ),
observers()
{ }
//=====================================================================
Player::Player(const Player &other) :
Drawable(other),
frames(other.frames),
currentFrame(other.currentFrame),
numberOfFrames(other.numberOfFrames),
frameInterval(other.frameInterval),
timeSinceLastFrame(other.timeSinceLastFrame),
worldWidth(other.worldWidth),
worldHeight(other.worldHeight),
frameWidth(other.frameWidth),
frameHeight(other.frameHeight),
origVelX(other.origVelX),
origVelY(other.origVelY),
flip(other.flip),
left(other.left),
right(other.right),
up(other.up),
down(other.down),
bark(other.bark),
barkPool(other.barkPool),
observers(other.observers)
{ }
//=====================================================================
void Player::draw() const
{
frames[currentFrame]->draw(getX(), getY(), flip, getScale());
barkPool.drawBarks();
}
//=====================================================================
void Player::idle()
{
if (!left && !right)
{
setVelocityX(0);
}
if (!up && !down)
{
setVelocityY(0);
}
}
//=====================================================================
void Player::update(Uint32 ticks)
{
checkEdges(); //Sets velocity to 0 if touching a boundary. Do this before the next two steps.
changeVelocity();
changeScale(); //Subtly change Player's size based off of vertical distance in world (lower y -> higher up in window -> further back within scene).
Vector2f incr = getVelocity() * static_cast<float>(ticks) * 0.001;
setPosition(getPosition() + incr);
advanceFrame(ticks);
if (bark) barkPool.bark(getFlip(), getX(), getY());
barkPool.update(ticks, getX());
for (auto o : observers)
{ o->determineEvade(getX(), getY()); }
idle();
left = false;
right = false;
up = false;
down = false;
bark = false;
}
//=====================================================================
void Player::changeScale()
{
int maxY = Gamedata::getInstance().getXmlInt(getName()+"/maxY");
int dist = Gamedata::getInstance().getXmlInt(getName()+"/maxY") - getY(); //Vertical distance away from max y. If 0, at that max border,
setScale( 1 - (1.1*dist)/maxY ); // If at maxY, scale=1.1. Use this info as a ratio. maxY:1.1, dist:scale
}
//=====================================================================
void Player::changeVelocity()
{
if (left)
{
setVelocityX(getScale() * origVelX);
flip = false;
}
else if (right)
{
setVelocityX(getScale() * -origVelX);
flip = true;
}
if (up)
{
setVelocityY(getScale() * -origVelY);
}
else if (down)
{
setVelocityY(getScale() * origVelY);
}
}
//=====================================================================
void Player::checkEdges()
{
//Reaching upper bounds (y origin at top) of walkable area.
if ( getY() < Gamedata::getInstance().getXmlInt(getName()+"/minY") )
{
up = false; //Disable going up more.
}
//Reaching lower bounds (y origin at top) of walkable area.
else if ( getY() > Gamedata::getInstance().getXmlInt(getName()+"/maxY") )
{
down = false; //Disable going down more.
}
//Reaching leftmost bound.
if ( getX() < 0)
{
left = false;
}
//Reaching rightmost bound.
else if ( getX() > worldWidth-frameWidth)
{
right = false;
}
}
//=====================================================================
void Player::advanceFrame(Uint32 ticks)
{
if (left || right || up || down)
{
timeSinceLastFrame += ticks;
if (timeSinceLastFrame > frameInterval)
{
currentFrame = (currentFrame+1) % (numberOfFrames);
timeSinceLastFrame = 0;
}
}
}
//=====================================================================
std::list<TwoWayMultiSprite*> Player::getActiveBarks() const
{
return barkPool.getActiveBarks();
}
PROJECT PAGE
Language: C++ (using SDL2)
Date: Spring 2017
Class: Data-Driven Game Development
​
You are a werewolf, and the Selkies had turned your love into a human! Collect the Rewolf Flowers to restore your love to her werewolf state. Hurry, though, because the Selkies can take them away!
This project is a 2D game built in C++ using Simple DirectMedia Layer 2.0. A brief video of the gameplay is provided. The code architecture is object-oriented and utilizes inheritance, object pools, containers and iterators, basic AI, and other programming techniques and C++ tools. The code sample is the implementation file of the Player (the werewolf) class.
​
Additionally, I created all of the art assets used. The bark and scream sound effects are also my own. The song used is Dreamless by Jake Bowen.
​
​