Jump to content

  • Log In with Google      Sign In   
  • Create Account


Request feedback on my drawing algorithms.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 black_darkness   Members   -  Reputation: 280

Like
0Likes
Like

Posted 22 January 2013 - 02:47 AM

Please tell me what I am doing inefficiently and wrong. The game runs properly but I think that there is some things I could improve before I move on with the game. What would you do differently? I often get bizzare slowdowns when my character moves around for a while. As far as I know I do not have any memory leaks. Are there any better ways to handle the game loop or animation? The three methods I am worried about the most are void walk_animation(int,int,int,int,int,int,int,int,int); void move_hero(); and void three_frame_animation(int,int,int,int,int,int,int,int,int,int,int);  I am using C++ with ALLEGRO.

 

Here is the Game_system class with method prototypes and variables.

 

class Game_system {
public:
enum KEYS{UP,DOWN,LEFT,RIGHT};
ALLEGRO_DISPLAY * display;
ALLEGRO_EVENT_QUEUE * event_queue;
ALLEGRO_TIMER * timer;
ALLEGRO_BITMAP * tileset;
ALLEGRO_BITMAP * gs_map;
ALLEGRO_BITMAP * en_map;
ALLEGRO_SAMPLE * sample;
ALLEGRO_FONT * font;
bool done;
bool keys[4];
bool redraw;
bool write_dialogue;
vector<int> wid_height;
int FPS;
float mapy;
float mapx;
time_t timer1;
int frame_counter;
string cur_map;
Creature hero;
vector<Entity> mve;
vector<Tile> mv;
void loop();
void set_values();
void draw_map(int,int);
void draw_hero(int,int);
void walk_animation(int,int,int,int,int,int,int,int,int);
void move_hero();
void three_frame_animation(int,int,int,int,int,int,int,int,int,int,int);
void make_map();
void ev_handler();
};

 

 

Here is set values method. This sets things up and is only called once.

 

void Game_system::set_values() {
/*
Allegro variables
*/
display=NULL;
event_queue=NULL;
timer=NULL;
tileset = NULL;
gs_map = NULL;
en_map = NULL;
sample = NULL;
font = NULL;
/*
Primitive variables
*/
done = false;
keys[0] = false;
keys[1] = false;
keys[2] = false;
keys[3] = false;
redraw = true;
write_dialogue = false;
    
/*
wid_height initialization
*/
wid_height.push_back(1);
wid_height.push_back(1);
wid_height[0] = 30; //col x
wid_height[1] = 30; //col y
/*
Integer variables
*/
FPS = 30;
mapx = 0;
mapy = 0;
/*
Timing variables
*/
timer1 = clock();
frame_counter = 0;
hero.set_loc(12,15);
hero.facing = 'd';
hero.is_swing_hoe = false;
hero.move_animation = false;
hero.wait_time=1;
display = al_create_display((28*16)-1,(28*16)-1);
gs_map = al_create_bitmap((wid_height[0]*16)-1,(wid_height[1]*16)-1);
en_map = al_create_bitmap((wid_height[0]*16)-1,(wid_height[1]*16)-1);
/*
Initialize allegro modules.
*/
al_install_keyboard();
al_init_primitives_addon();
al_init_image_addon();
al_install_audio();
al_init_acodec_addon();
al_reserve_samples(1);
al_init_font_addon();
al_init_ttf_addon();
/*
Initialize allegro variables.
*/
sample = al_load_sample("neg_resources/collision.ogg");
font = al_load_font("neg_resources/arial.ttf",16,0);
timer = al_create_timer(1.0/FPS);
event_queue = al_create_event_queue();
//game init
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_display_event_source(display));
al_start_timer(timer);
mve.resize(wid_height[0]*wid_height[1]);
init_map_house(cur_map, mve);
make_map();
init_map_house_entity(mve);
tileset = al_load_bitmap("neg_resources/tileset.png");
al_convert_mask_to_alpha(tileset, al_map_rgb(0,255,255));
draw_map(0,0);
}

 

 

Here is the game loop

 

