Sign in to follow this  
TraderJack

Platform is messing with my head

Recommended Posts

TraderJack    530
Alright, this is really wierd. I have an issue with a moving platform class in my sidescroller. It was kind of a mssy integration of a patrolling enemy class code and a still platform class code. Anyhow, here's the code itself, in order of 'main.cpp', 'movingplat.h' and 'movingplat.cpp'. I've been told that my code is easy to read, but excuse me if some parts are left un-commented. Also, I've labeled things fairly well in acordance with their implementation. I'm not going to use a debugger cause the Dev-C++ onboard debugger is screwy. Allegro is my API, though even if you don't know it, my code is still easily comprehendable (atleast I hope). Here. main.cpp
#include "allegro.h"
#include "player.h"
#include "solidobject.h"
#include "patrolent.h"
#include "platform.h"
#include "structure.h"
#include "movingplat.h"

BITMAP *image;
BITMAP *attackimage;
BITMAP *buffer;
BITMAP *longbar;
BITMAP *shortbar;
BITMAP *vertbar;
BITMAP *backround;
BITMAP *enemypic;
BITMAP *hurdle;
BITMAP *platunit;
BITMAP *building;

float scroll;

player player1;
solidobject sample[5];
patrolent ent[5];
platform sampleplat;
structure samplebuilding;
movingplat samplemoving;

/*******************Timer*********************/

volatile long speed_counter = 0;
void increment_speed_counter()
{
     speed_counter ++;
}
END_OF_FUNCTION(increment_speed_counter);

/******************LoadGFX********************/

void loadgfx()
{
     buffer = create_bitmap(1600, 600);
     image = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/StickStand.bmp", NULL);
     attackimage = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/StickAttack.bmp", NULL);
     longbar = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Longbar.bmp", NULL);
     shortbar = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Shortbar.bmp", NULL);
     vertbar = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Vertbar.bmp", NULL);
     backround = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Spaceback.bmp", NULL);
     enemypic = load_bitmap("C:/Program Code/Bitmaps/spaceinvaders/invader.bmp", NULL);
     hurdle = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Hurdle.bmp", NULL);
     platunit = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/BluePlatBlock.bmp", NULL);
     building = load_bitmap("C:/Program Code/Bitmaps/MyBitmaps/Samplebuild.bmp", NULL);
}

/***********Draw**************/

void draw()
{
     draw_sprite(buffer, backround, -300 - (scroll), 0);
     samplebuilding.draw();
     sampleplat.draw();
     sample[0].draw();
     sample[1].draw();
     sample[2].draw();
     sample[3].draw();
     sample[4].draw();
     ent[0].draw();
     ent[1].draw();
     ent[2].draw();
     ent[3].draw();
     player1.draw();
     samplemoving.draw();
     
     textprintf_ex(buffer, font, 0, 0, makecol(255, 0, 0), -1, "Player Health: %d", samplemoving.x);
}


/**********Main****************/

int main (int argc, char *argv[])
{
    
/**********Initialization*********/
    
    allegro_init();
    install_keyboard();
    install_timer();
    
    LOCK_VARIABLE(speed_counter);
    LOCK_FUNCTION(increment_speed_counter); 
    install_int_ex(increment_speed_counter, BPS_TO_TIMER(20));
    
    set_color_depth(16);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
    
/*********Load graphics**********/
    
    loadgfx();
    scroll = 0;

/*********Game Loop***********/
    
    player1.init();
    
    sample[0].init( 0, 400, longbar);
    sample[1].init( 450, 320, longbar);
    sample[2].init( -450, 320, longbar);
    sample[3].init( 200, 240, shortbar);
    sample[4].init( 390, 140, hurdle);
    
    ent[0].init( 900, (320 - enemypic->h), enemypic, 450, 1250);
    ent[1].init( -200, (320 - enemypic->h), enemypic, -450, 350);
    ent[2].init( 250, (240 - enemypic->h), enemypic, 200, 600);
    ent[3].init( 820, (220 - enemypic->h), enemypic, 700, 940);
    
    sampleplat.init(700, 220, platunit, 20, 12);
    samplebuilding.init(1050, 120, building);
    samplemoving.init(520, 120, platunit, 20, 5, 400, 600);
    
    while(!key[KEY_ESC])
    {
        player1.move();
        if (scroll < -300) scroll = -300;
        for(int a = 0; a < 5; a++) sample[a].move();
        
        ent[0].move();
        ent[1].move();
        ent[2].move();
        ent[3].move();
        
        sampleplat.move();
        samplebuilding.move();
        samplemoving.move();
        
        acquire_screen();
        draw();
        blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
        clear(buffer);
        release_screen();
    }   
    
    destroy_bitmap(buffer);
    destroy_bitmap(image);
    destroy_bitmap(longbar);
    destroy_bitmap(shortbar);
    destroy_bitmap(vertbar);
    destroy_bitmap(backround);
    destroy_bitmap(enemypic);
    destroy_bitmap(hurdle);
    destroy_bitmap(platunit);
    
    return 0;
}
END_OF_MAIN()

