在c ++中创建游戏对象时出错

时间:2016-01-14 03:09:25

标签: c++

我一直在僵尸街机游戏中工作,我正在尝试一个奇怪的问题。我创建了一个名为GameObject的类和一个名为Human的类,它继承自GameOBject,然后我声明了另外两个调用;僵尸和玩家。问题是当我创建这四个类的两个或更多个字符(实例)时游戏停止工作,我发现在Zombie和Player类中,问题只发生在我调用方法更新时(只有这些类使用它)。该方法应该控制每个角色的活动。 图形和动画精灵与角色分开管理,它们(角色)只调用一些方法来控制精灵更新,这些命令在更新屏幕时被处理。

我只是想让你告诉我发生了什么,我认为问题出在Zombie和Player类的更新方法中。

项目分为不同的文件。

我认为这不重要,但我使用的是CodeBlocks和tdm-gcc。

main.cpp中:

#include "game_classes.h"

bool working = true, redraw = true;

int main(){

    init_game_classes();

    Player player(200, 200);

    std::vector<Zombie *> zombie_list;

    for(unsigned int i = 0; i < 2; i++){

        Zombie *zombie = new Zombie(i * 100, 12, &player);
        zombie_list.push_back(zombie);

    }

    while(working){

        input();

        if(event.type == ALLEGRO_EVENT_TIMER){//main loop

            player.update();

            for(unsigned int i = 0; i < zombie_list.size(); i++){

                zombie_list[i]->update();

            }

            redraw = true;

        }

        else if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE){

            working = false;

        }

        if(redraw and al_is_event_queue_empty(event_queue)){//updating display

            update_animated_models();
            blit_models();
            update_display();
            redraw = false;

        }

    }

    for(unsigned int i = 0; i < zombie_list.size(); i++)
        delete zombie_list[i];

    quit();
    return 0;

}

render.h:

#include <vector>
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>

int global_ticks_per_frame = 0;

ALLEGRO_BITMAP *map_background = NULL;

class Model;

std::vector<Model *> model_list;

class Model{

protected:

    int x = 0, y = 0, width, height;
    int source_x = 0, source_y = 0, source_width, source_height;

public:

    ALLEGRO_BITMAP *sheet = NULL;
    bool hide = false;
    int flags = 0;

    Model(const char *path, int width, int height){

        this->sheet = al_load_bitmap(path);
        al_convert_mask_to_alpha(this->sheet, al_map_rgb(255, 0, 255));

        this->source_width = al_get_bitmap_width(this->sheet);
        this->source_height = al_get_bitmap_height(this->sheet);

        this->width = width;
        this->height = height;

        model_list.insert(model_list.begin(), this);

    }

    Model(ALLEGRO_BITMAP *image, int width, int height){

        this->sheet = image;
        al_convert_mask_to_alpha(this->sheet, al_map_rgb(255, 0, 255));

        this->source_width = al_get_bitmap_width(this->sheet);
        this->source_height = al_get_bitmap_height(this->sheet);

        this->width = width;
        this->height = height;

        model_list.insert(model_list.begin(), this);

    }

    ~Model(){

        al_destroy_bitmap(this->sheet);
        model_list.erase(model_list.begin() + this->index());

    }

    void show(){

        if(not this->hide){

            al_draw_scaled_bitmap(this->sheet, this->source_x, this->source_y, this->source_width, this->source_height, x, y, width, height, this->flags);

        }

    }

    void set_x(int x){

        this->x = x;

    }

    unsigned int index(){

        for(unsigned int i = 0; i < model_list.size(); i++){

            if(model_list[i] == this)
                return i;

        }

    }

    bool set_y(int y){

        this->y = y;
        model_list.erase(model_list.begin() + this->index());
        int this_relative_y = this->y + this->height;

        unsigned int i = 0;

        while(i < model_list.size()){

            int from_list_relative_y = model_list[i]->y + model_list[i]->height;

            if(this_relative_y < from_list_relative_y){

                model_list.insert(model_list.begin() + i, this);
                return false;

            }

            i += 1;

        }

        model_list.push_back(this);
        return false;

    }

    int get_y(){

        return this->y;

    }

    int get_x(){

        return this->x;

    }

    unsigned int get_width(){

        return this->width;

    }

    unsigned int get_height(){

        return this->height;

    }

};

