Jump to content


I've got a whopper!


6 replies to this topic

#1 IrishFarmer

    Member

  • Members
  • PipPip
  • 43 posts

Posted 18 October 2005 - 12:26 AM

My internet was down, which is why I haven't been around lately. Hi, everyone.

I have a horrible problem that's making my brain box hurt. I'm writing a 'vector' style Missile Command game with the Windows API. Everything has been going great. I've got the Missile class up and running EXCEPT one huge method. The method is called Move() (takes no parameters and returns void). Its purpose is to take the Missile class's X and Y position member variables and shifts them based on where the missile started out and where its headed. I'll just show you the missile class real quick.

class Missile
{
protected:
	//member variables
	int m_iPosX, m_iPosY; //where it is
	int m_iStartX, m_iStartY; //where it starts
	int m_iDestX, m_iDestY; //where its headed (mouse position)
	int m_iSpeed; //speed of the missile, in pixels
	BOOL m_bSource; //start at left or right? (this won't be used until after testing...so ignore it

public:
	//constructor(s)/destructors
	Missile(int a, int b, int x, int y, int speed, BOOL leftright);
	virtual ~Missile();
	//general methods
	void Draw(HDC hDC);
	void Move();
	void Explode();
	//accessors
	void SetX(int x) { m_iPosX = x; }
	int GetPosX() { return m_iPosX; }
	void SetY(int y) { m_iPosY = y; }
	int GetPosY() { return m_iPosY; }

	//void SetStartX(int x) { m_iStartX = x; }
	int GetStartX() { return m_iStartX; }
	//void SetStartY(int y) {m_iStartY = y; }
	int GetStartY() { return m_iStartY; }

	void SetDestX(int x) { m_iDestX = x; }
	int GetDestX() { return m_iDestX; }
	void SetDestY(int y) { m_iDestY = y; }
	int GetDestY() { return m_iDestY; }
};

Ok, if some things look a bit disorganized or unnecessary, that's how my classes always start out. Just ignore it, please.

Ok. Here's the Move() method.

void Missile::Move()
{
	m_iSpeed = 5;
	const maxSpeed = m_iSpeed * 2;
	double X, Y, A, B;
}

The way I'm displaying graphics is done completely without any sort of image files. Its all 'vector' style like the original missile command meaning I'm using the Windows API drawing commands. IE creating a pen then using the API functions to draw primitive lines, ellipses, rectangles, etc.

As you can see, this Move() method really doesn't do anything. I can't figure out an all purpose formula that will take the Missile's X and Y position and increase them each frame until it hits the EXACT X and Y position of its destination. Of course, it can be wrong by about 3 to 5 pixels because once the missile explodes the player won't care/know if it was off a little bit.

I wrote a version of Move() that got pretty close but started to fall apart when I tested it with different destination values. Weird behaviors started cropping up.

However, the formula needs to not care how fast (how many pixels) the missile moves, or where its destination is, it just have to figure out how to move the missile in increments until it gets there.


Please don't tell me things like, "Your constructor shouldn't have vague variables as parameters like int a, int b, int x, int y" because I understand the basics of programming. But I prefer to write a working class before I make it all pretty. Otherwise, if you're good at math and know some way to make the missile accurate with all of these different variables then thanks!




If you're patient enough to read it, I came up with a formula that works on paper, but for some reason seems to 'break' when I try and translate it into C++.

Basically it took the X distance from the source to the destination and the Y distance from the source to the destination and divided them through each other until they were turned into percentages. So let's say the X distance is 480 and the Y distance is 180 it would divide them by each other so that the X 'factor' would be 0.625 and the Y 'factor' would be 0.375 (they add up to one.......) then multiply both of those values by the maxSpeed and add the result into the respective X or Y position of the missile. I don't know if that made sense, but anyway, it works on paper but not in C. When I wrote it into the game it made the missile move all funky. I think the Y value wasn't even changing. Anyway, thanks for the help.

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 4780 posts
  • LocationBellevue, WA

Posted 18 October 2005 - 12:36 AM

You should keep the missile location in floating-point variables. That way your formula should work (it was probably not working right before due to roundoff error). Then when you draw the missiles on the screen, simply round the location to the nearest int.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 IrishFarmer

    Member

  • Members
  • PipPip
  • 43 posts

Posted 18 October 2005 - 12:50 AM

Ok, I use Float point variables and this is what I get. I was using double and it looked identical.

Posted Image

I'm guessing that...based on how the numbers work...the X is rounding down when sometimes it should be rounding up or something because that would help explain the results. Oh yeah, in that picture the bottom of the line that is going straight up is the marker for the missile's destination. The diagonal line is the missile of course.

Anyway, that's the closest I can get the little bastard to fly to its destination.

edit:

Oh yeah, here's the Move() method as it stands.

void Missile::Move()
{
	m_iSpeed = 10;
	const maxSpeed = m_iSpeed * 2;
	float X, Y;
	//do calculations to move the missile's position
	//m_iPosX, m_iPosY, m_iSourceX, m_iSourceY, m_iDestX, m_iDestY, m_iSpeed

	//set destination to somewhat center screen
	m_iDestX = 800 / 2;
	m_iDestY = 600 / 2;
	
	//perform calculations
	X = m_iDestX - m_iStartX;
	Y = m_iStartY - m_iDestY;
	X = min(X, Y) / max(X, Y);
	Y = 1 - X;
	X *= maxSpeed;
	Y *= maxSpeed;
	m_iPosX += X;
	m_iPosY -= Y;
}

Nevermind. The more I test it, the more the code breaks. If the Destination X position is anything about about 550, the missile shoots further left, which is exactly opposite of what it should do. I don't know. I'm lost here.

#4 Faelenor

    Member

  • Members
  • PipPip
  • 44 posts

Posted 18 October 2005 - 04:58 PM

Hmm, I don't really understand how you try to compute the new position, but the right way should be:
float dx = destX - currentX;
float dy = destY - currentY;
float distance = sqrt(dx*dx + dy*dy);
newX = currentX + speed * dx / distance;
newY = currentY + speed * dy / distance;


#5 Polar Sleuth

    Member

  • Members
  • PipPip
  • 34 posts

Posted 18 October 2005 - 05:25 PM

I agree. The code as you have it is shooting for mostly the center of the screen. It will not follow the cursor because you never re-evaluate the vector between the destination and the current position. For the missile to adjust its course, you need to do that evaluation periodically - every frame, every six frames, whatever.

#6 IrishFarmer

    Member

  • Members
  • PipPip
  • 43 posts

Posted 18 October 2005 - 05:27 PM

I don't know. This isn't as close as I'd like it to be.

Posted Image

Just kidding. That's awesome. This is why I'm going back to school though. I haven't gone through any kind of schooling for two years now and I'm getting slow/stupid. I should have been able to figure that out. Anyway, thanks for the help.

The only problem I've noticed thus far is that right when its about to reach its destination, it tends to shift more along the x-axis than the y-axis which makes the 'trail' seem to move over which looks awkward. I'm not sure if I should care considering this is my first real game with C++. Maybe after I finish the rest of the code I'll go back and try and figure out a solution. But for now...I can move on to ironing out the explosions.

#7 Rydinare

    New Member

  • Members
  • PipPip
  • 24 posts

Posted 19 October 2005 - 02:47 AM

I had responded to this last night, but my post got lost due to a board error. I was going to wait and if nobody responded, was going to go through the trouble of going through it all over again...

however, luckily someone answered it and saved me the trouble. Nice work, guys. :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users