movingplat.h
#ifndef __MOVINGPLAT_H__
#define __MOVINGPLAT_H__

#include "allegro.h"
#include "player.h"

class player;

extern BITMAP* image;
extern BITMAP* buffer;
extern float scroll;
extern player player1;

class movingplat
{
public:
       
        float origin_x;
        float progress_left;
        
        float x;
        float y;
        bool isactive;
        bool istouchingplayer;
        
        float top;
        float bottom;
        float left;
        float right;
        float iterations;
        float itlength;
        int progressleft;
        
        int leftmax;
        int rightmax;
        int leftmaxorigin;
        int rightmaxorigin;
        
        bool moveleft;
        bool moveright;
        
        movingplat();
        ~movingplat();
       
        BITMAP* graphic;
        
        void init(int, int, BITMAP*, int, int, int, int);
        void move();
        void setsides();
        void draw();
        
};

#endif

and movingplat.cpp
#include "movingplat.h"
#include "player.h"

movingplat::movingplat()
{
}

movingplat::~movingplat()
{
}

void movingplat::setsides()
{
     top = y;
     bottom = (y + graphic->h);
     left = x;
     right = (x + (itlength * iterations));
}

void movingplat::init(int _x, int _y, BITMAP* grafik, int graphlen, int itnum, int left, int right)
{
     origin_x = _x;
     y = _y;
     itlength = graphlen;
     iterations = itnum;
     
     moveleft = true;
     moveright= false;
     
     graphic = grafik;
     
     setsides();
     
     leftmaxorigin = left;
     rightmaxorigin = right;
     leftmax = left;
     rightmax = right;
}

void movingplat::draw()
{
     for(int g = 0; g < iterations; g++)
     {
          draw_sprite(buffer, graphic, (x + (g * itlength)), y);
     }
}

void movingplat::move()
{
     //if(isactive) 
     //{
           x = origin_x - scroll - progressleft;
     //}
     leftmax = (leftmaxorigin - scroll);
     rightmax = (rightmaxorigin - scroll);
     
     setsides();
     
     if(player1.jumping && player1.vv > 0)
     {
            setsides();
            player1.setsides();
            if( ( player1.bottom >= y) && (player1.bottom <= y + 10) && (player1.right >= x) && (player1.left <= right) && player1.jumping )
            {
                 player1.jumping = false;
                 player1.gravity = true;
                 player1.vv = .4;
                 player1.y = (y -(player1.currentimage()->h - 1 ) );
                 istouchingplayer=true;
            }
            else istouchingplayer=false;
     }
     
     if(player1.gravity)
     {
            setsides();
            player1.setsides();
            if( ( player1.bottom >= y) && (player1.bottom <= y + 10) && (player1.right >= x) && (player1.left <= right) && player1.gravity )
            {
                 player1.y = ( y -(player1.currentimage()->h - 1 ) );
                 player1.vv = .3;
            }
            else istouchingplayer=false;
     }
     
     if(x <= 800 + scroll && right >= 0 + scroll)
     {
          isactive = true;
     }
     
     if(isactive)
     {
            setsides();
            if(moveleft)
            {
                   progress_left += 2;
                   if(istouchingplayer && !player1.jumping) player1.x -= 2;
                   
                   if(left <= leftmax)
                   {
                        moveleft = false;
                        moveright = true;
                   }
            }
            
            if(moveright)
            {
                  progress_left -= 2;
                  if(istouchingplayer && !player1.jumping) player1.x += 2;
                  
                  if(right >= rightmax)
                  {
                       moveleft = true;
                       moveright= false;
                  }
            }
     }
     
}