void Game_system::loop() {
    while(!done)
    {
        ev_handler();
        //WAIT UNTIL ANIMATION IS OVER - If key is still pressed animate again. (Pokemon esque)
        if (hero.move_animation == false) {
            if (keys[UP]==true) {
                hero.creature_turning('u',mv);
            }    
            else if (keys[DOWN]==true) {
                hero.creature_turning('d',mv);
            }
            else if (keys[LEFT] == true) {
                hero.creature_turning('l',mv);
            }
            else if (keys[RIGHT] == true) {
                hero.creature_turning('r',mv);
            }
        }
        //CHECK FOR ON STEP EVENT
        if(mve[(hero.hloc*30)+hero.wloc].step_on == 'y') {
            if (mve[(hero.hloc*30)+hero.wloc].map_warp == "house") {
                hero.set_loc(mve[(hero.hloc*30)+hero.wloc].warp_col,mve[(hero.hloc*30)+hero.wloc].warp_row);
                init_map_entity_cleanup(mve);
                init_map_house_entity(mve);
                init_map_house(cur_map,mve);
                make_map();
                draw_map(0,0);
            }
            else if (mve[(hero.hloc*30)+hero.wloc].map_warp == "home") {
                hero.set_loc(mve[(hero.hloc*30)+hero.wloc].warp_col,mve[(hero.hloc*30)+hero.wloc].warp_row);
                init_map_entity_cleanup(mve);
                init_map_home_entity(mve);
                init_map_home(cur_map,mve);
                make_map();
                draw_map(0,0);
            }
        }
        hero.wait_time++;
        //This block runs FPS times per second
        if(redraw && al_is_event_queue_empty(event_queue))
        {
            redraw = false;
            //DRAW & ANIMATE HERO
            frame_counter++;
            if ((clock() - timer1) >= 1000) {
                cout<<frame_counter<<"\n";
                frame_counter = 0;
                timer1 = clock();
            }
            move_hero();
            //DRAW MAP
            al_set_target_backbuffer(display);
            al_draw_bitmap(gs_map,mapx-16,mapy-16,0);
            al_draw_bitmap(en_map,0-16,0-16,0);
            //display message
            if(write_dialogue == true) {
                entity_message(tileset,hero,font,mve,wid_height);
            }
            
            al_flip_display();
            al_clear_to_color(al_map_rgb(0,0,0));
        }
    }
}

 

 

Here is the draw map() method

 

 

void Game_system::draw_map (int radj, int cadj)
//Draws map and you can modify pixel by pixel with radj and cadj. (Row adjustment and Column adjustment). Set them to zero if you desire no modification.
{
    mapx = 0;
    mapy = 0;
    al_set_target_bitmap(gs_map);
    for(int col=0;col<wid_height[0];col++) {
        for(int row=0;row<wid_height[1];row++) {
            al_draw_bitmap_region(tileset,
                mv[(col*30)+row].sx * 16, mv[(col*30)+row].sy * 16,
                16,16,
                (row*16 - hero.wloc*16)+((wid_height[1]/2)*16) + radj,
                (col*16 - hero.hloc*16)+((wid_height[0]/2)*16) + cadj,
                0);
        }
    }    
}

 

 

Here is the walk animation

 

void Game_system::walk_animation (int tw, int aheight, int awidth, int ci1,int ci2,int ci3,int ri1, int ri2, int ri3)
/*
Draws the walking animation
Variable description
#######################
Entity being animated, tileset,map vector 1-3
tile width, animation height in tiles, and animation width in tiles
height, and width of map in tiles.
ci1,ci2,ci3 column of the three animations
ri1,ri2,ri3 row of the three animations
*/
{
    al_set_target_bitmap(en_map);
    if(hero.move_animation==true) {
        int hl=0;
        int vl=0;
        switch (hero.facing) {
        case 'u':
            vl = -1;
            mapy+=2;
            break;
        case 'd' :
            vl=1;
            mapy-=2;
            break;
        case 'l' :
            hl=-1;
            mapx+=2;
            break;
        case 'r':
            hl=1;
            mapx-=2;
            break;
        }
        if (hero.frame<= 3) {
            al_clear_to_color(al_map_rgba(0,0,0,0));
            al_draw_bitmap_region(tileset, ri2*tw, ci2*tw, tw, tw, 15*tw, 15*tw, 0);
        }
        else if (hero.frame < 7) {
            al_clear_to_color(al_map_rgba(0,0,0,0));
            al_draw_bitmap_region(tileset, ri3*tw, ci3*tw, tw, tw, 15*tw, 15*tw, 0);
        }
        else if(hero.frame == 7) {
            al_clear_to_color(al_map_rgba(0,0,0,0));
            al_draw_bitmap_region(tileset, ri3*tw, ci3*tw, tw, tw, 15*tw, 15*tw, 0);
            hero.move_animation = false;
            hero.hloc+=vl; //moving line.
            hero.wloc+=hl; // moving line.
            draw_map(0,0);
        }
        hero.frame++;
    }
    else {
        al_clear_to_color(al_map_rgba(0,0,0,0));
        al_draw_bitmap_region(tileset, ri1 * tw, ci1 * tw, tw, tw, 15*tw, 15*tw, 0);
    }
}

 

 

