Jump to content

  • Log In with Google      Sign In   
  • Create Account

HappyCoder

Member Since 28 Apr 2007
Offline Last Active Yesterday, 10:04 PM

#5190009 My goodness multiple inheritage is like a taboo. Why?

Posted by HappyCoder on 29 October 2014 - 02:29 PM

There have been times that I have found multiple inheritance useful, but in these cases I only have one class that I think of as the base class and all other base classes are more like interfaces. I still have some functionality in the "interfaces" at times.

 

As an example

class IUpdateReciever
{
public:
    void DisableUpdate();
    void RenableUpdate();

    virtual void Update(float deltaTime) = 0;

    virtual ~IUpdateReciever();
protected:
    IUpdateReciever(UpdateManager& manager);
    UpdateManager& mUpdateManager;
private:
    IUpdateReciever();
}

This is an example of an interface for any class that should recieve an update message. By designing the class in this way I can force all instances of IUpdateReciever to be added to an UpdateManager, I can keep common behavior in one place, such as storing the update manager and disabling and reenabling updates. Most importantly I can implement the destructor that will remove the update receiver from the update manager. This guarantees that the update manager wont have a pointer to an update receiver that has been destroyed. So in summary multiple inheritance can offer some nice features when used properly.

 

But just to be clear, it is really easy to abuse multiple inheritance. Below is an example of what NOT to do.

class MeshRenderer
{

}

class LuaScriptBehavior
{

}

class PhysicsObject
{

}

// DON'T DO THIS!
class GameObject: public MeshRenderer, public LuaScriptBehavior, public PhysicsObject
{

}

// Use aggregation like this instead
class GameObject
{
private:
    MeshRenderer mRenderer;
    LuaScriptBehavior mBehavior;
    PhysicsObject mPhysicsObject;
}

Truthfully, my example above of IUpdateReciever could even be refactored to use aggregation like the second game object example instead of inheritance and still maintain many of the same benefits. IMHO, my IUpdateReciever isn't abusing multiple inheritance. The class is very minimal and wouldn't cause the dreaded diamond inheritance problem. There is no one right way to do things, you just need to understand the advantages and disadvantages to how you end up doing it.




#5187065 max size for level using floats

Posted by HappyCoder on 14 October 2014 - 07:53 PM

You wont be able to specify the position with much precision on the edges of your star system. The limiting factor here is the fraction part of the floating point number. Your universe is about 2^58 meters across. A double has 53 bits of precision in the fractional part. This means, at the edges of the universe, you will only be able to represent the position of a ship in increments of 2^5, or about 32 meters. Floats are even worse, you can only have 24 bits of precision. This is about a precision of 2^34 meters or about 16 billion meters. Not good.

 

I would use 64 bit integers to store the galactic coordinates of objects in your universe. That would give you precision to about 2^-6 or about a precision of two centimeters. Of course, when rendering your scene, you wont be able to work in integers. So whenever you are rendering anything, you need to convert all of your coordinates to a local origin, then convert all active object coordinates to floats that are relative to the local origin.

 

EDIT: fixed computation error




#5184661 Visual Programming Language for Shading?

Posted by HappyCoder on 02 October 2014 - 05:21 PM

Take a look at Directed Graph Shader Language.

 

This is directx specific tool meaning you wont be able to create GLSL with it. One challege with shaders is they are usually tied to a specific game engine. That makes it harder to have a generic shader making tool you can use anywhere.




#5184614 new MOBA idea

Posted by HappyCoder on 02 October 2014 - 12:41 PM

Characters can be heroes from: 

1. different mythologies (Greek, Norse etc.)

 

That's what Smite does. If a game studio used that as an idea, that means it must be a good one. ;)

 

However, I agree with what jHaskell said, coming up with spell ideas is not the hard part. Most of the challenge comes from a well balanced game with good counterplay.




#5183562 OpenGL rotation matrix, [math] rotates in different direction

Posted by HappyCoder on 28 September 2014 - 05:19 PM

When calculating the sphere positions you are multiplying on the wrong side of the matrix

float rotm[16]; int i;
for (i=0; i<16;i++) rotm[i] = hull.rotation.AIR_MATRIX[i];

// switch the order of multiplication here
col_front_left = rotm * front_left;
col_front_left = col_front_left + pos;

