Sign in to follow this  
yurian

Using c++ and allegro, totally baffled by character not moving

Recommended Posts

Still somewhat new to this programming, could you all knowing masters help me once more? By the way, using C++ and allegro. I'm totally confused, I think I have done everything correctly, I have checked every part for an hour, and I cannot figure out why the dragon does not move on my window. What could I be doing wrong? main.cpp
#include <allegro.h>
using namespace std;
#include <iostream>
#include <fstream>
short int pfacing,pxpos,pypos;
BITMAP*playerdragon0,*playerdragon1,*playerdragon2,*playerdragon3,*buffer;
#include "wingtime.h"
#include "playercontrol.h"


int main(int argv, char*argc[])
{
    allegro_init();
    install_keyboard();
    install_timer();
    set_color_depth(16);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
    
    LOCK_VARIABLE(wingcounter);
    LOCK_FUNCTION(wingtime);
    install_int_ex(wingtime,MSEC_TO_TIMER(130));
    playerdragon0 = load_bitmap("pd0.bmp",NULL);
    playerdragon1 = load_bitmap("pd1.bmp",NULL);
    playerdragon2 = load_bitmap("pd2.bmp",NULL);
    playerdragon3 = load_bitmap("pd3.bmp",NULL);
    
    pfacing = 2;
    pxpos = 320;
    pypos = 240;
    
    buffer = create_bitmap(640,480);
    draw_sprite(screen,buffer,0,0);
    while(!key[KEY_ESC])
    {
                        pcontrol();
                        clear_bitmap(buffer);
    
                        
    }
    
    
    
    destroy_bitmap(playerdragon0);
    destroy_bitmap(playerdragon1);
    destroy_bitmap(playerdragon2);
    destroy_bitmap(playerdragon3);
    destroy_bitmap(buffer);
    
    clear_keybuf();
    return 0;
}
END_OF_MAIN();




wingtime.h
volatile long int wingcounter;

void wingtime()
{
     if(wingcounter == 4)
     {
                    wingcounter = 0;
     }
     else if(wingcounter >= 0)
     {
                 wingcounter ++;
     }
}END_OF_FUNCTION(wingtime);




playercontrol.h
#define adjust 50

void pcheckstats()
{
     
}

void pdraw()
{
     
     if(wingcounter == 0)
     {
                    if(pfacing == 1)
                    {
                               draw_sprite_h_flip(buffer,playerdragon0,pxpos-adjust,pypos-adjust);
                               draw_sprite(screen,buffer,0,0);
                    }
                    else if(pfacing == 2)
                    {
                               draw_sprite(buffer,playerdragon0,pxpos-adjust,pypos-adjust);
                               draw_sprite(screen,buffer,0,0);
                    }
     }
     else if(wingcounter == 1)
     {
                    if(pfacing == 1)
                    {
                               draw_sprite_h_flip(buffer,playerdragon1,pxpos-adjust,pypos-adjust);
                               draw_sprite(screen,buffer,0,0);
                    }
                    else if(pfacing == 2)
                    {
                              draw_sprite(buffer,playerdragon1,pxpos-adjust,pypos-adjust);
                              draw_sprite(screen,buffer,0,0);
                    }
     }
     else if(wingcounter == 2)
     {
                    if(pfacing == 1)
                    {
                               draw_sprite_h_flip(buffer,playerdragon2,pxpos-adjust,pypos-adjust);
                               draw_sprite(screen,buffer,0,0);
                    }
                    else if(pfacing == 2)
                    {
                               draw_sprite(buffer,playerdragon2,pxpos-adjust,pypos-adjust);
                               draw_sprite(screen,buffer,0,0);
                    }
     }
     else if(wingcounter == 3)
     {
                     if(pfacing == 1)
                     {
                                draw_sprite_h_flip(buffer,playerdragon3,pxpos-adjust,pypos-adjust);
                                draw_sprite(screen,buffer,0,0);
                     }
                     else if(pfacing == 3)
                     {
                                 draw_sprite(buffer,playerdragon3,pxpos-adjust,pypos-adjust);
                                 draw_sprite(screen,buffer,0,0);
                     }
     }
}

