Thursday 3 November 2016

3ds Max - basic shortcuts (2017)


Here is a list of common 3ds Max shortcuts, that will get you started with your modeling. I kept it short and sweet to keep it comprehensive.
"Obvious" shortcuts are grayed out, however I included them as they can be- not-so-obvious if you already have experience using any other 3d modeling software.

Alt + W –> Maximize/ minimize viewport
MMB –> Pan view
Alt + MMB –> Rotate view
Scroll –> Zoom
Ctrl + Z -> Undo
Shift + Scroll –> Fast scroll
Alt + Shift + Scroll – > Slow zoom
Z –> Focus on an object
7 –> Polygon count
M –> Open material editor / close material editor

LMB –> Selected an object
LMB outside of an object to unselect
Alt + LMB -> Deselect an object
Ctrl + LMB -> Select multiple objects
On selected object:
                W –> Move
                E –> Rotate
                R –> Scale
                Alt + X -> Enable/disable x-ray view
                Shift + Move -> Clone
      Space –> Lock select/unlock select

Wednesday 12 October 2016

C++ Seed generation

This is a quick tutorial on how to generate pseudo-random seeds in C++. It is important to understand that, this is a two-step process: first - setting a range with ran()%10- this will produce numbers from 0 to 9 (); and second - generating a seed for the program to work with, using srand(123)- this will generate a seed based on those numbers. In this tutorial I will go over 3 examples to demonstrate different outcomes.

The code below will output the same 10 numbers every time the program is ran.

#include "stdafx.h" // - Visual Studio only
#include <stdlib.h>
#include <iostream>

using namespace std;

void genRanNum() {
 int num = 10;
 do {
  cout << rand() % 10 << endl;
  num--;
 } while (num>0);
} 

 

int main()
{

 genRanNum();//--produce 10 random numbers
 cin.get();//-- pause
 
    return 0;

}

To generate a seed that will be different to the default output but same every time it is used, use srand(23232) - with numbers of your choice.

#include "stdafx.h" // - Visual Studio only
#include <stdlib.h>
#include <iostream>

using namespace std;

void genRanNum() {
 int num = 10;
 do {
  cout << rand() % 10 << endl;
  num--;
 } while (num>0);
}

void seedGen(int seed=0) {
 srand(seed);
}
int main()
{
 seedGen(3245);//--generate a seed based on numbers

 genRanNum();//--produce 10 random numbers
 cin.get();//-- pause
 
    return 0;

}

And finally to produce a pseudo-random seed every time the program is used, parse current time value into the srand(time(0)) function as a parameter. Include <time.h> header to work with time.
 
#include "stdafx.h" // - Visual Studio only
#include <stdlib.h>
#include <iostream>
#include <time.h>

using namespace std;

void genRanNum() {
 int num = 10;
 do {
  cout << rand() % 10 << endl;
  num--;
 } while (num>0);
}


void randSeedGen() {
 srand(time(0));
}

int main()
{
 randSeedGen();//--generate a random seed based on time
 
 genRanNum();//--produce random 10 number
 cin.get();//-- pause
 
    return 0;

}

C++ Operator Overloading

C++ compiler can use operators on basic types such as int, float and string. When you create a custom class and try to use an operator, the compiler does not know how to deal with provided information. Here is where operator overloading comes in. C++ allows operator overloading for specific types - effectively you can define custom behaviors for a wide range of operators.

In this example, I use a custom Point class which has x and y values. Shown operators (+,-,*,/,>,<,>>,<<) are altered to exhibit a particular behavior as to compare those values.

//overloading operators

#include "stdafx.h" //-- for Visual Studio only
#include <iostream>
#include <string>

using namespace std;

class Point {

 int _x, _y;

public:
 Point(int x, int y) :
  _x(x), _y(y) {
 }

 int x() const {
  return _x;
 }

 int y() const {
  return _y;
 }
 
 bool operator > (const Point &p)const {
  return (_x + _y) > (p._y + p._y);
 }

 bool operator < (const Point &p)const {
  return (_x + _y) < (p._x + p._y);
 }

 bool operator == (const Point &p)const {
  return (_x == p._x) && ( _x == p._y);
 }

 friend ostream& operator << (ostream& os,const Point &p) {
  os << "(" << p._x << "," << p._y << ")";
  return (os);
 }
 
 friend istream& operator >> (istream &input, Point &p)
 {
  input >> p._x;
  input >> p._y;
  return input;
 }

 Point operator = (Point &p) {
  _x=p._x;
  _y=p._y;
  return *this;  
 }

 Point operator + (const Point &p) const {
  return Point(_x+p._x, _y+p._y);
 }

 Point operator - (const Point &p)const {
  return Point(_x-p._x, _y-p._y);
 }

 Point operator * (const Point &p)const {
  return Point(_x * p._x, _y * p._y);
 }

 Point operator / (const Point &p)const {
  //---check for denominator - 0
  if (p._y == 0)return Point(0, 0);
  return Point(_x / p._x, _y / p._y);
 }
};