Here is the move hero

 

void Game_system::move_hero () {
    int tw = 16;
    if(hero.move_animation==false) {
        if(hero.is_swing_hoe == true) {
            switch (hero.facing) {
            case 'u':
                three_frame_animation(tw,16,16,16,0,1,2,2,1,-1,-2);
                break;
            case 'd' :
                three_frame_animation(tw,13,13,13,0,1,2,3,1,-1,-2);
                break;
            case 'l':
                three_frame_animation(tw,18,18,18,0,2,4,2,2,-2,-2);
                break;
            case 'r':
                three_frame_animation(tw,20,20,20,0,2,4,2,2,-1,-2);
                break;
            }
            hero.sta_frame++;
        }
    }
    if(hero.is_swing_hoe == false) {
        switch (hero.facing) {
        case 'u':
            walk_animation(tw,1,1,3,3,3,0,1,2);
            break;
        case 'd':
            walk_animation(tw,1,1,2,2,2,0,1,2);
            break;
        case 'l':
            walk_animation(tw,1,1,4,4,4,0,1,2);
            break;
        case 'r':
            walk_animation(tw,1,1,5,5,5,0,1,2);
            break;
        }
    }
}

 

 

Here is the three frame animation

 

void Game_system::three_frame_animation(int tw, int ci1,int ci2, int ci3, int ri1, int ri2, int ri3,int aheight,int awidth,int radj, int cadj)
/*draws 3 frame animations.
variables description
##############################
tileset, tile width, Entity being animated,  1-3
column for first, second, and third frames. 4-6
row for first,second, and third frames. 7-9
animation height in tiles, animation width in tiles. 10,11
radj, and cadj are for adjusting the center of animation. makes function tweakable.
*/
{
    al_set_target_bitmap(en_map);
    if(hero.sta_frame<=1) {
        al_clear_to_color(al_map_rgba(0,0,0,0));
        al_draw_bitmap_region(tileset, (ri1)*tw, (ci1)*tw, tw*awidth, tw*aheight, (16+radj)*tw, (16+cadj)*tw, 0);
    }
    else if(hero.sta_frame<=3) {
        al_clear_to_color(al_map_rgba(0,0,0,0));
        al_draw_bitmap_region(tileset, (ri2)*tw, (ci2)*tw, tw*awidth, tw*aheight, (16+radj)*tw, (16+cadj)*tw, 0);
    }
    else if(hero.sta_frame<=5) {
        al_clear_to_color(al_map_rgba(0,0,0,0));
        al_draw_bitmap_region(tileset, (ri3)*tw, (ci3)*tw, tw*awidth, tw*aheight, (16+radj)*tw, (16+cadj)*tw, 0);
    }
    else if (hero.sta_frame <= 6) {
        al_draw_bitmap_region(tileset, (ri3)*tw, (ci3)*tw, tw*awidth, tw*aheight, (16+radj)*tw, (16+cadj)*tw, 0);
        al_clear_to_color(al_map_rgba(0,0,0,0));
        hero.is_swing_hoe = false;
        draw_map(0,0);
    }
}

 

 

Here is make map

 

