Sign in to follow this  

Player movement "GTA-like"

This topic is 3583 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I want to create a game like GTA 2 (2D, top view). I know how to rotate the player (I'm using my DirectX based engine), but I don't know the mathematics to move (forward and back) according to the current angle (I'm using degree, should I use radians ?), Can someone explain this to me ?. Thanks :)

Share this post


Link to post
Share on other sites
XPosition += cos(theta) * Magnitude
YPosition += sin(theta) * Magnitude

Where theta is the angle. sin and cos have a range of [-1, 1], so use Magnitude as a scaling factor to make your character to move faster or slower.

Share this post


Link to post
Share on other sites
I've tried this thing (and I've understood why I'm using cosinus for abscissa et sinus for ordinate), but I think I'm using it badly because the player's movement are odd.

It's like the player follow the Trigonometrical Circle. I don't move forward or back.

Please download the executable here.



Soldier.h
#pragma once

#include "inc.h"
#include "Entity.h"

#include "Bullet.h"

class Soldier : public Entity
{
private:
float m_Angle;
float m_TurnSpeed;

LPD3DXSPRITE m_Sprite;

D3DXMATRIX m_RotationMatrix;
D3DXVECTOR2 m_RotationCenter;

vector <Bullet *> m_Bullets;

public:
Soldier();
~Soldier();

void Begin();
void Draw();
void End();

void TurnVanClockwise();
void TurnVanCounterClockwise();

void MoveForward();
void MoveBack();

void UpdatePosition(int x, int y) { SetPosition(x, y); }

void Fire();
void UpdateBullets();
};


Soldier.cpp
#include "Soldier.h"

Soldier::Soldier() : Entity("matsoldier", 300, 300+35)
{
m_Angle = 0.0f;
m_TurnSpeed = 1.0f;

if (FAILED(D3DXCreateSprite(Engine::GetInstance()->GetGraphicsModule()->GetDevice(), &m_Sprite)))
{
MSG_ERROR("Couldn't create sprite");
}
}

Soldier::~Soldier()
{
D3DSAFE_RELEASE(m_Sprite);
}

void Soldier::Begin()
{
if (FAILED(m_Sprite->Begin(D3DXSPRITE_ALPHABLEND)))
{
MSG_ERROR("Couldn't begin draw");
}
}

void Soldier::End()
{
if (FAILED(m_Sprite->End()))
{
MSG_ERROR("Couldn't end draw");
}
}

void Soldier::MoveForward()
{
D3DXVECTOR3 pos;

pos = GetPosition();

pos.x += cos(D3DXToRadian(m_Angle)) * 1.0f;
pos.y += sin(D3DXToRadian(m_Angle)) * 1.0f;

SetPosition(pos);
}

void Soldier::MoveBack()
{
D3DXVECTOR3 pos;

pos = GetPosition();

pos.x -= cos(D3DXToRadian(m_Angle)) * 1.0f;
pos.y -= sin(D3DXToRadian(m_Angle)) * 1.0f;

SetPosition(pos);
}


void Soldier::Draw()
{
m_RotationCenter.x = (GetPosition().x + 16);
m_RotationCenter.y = (GetPosition().y + 16);

D3DXMatrixTransformation2D(&m_RotationMatrix, NULL, 0, NULL, &m_RotationCenter, D3DXToRadian(m_Angle), NULL);

m_Sprite->SetTransform(&m_RotationMatrix);

if (FAILED(m_Sprite->Draw(GetTexture(), GetCurrentSequence(), NULL, &GetPosition(), D3DCOLOR_ARGB(255,255,255,255))))
{
MSG_ERROR("Couldn't draw sprite");
}
}

void Soldier::UpdateBullets()
{
for (unsigned int i = 0; i < m_Bullets.size(); i++)
{
m_Bullets[i]->Update();
}
}

void Soldier::TurnVanClockwise()
{
m_Angle += m_TurnSpeed;
}

void Soldier::TurnVanCounterClockwise()
{
m_Angle -= m_TurnSpeed;
}



void Soldier::Fire()
{
m_Bullets.push_back(new Bullet(D3DXVECTOR2(GetPosition().x, GetPosition().y), "Soldier", m_Angle, 5));
}


GameManager.cpp
void GameManager::ManageInput()
{
//m_TimerInput.Update();

//float time = m_TimerInput.GetTime();

if (Engine::GetInstance()->GetInputModule()->GetKey('Z'))
{
m_Soldier->MoveForward();
}

if (Engine::GetInstance()->GetInputModule()->GetKey('S'))
{
m_Soldier->MoveBack();
}

if (Engine::GetInstance()->GetInputModule()->GetKey('Q'))
{
m_Soldier->TurnVanCounterClockwise();
}

if (Engine::GetInstance()->GetInputModule()->GetKey('D'))
{
m_Soldier->TurnVanClockwise();
}

if (Engine::GetInstance()->GetInputModule()->GetKey(VK_SPACE))
{
m_Soldier->Fire();
}
}


Another question: I'm trying to implement bullets with ID3DXLine, but it don't work. Nothing is drew when I press the button "fire".

Bullet.h
#pragma once

#include "Engine.h"

#include "inc.h"


class Bullet
{
private:
LPD3DXLINE m_BulletView;

D3DXVECTOR2 m_Position;
D3DXVECTOR2 m_Velocity;

float m_Angle;
float m_Speed;

string m_Owner;

public:
Bullet(D3DXVECTOR2 entity_pos, string owner, float angle, float speed);
~Bullet();

void Update();
};


Bullet.cpp
#include "Bullet.h"

Bullet::Bullet(D3DXVECTOR2 entity_pos, string owner, float angle, float speed)
{
m_Owner = owner;
m_Angle = angle;
m_Speed = speed;

m_Velocity.x = 0;
m_Velocity.y = 0;

m_Position = D3DXVECTOR2(0, 0);

HRESULT hr;

if ((hr = D3DXCreateLine(Engine::GetInstance()->GetGraphicsModule()->GetDevice(), &m_BulletView)) != D3D_OK)
{
MSG_ERROR("Couldn't create the bullet model! Error: " + hr);
}

m_BulletView->SetPattern(1);
m_BulletView->SetAntialias(true);
m_BulletView->SetWidth(50);
}

Bullet::~Bullet()
{

}

void Bullet::Update()
{
m_Velocity.x += (0.1 * sin(m_Angle));

m_Velocity.y += (-(0.1 * cos(m_Angle)));

m_Position += m_Velocity;

D3DXVECTOR2 vertices = D3DXVECTOR2(m_Position.x + 50, m_Position.y + 50);

m_BulletView->Begin();
m_BulletView->Draw(&vertices, 1, D3DCOLOR_XRGB(0, 255, 0));
m_BulletView->End();
}





What I am doing badly ?

Thanks for everything :)

Share this post


Link to post
Share on other sites
Insane controls is probably just because you are using an Azerty keyboard (so ZQSD keys to move) but it's not very friendly on a Qwerty keyboard :P. As for your problem, all the movements seem perfectly fine, however, the soldier moves sideways instead of a forward/backward movement. Rotating the soldier sprite 90° should correct the problem. The thing is just that the angle 0° is currently associated with the soldier looking at the bottom.

Share this post


Link to post
Share on other sites

This topic is 3583 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this