int main()
{

 Point alpha(2,2), beta(4,4), gamma(8,8);
 cout << "3 points (custom class)" << endl;
 cout << endl;
 cout << alpha << " alpha" << endl;
 cout << beta << " beta" << endl;
 cout << gamma << " gamma" << endl;
 cout << endl;
 cout << "overloaded operators (+,-,*,/,>,<,>>,<<)" << endl;
 cout << endl;
 cout << (alpha + beta) << " alpha + beta" << endl;
 cout << (alpha + beta + gamma) << " alpha + beta + gamma" << endl;
 cout << (alpha - beta) << " alpha - beta" << endl;
 cout << (alpha * beta) << " alpha * beta" << endl;
 cout << (beta / alpha) << " alpha / beta" << endl;
 cout << (alpha > beta) << "  is alpha bigger than beta (0=false)" << endl;
 cout << (alpha < beta) << "  is alpha smaller than beta (1=true)" << endl;
 cout << endl;
 cout << "3 Points (unaltered after using operators)" << endl;
 cout << endl;
 cout << alpha << " alpha" << endl;
 cout << beta << " beta" << endl;
 cout << gamma << " gamma" << endl;

 cin.get();

    return 0;
}

Sunday 9 October 2016

C++ Exception Handling

This code requires <stdexcept> header. ( alternatively you can prepend namespace “exception::” )

The following code has a simple divide function and some code handling exceptions.
This program would output:
3
error!

The divide function can throw an exception if the denominator is equal to 0. Notice how after dealing with the exception, the compiler breaks out of the code block and does not calculate the third statement.

#include "stdafx.h"// -- only for Visual Studio ( Windows)
#include <iostream>
#include <stdlib.h>
#include <stdexcept>

using namespace std;



int divide(int a, int b) {

 if (b == 0) {
  throw exception();
 }
 return (a / b);

}


int main()
{

 try {
  cout << divide(6, 2) << endl;
  cout << divide(5, 0) << endl;
  cout << divide(5, 5) << endl;
 }
 catch (...){
  cout << "error!" << endl;
 }


 system("pause");// -- only for Visual Studio ( Windows)
    return 0;
}



If you expect a particular exception, you can throw the exception value, and catch it, as shown below.
This code would output:
3
error! 0- cannot be used!


#include "stdafx.h"// -- only for Visual Studio ( Windows)
#include <iostream>
#include <stdlib.h>
#include <stdexcept>

using namespace std;



int divide(int a, int b) {

 if (b == 0) {
  throw b;
 }
 return (a / b);

}


int main()
{

 try {
  cout << divide(6, 2) << endl;
  cout << divide(5, 0) << endl;
  cout << divide(5, 5) << endl;
 }
 catch (int e){
  cout << "error! " << e << "- cannot be used!"<< endl;
 }
 

 system("pause");// -- only for Visual Studio ( Windows)
    return 0;
}

Wednesday 18 November 2015

Exploring Hooks in Crossy Road

After playing a little too much of Crossy Road, I suddenly had a vision of how every little part of the game combines in to the greater whole. In particular, I will discuss how: a minimal amount of gameplay can yield a lot of replayability.

Game Design & Intentions
This is a quick recap on game design and intentions. Developers were focused to create a game that would reach as many people as possible. The goal was to keep it user-friendly and avoid: paywalls, pop-up ads and other money-hungry monetization techniques. The gameplay is never intrusive, in fact it is optional to watch a video-ad to earn some points. This decision enhances the game as it increases intrinsic motivation, giving player a choice. Personally, Crossy Road is a first game where I almost enjoyed watching an ad, because it is not forced and feels natural.

Identifying Game Goal
It it important to acknowledge that gameplay is based on 80's Frogger, which is familiar and accessible to most players. Most of the core-mechanics can be seen within first 5 minutes of play. However the game remains fresh because of the unlockable characters, which can offer slight variation on theme and sometimes gameplay. Hence long-term objective of the game is to discover all characters, to see all possible outcomes. Characters can be purchased from the app store, or alternatively they can be earned from the prize-machine. Earning an in-game characters feels super rewarding when there is a real price tag on it. In order to enter a prize draw player has to collect 100 points - simple and tangible.

Time-capping Game modes
First 10 minutes of the game are excessively rewarding. There are: free prizes, easy challenges - all contributing to unlocking several characters. However after that initial "rewarding- mode", the game slips into "grinding-mode", where collecting points becomes slow and tedious. The only fast way is to watch an ad, which earns about 20-30 points. Moreover, the ad prompt appears approximately every 5 minutes, making it practically desirable. After a while of grinding, player is likely to change attention and forget about the game. This is where push-notifications come in handy. Every 6 hours after opening your last gift, Crossy Road will remind you that -"your free gift is here". If player responds to that notification, the game will go back to "rewarding-mode", and later back to "grinding mode". On the other side, ignoring notification will result in suspending the gift until the next time. Effectively, game is rewarding after 6 hour interval. Which, conditions player to come back few times a day. What is interesting, when player comes back to the game for a present, player has to play the game, in order to get to the menu which allows you to retrieve your present.

Inconsistent Menu
After game over condition is met, menu pops up. In most cases it has 2 stages: part 1 - call-to-action, part 2 - standard menu(settings/share/reply/score). The second part is usually delayed by approximately 2 seconds. This matters because the game loop is short and players tap on "replay" all the time. When the first part appears, player is likely to press it simply because there is nothing else to press.  So, there is a certain level of generated excitement/impatience which assists on responding to call-to-action. Not to mention, call-to-action is animated and presented in a much more eye-catching way than the standard menu.
(See bellow: Initial call to action, Standard menu, Combined menu)

 


Conclusion
Final catch. Crossy Road is highly replayable and game system seems to be fair, so what is stopping players from eventually completing it? Game developers took a good care of that. For example, after a while prize draw starts repeating, there are 130+ characters -some of them can be unlocked, some of them can be achieved by performing a certain task, and other can only be purchased. Crossy Road is a great example of a game that provides minimal gameplay for a lot of content and engagement.