Sign in to follow this  

2D projectile motion for jumping platformer motion...?

This topic is 4344 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

I'm writing a program to test a platformer game, which involves "2D projectile motion"-based jumping. The test basically involves a character jumping forward. The code below is for the child view of an MFC frame (using VC++ 2003): mainview.h:
// ...
#define _USE_MATH_DEFINES
#include <math.h>

class MainView : public CWnd {
// ...
private:
// ...
#define XNAUGHT 0.0 // starting x-position (in meters)
#define YNAUGHT 0.0 // starting y-position (in meters)
#define VNAUGHT 0.5 // starting vector velocity magnitude (in meters/second)
#define THETA (M_PI / 4) // starting vector velocity angle (in radians)
#define GRAVITY 9.81 // value of g (in meters/second^2)
#define TIME_INCREMENT 0.001 // amount to add to t in each frame
  double vx; // x-component of vector velocity (in meters/second)
  double vy; // y-component of vector velocity (in meters/second)
  double x; // x-position (in meters)
  double y; // y-position (in meters)
  double t; // time (in seconds)
  double tland; // time of landing (in seconds)
// ...
  friend class Animator; // definition below
  Animator *animator;
// ...
};

// note: this class works as a thread class, it's just here for clarity
class Animator : public CWinThread {
  DECLARE_DYNCREATE(Animator)
public:
  virtual BOOL InitInstance() { m_bAutoDelete = TRUE; return TRUE; }
  virtual int ExitInstance() { return CWinThread::ExitInstance(); }
protected:
  afx_msg void onBegin(WPARAM wParam, LPARAM lParam);
  afx_msg void onEnd(WPARAM wParam, LPARAM lParam) { ::PostQuitMessage(0); }
  DECLARE_MESSAGE_MAP()
};

mainview.cpp:
// ...

MainView::MainView() {
  vx = VNAUGHT * cos(THETA);
  vy = VNAUGHT * sin(THETA);
  x = XNAUGHT;
  y = YNAUGHT;
  t = 0.0;
// ...
  double range = ((VNAUGHT * VNAUGHT) / GRAVITY) * sin(2.0 * THETA);
  tland = range / (VNAUGHT * cos(THETA);
}

// ...

IMPLEMENT_DYNCREATE(Animator, CWinThread)

BEGIN_MESSAGE_MAP(Animator, CWinThread)
  ON_THREAD_MESSAGE(WM_USER, onBegin)
  ON_THREAD_MESSAGE(WM_USER + 1, onEnd)
END_MESSAGE_MAP()

void Animator::onBegin(WPARAM wParam, LPARAM lParam) {
  MainView *mv = (MainView *)lParam;
  Sleep(1000);
  do {
    Sleep(100);
    mv->t += TIME_INCREMENT;
    mv->y += mv->vy * mv->t - 0.5 * GRAVITY * mv->t * mv->t;
    mv->vy = VNAUGHT * sin(THETA) - GRAVITY * mv->t;
    mv->x += mv->vx * mv->t;
// ...
// convert meters to pixels and post paint message
// ...
  } while(mv->t < mv->tland / 2.0);
// ...
// the loop is split into two b/c I have two different images for ascending and
// descending (code for handling not shown)
// ...
  do {
    Sleep(100);
    mv->t += TIME_INCREMENT;
    mv->y += mv->vy * mv->t - 0.5 * GRAVITY * mv->t * mv->t;
    mv->vy = VNAUGHT * sin(THETA) - GRAVITY * mv->t;
    mv->x += mv->vx * mv->t;
// ...
  } while(mv->t < mv->tland);
// ...
}

Note that this program is just a test for the game, and runs much slower so that I can analyze it. When I run the program, the character ends up going below the start height. Are my equations correct? If anyone sees any problems with my math or whatever, please tell me!

Share this post


Link to post
Share on other sites
There are several small problems:

Calculate mv->vy first, but

mv->vy = VNAUGHT * sin(THETA) - GRAVITY * mv->t;
mv->y += mv->vy * mv->t - 0.5 * GRAVITY * mv->t * mv->t;

should be:

mv->vy -= GRAVITY * mv->t;
mv->y += mv->vy * mv->t;

because you've already accelerated the particle, you don't need to include the acceleration term again.

[Edited by - erissian on January 26, 2006 9:29:14 PM]

Share this post


Link to post
Share on other sites
Thanks... your corrections were slightly wrong, but I managed to fix it:

First, according to my college physics book, cosine corresponds to the x-component, and sine corresponds to the y-component. So, I was right about that the first time.

Second, you were right about excluding the acceleration from the position-adjusting functions, but instead of using mv->t, I used TIME_INCREMENT. That gave me the results I wanted.

But hey, your suggestions still pointed me in the right direction, so thanks again!

Share this post


Link to post
Share on other sites

This topic is 4344 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