void Game_system::make_map() {
    mv.resize(wid_height[0]*wid_height[1]);
    for(int i=0;i<mv.size();i++) {
        switch(cur_map[i]) {
        case 'X'://Wooden log
            mv[i].set_values('x','n',0,0);
            break;
        case 'O' ://empty
            mv[i].set_values('o','y',1,3);
            break;
        case 'V': //the void
            mv[i].set_values('v','n',2,4);
            break;
        case 'G'://grass (long)
            mv[i].set_values('g','y',1,1);
            break;
        case 'T'://tree
            mv[i].set_values('t','n',0,2);
            break;
        case 'S'://sign
            mv[i].set_values('s','n',0,3);
            break;
        case 'B'://blood
            mv[i].set_values('b','y',1,4);
            break;
        case 'D': //dirt
            mv[i].set_values('d','y',2,3);
            break;
        case 'W': //dirt
            mv[i].set_values('w','y',4,3);
            break;
        case 'F': //floor
            mv[i].set_values('f','y',1,2);
            break;
        case 'R': //left rug
            mv[i].set_values('r','y',5,3);
            break;
        case 'Y': //right rug
            mv[i].set_values('y','y',5,4);
            break;
        case '1'://left of roof
            mv[i].set_values('1','n',7,3);
            break;
        case '2'://roof center
            mv[i].set_values('2','n',7,4);
            break;
        case '3'://small window leftside on roof
            mv[i].set_values('3','n',7,5);
            break;
        case '4': //flowerpot window
            mv[i].set_values('4','n',7,6);
            break;
        case '5': //small window rightside on roof
            mv[i].set_values('5','n',7,7);
            break;
        case '6'://right of roof
            mv[i].set_values('6','n',7,8);
            break;
        case '7': //left wall
            mv[i].set_values('7','n',8,3);
            break;
        case '8': //wall
            mv[i].set_values('8','n',8,4);
            break;
        case '9': //rake
            mv[i].set_values('9','n',8,5);
            break;
        case '!': //door
            mv[i].set_values('!','y',8,6);
            break;
        case '@': //broom
            mv[i].set_values('@','n',8,7);
            break;
        case '#': //right wall
            mv[i].set_values('#','n',8,8);
            break;
        case '

 

 

Here is the ev handler

 

void Game_system::ev_handler()
{
    ALLEGRO_EVENT ev;
    al_wait_for_event(event_queue,&ev);
        
    if(ev.type == ALLEGRO_EVENT_TIMER){
        redraw = true;
    }
    if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
    {
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            write_dialogue = false;
            keys[UP] = true;
            break;
        case ALLEGRO_KEY_DOWN:
            write_dialogue = false;
            keys[DOWN]=true;
            break;
        case ALLEGRO_KEY_RIGHT:
            write_dialogue = false;
            keys[RIGHT]=true;
            break;
        case ALLEGRO_KEY_LEFT:
            write_dialogue = false;
            keys[LEFT]=true;
            break;
        case ALLEGRO_KEY_RCTRL:
            if (hero.move_animation == false && hero.is_swing_hoe == false) {
                hero.sta_frame = 1;
                hero.is_swing_hoe = true;
            }
            break;
        case ALLEGRO_KEY_Z:
            if(write_dialogue == true) {
                write_dialogue = false;
            }
            else if (hero.can_interact(write_dialogue,mve) == true){ //neeeds if statement.
                write_dialogue = true;
            }
        }
    }
    else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
        if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
            done = true;
        }
        //keys no longer held down.
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            keys[UP] = false;
            break;
        case ALLEGRO_KEY_DOWN:
            keys[DOWN]=false;
            break;
        case ALLEGRO_KEY_RIGHT:
            keys[RIGHT]=false;
            break;
        case ALLEGRO_KEY_LEFT:
            keys[LEFT]=false;
            break;
        }
    }
    else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
    {
        done = true;
    }
}

 

 

Here is the main loop.

 

#include "neg_headers/main.h"
#include "neg_headers/creature.h"
#include "neg_headers/maps.h"
#include "neg_headers/map_entity.h"
#include "neg_headers/entity_message.h"
#include "neg_headers/game_system.h"
int main(void)
{
    if(!al_init())
        return -1;
    Game_system gs;
    gs.set_values();
    gs.loop();
    return 0;
}

 

 

Here are the map entity functions

 

//HOUSE - entities for house.
vector<Entity> init_map_house_entity(vector<Entity> &mve) {
    Entity rug;
    rug.set_warp("home");
    rug.set_hero_loc(5,9);
    mve[(17*30)+15] = rug;
    mve[(17*30)+16] = rug;
    Entity spider;
    spider.entity_event("I am the holy log. You will do my bidding.");
    mve[(15*30)+13] = spider;
    return mve;
}
//HOME - entities for home.
vector<Entity> init_map_home_entity(vector<Entity> &mve) {
     Entity sign;
    sign.entity_event("Levis House.");
    mve[(22*30)+5] = sign;
        
    Entity door;
    door.set_warp("house");
    door.set_hero_loc(16,15);
    mve[(4*30)+9] = door;
    return mve;
}
//RESET MVE
vector<Entity> init_map_entity_cleanup(vector<Entity> &mve) {
    for (int i=0;i<mve.size();i++){
        mve[i].cleanup();
    }
    return mve;
}

 

 

