Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


oler117

Member Since 28 Nov 2013
Offline Last Active Feb 03 2014 07:59 AM

Topics I've Started

Pathfinding with virtual fields

14 December 2013 - 09:34 AM

Hi! I have problems with implementing pathfinding using virtual potentional fields. I have square-tiled 2D world, where we can put start, finish and wall (not walkable) blocks. I've read about "potentional fields" method, but I couldn't find any example, how to realize it and decide to do it myself.
 
Here is my code:
Point* currentPlayer = start; //current player position
	Point* currentBlock;  //current blocked point
	XMFLOAT2 blockedForce;
	XMFLOAT2 lastsResultative = XMFLOAT2(0, 0);
	XMFLOAT2 finishForce;
	float squaredDist;
	int i = 0;

	while (*currentPlayer != *end)
	{
		finishForce = XMFLOAT2(
			end->getX() - currentPlayer->getX(),
			end->getY() - currentPlayer->getY() );
		finishForce = Calculations::VecNormalize2D(finishForce);
		/*finishForce.x *= 10;
		finishForce.y *= 10;*/

		i = 0;
		while (i < blockedPoints.size())
		{
			currentBlock = blockedPoints[i];

			squaredDist = pow( (currentPlayer->getX() - currentBlock->getX()),2 )
				+ pow( (currentPlayer->getY() - currentBlock->getY()),2 );

			blockedForce = XMFLOAT2(
				(currentPlayer->getX() - currentBlock->getX()) / squaredDist,
				(currentPlayer->getY() - currentBlock->getY()) / squaredDist);

			lastsResultative = XMFLOAT2(
				lastsResultative.x + blockedForce.x,
				lastsResultative.y + blockedForce.y);
			i++;
		}

		lastsResultative = XMFLOAT2(
			lastsResultative.x + finishForce.x,
			lastsResultative.y + finishForce.y);

		lastsResultative = Calculations::VecNormalize2D(lastsResultative);

		// ++++++++++++++ Make decision to what cell we have to walk, ++++++++++++++
		// ++++++++++++++ based on the resultant vector ++++++++++++++++++++++++++++
		float factor, prevFactor = 1000;
		Point *cell = nullptr, *tempCell;
		for (int j=-1; j<2; j++)
		{
			for (int k=-1; k<2; k++)
			{
				tempCell = GetCell(XMUSHORT2((USHORT)(currentPlayer->getX() + j),
					(USHORT)(currentPlayer->getY() + k)));
				if ((j==0 && k==0) || tempCell==nullptr) continue;

				XMFLOAT2 cellVec = XMFLOAT2((tempCell->getX() - currentPlayer->getX()),
					(tempCell->getY() - currentPlayer->getY()));
				factor = abs(cellVec.x - lastsResultative.x) + abs(cellVec.y - lastsResultative.y);
				if (factor < prevFactor)
				{
					cell = tempCell;
				} else factor = prevFactor;

				prevFactor = factor;
			}
		}
		if (cell != nullptr)
		{
			currentPlayer = cell;
			path.push_back(currentPlayer);
		}
		// ----------------------------------------------------------------------------
	}
I've attached screens. In most cases, algorithm steps into eternal loop.
 
Help please with this issue.

2D Rects collision problems

05 December 2013 - 11:51 AM

Hi! I've written my own simple function to detect collisions of rectangles and it works not accurate and not always. So here is my code:

