Shepard Fairey VR – DAMAGED

2019-03-07T17:38:35+00:00

Join Shepard Fairey in this state of the art virtual reality experience, where he will share his thoughts and methods behind his artwork. The app delivers:

  • Listen to over 100 minutes of exclusive narration by Shepard Fairey.
  • Interact with hundreds of artworks, including world premier exclusives.
  • A full three dimensional photo realistic representation of his Damaged show.

My involvement in the project:

  • Motion controls (gyroscope)
  • AR integration
  • Realtime planar reflections. (Mobile and VR)
  • Optimization

Project Rampage VR

2019-03-07T17:27:19+00:00

A VR game based on the 2018 Rampage movie for Mobile and Desktop. Using CRISPR technology, create monster mutations in Energyne’s lab and unleash destruction across the world. Play as George, Ralph and Lizzie as you run, climb, throw and smash your way through Chicago and Paris! Complete challenges and rack up points as you destroy your surroundings.

My involvement in the project:
• Technical lead on the project, deciding on the overall technical design and guiding team members in their implementation
• Destruction mechanics
• Optimization

Geostorm

2019-03-07T17:10:41+00:00

A puzzle game much like the Lara Croft and Hitman GO series for mobile and desktop.

Some of the thing I did on this project:

  • Puzzle design
  • Implementing mechanics
    • Floating objects
    • Pushing/pulling object interactions
    • Oil barrel logic
    • Fire/explosion logic
    • Lightning logic
  • Desktop porting, including steam integration and controller/mouse & keyboard support.

King Arthur: Legend of the Sword

2019-03-07T18:04:42+00:00

A brawler game based on the same 2017 movie for Mobile devices.

My involvement in the project

  • Fighting mechanics
    • Both enemy and player
  • Player – AI interaction
    • Connecting animations
  • Spawning logic for enemies
  • Various enemy AI logic

The Man From Uncle: Mission Berlin

2019-03-03T15:22:33+00:00

My main responsibility for this game was the mission system. Every mission in this game is defined from a subset of conditions that were configured by a designer to fit within the flow of the game. The mission system took care of defining what kind of mission should be chosen, where it should logically spawn and how many and what kind of enemies were needed.

Next to the mission system, I was also responsible for the tutorial, which made practical use of the mission system.

Other minor things I helped out with:

  • Camera behaviour
  • A.I.
  • Optimizations

The game is playable on:

Interstellar

2019-03-03T15:17:54+00:00

The first project I worked on at Sticky Studios was the web and mobile game: Interstellar.

For this game I was responsible for the looks and customization of the different planets you can create in your solar system. For this I created the shader(s) and the tools for both the artists and the players. With these tools the artists could define specific ranges exposed to the player to create a wide range of unique planets from within the game.

Almost all planets share the same shader.

The game is playable at the following platforms:

Metrico

2019-03-03T15:17:27+00:00

As part of my internship at Digital Dreams, I have been working on the game: Metrico.

Metrico is a puzzle game with platforming elements that makes use of so called “input morphing”. Input morphing means that all kinds of input, ranging from the player character walking in the game to physical input from the player, will have an impact on the game world. This impact comes in two variants:

  • Environment altering that prevents the player from progressing in a linear sense so the player has to take his or her actions in consideration. This is the puzzle element of the game where the player needs to solve the puzzles by carefully considering its input.
  • Environment altering from a pure aesthetical viewpoint where the actions of the player have no direct impact on the gameplay.

The game has been released for the Playstation Vita exclusively.

During my internship I got full responsibility over the graphics programming side of the game. I was in charge of creating all the shaders that define the look of the game as well as all the visual effects that happen in the game. Next to graphics programming and visual effects, I also helped with game play programming where needed and did my share of optimizing where needed.

 

Super Puzzle Platformer

2019-03-03T15:17:04+00:00

This is a game made in a group of 7 people (2 programmers, 4 artists and 1 designer) in roughly 14 days in Unity3D as a student project. The aim of this student project is to deliver a fully working game within this given time period.

The tasks I had in this project:

  • Creating a particle manager
  • Creating an audio manager
  • In game GUI handling
  • Menu
  • Rim shader
  • Animation handles (for use in Mecanim)
  • Shark behaviour
  • Waves of blocks
  • Camera behaviour
  • Dynamic weather simulation
  • General configuration manager
  • Player feedback system
  • Tutorial

It’s based on the original Super Puzzle Platformer game, recently released on steam.

It is a platformer game in which the player tries to stay alive as long as possible, to get the highest score by destroying blocks and collecting coins.

Will of Nature

2019-03-03T15:15:08+00:00

Will of Nature is a game that has been made in roughly 14 days as a college project with 14 other students.

The game is about a waterdrop that has to manoeuvre through a series of levels where puzzles have to be solved to continue.
These puzzles are solveable by influences from different environmental effects to turn you into ice, or vaporize yourself in a cloud.

In this project I was the technical lead of 3 other programmers, with my main task of having an oversight of what was going on, deciding on implementation choices and bringing design choices/changes through for proper implementation. Next to a lead role I also spent time on general gameplay programming, animation and the effects.