Here is main.h including Entity and Tile classes.

 

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
using namespace std;
class Tile {
public:
    char cid, pass;
    int sy,sx;
    void set_values (char,char,int,int);
};
void Tile::set_values(char cid1,char pass1,int sy1,int sx1) {
    cid = cid1;
    pass = pass1;
    sy = sy1;
    sx = sx1;
}
class Entity {
public:
    int wloc, hloc;
    int warp_row, warp_col;
    char interact,step_on;
    string dialogue,map_warp;
    void set_loc(int,int);
    void entity_event(string);
    void set_warp(string);
    void set_hero_loc(int,int);
    void cleanup ();
    bool action_button;
    
};
void Entity::cleanup() {
    wloc = NULL;
    hloc = NULL;
    warp_row = NULL;
    warp_col = NULL;
    interact = NULL;
    step_on = NULL;
    dialogue = "";
    map_warp = "";
}
void Entity::set_hero_loc(int row,int col) {
    warp_row = row;
    warp_col = col;
}
void Entity::set_warp(string map_warp1) {
    step_on = 'y';
    map_warp = map_warp1;
}
void Entity::set_loc(int wloc1,int hloc1) {
    hloc = hloc1;
    wloc = wloc1;
}
void Entity::entity_event(string dialogue1) {
    interact = 'y';
    dialogue = dialogue1;
}
 

 

: //left of shingles             mv[i].set_values('

 

 

Here is the ev handler

 

void Game_system::ev_handler()
{
    ALLEGRO_EVENT ev;
    al_wait_for_event(event_queue,&ev);
        
    if(ev.type == ALLEGRO_EVENT_TIMER){
        redraw = true;
    }
    if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
    {
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            write_dialogue = false;
            keys[UP] = true;
            break;
        case ALLEGRO_KEY_DOWN:
            write_dialogue = false;
            keys[DOWN]=true;
            break;
        case ALLEGRO_KEY_RIGHT:
            write_dialogue = false;
            keys[RIGHT]=true;
            break;
        case ALLEGRO_KEY_LEFT:
            write_dialogue = false;
            keys[LEFT]=true;
            break;
        case ALLEGRO_KEY_RCTRL:
            if (hero.move_animation == false && hero.is_swing_hoe == false) {
                hero.sta_frame = 1;
                hero.is_swing_hoe = true;
            }
            break;
        case ALLEGRO_KEY_Z:
            if(write_dialogue == true) {
                write_dialogue = false;
            }
            else if (hero.can_interact(write_dialogue,mve) == true){ //neeeds if statement.
                write_dialogue = true;
            }
        }
    }
    else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
        if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
            done = true;
        }
        //keys no longer held down.
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            keys[UP] = false;
            break;
        case ALLEGRO_KEY_DOWN:
            keys[DOWN]=false;
            break;
        case ALLEGRO_KEY_RIGHT:
            keys[RIGHT]=false;
            break;
        case ALLEGRO_KEY_LEFT:
            keys[LEFT]=false;
            break;
        }
    }
    else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
    {
        done = true;
    }
}

 

 

Here is the main loop.

 

#include "neg_headers/main.h"
#include "neg_headers/creature.h"
#include "neg_headers/maps.h"
#include "neg_headers/map_entity.h"
#include "neg_headers/entity_message.h"
#include "neg_headers/game_system.h"
int main(void)
{
    if(!al_init())
        return -1;
    Game_system gs;
    gs.set_values();
    gs.loop();
    return 0;
}

 

 

Here are the map entity functions

 

//HOUSE - entities for house.
vector<Entity> init_map_house_entity(vector<Entity> &mve) {
    Entity rug;
    rug.set_warp("home");
    rug.set_hero_loc(5,9);
    mve[(17*30)+15] = rug;
    mve[(17*30)+16] = rug;
    Entity spider;
    spider.entity_event("I am the holy log. You will do my bidding.");
    mve[(15*30)+13] = spider;
    return mve;
}
//HOME - entities for home.
vector<Entity> init_map_home_entity(vector<Entity> &mve) {
     Entity sign;
    sign.entity_event("Levis House.");
    mve[(22*30)+5] = sign;
        
    Entity door;
    door.set_warp("house");
    door.set_hero_loc(16,15);
    mve[(4*30)+9] = door;
    return mve;
}
//RESET MVE
vector<Entity> init_map_entity_cleanup(vector<Entity> &mve) {
    for (int i=0;i<mve.size();i++){
        mve[i].cleanup();
    }
    return mve;
}

 

 