bool GameLogic::IsRectsCollide(float* rect1, float* rect2, float eps)
{
	float r1_left = rect1[0];
	float r1_top = rect1[1];
	float r1_right = rect1[2];
	float r1_bottom = rect1[3];
	float r2_left = rect2[0];
	float r2_top = rect2[1];
	float r2_right = rect2[2];
	float r2_bottom = rect2[3];
	if (r2_right - r2_left < r1_right - r1_left)
	{
		swap(r1_left, r2_left);
		swap(r1_top, r2_top);
		swap(r1_right, r2_right);
		swap(r1_bottom, r2_bottom);
	}

	if ( ( r1_left >= r2_left && r1_left <= r2_right && r1_top >= r2_bottom && r1_top <= r2_top ) ||
		( r1_right >= r2_left && r1_right <= r2_right && r1_top >= r2_bottom && r1_top <= r2_top ) ||
		( r1_right >= r2_left && r1_right <= r2_right && r1_bottom >= r2_bottom && r1_bottom <= r2_top ) ||
		( r1_left >= r2_left && r1_left <= r2_right && r1_bottom >= r2_bottom && r1_bottom <= r2_top ) )
	{
		return true;
	}

	return false;
}

Image shows typical fail... blink.png


2D rotation problems

29 November 2013 - 03:38 PM

Hi 2 all! I have some problems with rectangle rotation. The sense of my test application: there are player in the center of screen, he can rotate around and shoot; bullets have to reflect from walls. All works fine except of walls rendering. The issues related to walls definition:

struct Line
{
	XMFLOAT2 point1;
	XMFLOAT2 point2;
	Line(XMFLOAT2 p1, XMFLOAT2 p2) : point1(p1), point2(p2) { };
};
vector<Line> SidesCoordList;
vector<GameObject> sides;

	SidesCoordList.push_back(Line(XMFLOAT2(0.0f, 0.0f),     XMFLOAT2(0.0f, 600.0f)   ));
	SidesCoordList.push_back(Line(XMFLOAT2(0.0f, 600.0f),   XMFLOAT2(800.0f, 600.0f) ));
	SidesCoordList.push_back(Line(XMFLOAT2(800.0f, 600.0f), XMFLOAT2(800.0f, 0.0f)   ));
	SidesCoordList.push_back(Line(XMFLOAT2(800.0f, 0.0f),   XMFLOAT2(0.0f, 0.0f)     ));

        ...
        
        for (Line& line: SidesCoordList)
	{
           GameObject temp;
           ...
           temp.SetPosition(center);
	   temp.SetRotation(XM_PIDIV2);
	   temp.SetScale(XMFLOAT2( 20.0f, length ));
           sides.push_back(temp);
        }
        
        ...
        
        for (int i = 0; i<instanceCount; i++)
	{
		if (i >= sides->size()) break;
		XMMATRIX mat = sides->at(i).GetWorldMatrix();
		instances[i].M1 = mat.m[0];
		instances[i].M2 = mat.m[1];
		instances[i].M3 = mat.m[2];
		instances[i].M4 = mat.m[3];
	}
        d3dContext_->UpdateSubresource(instanceBuffer, 0, 0, instances, 0, 0);

        ...

        d3dContext_->DrawInstanced(vertexCount, instanceCount, 0, 0 );

Code for matrices from GameObject class:

XMMATRIX GameObject::GetWorldMatrix( )
{
    XMMATRIX translation = XMMatrixTranslation( position_.x, position_.y, 0.0f );
    XMMATRIX rotationZ = XMMatrixRotationZ( rotation_ );
    XMMATRIX scale = XMMatrixScaling( scale_.x, scale_.y, 1.0f );
	
    return rotationZ * scale * translation;
}


void GameObject::SetPosition( XMFLOAT2& position )
{
    position_ = position;
}


void GameObject::SetRotation( float rotation )
{
    rotation_ = rotation;
}


void GameObject::SetScale( XMFLOAT2& scale )
{
    scale_ = scale;
}

HLSL code:

cbuffer cbMatrices : register( b0 )
{
	matrix world;
	matrix proj;
};

cbuffer cbParameters : register( b1 )
{
	bool isTextured;
	float4 color;
};

Texture2D colorMap_ : register( t0 );
SamplerState colorSampler_ : register( s0 );

struct VS_Input
{
	float4 position			: POSITION;
	float2 tex				: TEXCOORD0;
	
	float4 W0 : TEXCOORD1;
    float4 W1 : TEXCOORD2;
    float4 W2 : TEXCOORD3;
    float4 W3 : TEXCOORD4;
};