void blit_models(){

    for(unsigned int i = 0; i < model_list.size(); i++)
        model_list[i]->show();

}

class AnimatedModel;

std::vector<AnimatedModel *> animated_model_list;

class AnimatedModel : public Model{

private:

    unsigned int ticks_per_frame, ticks_counter = 0;
    unsigned int current_frame = 0, frame_count;

public:

    bool stop = false;

    void set_speed(unsigned int new_speed){

        this->ticks_per_frame = new_speed;

    }

    AnimatedModel(const char *path, unsigned int frames, unsigned int ticks_per_frame, int width, int height) : Model(path, width, height){

        this->ticks_per_frame = ticks_per_frame;
        this->frame_count = frames;
        this->source_width /= frames;

        animated_model_list.push_back(this);

    }

    AnimatedModel(ALLEGRO_BITMAP *image, unsigned int frames, unsigned int ticks_per_frame, int width, int height) : Model(image, width, height){

        this->ticks_per_frame = ticks_per_frame;
        this->frame_count = frames;
        this->source_width /= frames;

        animated_model_list.push_back(this);

    }

    ~AnimatedModel(){

        for(unsigned int i = 0; i < animated_model_list.size(); i++){

            if(animated_model_list[i] == this){

                animated_model_list.erase(animated_model_list.begin() + i);

            }

        }

    }

    void fix_sheet_looking(){

        if(not this->stop)
            this->source_x = this->current_frame*this->source_width;

    }

    void play(){

        if(this->ticks_counter >= this->ticks_per_frame + global_ticks_per_frame){

            this->current_frame += 1;

            if(this->current_frame >= this->frame_count)
                this->current_frame = 0;

            this->ticks_counter = 0;

        }

        else{

            this->ticks_counter += 1;

        }

    }

    void update(){

        if(not this->stop){

            this->play();
            this->fix_sheet_looking();

        }

    }

    void set_frame(unsigned int i){

        this->current_frame = i;

    }

    unsigned int get_frame(){

        return this->current_frame;

    }

};

void update_animated_models(){

    for(unsigned int i = 0; i < animated_model_list.size(); i++)
        animated_model_list[i]->update();

}

game_classes.h:

#include "render.h"
#include "touch.h"
#include "window_control.h"
#include <string>
#include <iostream>

ALLEGRO_BITMAP *zombie_sprite = NULL;
ALLEGRO_BITMAP *human_sprite = NULL;

void init_game_classes(){

    init_window_control();

    zombie_sprite = al_load_bitmap("textures/zombie/sprite.png");
    human_sprite = al_load_bitmap("textures/human/sprite.png");

}

int control_key_up = ALLEGRO_KEY_UP, control_key_down = ALLEGRO_KEY_DOWN, control_key_right = ALLEGRO_KEY_RIGHT, control_key_left = ALLEGRO_KEY_LEFT;
int control_key_run = ALLEGRO_KEY_Z;

HitBoxList character_body_reg;
HitBoxList item_body_reg;

class GameObjec{

protected:

    unsigned int walking_speed;
    HitBoxList *last_coll_test = NULL;
    int last_x, last_y;
    int body_high;
    int left_distance;

public:

    HitBox *body = NULL;
    AnimatedModel *sprite = NULL;

    void set_x(int x){

        this->sprite->set_x(x);
        this->last_x = this->body->x;
        this->body->x = x + this->left_distance;

    }

    void set_y(int y){

        this->sprite->set_y(y);
        this->last_y = this->body->y;
        this->body->y = y + this->body_high;

    }

    int get_x(){

        return this->sprite->get_x();

    }

    int get_y(){

        return this->sprite->get_y();

    }

    void slide_x(short int direction){

        character_body_reg.pop(this->body);
        this->last_coll_test = this->body->slide_x(this->walking_speed*direction, &character_body_reg);
        character_body_reg.push(this->body);

        this->set_x(this->body->x - this->left_distance);

    }

    void slide_y(short int direction){

        character_body_reg.pop(this->body);
        this->last_coll_test = this->body->slide_y(this->walking_speed*direction, &character_body_reg);
        character_body_reg.push(this->body);

        this->set_y(this->body->y - this->body_high);

    }

    void show_hitbox(){

        al_draw_rectangle(this->body->x, this->body->y, this->body->x + this->body->width, this->body->y + this->body->height, al_map_rgb(255, 0, 0), 1);

    }