Here is main.h including Entity and Tile classes.

 

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
using namespace std;
class Tile {
public:
    char cid, pass;
    int sy,sx;
    void set_values (char,char,int,int);
};
void Tile::set_values(char cid1,char pass1,int sy1,int sx1) {
    cid = cid1;
    pass = pass1;
    sy = sy1;
    sx = sx1;
}
class Entity {
public:
    int wloc, hloc;
    int warp_row, warp_col;
    char interact,step_on;
    string dialogue,map_warp;
    void set_loc(int,int);
    void entity_event(string);
    void set_warp(string);
    void set_hero_loc(int,int);
    void cleanup ();
    bool action_button;
    
};
void Entity::cleanup() {
    wloc = NULL;
    hloc = NULL;
    warp_row = NULL;
    warp_col = NULL;
    interact = NULL;
    step_on = NULL;
    dialogue = "";
    map_warp = "";
}
void Entity::set_hero_loc(int row,int col) {
    warp_row = row;
    warp_col = col;
}
void Entity::set_warp(string map_warp1) {
    step_on = 'y';
    map_warp = map_warp1;
}
void Entity::set_loc(int wloc1,int hloc1) {
    hloc = hloc1;
    wloc = wloc1;
}
void Entity::entity_event(string dialogue1) {
    interact = 'y';
    dialogue = dialogue1;
}
 

 

,'n',6,3);             break;         case '%': //shingles             mv[i].set_values('%','n',6,4);             break;         case '^': //right of shingles             mv[i].set_values('^','n',6,5);             break;         case 'P': //Turnip greens             mv[i].set_values('p','y',5,5);             break;         }     } }

 

 

Here is the ev handler

 

void Game_system::ev_handler()
{
    ALLEGRO_EVENT ev;
    al_wait_for_event(event_queue,&ev);
        
    if(ev.type == ALLEGRO_EVENT_TIMER){
        redraw = true;
    }
    if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
    {
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            write_dialogue = false;
            keys[UP] = true;
            break;
        case ALLEGRO_KEY_DOWN:
            write_dialogue = false;
            keys[DOWN]=true;
            break;
        case ALLEGRO_KEY_RIGHT:
            write_dialogue = false;
            keys[RIGHT]=true;
            break;
        case ALLEGRO_KEY_LEFT:
            write_dialogue = false;
            keys[LEFT]=true;
            break;
        case ALLEGRO_KEY_RCTRL:
            if (hero.move_animation == false && hero.is_swing_hoe == false) {
                hero.sta_frame = 1;
                hero.is_swing_hoe = true;
            }
            break;
        case ALLEGRO_KEY_Z:
            if(write_dialogue == true) {
                write_dialogue = false;
            }
            else if (hero.can_interact(write_dialogue,mve) == true){ //neeeds if statement.
                write_dialogue = true;
            }
        }
    }
    else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
        if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
            done = true;
        }
        //keys no longer held down.
        switch(ev.keyboard.keycode) {
        case ALLEGRO_KEY_UP:
            keys[UP] = false;
            break;
        case ALLEGRO_KEY_DOWN:
            keys[DOWN]=false;
            break;
        case ALLEGRO_KEY_RIGHT:
            keys[RIGHT]=false;
            break;
        case ALLEGRO_KEY_LEFT:
            keys[LEFT]=false;
            break;
        }
    }
    else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
    {
        done = true;
    }
}

 

 

Here is the main loop.

 

#include "neg_headers/main.h"
#include "neg_headers/creature.h"
#include "neg_headers/maps.h"
#include "neg_headers/map_entity.h"
#include "neg_headers/entity_message.h"
#include "neg_headers/game_system.h"
int main(void)
{
    if(!al_init())
        return -1;
    Game_system gs;
    gs.set_values();
    gs.loop();
    return 0;
}

 

 

Here are the map entity functions

 

