C#

What about code?!

Fools ignore complexity; pragmatists suffer it; experts avoid it; CREATIVES remove it.

Friday, November 23, 2018

Mimic an object - Unity C#


Imagine that you want to mimic an object considering its orientation and position but at the same time you don't want to use all of the axis. Here is the way I did it.

using UnityEngine;
using System.Collections;

public class Mimic : MonoBehaviour
{
        public Transform MimicWho;
        public Vector3 OffSet = Vector3.zero;
        public bool MimicPosition = true;
        public bool MimicRotation = true;
public bool IgnoreX = false;
public bool IgnoreY = false;
public bool IgnoreZ = false;
public bool IgnoreRotX = false;
public bool IgnoreRotY = false;
public bool IgnoreRotZ = false;

Vector3 _ignorePos;
Vector3 _ignoreRot;
Vector3 _euler;

    void LateUpdate()
    {
if (MimicRotation)
{
_euler = MimicWho.rotation.eulerAngles;
_ignoreRot = Vector3.zero;
_ignoreRot.x = IgnoreRotX ? 0 : _euler.x;
_ignoreRot.y = IgnoreRotY ? 0 : _euler.y;
_ignoreRot.z = IgnoreRotZ ? 0 : _euler.z;
transform.rotation = Quaternion.Euler(_ignoreRot);
}

if (MimicPosition)
{
_ignorePos = Vector3.zero;
_ignorePos.x = IgnoreX ? 0 : MimicWho.position.x;
_ignorePos.y = IgnoreY ? 0 : MimicWho.position.y;
_ignorePos.z = IgnoreZ ? 0 : MimicWho.position.z;
transform.position = (transform.rotation*OffSet)+_ignorePos;
}
    }
}

Eventually, you may want to mimic it with some damping, then, you can use this next code and  merging both solutions.

using UnityEngine;
using System.Collections;

public class MimicWithDamping : MonoBehaviour
{
    public Transform MimicWho;
    public Vector3 OffSet = Vector3.zero;
    public bool MimicPosition = true;
    public bool MimicRotation = true;
public float Damping = 1;

    void Update()
    {
if (MimicRotation)
transform.rotation = Quaternion.Slerp( transform.rotation, MimicWho.rotation, Time.deltaTime*Damping);

if (MimicPosition)
transform.position = Vector3.Lerp( transform.position, (transform.rotation*OffSet)+MimicWho.position, Time.deltaTime*Damping);
    }
}

:)

Does it implement this interface? (C# Unity)


Does it implement this interface?

Sometimes when using Unity, you need to know, in realtime, if your object has implemented such interface, here is a function that can help.


    static public T HasImplementedInterface(GameObject o)
    {
        return o.GetComponents().OfType().FirstOrDefault();
    }

if you don't want to use RTT System.linq, you can do it even easier:


//imagine an interface called ICarPanel
ICarPanel cp = obj as ICarPanel;
if (cp!=null)
Debug.Log("Implements ICarPanel");


:) !

Tuesday, November 19, 2013

Shuffle C# List



Long time without posting. 

Too many things happened in my life during that time but it's not topic for this blog, then,
what about code this time? 



Simple put, I needed shuffle a simple List in C# and I was not able to find some easy way over the internet, so I spent some minutes to create my own way, a small handly function to shuffle IList, use it, enjoy it and improve it (in this case, just let me know how to do it better).

long life and stay creative!

    void Shuffle<T>(ref List<Tt)
    {
        //create a temporary empty list
        List<Ttmp = new List<T>();
        
        System.Random rand = new System.Random();
        
        //create a temporary index list
        List<intindexList = new List<int>();
        for (int j = 0j < t.Count; ++j)
            indexList.Add(j);
        
        while (indexList.Count > 0)
        {
            int k = rand.Next(0indexList.Count - 1);
            // Console.WriteLine("index: " + indexList[k] + " content: " + t[indexList[k]]);
            tmp.Add(t[indexList[k]]);
            indexList.RemoveAt(k);

            tmp.Reverse ();
        }

        
        t = new List<T>(tmp);
        
        return;
    }

Tuesday, November 10, 2009

Generic interface game flow



Question? is that possible to create an architecture, interface based, which allows you programming a game flow independent of his content?

answer: yes!

Note that Minigame_Pinball and Minigame_Pinball_Score are just interface implementations that don't know nothing about the game flow, they are using IGameObj to connect to the flow and returning a condition from FLOW_CONDITIONS, they register themselves and they are allocated only when I need them :) (it's easy to pre-allocate if you want to)