During implementation, it draws the platform to the correct location. It does not move however. It does, however, respond to the player interecting with it (pushing him to the left, as it should if it was moving left, for a moving platform moves a player with it). From checking each value individually during runtime, I can determine the values of the following variables: isactive == true moveleft == true moveright == false leftmax == it's proper place during runtime rightmax == ditto leftmaxorigin == 400 rightmaxorigin == 600 left, right, top, bottom, x, y == always 0 The strange thing is, it doesn't know it's position values, but it knows where to draw, and it doesn't know it's sides but it knows how to interact with the player. Any input would be greatly appreciated. If you need more info, I will gladly provide. -IV

Share this post


Link to post
Share on other sites
Dave Hunt    4872
You're updating 'progress_left', but using 'progressleft' in your 'x' coordinate calculation...

I would also recommend that you initialize all of your variables to sane values in your constructor and/or init method. Some of the variables you are using aren't set in the init method, and could have strange values in them.

Share this post


Link to post
Share on other sites
TraderJack    530
Quote:
I would also recommend that you initialize all of your variables to sane values in your constructor and/or init method. Some of the variables you are using aren't set in the init method, and could have strange values in them.


Well, I turned the movingplat.cpp into this...


#include "movingplat.h"
#include "player.h"

movingplat::movingplat()
{
}

movingplat::~movingplat()
{
}

void movingplat::setsides()
{
top = y;
bottom = (y + graphic->h);
left = x;
right = (x + (itlength * iterations));
}

void movingplat::init(int _x, int _y, BITMAP* grafik, int graphlen, int itnum, int left, int right)
{
origin_x = _x;
x = _x;
y = _y;
itlength = graphlen;
iterations = itnum;

moveleft = true;
moveright= false;

graphic = grafik;

progressleft = 0;

setsides();

leftmaxorigin = left;
rightmaxorigin = right;
leftmax = left;
rightmax = right;

isactive = false;
}

void movingplat::draw()
{
for(int g = 0; g < iterations; g++)
{
draw_sprite(buffer, graphic, (x + (g * itlength)), y);
}
}

void movingplat::move()
{
//if(isactive)
//{
x = origin_x - scroll - progressleft;
//}
leftmax = (leftmaxorigin - scroll);
rightmax = (rightmaxorigin - scroll);

setsides();

if(player1.jumping && player1.vv > 0)
{
setsides();
player1.setsides();
if( ( player1.bottom >= y) && (player1.bottom <= y + 10) && (player1.right >= x) && (player1.left <= right) && player1.jumping )
{
player1.jumping = false;
player1.gravity = true;
player1.vv = .4;
player1.y = (y -(player1.currentimage()->h - 1 ) );
istouchingplayer=true;
}
else istouchingplayer=false;
}

if(player1.gravity)
{
setsides();
player1.setsides();
if( ( player1.bottom >= y) && (player1.bottom <= y + 10) && (player1.right >= x) && (player1.left <= right) && player1.gravity )
{
player1.y = ( y -(player1.currentimage()->h - 1 ) );
player1.vv = .3;
}
else istouchingplayer=false;
}

if(x <= 800 + scroll && right >= 0 + scroll)
{
isactive = true;
}

if(isactive)
{
setsides();
if(moveleft)
{
progress_left += 2;
if(istouchingplayer && !player1.jumping) player1.x -= 2;

if(left <= leftmax)
{
moveleft = false;
moveright = true;
}
}

if(moveright)
{
progress_left -= 2;
if(istouchingplayer && !player1.jumping) player1.x += 2;

if(right >= rightmax)
{
moveleft = true;
moveright= false;
}
}
}

}



... and I get the same behavior. I now initialize all variables to sane values as suggested.

Quote:
You're updating 'progress_left', but using 'progressleft' in your 'x' coordinate calculation...


Trust me, it works. Take a look at the following patrolling enemy class that exibits identical movement behavior, and... well, works.

patrolent.h + .cpp


// .h

#include "player.h"
#include "solidobject.h"

class player;
class object;

extern BITMAP* image;
extern BITMAP* buffer;
extern float scroll;

