Jump to content
  • Advertisement
Sign in to follow this  
Kr00pS

Player movement "GTA-like"

This topic is 3797 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
Advertisement
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
Hidden
And also, theta is the angle in radians and not degrees. To convert from degrees to radians, simply do:

theta = angle * (pi / 180);

Share this post


Link to post
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->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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!