Now, you can copy the code, create your own game class, derive that from IGameCreateObj and implementing your own IGameObj and have fun!!!!



//class MyOwn : public IGameCreateObj<MyOwn>

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <typeinfo>
#include <time.h>

using namespace std;

enum FLOW_CONDITIONS { LOOP = 0, NEXT_FLOW, BACK, NEXT };

class IGameObj
{
public:
virtual void Init() = 0;
virtual FLOW_CONDITIONS Loop() = 0;
virtual void Uninit() = 0;
virtual IGameObj *CreateANew() = 0;

virtual ~IGameObj(){};
};

template<class X>
class IGameCreateObj : public IGameObj
{
public:
//make singleton
static X* GetInstance() { static X x; return &x; }
//able to get a copy
IGameObj *CreateANew() { return new X(); };

virtual ~IGameCreateObj(){};
};

class Minigame_Pinball : public IGameCreateObj<Minigame_Pinball>
{
private:
double timeOut;

public:
void Init() { timeOut = clock(); };
FLOW_CONDITIONS Loop()
{

timeOut += clock()-timeOut;

if (timeOut > 3000)
return NEXT;

cout << "Minigame_Pinball " << timeOut << endl;

return LOOP;
};

void Uninit() {};
};

class Minigame_Pinball_Score : public IGameCreateObj<Minigame_Pinball_Score>
{
public:
void Init() {};
FLOW_CONDITIONS Loop() { return LOOP;};
void Uninit() {};
};

struct FlowCondition
{
IGameObj *obj1;
FLOW_CONDITIONS fc;
IGameObj *obj2;
};

class IGameFlow
{
public:
virtual bool Loop() = 0;
};

class GameFlow : public IGameFlow
{
private:
vector<const FlowCondition* const> _list;

IGameObj *_currentObj;

IGameObj *AllocType( IGameObj *obj_info )
{
IGameObj *mg = NULL;
mg = obj_info->CreateANew();
return mg;
}

FlowCondition *SearchCondition( FLOW_CONDITIONS fc )
{
vector<const FlowCondition* const>::iterator it;
for( it = _list.begin(); it != _list.end(); ++it )
if ((*it)->fc == fc) return (FlowCondition *)*it;
return NULL;
};

public:
GameFlow() : _currentObj(NULL) {};

void RegisterCondition(IGameObj *obj1, const FLOW_CONDITIONS fc, IGameObj *obj2 )
{
FlowCondition *p = new FlowCondition();
p->fc = fc;
p->obj1 = obj1;
p->obj2 = obj2;
_list.push_back( p );

if (_currentObj == NULL)
{
_currentObj = AllocType(obj1);
_currentObj->Init();
}
return;
}

virtual ~GameFlow()
{
vector<const FlowCondition* const>::iterator it;
for( it = _list.begin(); it != _list.end(); ++it )
delete *it;

delete _currentObj;
}

bool Loop()
{
FLOW_CONDITIONS fc = _currentObj->Loop();
if (fc==NEXT_FLOW) return false;

FlowCondition *tmp = SearchCondition( fc );
if (tmp != NULL)
{
_currentObj->Uninit();
delete _currentObj;
_currentObj = AllocType(tmp->obj2);
_currentObj->Init();
}

return true;
}
};

class GameFlowManager
{
private:
vector<const IGameFlow* const> _list;

IGameFlow* _gFlowCurrent;

public:
GameFlowManager() : _gFlowCurrent(NULL) {};

void RegisterFlow(IGameFlow *gflow)
{
if (_gFlowCurrent==NULL) _gFlowCurrent = gflow;
_list.push_back( gflow );
return;
}

void Loop()
{
while(_gFlowCurrent->Loop())
{
}
}
};


int _tmain(int argc, _TCHAR* argv[])
{
GameFlow minigameFlow;
minigameFlow.RegisterCondition( Minigame_Pinball::GetInstance(), NEXT, Minigame_Pinball_Score::GetInstance());
minigameFlow.RegisterCondition( Minigame_Pinball_Score::GetInstance(), BACK, Minigame_Pinball::GetInstance());
minigameFlow.RegisterCondition( Minigame_Pinball_Score::GetInstance(), NEXT_FLOW, NULL );

GameFlowManager game;
game.RegisterFlow( (IGameFlow*)&minigameFlow );
game.Loop();

return 0;
}


