Jump to content

  • Log In with Google      Sign In   
  • Create Account


Irlan

Member Since 08 May 2012
Online Last Active Today, 10:24 AM

Topics I've Started

Question about game events

18 June 2014 - 05:43 AM

I want to know if game events should be generated by the Game itself or, for instance, the game world can generate game events based on things that happen inside the world?

 

So my world can have a EventListener attached to it?

 

 

Eg.

 

BeginContact->GenerateGameEvent->DispatchEventViaEventListener

 

?


About the Game Logic Class

20 May 2014 - 07:40 AM

So, I've just figure out that my Actor Component Model is flawed by reading L. Spiro posts saying that the game logic handles all the logic of a Character/Player/Node (that actually make a lot of sense).

In my simple implementation I have a IBehaviour class that goes in the Actor class, but AI and Game Logic is supposed to be in a AI class (the Game class in that case). Do you think the following approach is +- correct?
 

class Character : public Behaviour
{
public:
enum StateMask
{
CHARACTER_CAN_JUMP,
CHARACTER_CAN_FLY
};

Character() : mask(0) { }

virtual void Update(Actor* _pActor)
{
if ( mask & CHARACTER_CAN_JUMP ) //just an example
{
//Do something with jump code
}
}
private:
bool mask;
};

class Game
{
public:

void Update()
{

for ( size_t i = 0; i < characters.size(); ++i )
{

if ( SOME_CONDITION )
{
characters[i]->SetMask( characters[i]->GetMask() | CHARACTER_CAN_JUMP ); //just an example
}

}

}
private:

std::vector characters;

};

class Actor
{
public:
void Update( const Time& _time )
{
pBehaviour->Update( this );
}
private:

IBehaviour* pBehaviour;
};

In this case, I'm removing all the Behaviour stuff and putting into the AI class (the Game class in this case).
Then, I'll pass all data related to the Game in a game_config.xml file. When detects a Character, it's added to be managed by it, and adds a new Actor to the Scene.

Whenever my Actor gets created/destroyed, I need to notify to the Game class to remove the pBehaviour, but by doing this, I'm going in the wrong side of the Single Responsability Principle. Now my Scene knows about the Game class (the AI class (the Game class in this case) ).

Any good advice will be instantaneously voted up.


Code inside Character Controller/Steering/ or inside Gameplay/Targeting System?

24 March 2014 - 11:21 AM

I have a Steering class that has a pointer to a Pathfinder (nodes, goal target etc.).

Another class is the Character that have pointers to Input State and Input Axis.

 

I have tags for my actors (character, enemy etc.) and a scene that have queries like find all actors of type etc.

 

My question is: is better to put character/enemies behaviours explicity inside the Gameplay State/Objective class or should I go to the OOP side and increase the dependencies (put a pointer to InputState and Pathfuider in character). The OOP side doesn't make sense!

 

The "player" is just an actor with a energy bar and the enemy is just another actor with steering forces applied and etc.

Another problem is: the "player" can only jump if is on ground and now it has to be acess to the physics class.

 

My Gameplay State code:

