Jump to content
  • Advertisement
Sign in to follow this  
lodoss118

help with my scrolling beat em up !!UPDATED!!

This topic is 4411 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 here is my code lol, basically the way i have implemented it is that each sprite is sorted via their y value but the problem is when i will jump as in a char that would mean if i was in front of that char and jumped then i would be behind him. How should i fix this?
 

#include "RenderManager.h"

RenderManager::RenderManager()
{
	
}

RenderManager::~RenderManager()
{

}

void RenderManager::addChar(Character *pC)
{
	// Add a character to the character vector
	// Note all characters are just sprites :)
	if(pC != NULL)
	{
		 // See if there are characters already in the character vector
		if (m_vChar.size() > 0)
		{
			vector<Character *>::iterator iChar;

			// Find a spot in the character vector to insert the character by its z-order
			for(iChar = m_vChar.begin(); iChar != m_vChar.end(); iChar++)
			{
				if(pC->getZOrder() < (*iChar)->getZOrder())
				{
					// Insert the character into the character vector
					m_vChar.insert(iChar, pC);
					return;
				}
			}
		}

		// The character's z-order is highest, so add it to the end of the vector,
		// position is first to render.
		m_vChar.push_back(pC);
	}
}

bool RenderManager::sortSprites(Character *c1, Character *c2)
{
	// Sort sprites according to their y value and not when each sprite state is to jump or any other jump move.
	if(c1->getState() != JUMP && c2->getState() != JUMP)
	{
		return c1->getPosY() < c2->getPosY();
	}
	else
		return false;
}

void RenderManager::findStateToRender()
{
	/*
		This function checks each character state and assigns the appropriate sprite to render.
	*/
	vector<Character *>::iterator iChar;
	
	for(iChar = m_vChar.begin(); iChar != m_vChar.end(); iChar++)
	{
		if((*iChar)->getState() ==  DIE)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getStance());	
		}
		else if((*iChar)->getState() ==  FALL)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getStance());	
		}
		else if((*iChar)->getState() ==  ATTACK3)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getAttack3());	
		}
		else if((*iChar)->getState() ==  ATTACK2)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getAttack2());	
		}
		else if((*iChar)->getState() ==  ATTACK1)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getAttack1());	
		}
		else if((*iChar)->getState() ==  JUMP)
		{
			//(*iChar)->setSpriteToRender((*iChar)->getJump());	
		}
		else if((*iChar)->getState() ==  WALK)
		{
			(*iChar)->setSpriteToRender((*iChar)->getWalk());	
		}
		else // draw stance/idle animation
		{
			(*iChar)->setSpriteToRender((*iChar)->getStance());	
		}
	}
}

void RenderManager::renderHitEffect()
{
	vector<Character *>::iterator iChar;

	for(iChar = m_vChar.begin(); iChar != m_vChar.end(); iChar++)
	{
		if((*iChar)->isHitEffect() == true)
		{
			int current = (*iChar)->getSprtieToRender()->getCurrentFrame();
			int alpha = (*iChar)->getAlpha();
			int speed = (*iChar)->getHSpeed(); 

			(*iChar)->setAlpha(alpha - speed);
			(*iChar)->getSprtieToRender()->getCurrentSprite(current).colour = (alpha, 255, 255, 255);

			(*iChar)->setHit_E_Timer((*iChar)->getHit_E_Timer() + 1);

			if((*iChar)->getHit_E_Timer() > = 23)
			{	
				int newAlpha = 255;
				(*iChar)->setHeffect(false);
				(*iChar)->setIeffect(false);
				(*iChar)->setHit_E_Timer(0);
				(*iChar)->getSprtieToRender()->getCurrentSprite(current).colour = (newAlpha, 255, 255, 255);	
			}
		}	
	}	
}

void RenderManager::renderInvisibleEffect()
{
	vector<Character *>::iterator iChar;

	for(iChar = m_vChar.begin(); iChar != m_vChar.end(); iChar++)
	{
		if((*iChar)->isInvisibleEffect() && !(*iChar)->isHitEffect())// might not need the boolean vairable to start invisible effect?
		{
			int current = (*iChar)->getSprtieToRender()->getCurrentFrame();
			int amount = (*iChar)->getIAmount(); 
			(*iChar)->getSprtieToRender()->getCurrentSprite(current).colour = (amount, 255, 255, 255);	
		}
	}
}

void RenderManager::render()
{
	// Check character vector size and reserve amount for future.
	if (m_vChar.size() >= (m_vChar.capacity() / 2))
	{
		m_vChar.reserve(m_vChar.capacity() * 2);
	}

	// Sort all sprites according to their y values before rendering
	sort(m_vChar.begin(), m_vChar.end(), sortSprites);
	
	// Check which sprite state to render 
	findStateToRender();
	
	// Check to see if char is hit, if so call hit effect - maybe add timer to finish hit effect.
	renderHitEffect();

	// Check if we need to make char invisible.
	renderInvisibleEffect(;)	

	vector<Character *>::iterator iChar;

	for(iChar = m_vChar.begin(); iChar != m_vChar.end(); iChar++)
	{
		// Is current character alive? if not then this loop won't happen
		if((*iChar)->getAlive())
		{
			//At this stage we check to see what sprite needs updating according to getUpdateType(),
			//there are 3 types that each sprite can call to the renderManager. This will increment
			//each sprite frame to the amount of frames available.
			int type = (*iChar)->getSprtieToRender()->getUpdateType();
			(*iChar)->getSprtieToRender()->updateFrames(type);

			// Get current frame for sprite
			int current = (*iChar)->getSprtieToRender()->getCurrentFrame();
			sprite = (*iChar)->getSprtieToRender()->getCurrentSprite(current);

			// Mirror current sprite
			DXUMirrorSprite(&sprite, (*iChar)->isLeft(), false);
			// Scale current sprite
			DXUScaleSprite(&sprite, (*iChar)->scaleX(), (*iChar)->scaleY());
			
			//At this stage we need to check each current sprite world position and add any offsets.
			if((*iChar)->isLeft() == true)
			{
				DXUMoveSprite(&sprite, (*iChar)->getPosX() - (*iChar)->getSprtieToRender()->xOffSet(), 
									(*iChar)->getPosY() + (*iChar)->getSprtieToRender()->yOffSet());
			}
			else
			{	
				DXUMoveSprite(&sprite, (*iChar)->getPosX() + (*iChar)->getSprtieToRender()->xOffSet(), 
									(*iChar)->getPosY() + (*iChar)->getSprtieToRender()->yOffSet());	
			}
			
			// Finally we end up here and render each frame, if the current character is alive offcourse.
			DXUDrawSprite(&sprite);
		}
	}
}


[Edited by - lodoss118 on September 20, 2006 12:47:24 PM]

Share this post


Link to post
Share on other sites
Advertisement
What I would suggest is that you anchor your sprites at a point in the middle at the bottom of the rectangle but also have an offset pair of co-ordinates that dictates where relative to the anchor point you draw and compute collisions and so on.

When you jump, you just increase the y offset but leave the anchor where it is. You can then sort via the anchor point but draw at anchorx-offsetx etc and your z-order should work okay.

Share this post


Link to post
Share on other sites
Seems a bit messy to me. A sort function should sort in my view and not be complicated by other factors like that. If you later wanted to replace your sort with std::super_fast_sort or boost::my_god_that_is_a_fast_sort or something, you'd only have to change it.

The advantage of having an anchor is that it represents the point on the floor in 3D terms that the sprite is directly above, which I imagine would be useful in a lot of other situations as well.

Dunno though. Give it a try. Just bear in mind that your code will need to develop as the game progresses and complications like this may bite you in the backside later on.

Share this post


Link to post
Share on other sites
I'm assuming we're looking at something similar to Double Dragon here. Whilst you are drawing in a 2D sense your characters should still have a 3D record of their location.

So, one axis is left/right(X), one is up/down(Y), and the other is into/outof(Z) the screen. Left and Right controls affect the X axis, Up and Down will affect the Z axis, and Jump would affect the Y axis.

When you come to draw the sprites draw them at the coords (X, Y + (Z/2));

So, as your sprites move into/outof the screen they will actually move up/down on the screen and you can use the true Z value for depth sorting and not worry about a jump flag or any other cack-handed solution.

I halve the Z offset a little as you're trying to mimic a depth to the scene. The more you decrease it, the shallower the simulated angle.

Share this post


Link to post
Share on other sites
makes sense. I use the DXUMoveSprite(&sprite, x, y); which gets the sprites x and y coords and moves sprite to that position. I got a z coord but haven't used only for entering the chars into vector?

Share this post


Link to post
Share on other sites
Quote:
Original post by lodoss118
makes sense. I use the DXUMoveSprite(&sprite, x, y); which gets the sprites x and y coords and moves sprite to that position. I got a z coord but haven't used only for entering the chars into vector?


First a couple comments on your code:

First, iChar is a horrible horrible name for a variable. I had to re-read lines over and over again because that variable is so misleading. I have no issues with the i for iterator, but please spend the extra few key presses and make it iCharacter. Its instantly ten times more readable.

Second, ::sortSprites is actually misnamed. Its actually a comparison.

Finally, getSprtieToRender.


As to your question, what is your "desired" behavior on jump?

Share this post


Link to post
Share on other sites
sorry wats wrong with getSpriteTorender? it basically tells the renderManager wat sprite to render i.e STANCE = setSpriteToRender(getStance()); etc.

basically i haven't implemented jump but what your saying by introducing the z i was wondering how the move method would look like?

Share this post


Link to post
Share on other sites
Quote:
Original post by lodoss118
so to move the char up and down wat would be the method i.e
void move(x, y)
{
sprite.x += x;
sprite.y += y + (z/2);
}



Well that depends on what you mean by up and down. If you mean into/out of the screen then simply use...

void move(x, z)
{
sprite.x += x;
sprite.z += z;
}



Jumping deals with the Y axis. And, obviosuly, the above code assumes you are drawing sprites based on what I suggested earlier.

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!