Code Snippits

void Player::UpdateStateWater()
{
  // Not every line of code is done by me.

  XboxController * controller = Framework::GetApplication()->GetController();
  Keyboard* keyboard = Framework::GetApplication()->GetKeyboard();

  const bool leftkey =	keyboard->GetKey(Keys::PlayerMoveLeft)  ||
    keyboard->GetKey(Keys::PlayerMoveLeftA)||
    controller->GetLeftThumbStateXI() < 0;

  const bool rightkey =	keyboard->GetKey(Keys::PlayerMoveRight)||
    keyboard->GetKey(Keys::PlayerMoveRightD) ||
    controller->GetLeftThumbStateXI() > 0;

  const bool jumpkey =	keyboard->GetKey(Keys::PlayerJump)|| 
    controller->GetButtonState(Keys::PlayerControlerJump);

  const bool keydown =	keyboard->GetKey(Keys::PlayerMoveDown) ||
    keyboard->GetKey(Keys::PlayerMoveDownS)|| 
    (controller->GetLeftThumbStateYI() < 0);

  const bool keyup =		keyboard->GetKey(Keys::PlayerMoveUp) ||
    keyboard->GetKey(Keys::PlayerMoveUpW)|| 
    (controller->GetLeftThumbStateYI() > 0);

  const bool keydrop =	keyboard->GetKey(Keys::PlayerDropItem)  ||
    controller->GetButtonState(Keys::PlayerControlerDrop);

  mIsRainingDown = false;
  // Only movement behavior in here
  FVector3 disp;

  //plant stuff
  std::vector<Plant*>& plantvec = mLevel->GetPlants();
  std::vector<Plant*>::iterator plantit = plantvec.begin();
  Plant* CurrentClimbing = NULL;
  bool ontop = false;

  if (mPhysChar->isJump()==false)
  {
    for (; plantit < plantvec.end();++plantit)
    {
      Plant * currentplant = (*plantit);
      if (currentplant->IsTouching(mPosition))
      {
        CurrentClimbing = currentplant;
        break;
      }
    }
  }

  if (CurrentClimbing == NULL)
  {
    mPhysChar->ToggleGravity(true);
  }
  else
  {

    if (keyup)
    {
      mPhysChar->ToggleGravity(false);
      disp.y += PlayerClimbSpeed;
      mPlayerMesh->SetAnimation("MainCharClimb");
    }
    else if (keydown)
    {
      mPhysChar->ToggleGravity(false);
      disp.y -= PlayerClimbSpeed;
      mPlayerMesh->SetAnimation("MainCharClimb");
    }
    else
    {
      mPlayerMesh->SetAnimation("MainCharIdle");
    }
  }	

  if(Framework::GetApplication()->GetCamera() == mCamera)
  {
    if (leftkey)
    {
      disp.x  = PlayerSpeedWater;
      if(!jumpkey)
      {
        mPlayerMesh->SetAnimation("MainCharRun");
        mAnimationSpeedModifier = .17f;
      }
      mGoingRight = false;
    }
    else if (rightkey)
    {
      disp.x = -PlayerSpeedWater;
      if(!jumpkey && !mWasJumping)
      {
        mPlayerMesh->SetAnimation("MainCharRun");
        mAnimationSpeedModifier = .17f;
      }
      mGoingRight = true;
    }
    else if(mPlayerMesh->GetCurrentAnimation() != mPlayerMesh->GetAnimation("MainCharIdle") && CurrentClimbing == NULL)
    {
      mPlayerMesh->SetAnimation("MainCharIdle");
    }

 		if (CurrentClimbing == NULL && jumpkey)
    {
      mPhysChar->Jump();
    }

    if(CurrentClimbing == NULL && (mPhysChar->getStatus() == PhysXCharacter::CHAR_STARTJUMP || mPhysChar->getStatus() == PhysXCharacter::CHAR_JUMPING))
    {
      mPlayerMesh->SetAnimation("MainCharJump");
    }

    if(mPhysChar->getStatus() == PhysXCharacter::CHAR_STARTJUMP)
    {
      if(!sndWaterJump->IsPlaying())
        sndWaterJump->Play(false);
    }

    if(mPhysChar->getStatus() == PhysXCharacter::CHAR_FALLING)
      if(mPlayerMesh->GetCurrentAnimation() != mPlayerMesh->GetAnimation("MainCharJump"))
      {
        mPlayerMesh->SetAnimation("MainCharJump");
        mPlayerMesh->GetCurrentAnimation()->SetTime(0.20);
      }

    if(mPhysChar->getStatus() == PhysXCharacter::CHAR_HITGROUND)
    {
      if(!sndWaterLand->IsPlaying())
        sndWaterLand->Play(false);
      mPlayerMesh->GetAnimation("MainCharJump")->Reset();
      if(leftkey || rightkey)
      {
        mPlayerMesh->SetAnimation("MainCharRun");
        mAnimationSpeedModifier = 0.17f;
      }
      else
        mPlayerMesh->SetAnimation("MainCharIdle");
    }

  }
  mPhysChar->setFriction(FrictionNormal); //.1f --> tweakable var
  mPhysChar->Update(disp);
  mPosition = mPhysChar->GetPosition();
  mPosition.y -= 4.5f;
  mPlayerMesh->SetPosition(mPosition);
  mCamera->SetCameraSetting(ThirdPersonCamera::CAM_NORMAL);

  // drop item ?
  mHasDroppedItem = 0;
  if(keydrop && mInventoryItem)
  {
    mHasDroppedItem = mInventoryItem->getItemType();
    mLastDropped = getInventoryItem();
    mInventoryItem->dropItem();
    mInventoryItem = 0;
  }
  //If player has free inventory slot, update and find a collidable item
  if(getInventoryItem() == 0)
  {
    Item* newItem = 0;
    std::vector<Item*>& itemptr = mLevel->GetItemList();
    std::vector<Item*>::iterator it = itemptr.begin();
    for(; it < itemptr.end(); it++)
    {
      if((*it)->IsPickupable() && ((*it)->getItemType() == Item::ITEM_SEED || (*it)->getItemType() == Item::ITEM_WOOD))
      {
        float dist = (*it)->getDistance(GetPosition());
        if(dist < 0)
        {
          newItem = (*it);
          break;
        }
      }
    }
    //if we found a collided, do stuff with it
    if(newItem != 0)
    {
      setInventoryItem(newItem);
      newItem->GetParticle()->Hide();
      sndItemPickup->Play();
    }
  }

  //If ice, do stuff
  if(mPhysChar->GetGroundType() == ICE)
  {
    gTrace("Player water entered Ice, converting!");
    setPlayerChangeState(Player::ChangeWaterToIce);
  }
}
void Player::UpdateStateIce()
{
  // Not every line of code is done by me.

  XboxController * controller = Framework::GetApplication()->GetController();
  Keyboard* keyboard = Framework::GetApplication()->GetKeyboard();

  const bool leftkey =	keyboard->GetKey(Keys::PlayerMoveLeft)  ||
    keyboard->GetKey(Keys::PlayerMoveLeftA)||
    controller->GetLeftThumbStateXI() < 0;

  const bool rightkey =	keyboard->GetKey(Keys::PlayerMoveRight)||
    keyboard->GetKey(Keys::PlayerMoveRightD) ||
    controller->GetLeftThumbStateXI() > 0;

  const bool jumpkey =	keyboard->GetKey(Keys::PlayerJump)|| 
    controller->GetButtonState(Keys::PlayerControlerJump);

  mIsRainingDown = false;
  // Only movement behavior in here
  FVector3 disp;
  if(Framework::GetApplication()->GetCamera() == mCamera)
  {
    if(jumpkey)
    {
      mPlayerMesh->SetAnimation("MainCharIceJump");
    }

    float speed = mPhysChar->GetVelocity().x;
    float maxspeed = 120;
    if (leftkey) 
    {
      disp.x = PlayerSpeedIce;
      mGoingRight = false;
      if(speed > maxspeed || speed < -maxspeed) mPlayerMesh->SetAnimation("MainCharIceRunFaster");
      else mPlayerMesh->SetAnimation("MainCharIceRun");
    }
    else if (rightkey)
    {
      disp.x = -PlayerSpeedIce;
      mGoingRight = true;
      if(speed > maxspeed || speed < -maxspeed) mPlayerMesh->SetAnimation("MainCharIceRunFaster");
      else mPlayerMesh->SetAnimation("MainCharIceRun");
    }
    else
    {
      if (mPlayerMesh->GetCurrentAnimation() == mPlayerMesh->GetAnimation("MainCharIceJump"))
      {
        if(mPlayerMesh->GetAnimation("MainCharIceJump")->IsDone())
        {
          mPlayerMesh->SetAnimation("MainCharIceIdle");
          mPlayerMesh->GetAnimation("MainCharIceJump")->Reset();
        }
      }
      else
      {
        mPlayerMesh->SetAnimation("MainCharIceIdle");
      }

    }

    if (leftkey) disp.x = PlayerSpeedIce;
    else if (rightkey) disp.x = -PlayerSpeedIce;

  }
  PhysXGroundType ground = mPhysChar->GetGroundType();

  if(ground == NORMAL) mPhysChar->setFriction(FrictionNormal);
  if(ground == HOT) mPhysChar->setFriction(FrictionIce);
  else mPhysChar->setFriction(FrictionRest);

  mPhysChar->Update(disp);

  mPosition = mPhysChar->GetPosition();
  mPosition.y -= 4.5f;
  mPlayerMesh->SetPosition(mPosition);
  mCamera->SetCameraSetting(ThirdPersonCamera::CAM_ICE);

  // 	if (ground == SPECIAL) 
  // 		mSpecialHit = true; 
  // 	else mSpecialHit = false;

  if (ground == BREAKWALL)
  {
    mWallHit = true; 
  }
  else mWallHit = false;

  mIce->SetPosition(mPosition);

  if(ground == HOT) 
  {
    setPlayerChangeState(Player::ChangeIceToWater);
  }
}