//HOUSE - entities for house.
vector<Entity> init_map_house_entity(vector<Entity> &mve) {
    Entity rug;
    rug.set_warp("home");
    rug.set_hero_loc(5,9);
    mve[(17*30)+15] = rug;
    mve[(17*30)+16] = rug;
    Entity spider;
    spider.entity_event("I am the holy log. You will do my bidding.");
    mve[(15*30)+13] = spider;
    return mve;
}
//HOME - entities for home.
vector<Entity> init_map_home_entity(vector<Entity> &mve) {
     Entity sign;
    sign.entity_event("Levis House.");
    mve[(22*30)+5] = sign;
        
    Entity door;
    door.set_warp("house");
    door.set_hero_loc(16,15);
    mve[(4*30)+9] = door;
    return mve;
}
//RESET MVE
vector<Entity> init_map_entity_cleanup(vector<Entity> &mve) {
    for (int i=0;i<mve.size();i++){
        mve[i].cleanup();
    }
    return mve;
}

 

 

Here is main.h including Entity and Tile classes.

 

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
using namespace std;
class Tile {
public:
    char cid, pass;
    int sy,sx;
    void set_values (char,char,int,int);
};
void Tile::set_values(char cid1,char pass1,int sy1,int sx1) {
    cid = cid1;
    pass = pass1;
    sy = sy1;
    sx = sx1;
}
class Entity {
public:
    int wloc, hloc;
    int warp_row, warp_col;
    char interact,step_on;
    string dialogue,map_warp;
    void set_loc(int,int);
    void entity_event(string);
    void set_warp(string);
    void set_hero_loc(int,int);
    void cleanup ();
    bool action_button;
    
};
void Entity::cleanup() {
    wloc = NULL;
    hloc = NULL;
    warp_row = NULL;
    warp_col = NULL;
    interact = NULL;
    step_on = NULL;
    dialogue = "";
    map_warp = "";
}
void Entity::set_hero_loc(int row,int col) {
    warp_row = row;
    warp_col = col;
}
void Entity::set_warp(string map_warp1) {
    step_on = 'y';
    map_warp = map_warp1;
}
void Entity::set_loc(int wloc1,int hloc1) {
    hloc = hloc1;
    wloc = wloc1;
}
void Entity::entity_event(string dialogue1) {
    interact = 'y';
    dialogue = dialogue1;
}
 

Here is the creature class.

class Creature: public Entity {
public:
    int frame,sta_frame;
    int corn_seeds, turnip_seeds;
    int wait_time;
    bool move_animation, is_swing_hoe;
    char facing;
    bool can_interact(bool,vector<Entity>&);
    bool can_pass(char,vector<Tile>&);
    void creature_turning(char,vector<Tile>&);
};
bool Creature::can_interact (bool write_dialogue, vector<Entity> &mve)
/*
   can_interact: hvar and wvar are used to convert char facing into
   a + or - value used to call the .interact function of Hero class
*/
{
    bool can_interact = false;
    int hvar = 0;
    int wvar = 0;
    switch(facing) {
    case 'u':
        hvar = -1;
        break;
    case 'd':
        hvar = 1;
        break;
    case 'l':
        wvar = -1;
        break;
    case 'r':
        wvar = 1;
        break;
    }
    if(mve[( (hloc+hvar)*30)+wloc+wvar].interact == 'y') {
        can_interact = true;
        write_dialogue = true;
    }
    return can_interact;
}
void Creature::creature_turning(char facing1, vector<Tile> &mv) {
    if (is_swing_hoe == false) {
                    
        if(facing != facing1) {
            facing = facing1;
            wait_time = 0;
        }
        else if (can_pass(facing,mv)&& wait_time > 3) {
            frame = 1;
            move_animation = true;
        }
    }
}
bool Creature::can_pass(char dir, vector<Tile> &mv) {
    switch(dir) {
    case 'l':
        if(mv[(hloc*30)+wloc-1].pass == 'y') {
            return true;
        }
        else
            return false;
        break;
    case 'r':
        if(mv[(hloc*30)+wloc+1].pass == 'y') {
            return true;
        }
        else
            return false;
        break;
    case 'u':
        if(mv[( (hloc-1)*30)+wloc].pass == 'y') {
            return true;
        }
        else
            return false;
        break;
    case 'd':
        if(mv[( (hloc+1)*30)+wloc].pass == 'y') {
            return true;
        }
        else
            return false;
        break;
    }
}


Edited by black_darkness, 22 January 2013 - 02:52 AM.


Sponsor:

#2 Nyssa   Members   -  Reputation: 426

Like
0Likes
Like

Posted 23 January 2013 - 03:44 AM

Just at a quick glance...

 

Alot of your functions are returning a new copy of the vector passed in. This could be causing a big slow down. Eg,

vector<Entity> init_map_house_entity(vector<Entity> &mve) 
{
    /*do stuff to mve*/
    return mve
}

 

