Jump to content

  • Log In with Google      Sign In   
  • Create Account

Finalspace

Member Since 29 Mar 2012
Offline Last Active Yesterday, 01:52 PM

Posts I've Made

In Topic: To use tiles or pre rendered images for game graphics

04 February 2016 - 07:27 AM

 

In my own game - which is a 2D overhead RPG - I have multiple different layer types, and each layer type can go into any position.

 

However, you might not need that flexibility/complexity. Instead, I'd start with something like this and tweak it as I go:

//Pseudocode:
struct World
{
     Array<Layer> layers;
};
 
struct Layer
{
     Backdrop backdrop; //Drawn first.
     Tilemap tilemap; //Drawn second. Can collide with.
     Array<Decal> decals; //Draw third.
 
     Array<Entity> activeEntities;

     //This controls player-movement-related scrolling. i.e. you multiply this against the player's position to get the layer's scroll position.
     //For example, you may want a layer FIXED to the viewpoint with NO scrolling no matter how much the player moves. Like sun rays.
     Vector2f parallax;
};

//What I call a large repeating image that scrolls, and can be UNDER (i.e. background) or OVER (i.e. foreground) a player
struct Backdrop
{
     ImageID appearance;

     //This is the scrolling that occurs automatically, without the player moving. Things like clouds or mist.
     Vector2f scrollSpeed;
};

//What I call a freely-placed, freely-rotated, freely-scaled image
struct Decal
{
     Position position;
     float scale;
     float rotation;
     ImageID appearance;
};
 
struct Tile
{
     Shape collisionShape;
     ImageID appearance;
};
 
struct Tilemap
{
      Grid<Tile> tiles; //Note: Breakable/interactive tiles are entities pretending to be tiles, as are invisible triggers, movable doors, and so on.
};

[Edit:] Forgot to include the Backdrop definition.

Why use structs and not a class?

 

 

These seems to be just data structures - so structs are the best way to define those. No need for classes which is great ;-)


In Topic: My Simple Circle-AABB Collision Resolution Algorithm Isn't Working

29 January 2016 - 08:40 AM

Just take the movement vector into account, so that you prefer a closest point in the direction you are walking.

 

Something like this (not tested and can be better written):

void PhysicsSystem::resolve_collision(DynamicEntity& entity, int x, int y)
{
  Vector2f tile_pos(x, y);
  Vector2f nearest(entity.pos);
  Vector2f min(x, y), max(x, y);
  if (entity.vel.x() < 0) {
    min.x = x - 1;
  } else {
    max.x = x + 1;
  }
  if (entity.vel.y() < 1) {
    min.y = y - 1;
  } else {
    max.x = y + 1;
  }
  ...
}

In Topic: Resolving collisions with enums

18 January 2016 - 12:27 PM

Hey all, just looking for some suggestions on how to resolve collisions in my game engine. 

 

Here's what I'm working with:

 

I have a spatial partition of GameObjects, where I do my collision detection. If a collision is detected, A Resolution object is returned with the following format:

 

struct Resolution{

  unsigned int colBoxA;   //Index of collision box within object

  unsigned int colBoxB;

  //One or two trival members not important here

};

 

1. I iterate through all the Partition buckets to test for collisions.

 

2. I have a Map container which stores all the Resolution objects. To ensure each collision is unique they key for the map is

   a pair of both GameObject_ID's, and the value is the Resolution object. 

 

3. colBoxA and colBoxB are indices to AABB's that reside in each object. Let's say ObjectA has two collision boxes: A hitbox and a shield, while ObjectB has a single collision box: a projectile. So an entry in my Resolution container has information on which two objects are colliding, and on which respective collisionbox.

 

4.  Each Collisionbox has an enumerated type associated with it (Wall,projectile,hitbox,melee) etc.....

 

I want to resolve the collision based on both the types associated with the collision, and apply the result correctly to each object. I've looked around,  and it seems like I should be using some type of Strategy Pattern. By not using this, it looks like I am facing nested switches (not going to happen). Even with the Strategy Pattern, I am unsure on how to implement this.

 

Any advice or similar documentation would be greatly appreciated smile.png

 

A simple solution would be to use a 2d array for the collision type. This can be a const fixed array or a dynamic array created on the game initialization process. This would look like this (I use this for my contact generators - copied from my java source):

public final class ContactGeneratorFactory {
	private final int MAX_GENERATORS_PER_SHAPE = ShapeType.COUNT.id;
	private final ContactGenerator[][] generators = new ContactGenerator[MAX_GENERATORS_PER_SHAPE][MAX_GENERATORS_PER_SHAPE];
	
	public ContactGeneratorFactory() {
		generators[ShapeType.Plane.id][ShapeType.Circle.id] = new PlaneCircleContactGenerator();
		generators[ShapeType.Plane.id][ShapeType.Box.id] = new PlaneEdgeContactGenerator();
		generators[ShapeType.Plane.id][ShapeType.Polygon.id] = new PlaneEdgeContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Box.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Box.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Polygon.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.Polygon.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Circle.id][ShapeType.Circle.id] = new CircleCircleContactGenerator();
	}
	
	public int generate(Transform transformA, Transform transformB, Shape shapeA, Shape shapeB, int offset, Contact[] contacts, ContactAcceptor acceptor) {
		int result = 0;
		
		// Sort shape types
		boolean flip = false;
		ShapeType typeA = shapeA.type;
		ShapeType typeB = shapeB.type;
		if (typeA.id > typeB.id) {
			ShapeType temp = typeA;
			typeA = typeB;
			typeB = temp;
			flip = true;
		}
		
		// Find generator by both shape type id´s
		ContactGenerator generator = generators[typeA.id][typeB.id];
		if (generator != null) {
			// do something with the found generator
		}
	}
}

You just create classes based on some simple CollisionResponse interface and create instances for every possible pairs.

 

Important: The order of your object collision enumeration matters, see:

public enum ShapeType {
	Plane(1),
	LineSegment(2),
	Box(3),
	Polygon(4),
	Circle(5),
	COUNT(6);
	
	public final int id;
	
	private ShapeType(int id) {
		this.id = id;
	}
}

In Topic: Understanding cross product without delving too much on Linear algebra

15 January 2016 - 11:26 AM

 


This means there is an infinite number of vectors that are parallel to a plane, so all three of the edges of a triangle are parallel to the plane of the triangle.

Still confuse about this. so that means this plane is also the surface? That means in 2D, this plane is facing up or facing to any direction? But let say if the plane is pointing up, does that mean the vertices as well?

 

 

A plane does not have any vertices at all - a plane is just either a point + a unit vector or the plane is defined as a unit vector and some signed distance (scalar) to the origin. And in 2D a plane is just a line with infinite width.

 

Try to imagine just a point in some world and some arrow from the point to a specific direction - Thats the easiest way to understand the concept behind it.

 

For a triangle in 3D, vertices can be seen as planes as well. Each 3D Vertex in world space can also be defined as a unit normal with a distance to the origin. Each vertex may have its own normal overriden, so each point can face in a different direction - this is important when you want some smoothness for lightning as a example.


In Topic: Simple CCD for a game

10 January 2016 - 06:36 AM

but you will lose the ability to control the bounce.
why exactly? due the possible time cutting? and what about accumulation?

 

With speculative contacts, you adjust the velocities so that the objects just touch each other. This results in cutting of energy which may be used to let the object bounce. But you can regain that lost energy by saving the contacts from the last frame and save the separation impulse and include this in the final impulse for the new frame.


PARTNERS