extern player player1;
extern solidobject sample[5];

class patrolent
{
public:

float x;
float y;
bool isliving;
bool isactive;

float origin_x;
float progress_left;

float top;
float bottom;
float left;
float right;

int leftmax;
int leftmaxorigin;
int rightmax;
int rightmaxorigin;

bool moveleft;
bool moveright;

patrolent();
~patrolent();

BITMAP* graphic;

void init(int, int, BITMAP*, int, int);
void move();
void setsides();
void draw();
void kill();

};

#endif

//////////////////////////////////////////////////////////////

// .cpp

#include "patrolent.h"
#include "player.h"

patrolent::patrolent()
{
}

patrolent::~patrolent()
{
}

void patrolent::setsides()
{
top = y;
bottom = (y + graphic->h);
left = x;
right = (x + graphic->w);
}

void patrolent::init(int _x, int _y, BITMAP* grafik, int left, int right)
{
origin_x = _x;
x = _x;
y = _y;
progress_left = 0;

graphic = grafik;
setsides();
isliving = true;
isactive = false;

moveleft = true;
moveright= false;

leftmaxorigin = left;
rightmaxorigin = right;
leftmax = left;
rightmax = right;
}

void patrolent::draw()
{
if(isliving) draw_sprite(buffer, graphic, x, y);
}

void patrolent::move()
{
leftmax = (leftmaxorigin - scroll);
rightmax = (rightmaxorigin - scroll);

if(isliving)
{
x = origin_x - scroll - progress_left;

setsides();
if(x <= 800 + scroll && right >= 0 + scroll)
{
isactive = true;
}

if(isactive)
{
setsides();
if(moveleft)
{
progress_left += 3;

if(left <= leftmax)
{
moveleft = false;
moveright = true;
}
}

if(moveright)
{
progress_left -= 3;

if(right >= rightmax)
{
moveleft = true;
moveright= false;
}
}

bool collision = false;
bool unkill= false;

setsides();

if( (player1.right <= right) && (player1.right >= x) && (player1.y <= bottom) && (player1.bottom >= y) )
{
collision = true;
}
if( (player1.x >= x) && (player1.x <= right) && (player1.y <= bottom) && (player1.bottom >= y) )
{
collision = true;
}

if( (player1.x - 25 >= x) && (player1.x -25 <= right) && (player1.y <= bottom) && (player1.bottom >= y) && player1.moveleft && player1.isattacking)
{
collision = true;
}

if( (player1.bottom <= bottom) && (player1.bottom >= y) && (player1.x <= right) && (player1.right >= x) )
{
unkill = true;
}
if( (player1.y >= y) && (player1.y <= bottom) && (player1.x <= right) && (player1.right >= x) )
{
unkill = true;
}

if(collision && player1.isattacking) kill();
else if(collision && !player1.isattacking) player1.dodamage(5);
if(unkill) player1.dodamage(5);
if(unkill) player1.dodamage(5);
}

}
}

void patrolent::kill()
{
isliving = false;
isactive = false;
}



Ugh, this is so frustrating. Anyone?

-IV

Share this post


Link to post
Share on other sites
Dave Hunt    4872
Quote:
Original post by TraderJack
Quote:
You're updating 'progress_left', but using 'progressleft' in your 'x' coordinate calculation...


Trust me, it works. Take a look at the following patrolling enemy class that exibits identical movement behavior, and... well, works.

patrolent.h + .cpp

*** Source Snippet Removed ***

Ugh, this is so frustrating. Anyone?

-IV


No, they're not the same. Your patrolent class only updates/uses 'progress_left'. However, your movingplat class updates 'progress_left', but uses 'progressleft'. Trust me. That's the problem.

Share this post


Link to post
Share on other sites
TraderJack    530
Oh my god, I didn't even notice there were two differnet variables. Ugh, I knew this was going to turn out to be a dumb oversight. Oh well, now I'm working through a few more minor glitches with the code, but thanks!

-IV

Share this post


Link to post
Share on other sites
Dave Hunt    4872
Quote:
Original post by TraderJack
Oh my god, I didn't even notice there were two differnet variables. Ugh, I knew this was going to turn out to be a dumb oversight.

-IV


Been there. Done that. Glad I could help!

Share this post


Link to post
Share on other sites

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