    GameObjec(int x, int y, unsigned int walking_speed, const char *sprite_image_path, int frames, int ticks_per_frame, int sprite_width, int sprite_height, int body_high, int body_len){

        this->walking_speed = walking_speed;
        this->body_high = body_high;

        this->sprite = new AnimatedModel(sprite_image_path, frames, ticks_per_frame, sprite_width, sprite_height);

        this->left_distance = (this->sprite->get_width() - body_len)/2;

        this->body = new HitBox;

        this->sprite->set_x(x);
        this->sprite->set_y(y);

        this->body->width = body_len;
        this->body->height = this->sprite->get_height() - this->body_high;
        this->body->x = x + left_distance;
        this->body->y = y + this->body_high;

        this->last_x = this->body->x;
        this->last_y = this->body->y;

        character_body_reg.push(this->body);

    }

    ~GameObjec(){

        delete this->sprite;
        character_body_reg.pop(this->body);
        delete this->body;

    }

    void draw_hitbox(){

        al_draw_rectangle(this->body->x, this->body->y, this->body->x + this->body->width, this->body->y + this->body->height, al_map_rgb(255, 0, 0), 0);

    }

};

class Human : public GameObjec{

protected:

    bool walking = false;

public:

    Human(int x, int y, const char *sprite_image_path) : GameObjec(x, y, 2, sprite_image_path, 2, 7, 64, 80, 60, 32){}

    ~Human(){}

    void walk_down(){

        this->slide_y(1);
        this->sprite->stop = false;
        this->walking = true;

    }

    void walk_up(){

        this->slide_y(-1);
        this->sprite->stop = false;
        this->walking = true;

    }

    void walk_right(){

        this->slide_x(1);
        this->sprite->stop = false;
        this->sprite->flags = 0;
        this->walking = true;

    }

    void walk_left(){

        this->slide_x(-1);
        this->sprite->stop = false;
        this->sprite->flags = ALLEGRO_FLIP_HORIZONTAL;
        this->walking = true;

    }

};

class Player : public Human{

public:

    Player(int x, int y) : Human(x, y, "textures/human/sprite.png"){
    }

    void control(){

        if(get_key(control_key_down))
            this->walk_down();

        else if(get_key(control_key_up))
            this->walk_up();

        if(get_key(control_key_right))
            this->walk_right();

        else if(get_key(control_key_left))
            this->walk_left();

        if(not this->walking){

            this->sprite->set_frame(0);
            this->sprite->fix_sheet_looking();
            this->sprite->stop = true;

        }

        if(this->last_x == this->body->x and this->last_y == this->body->y)
            this->walking = false;

    }

    void update(){

        this->control();

    }

};

class Zombie : public Human{

private:

    //Player *to_kill;
    int to_kill_x, to_kill_y;
    unsigned int walk_ticks_counter = 0, follow_ticks_counter = 0;

public:

    Player *to_kill;

    void fix_to_kill_position(){

        if(this->to_kill){

            this->to_kill_x = this->to_kill->body->x;
            this->to_kill_y = this->to_kill->body->y;

        }

        else{

            this->to_kill_x = this->body->x;
            this->to_kill_y = this->body->y;

        }

    }

    Zombie(int x, int y, Player *to_kill) : Human(x, y, "textures/zombie/sprite.png"){

        this->sprite->set_speed(23);
        this->walking_speed = 1;
        this->to_kill = to_kill;

        this->fix_to_kill_position();

    }

   void control(){

        if(this->body->y < to_kill_y)
            this->walk_down();

        else if(this->body->y > to_kill_y)
            this->walk_up();

        if(this->body->x < to_kill_x)
            this->walk_right();

        else if(this->body->x > to_kill_x)
            this->walk_left();

        if(not this->walking){

            this->sprite->set_frame(0);
            this->sprite->fix_sheet_looking();
            this->sprite->stop = true;

        }

    }

    void update(){

        if(this->follow_ticks_counter == 78){

            this->fix_to_kill_position();
            this->follow_ticks_counter = 0;

        }

        else{

            this->follow_ticks_counter += 1;
        }

        if(this->walk_ticks_counter == 2){

            this->control();
            this->walk_ticks_counter = 0;

        }

        else{

            this->walk_ticks_counter += 1;
        }

        if(this->last_x == this->body->x and this->last_y == this->body->y)
            this->walking = false;

    }

};

0 个答案:

没有答案