Nowadays, I'm working as director of pre-production so "officially" I do not write code, anyway, I hope it can help someone :)

Thursday, February 12, 2009

From 3D coordenates to 2D




I'm working as producer now; thats not really an easy job, no time for anything else a team of 20, but when I have some chance, I'm used to code anything.

This code was done really fast, it convert from any 3d coordenates to 2D, for instance, you can use that to do a 2D map which refers a 3D space.

Vector2D From3DTo2D( const Vector2D &currPos3D, const Vector2D &initialCoord3D, const Vector2D &finalCoord3D, const Vector2D &initialCoord2D, const Vector2D &finalCoord2D )
{
 Vector2D tmp(0,0);

 tmp.X = 1-(finalCoord3D.X-currPos3D.X)/(finalCoord3D.X-initialCoord3D.X);
 tmp.Y = 1-(finalCoord3D.Y-currPos3D.Y)/(finalCoord3D.Y-initialCoord3D.Y);

 tmp.X = ((finalCoord2D.X-initialCoord2D.X)*tmp.X)+initialCoord2D.X;
 tmp.Y = ((finalCoord2D.Y-initialCoord2D.Y)*tmp.Y)+initialCoord2D.Y;

 return tmp;
}

Monday, September 24, 2007

Design Pattern Books

Sometimes you get all information you need in one book only, but sometimes, even including all information directly from core, it's possible that book has not been written best way it could do, I'm mean format.
if you ask me a good book about Design Patterns I would like to suggest two, first one it's the bible:



I'm used to say if you want to learn about C start reading “The C programming language” from Kernighan and Ritchie or if you want to learn about C++ start reading “The C++ programming language” from Stroustrup because those books are bibles written by creators of those languages; to learn with creators really works for me, the same can be said about Design Patterns, you can start reading the book above, after a first contact with idea, in order to get some fluency, you will need practice, more research and more samples, internet is full of them, but you know internet is a free land, so take care with pseudo gurus; in order to help you, I would like to suggest a second book about patterns that worked for me, this second book has a practical approach, I love practical things, less academic, the only bad point about this book is about language, they have been using Java, I’m not a Java programmer but if you know C++ or even C+# and OO you can read without any reserve.



I've friends that confessed me they ignored this book because the cover, don’t do that, it’s a nice book!
Keep studying and keep creative.










Another very very nice work, this time, they've provided codes in other languages and all kind of examples; really excellent job.




Design Patterns: Simply


http://sourcemaking.com/design-patterns-simply-course

Good reading!

Thursday, September 20, 2007

Float random in 15 minutes

I was reading Gamasutra website when I saw an interesting job offer, please check out, http://jobs.gamasutra.com/jobseekerx/viewjobrss.asp?cjid=12163&accountno=219
I couldn't avoid write that function they are describing in the first part of test.

* The function rand_FloatRange(float a, float b) returns a random float number, 'x', such that a <= x <= b.


I’ve decided to invest 15 minutes from my spare time, so after 5 minutes trying the conventional approach I just decided change strategy in order to make that function work in the last 10 minutes; Pressing creative button all became clear: we need to return a number that needs match AB range, the difference between A and B can be considered a distance as well, a percent, that was my approach:


float rand_FloatRange(float a, float b)
{
return ((b-a)*((float)rand()/RAND_MAX))+a;
}


All I did was transform conventional rand() in percent, now that I’ve a percent I can apply that to range between A and B, it doesn't matter if they are negative or positive values, easy, huh?

that’s all!!! nothing bad for 15 minutes

Keep creative!

Saturday, August 25, 2007

Tic Tac Toe - checking winner without matrices



Recently I was interviewed for a big company, (no names here); it was an exciting and interesting interview by phone; the recruiter started asking me about linked lists, data structures, collisions trees, path finding, etc… It was strange talking about code by phone, I had never been interviewed that way before, not by phone; worst than that I was under strong medicines, I had caught a cold one night before, summarizing, that was not my day, during interview one of the questions allowed me show to recruiter exactly how I’m used to think, He asked me:

"How would you implement the rules of a Tic Tac Toe game?"