col_front_right = rotm * front_right;
col_front_right = col_front_right + pos;

col_rear_left = rotm * rear_left;
col_rear_left = col_rear_left + pos;

col_rear_right = rotm * rear_right;
col_rear_right = col_rear_right + pos;

EDIT: Thought I should explain why this is.

For a rotation matrix, the transpose is the same as the inverse

 

RT = R-1

 

Changing the order of multiplication is the same as multiplying by the transpose

 

R * vector = vector * RT

 

 

But since the transpose is the same as the inverse you were basically multiplying the points by the inverse of the rotation.




#5182457 Free game engines for 3d games

Posted by HappyCoder on 23 September 2014 - 12:38 PM

Unity lets you do quite a bit using the free version. If you do make a something financially successful with unity, they require to buy a license, but at that point paying for a licence isn't such a big deal.




#5178954 How to design my game

Posted by HappyCoder on 08 September 2014 - 04:06 PM

If all the content in your game could be loaded from a file, then each package could simply be a collection of content for you game. This means levels, models, textures, and even game logic all needs to be independent of the compile time code.

 

Another option is to have the game come bundled with all of the content but downloading a 'package' simply unlocks it.




#5177299 OpenGL Camera

Posted by HappyCoder on 31 August 2014 - 05:17 PM

I'm not sure what you mean by the axis drifting, but there is something that looks off in your code.

looking at the quaternion reference form glm, it looks like you are getting the parameter order wrong in the quat constructor. It expects w first, you are passing it in last.

 

Also, usually the forward vector for the camera goes along the z axis. For your up down rotation, it looks like you are rotating around the z axis. This will result in the camera rolling instead of pitching. Try switching the rotUP to rotate around the x axis.




#5177229 learning to render

Posted by HappyCoder on 31 August 2014 - 10:59 AM

I would recommend learning DirectX 11. OpenGL is full of legacy code for backwards functionality. This means OpenGL will let you continue to do things the old way so you may be using functionally that has been outdated since the 90s.

 

Directx 11, on the other hand, has trimmed the fat and only offers an interface to graphics that is up to date. This will help you learn the more modern way of doing things. OpenGL will also have much of the same updated functionality but it is hard to know what is the state of the art in all of those API calls.

 

With modern graphics, there is a lot to take in. You will find you have to write a lot of code just to draw a single triangle. Don't be frustrated if you don't understand it all right away. Just try following some tutorials and get those working. Then start to play around with the tutorial code to get it to do what you want it to. You will learn as you experiment. If you have any questions or hit any roadblocks feel free to post your questions here.

 

Here are some good tutorials to get you started




#5177224 How to organize your code and design your system

Posted by HappyCoder on 31 August 2014 - 10:39 AM

Learning good design comes in part by trail and error. You find out what works and what doesn't. A few tips to help you out though.

 

Each class should only do one thing. Other classes should not need to know the inner workings of another class to use it. As an example below, say there is a class, Foo, where every time you assign fooBar you should incriment bar

////////////////////////
// The wrong way to do it
class Foo
{
    public int bar = 0;
    public int fooBar = 0;
}

Foo foo = new Foo();

++foo.bar;
foo.fooBar = x;

////////////////////////
// The better way to do it
class Foo
{
   private int bar = 0;
   private int fooBar = 0;

   public void SetFooBar(int value)
   {
        ++bar;
        fooBar = value;
   }
}

Foo foo = new Foo();
foo.SetFooBar(x);

If you find that you are repeating the same lines of code over and over again try to find a way to make a method out of it and make that method part of a class where it makes the most sense, the method should work with either members of the class or parameters passed to the method. Do not use global variables or singletons. Global constants are good though, they help you avoid magic numbers.

 

Only use inheritance when you need polymorphism. If you just need the functionality of another class just make it use the other class

////////////////////////
// Bad
class Foo extends Array
{

}

Foo foo = new Foo();
foo.Add(item);

//////////////////////
// Better
class Foo
{
    private Array array;
    void Add(Item item)
    {
        array.Add(item);
    }
}

If any single function gets long split it up into smaller functions where each function does one well defined thing and the original function uses these small functions. This practice when done right will also help your reduce duplicate code. The same goes for large classes. If you have a large class, split up the functionality. There is no exact value for what is too long, but when a functions is over 50 lines of code you should consider breaking it up. If a class is approaching a few hundred lines of code, you should break it up.