Instead I would work on the vector passed in by reference. This avoids newing memory and copy operations. Eg,

void init_map_house_entity(vector<Entity> &mve) 
{
    /*do stuff to mve*/
}

 

This may gain some speed as well... instead of calling .size() on each iteration, store the size before entering the loop. I say you "may" gain speed here because the compiler could be doing some optimizing on its own anyway, but it's something to try... So instead of the following...

void Game_system::make_map() 
{
    mv.resize(wid_height[0]*wid_height[1]);
    for(int i=0;i<mv.size();i++) 
    {
         /*do stuff*/
    }
    
    /*do more stuff*/
}

 

Try...

void Game_system::make_map() 
{
    int arraySize = wid_height[0]*wid_height[1];
    mv.resize(arraySize);
    for(int i=0;i<arraySize;i++) 
    {
         /*do stuff*/
    }
    
    /*do more stuff*/
}

 

And with the functions such as:

void walk_animation(int,int,int,int,int,int,int,int,int);

 

It's faster to pass a single struct by reference then it is to pass lots of values. But with that said, you'd probably not be able to measure the optimization in this case cause your not passing large objects. Just something to keep in mind I guess. 



#3 larspensjo   Members   -  Reputation: 1525

Like
0Likes
Like

Posted 23 January 2013 - 06:19 AM

Have you tried profiling of you code?

 

If you do that, especially when you experience the slow down, you will get nice statistics how much time is spent in each function as well as the accumulated sum of all functions called. Do profiling is very important before you start optimizing, or you may spend your time on things that have negligible effects.

 

Otherwise, as Nyssa stated, making copies of vectors looks inefficient.


Current project: Ephenation.
Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

#4 black_darkness   Members   -  Reputation: 280

Like
0Likes
Like

Posted 25 January 2013 - 11:21 AM

Have you tried profiling of you code?

 

If you do that, especially when you experience the slow down, you will get nice statistics how much time is spent in each function as well as the accumulated sum of all functions called. Do profiling is very important before you start optimizing, or you may spend your time on things that have negligible effects.

 

Otherwise, as Nyssa stated, making copies of vectors looks inefficient.

 

I just got access to Visual Studio premium I think using Microsoft Dreamspark. I will profile my code soon and check which functions and methods are slowing it down.



#5 black_darkness   Members   -  Reputation: 280

Like
0Likes
Like

Posted 25 January 2013 - 11:23 AM

Just at a quick glance...

 

Alot of your functions are returning a new copy of the vector passed in. This could be causing a big slow down. Eg,

vector<Entity> init_map_house_entity(vector<Entity> &mve) 
{
    /*do stuff to mve*/
    return mve
}

 

Instead I would work on the vector passed in by reference. This avoids newing memory and copy operations. Eg,

void init_map_house_entity(vector<Entity> &mve) 
{
    /*do stuff to mve*/
}

 

This may gain some speed as well... instead of calling .size() on each iteration, store the size before entering the loop. I say you "may" gain speed here because the compiler could be doing some optimizing on its own anyway, but it's something to try... So instead of the following...

void Game_system::make_map() 
{
    mv.resize(wid_height[0]*wid_height[1]);
    for(int i=0;i<mv.size();i++) 
    {
         /*do stuff*/
    }
    
    /*do more stuff*/
}

 

Try...

void Game_system::make_map() 
{
    int arraySize = wid_height[0]*wid_height[1];
    mv.resize(arraySize);
    for(int i=0;i<arraySize;i++) 
    {
         /*do stuff*/
    }
    
    /*do more stuff*/
}

 

And with the functions such as:

void walk_animation(int,int,int,int,int,int,int,int,int);

 

It's faster to pass a single struct by reference then it is to pass lots of values. But with that said, you'd probably not be able to measure the optimization in this case cause your not passing large objects. Just something to keep in mind I guess. 

 

Thank you I will fix this. Great find. I kept missing those.



#6 EWClay   Members   -  Reputation: 655

Like
0Likes
Like

Posted 25 January 2013 - 12:51 PM

Drawing large numbers of bitmaps can be slow. You could try al_hold_bitmap_drawing() around the map drawing loop.

The event handling looks suspect. The main loop should look like:

Process all events
Update
Draw
Flip display

It may look smoother if you remove the timer and rely on vsync. If your refresh rate is 60 and you want 30 fps, set ALLEGRO_VSYNC to 2 before creating the display.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS