Public Group

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

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

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()
{

}

{
// 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 on other sites
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 on other sites
in my sortSprites method i added that if state != JUMP etc would that really work?

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 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 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 on other sites
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);
}

Share on other sites
Quote:
 Original post by lodoss118makes 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, 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.

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 on other sites
Quote:
 Original post by lodoss118so 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.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 28
• 16
• 10
• 10
• 11
• Forum Statistics

• Total Topics
634111
• Total Posts
3015560
×