/////////////////////////
// Bad
void Update(float timeStep)
{
  // update position 
  position.x = position.x + velocity.x * timeStep;  position.y = position.y + velocity.y * timeStep;
  velocity.x = velocity.x + acceleration.x * timeStep;  velocity.y = velocity.y + acceleration.y * timeStep;

  if (doesCollide(world))
  {
     // collision code
  }

  // update AI
}

////////////////////////////
// Better
Point Add(Point a, Point b)
{
    return new Point(a.x + b.x, a.y + b.y)
}

Point Scale(Point a, float b)
{
   return new Point(a.x * b, a.y * b);
}

void UpdatePhysics(float timeStep)
{
  position = Add(position, Scale(velocity, timeStep));
  velocity = Add(velocity, Scale(acceleration, timeStep));
}

void UpdateCollision(float timeStep)
{ 
  if (doesCollide(world))
  {
     // collision code
  }
}

void UpdateAI(float timeStep)
{
  // update AI
}

void Update(float timeStep)
{
  UpdatePhysics(timeStep);
  UpdateCollision(timeStep);
  UpdateAI(timeStep);
}

I am going to stop there for now before I turn this into an article, but hopefully this is useful to you.

 

EDIT:

I would also suggest looking at Unity to see how they use a component based system. It by no means is the only way to organize a game, but it is a good example of how to solve the problem, it definitely isn't an easy one to solve.




#5176754 Include file not found in GCC, due to path size?

Posted by HappyCoder on 28 August 2014 - 03:13 PM

If you add the path D:\ZTUFF\Projects\EDGE\ as an include path for your project, you can include a file based on its absolute location relative to project

#include "Source\Engine\Resources\Material Resource\MaterialResource.h"



#5176303 [2D]Make a camera follow multiple characters.

Posted by HappyCoder on 26 August 2014 - 04:21 PM

The bounding box is the smallest box that contains a list of points. You can represent a bounding box by the location top, bottom, left, and right edges. The top and bottom only need to store a y coordinate value, right and left store an x coordinate. To calculate the bounding box, you loop through all points and for each one, you extend the bounds of the box if the point isn't contained in the bounding box. However, the first point in the list needs to initialize the bounding box.

 

 

Calculate the bounding box

boundingBox.left = points[0].x
boundingBox.right = points[0].x
boundingBox.top = points[0].y
boundingBox.bottom = points[0].y

// set i to 1 to skip the first point since it was used to initialize the bounding box
for (int i = 1; i < points.count; ++i)
{
   if (points[i].x < boundingBox.left)
      boundingBox.left = points[i].x

   if (points[i].x > boundingBox.right)
      boundingBox.right = points[i].x

   if (points[i].y < boundingBox.top)
      boundingBox.top = points[i].y

   if (points[i].y > boundingBox.bottom)
      boundingBox.bottom = points[i].y
}

The aspect ratio is just the width divided by the height. where the width of the bounding box is boundingBox.right - boundingBox.left and the height is boundingBox.bottom - boundingBox.top




#5176057 Funniest line of code ever ?

Posted by HappyCoder on 25 August 2014 - 02:09 PM

The comment here is kinda funny
 

class Lens
{
public:
	virtual ~Lens();

	virtual Matrix4f GetProjectionMatrix() const = 0;
protected:
	Lens(float near, float far); 
	
	float mNear;
	float mFar;
	//float mWhereEeeeeevarYouAre;
private:
};



#5176044 Sampling the Render target while rendering to it

Posted by HappyCoder on 25 August 2014 - 12:44 PM

Another option would be to use two seperate render targets. You render everything to one target that doesn't require any special treatment, then you copy the contents of that render target to another render target. You then use one as the input and one as the output.




#5175884 [2D]Make a camera follow multiple characters.

Posted by HappyCoder on 24 August 2014 - 05:47 PM

First you create a bounding box of your level that contains all of your characters plus a bit of a margin so a character isn't right on the edge.

 

You then compare the aspect ratio of this bounding box to the aspect ratio of the screen. If the bounding box has a larger aspect ratio, then you base the zoom of the camera on screen.width / boundingBox.width, otherwise you use screen.height / boundingBox.height. The center point of the camera is simply the midpoint of the bounding box.






PARTNERS