void pgetcommand()
{
     if(key[KEY_UP])
     {
                    pypos - 5;
     }
     else if(key[KEY_LEFT])
     {
                    pxpos - 5;
                    pfacing = 1;

     }
     else if(key[KEY_RIGHT])
     {
          pxpos + 5;
          pfacing = 2;
     }
     else if(key[KEY_DOWN])
     {
          pypos + 5;
     }
    ofstream savefile;
    savefile.open("SAVEFILE.txt");
    savefile << "What the hell? What is wrong then?" <<endl;
    savefile.close();


    void pexecommand()
    {
     
    }

    void pcontrol()
    { 
         pcheckstats();  
         pdraw();
         pgetcommand();
         pexecommand();
     
    }
}




[Edited by - yurian on January 2, 2008 12:55:32 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Dave Hunt
In pgetcommand, you have code like:

pypos - 5;

That doesn't do anything. It should be:

pypos -= 5;

to assign a new value to the variable.


Still doesn't work.
Don't really wish to assign new value, only make big or smaller.

Share this post


Link to post
Share on other sites
Quote:
Original post by yurian
Don't really wish to assign new value, only make big or smaller.


yes but:


pypos - 5;



does not make pypos smaller. it doesn't do anything to the variable at all.

Everywhere that you have "pypos - 5" or "pypos + 5" or pypos +/- anything it should be += or -=. Otherwise the value of pypos never changes.

-me

Share this post


Link to post
Share on other sites
Quote:

volatile long int wingcounter;

void wingtime()
{
if(wingcounter == 4)
{
wingcounter = 0;
}
else if(wingcounter >= 0)
{
wingcounter ++;
}
}END_OF_FUNCTION(wingtime);


There is no guarantee made about the initial value of wingcounter. If it's negative, wingtime() will never update it; if it's greater than 4, it will increase continually until it overflows and becomes negative (at which point it will stop changing). You need to give it an initial value of 0:

volatile long int wingcounter = 0;

Also, for the record, "long int" is usually just written "long". There is no kind of long that is not an int.

And by the way, what the heck's that "END_OF_FUNCTION" thing?

Quote:
   else if(key[KEY_DOWN])
{
pypos + 5;
}
ofstream savefile;
savefile.open("SAVEFILE.txt");
savefile << "What the hell? What is wrong then?" <<endl;
savefile.close();


void pexecommand()
{

I'm surprised that this even compiles; you're missing a close-brace at the end of your 'savefile' code, which would make pexecommand/pcontrol local functions inside pgetcommand, which I thought was illegal in C++.

You really should make yourself familiar with the kind of tools we use to solve problems like this.

Share this post


Link to post
Share on other sites
You're drawing a dragon to your buffer, and then you're drawing that buffer to the screen. It looks like you assume you need to draw the buffer to screen each time you've drawn something to it, but that's not the purpose of such a buffer. The idea is to draw stuff to it first, and at the end, once everything is drawn, you draw the buffer to screen, so the screen gets updated instantly, without flickering. To ensure this, place the following line at the end of your pdraw() function, and only there:
draw_sprite(screen,buffer,0,0);

Let's look a bit further. You declare some global variabeles in main.cpp, which are used in playercontrol.h, which also uses a variabele from wingtime.h... even the slightest change in include order can throw up your whole program! Not to mention that in most cases, it's a bad idea to put implementations inside .h files - that's what .cpp files are for. And you shouldn't forget inclusion guards in header files, either. This article on code organization in C and C++ should be helpfull. Also note that globals are generally seen as a bad habit, because everything can access them, which can make it hard to track down what piece of code changed what variabele.

Your pdraw() function can be simplified a lot. Rather than repeating the same code for every dragon image, store those images in an array, or better, a std::vector, and select the image you want to draw using wingcounter as an index for the array or vector. Don't repeat code if you don't have to, because it makes code much harder to maintain: if something needs to be changed, it needs to be changed in multiple places now, and it's easy to forget one.

And although this one isn't as troublesome, wingtime() can be written simpler, too, using the modulus operator:
wingcounter = (wingcounter + 1) % ANIMATION_FRAMES_COUNT;
Note that using a variabele or define or such rather than a number can make code easier to comprehend. '4' doesn't really say much about it's purpose after all.


Those things probably won't help you solve your problem, although they may help you track down the problem faster. Learning better programming habits can certainly help you prevent such problems. And as superpig said, check what actually happens with a debugger. It should help you figure out where things go wrong much faster than we can help you. :)


@superpig: those seem to be Allegro macro's. Their purpose looks pretty arcane to me, however.

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