He asked me to think while telling him what I was thinking. I was under pressure and doesn’t matter how much recruiter tried to calm down it was still an interview for a big company, describing code techniques by phone, so I started answering conventional way, I meaning not the way I'm used to do, (creative way), I started creating a 3x3 matrices considering game positions, etc… suddenly some voice inside of me started screaming: “Wake up Flavio! What you are doing! that’s your opportunity to show how you think, don’t fear, don’t be conventional!” Instantly I started thinking the way as I’m used to do, I'm used to think visually first, metaphorical way second, design third and coding at last so I said to recruiter: “Forget everything you heard I would like to start again, Tic Tac Toe is a game which the rules are fixed, it never changes, you can visualize board so that, you can see results visually and map them all in any place, its about 8 possibilities of victory starting count after three choices, a bit field should work fine for that" so I suggested a bit field which would avoid matrices manipulation overhead. I felt some “what? show me the money” feeling coming from other phone line, and He asked me to tell him the code for this, by phone, He asked me to write the code in a piece of paper, or compiler, or any text editor and keep telling him what I was writing and thinking, well, I was not comfortable, I was sick and under pressure and I was not able to do the code that time, after sleep a little and wake up better here is the code.




// tictactoe.cpp : This code is only for illustrate an idea.
// 08/26/2007 by flavio.rodriguez@gmail.com

#include "stdafx.h"
#include <iostream>

#define TEST_IF_PLAYER_WIN(playerMoves, bitTest) (playerMoves&bitTest) == bitTest

using namespace std;

/*

Mapping Tic Tac Toe victory possibilities

X|X|X = 111
0|0|0 = 000
0|0|0 = 000
-----------
111000000

0|0|0 = 000
X|X|X = 111
0|0|0 = 000
-----------
000111000

0|0|0 = 000
0|0|0 = 000
X|X|X = 111
-----------
000000111

X|0|0 = 100
X|0|0 = 100
X|0|0 = 100
-----------
100100100

0|X|0 = 010
0|X|0 = 010
0|X|0 = 010
-----------
010010010

0|0|X = 001
0|0|X = 001
0|0|X = 001
-----------
001001001

X|0|0 = 100
0|X|0 = 010
0|0|X = 001
-----------
100010001

0|0|X = 001
0|X|0 = 010
X|0|0 = 100
-----------
001010100

*/

typedef struct
{
unsigned long _LD : 9; // 111000000
unsigned long _LM : 9; // 000111000
unsigned long _LU : 9; // 000000111

unsigned long _CL : 9; // 100100100
unsigned long _CM : 9; // 010010010
unsigned long _CR : 9; // 001001001

unsigned long _LR : 9; // 100010001
unsigned long _RL : 9; // 001010100

}WINNING;

int _tmain(int argc, _TCHAR* argv[])
{
WINNING win;

//The 8 victory possibilites
win._LD = 0x1C0;
win._LM = 0x38;
win._LU = 0x7;
win._CL = 0x124;
win._CM = 0x92;
win._CR = 0x49;
win._LR = 0x111;
win._RL = 0x54;

/*
* Although this code works it was made as pseudo, I mean no structure or functions,
* the objective here is just check victory
* then imagine a player called A
*/
unsigned long playerA = 0;

/*
each quad represents a position in game

| | | |
|--|--|--|
| | | |
|--|--|--|
| | | |

and here is their relative values

|1 | 2| 4|
|--|---|---|
|8 | 16| 32|
|--|---|---|
|64|128|256|
*/

/*
* Now you can simulate any player move;
* in case of two players, we should just to create a player called B
* each time player click a quad, a bit is incremented
* and that would begin to be tested after the third move, once
* before that time we don't know winner
*/

//player move - Good choice
playerA |= 64;
//play move - Good Choice
playerA |= 128;
//play move - Bad choice
playerA |= 2;
//play move - good choice you won!
playerA |= 256;

//CHECKING VICTORY
//please, FOR SURE it would be in a function
//its only to illustrate
if (TEST_IF_PLAYER_WIN( playerA, win._LD ))
cout << "WON LINE DOWN" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._LM ))
cout << "WON LINE MIDDLE" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._LU ))
cout << "WON LINE UP" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._CL ))
cout << "WON COL LEFT" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._CM ))
cout << "WON COL MIDDLE" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._CR ))
cout << "WON COL RIGHT" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._LR ))
cout << "WON LEFT TO RIGHT" << endl;
else if (TEST_IF_PLAYER_WIN( playerA, win._RL ))
cout << "WON RIGHT TO LEFT" << endl;

return 0;
}



Learned lessons, never to be interviewed sick!

That's it! stay creative!
Powered By Blogger