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

This topic is 4171 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.

##### Share on other sites
ok thanks, and in DXUMoveSprite(&sprite, x, y + (z/2)); ?

##### Share on other sites
Quote:
 Original post by lodoss118sorry 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?

There is nothing wrong with SpriteToRender. Yours is SprtieToRender :) Just a typo.

As to your jump system, it is really just a matter of implementing it. Your sort code shouldnt make a difference, or for the most part even need to be called.

##### Share on other sites
Yeah, thats the one.

It's basically a case of seperating the 'behaviour' from the 'drawing'. So, the moving the characters closer or further from the camera does nothing more than alter their Z component. When it comes to the drawing, seeing as you want to be able to show the Z component, you do so by adding it to the Y value when drawing (albeit trimmed a little). That way, as people move further away from the camera, they slide up slowly.

Actually, just thinking about it, you'll probably want to trim it by more than half if you really are doing something similar to Double Dragon as the suggested angle is quite shallow. Try dividing it by 4, maybe even 5.

Hope it all works out.

##### Share on other sites
thanks guys hopefully i will get it done by this week will post screenshots soon, thanks again :). I am just a beginner always failing but never gived up and now i am slowly getting there: )/

##### Share on other sites
http://rapidshare.de/files/33825071/zOrder.avi.html

ok i done the z implement seems it works. Just need to add jump. Check the video out, although it seems from the video that leo (lion guy) seems to draw behind another char abit early as his feet r still abit lower any fixes?

##### Share on other sites
Wow, some nice looking graphics there. You do them yourself?

Anyway, without seeing any source it's hard to determine what is causing the Leo character to overlap. All I can do is suggest a few potential areas...

1. Check there is no negative value on the characters Y axis. This would obviously mean his feet are technically 'in' the ground and would result in him begin displayed lower than he should, despite being Z-sorted fine.

2. Check all the sprites feet line up with their actual location on the Y axis. Assuming their location values represents their feet. Perhaps the Leo character is drawn slightly higher in his bitmap image than the other characters, this will have an effect. You need to very methodical about how you draw your sprites and make rules such as "The feet will always be touching the bottom of the bitmap image and I will draw with this position at their world coordinates."

3. Simply check the sorting method. Although it would appear it's probably one of the other two as he is sorting properly, just slightly out.

Hope that helps.

##### Share on other sites
the sprites have been stolen from mugen chars, just testing out the engine with them. THe leo char is scaled abit larger (i think) and thats what is cauing the problem i am sure i can think of something to fix not a biggy.

king leo inherits from character

#ifndef KINGLEO_H#define KINGLEO_H#include "Character.h"class KingLeo : public Character{public:		KingLeo();		~KingLeo();		void load(int type);};#endif#include "KingLeo.h"KingLeo::KingLeo():Character("LEO", PLAYER, 700){	load(1);	setAlive(true);	setScaleX(2.5);	setScaleY(2.9);	setPosX(400);	setSpeed(5.8);}KingLeo::~KingLeo(){}void KingLeo::load(int type){	stance = new AnimatedSprite(20, 0.26, 1, 0, 0);	stance->addImage(0, "Data\\Characters\\King Leo\\Stance\\stance 01.bmp", 255, 0, 255);	stance->addImage(1, "Data\\Characters\\King Leo\\Stance\\stance 02.bmp", 255, 0, 255);	stance->addImage(2, "Data\\Characters\\King Leo\\Stance\\stance 03.bmp", 255, 0, 255);	stance->addImage(3, "Data\\Characters\\King Leo\\Stance\\stance 04.bmp", 255, 0, 255);	stance->addImage(4, "Data\\Characters\\King Leo\\Stance\\stance 05.bmp", 255, 0, 255);	stance->addImage(5, "Data\\Characters\\King Leo\\Stance\\stance 06.bmp", 255, 0, 255);	stance->addImage(6, "Data\\Characters\\King Leo\\Stance\\stance 07.bmp", 255, 0, 255);	stance->addImage(7, "Data\\Characters\\King Leo\\Stance\\stance 08.bmp", 255, 0, 255);	stance->addImage(8, "Data\\Characters\\King Leo\\Stance\\stance 09.bmp", 255, 0, 255);	stance->addImage(9, "Data\\Characters\\King Leo\\Stance\\stance 10.bmp", 255, 0, 255);	stance->addImage(10, "Data\\Characters\\King Leo\\Stance\\stance 11.bmp", 255, 0, 255);	stance->addImage(11, "Data\\Characters\\King Leo\\Stance\\stance 12.bmp", 255, 0, 255);	stance->addImage(12, "Data\\Characters\\King Leo\\Stance\\stance 13.bmp", 255, 0, 255);	stance->addImage(13, "Data\\Characters\\King Leo\\Stance\\stance 14.bmp", 255, 0, 255);	stance->addImage(14, "Data\\Characters\\King Leo\\Stance\\stance 15.bmp", 255, 0, 255);	stance->addImage(15, "Data\\Characters\\King Leo\\Stance\\stance 16.bmp", 255, 0, 255);	stance->addImage(16, "Data\\Characters\\King Leo\\Stance\\stance 17.bmp", 255, 0, 255);	stance->addImage(17, "Data\\Characters\\King Leo\\Stance\\stance 18.bmp", 255, 0, 255);	stance->addImage(18, "Data\\Characters\\King Leo\\Stance\\stance 19.bmp", 255, 0, 255);	stance->addImage(19, "Data\\Characters\\King Leo\\Stance\\stance 20.bmp", 255, 0, 255);	stance->setSprite();	walk = new AnimatedSprite(14, 0.32, 1, 0, 20);	walk->addImage(0, "Data\\Characters\\King Leo\\Walk\\walk 01.bmp", 255, 0, 255);	walk->addImage(1, "Data\\Characters\\King Leo\\Walk\\walk 02.bmp", 255, 0, 255);	walk->addImage(2, "Data\\Characters\\King Leo\\Walk\\walk 03.bmp", 255, 0, 255);	walk->addImage(3, "Data\\Characters\\King Leo\\Walk\\walk 04.bmp", 255, 0, 255);	walk->addImage(4, "Data\\Characters\\King Leo\\Walk\\walk 05.bmp", 255, 0, 255);	walk->addImage(5, "Data\\Characters\\King Leo\\Walk\\walk 06.bmp", 255, 0, 255);	walk->addImage(6, "Data\\Characters\\King Leo\\Walk\\walk 07.bmp", 255, 0, 255);	walk->addImage(7, "Data\\Characters\\King Leo\\Walk\\walk 08.bmp", 255, 0, 255);	walk->addImage(8, "Data\\Characters\\King Leo\\Walk\\walk 09.bmp", 255, 0, 255);	walk->addImage(9, "Data\\Characters\\King Leo\\Walk\\walk 10.bmp", 255, 0, 255);	walk->addImage(10, "Data\\Characters\\King Leo\\Walk\\walk 11.bmp", 255, 0, 255);	walk->addImage(11, "Data\\Characters\\King Leo\\Walk\\walk 12.bmp", 255, 0, 255);	walk->addImage(12, "Data\\Characters\\King Leo\\Walk\\walk 13.bmp", 255, 0, 255);	walk->addImage(13, "Data\\Characters\\King Leo\\Walk\\walk 14.bmp", 255, 0, 255);	walk->setSprite();}

##### Share on other sites
ok i going to implement the jump method but not sure how to do the jump where u have two heigh jumps one low and one high according how long the user presses the button for, wats the easiest way to do it.