struct PS_Input
{
	float4 position : SV_POSITION;
	float2 tex		: TEXCOORD0;
};

PS_Input VS_Main(VS_Input input)
{
	PS_Input vsOut = ( PS_Input )0;

	float4x4 world_ = float4x4(input.W0, input.W1, input.W2, input.W3);
    float4x4 WVP = mul(world_, proj);
    vsOut.position = mul(input.position, WVP);

	vsOut.tex = input.tex;
	return vsOut;
}

float4 PS_Main( PS_Input frag ) : SV_TARGET
{
	if (isTextured)
		return colorMap_.Sample( colorSampler_, frag.tex );
	else
		return float4(color.xyz, 1.0f);

	return (float4)(0);
}

Quit strangely that all the objects (player, bullets) are rendered correctly, except of walls. Walls don't want to rotate on Pi/2, another values of angles make distortions similar to incorrect setting of projection matrix. I've used VS Graphics debugger to track values in matrices and it seems correct. On the attached image the first one is matrix of player object, the second one - wall.

 

I try to understand what I made wrong and debug code during the whole day. Help please


BulletManager, reflection from walls

28 November 2013 - 07:17 AM

Hello everybody! I'm trying to solve test task:


 Given a list of segments (walls) , given the coordinates of two points on a two-dimensional space . Need to write a class BulletManager, which will include the following functions:

• void Update (float time), where time - global time of update in seconds. Function calculates the trajectory of bullets at a specified time and in contact with the wall, remove it from the list of segments . While hitting the wall, the bullet is reflected.
• void Fire (float2 pos, float2 dir, float speed, float time, float life_time), where pos - the starting position of the bullet in meters , dir - direction , speed - speed in meters per second , time - the shot in seconds , life_time - time to self-destruction bullets . This function adds a bullet in manager for further processing by an update .

Sorry for my English, the text above is google-translated.

 

I've made it, all is good, except of reflextion: bullet reflects, but not always correctly. Here is my function:

void BulletManager::Update(float time)
{
	for (int n = 0; n < bullets.size();)
	{
		auto bul = bullets.begin() + n;
		XMFLOAT2* bulDir = &bul->get()->GetDir();

		float x = bul->get()->GetInitPosition().x + (bulDir->x * (time - bul->get()->GetTime()) * bul->get()->GetSpeed());
		float y = bul->get()->GetInitPosition().y + (bulDir->y * (time - bul->get()->GetTime()) * bul->get()->GetSpeed());
		XMFLOAT2 point = XMFLOAT2(x, y);
		bul->get()->SetPosition(point);

		//Check bullet life time
		if (bul->get()->GetLifeTime() - (time - bul->get()->GetTime()) <= 0.0f)
		{
			bullets.erase(bul);
			n--;
			continue;
		}

		//Check, if bullet collides with sides
		for (int i=0; i<SidesCoordList.size(); i++)
		{
			if ( IsIntersecting(SidesCoordList[i], point, 1.0f) )
			{
				//Calculating normal vector for current side
				float A = abs(SidesCoordList[i].point1.y - SidesCoordList[i].point2.y);
				float B = abs(SidesCoordList[i].point2.x - SidesCoordList[i].point1.x);
				XMFLOAT2 normal = XMFLOAT2(A, B);
				normal = XMFLOAT2(normal.x / Calculations::VecLength(normal), normal.y / Calculations::VecLength(normal));

				//Calculating angles to get reflected directional vector
				float alpha = atan(A/B);
				float beta = acos(bulDir->x);
				float gamma = XM_PIDIV2 - (alpha - beta);
				float theta = beta + 2*gamma + XM_PI;

				//Setting new direction (after reflection)
				bul->get()->GetDir() = Calculations::RotateVector(bul->get()->GetDir(), theta);

				bul->get()->GetInitPosition() = bul->get()->GetPosition();
				bul->get()->GetTime() = time;
			}
		}
		n++;
	}
}

What's wrong with my code?

 

Thanks.


PARTNERS