void Gameplay::Update(Game* pGame, float dt) 
{
	Physics* pPhysics = pGame->pPhysics;
	Scene* pScene = pGame->pScene;

	pPhysics->Update(dt, pGame); //pGame is a abstract Event Listener
	pScene->Update(dt); //manages actors

	Core* pCore = pGame->pCore;
	InputAxis* pInputAxis = pCore->GetInputAxis();
	InputState* pInputState = pCore->GetInputState();

	std::vector<Actor*> characters;
	pScene->GetActorsOfType(MASK_CHARACTER, characters);

	for (size_t i = 0; i < characters.size(); ++i)
	{
		RigidBody* pCharacterBody = characters[i]->GetRigidBody();

		const glm::vec3& normal = pCharacterBody->orientationMatrix[2];
		const float speed = 100.0f;

		pCharacterBody->Rotate(-pInputAxis->y * dt, -pInputAxis->x * dt, 0.0f);

		if (pInputState->isUp)
		{
			pCharacterBody->ApplyForce(normal * speed * dt);
		}
		if (pInputState->isDown)
		{
			pCharacterBody->ApplyForce(-normal * speed * dt);
		}

		std::vector<Actor*> enemies;
		pScene->GetActorsOfType(MASK_ENEMY, enemies);

		for (size_t j = 0; j < enemies.size(); ++j)
		{
			RigidBody* pEnemyBody = enemies[j]->GetRigidBody();

			const glm::vec3& position = pEnemyBody->GetPosition();
			const glm::vec3& target = pCharacterBody->GetPosition();

			const glm::vec3& toTarget = target - position;
			float distance = glm::length(toTarget);

			const float maxDistance = 10.0f;

			if (distance > 0.0f && distance < maxDistance)
			{
				glm::vec3 normal = glm::normalize(toTarget);
				glm::vec3 force = normal * 10.0f;

				glm::mat4 lookAt = glm::lookAt(position, target, glm::vec3(0.0f, 1.0f, 0.0f);
				glm::mat3 orientationMatrix = glm::transpose(glm::mat3(lookAt));

				glm::quat orientation = glm::toQuat(orientationMatrix);

				pEnemyBody->ApplyForce(force * dt);
				pEnemyBody->SetOrientation(orientation);
			}
		}
	}
}

Is my Game Architeture/Loop ok?

19 February 2014 - 11:26 AM

My friends, I need a advice in my design if possible.

 

Some classes are based on the book Game Engine Architeture. It's not a very large project but I'm thinking in keep the structure for use in the future. I'm going to post some questions that I think could help the others too.

 

Game.h

class Game
{
public:
bool Init();
void HandleEvent(Event* e);
void Update();

private:
Core core;
Renderer renderer;
Physics physics;
GameWorld gameWorld;

EffectDatabase effectDb;
TextureDatabase textureDb;
MaterialDatabase materialDb;
MeshDatabase meshDb;
};

Game.cpp

bool Game::Init()
{
if (!core.Init())
{
return false;
}
if (!renderer.Init())
{
return false;
}

//details ommited
return true;
}


void Game::HandleEvent(Event* e)
{
switch (e->type)
{
case EVENT_SPAWN:
{
Spawn* spawn = (Spawn*) e;
//todo
}
break;
default:
break;
}
}


void Game::Update()
{
sf::Clock clock;


float lagTime = 0.0f;
const float dt = 1.0f / 60.0f;


while (core.isActive)
{
core.HandleEvents(this);


const float frameTime = clock.restart().asSeconds();


lagTime += frameTime;
while (lagTime >= dt)
{
gameWorld.Update(dt); //update behaviours
physics.Update(dt); //check collisions

lagTime -= dt;
}

renderer.Draw(); //render mesh instances
core.Display(); //refresh window and swap buffers
}
}

The core system is just a wrapper for Windows Message and keep dispatching Windows Messages to the game.

The GameWorld holds a list of game objects.

 

I need to think in how I'm going to control the objects (add some filters, Input Controllers, etc.) because I'm using the component pattern. I'm kind of lost in that aspect. I've read Appochi's Input Mapping tutorial and I'm thinking how I can implement this into my game without extend everything from a Context.

 

I was reading some topics that states that GameStates are losing their forces and Behaviour Trees are a better way. Can I simulate a Game State using Behaviour Trees? Just to not get complicated, I should continue with my simple State Pattern?

 

I'm not fan of Design Patterns. I like to apply the ideas that they bring to us, but not completely extending interfaces and following the pattern.

For example: having a MenuState extended from a state is a bad idead. It's better to pass a Game* to a Menu member function and if a button is selected, send an Event to the Game.

 

The subsystems interconnections are disturbing me too. Should all the systems be connected with the Game World? When I spawn an GameObject, should I redirect a event to the GameWorld or just add the GameObject via gameWorld.PushGameObject(GameObject*) ?

 

Any kind of advice is welcome and may serve as a help to the others, OK?


OpenGL Lighting Issue

17 February 2014 - 10:37 AM

The issue is: the more distant the light is more the object is illuminated. Seems to be the normals or shaders.
Here is the shader's sources:
#version 330


layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_texCoord;
layout(location = 2) in vec3 in_normal;


out vec2 out_texCoord;
out vec4 out_color;


uniform mat4 perspectiveMatrix;
uniform mat4 viewMatrix;
uniform mat4 worldMatrix;

uniform vec3 viewPosition;
uniform vec3 globalAmbient;
uniform vec3 lightPosition;
uniform vec3 lightColor;

uniform vec3 emission;
uniform vec3 ambient;
uniform vec3 diffuse;
uniform vec3 specular;
uniform float shininess;

void main() 
{
  mat3 worldMatrix3 = mat3(worldMatrix);
  vec3 position = worldMatrix3 * in_position;
  vec3 surfaceNormal = normalize(transpose(inverse(worldMatrix3)) * in_normal);
  
  vec3 a = ambient * globalAmbient;
  vec3 d = diffuse * lightColor;
  vec3 s = specular * lightColor;
  
  vec3 lightDirection = normalize(lightPosition - position); 
  float cosIncidence = clamp(dot(surfaceNormal, lightDirection), 0.0f, 1.0f);
  
  d *= cosIncidence;

  if (cosIncidence > 0.0f)
  {
    vec3 viewDirection = normalize(viewPosition - position);
    vec3 halfDirection = normalize(lightDirection + viewDirection);

    float phongTherm = clamp(dot(surfaceNormal, halfDirection), 0.0f, 1.0f);
    phongTherm = pow(phongTherm, shininess);

    s *= phongTherm;
  }
  
  gl_Position = (perspectiveMatrix * viewMatrix * worldMatrix) * vec4(in_position, 1.0f);
  out_texCoord = in_texCoord;
  out_color = vec4(emission + a + d + s, 1.0f);
}
 
#version 330


in vec2 out_texCoord;
in vec4 out_color;


out vec4 ex_color;


void main()
{
    ex_color = out_color;
}

PARTNERS