Проблема с анимацией? - PullRequest
       17

Проблема с анимацией?

1 голос
/ 23 августа 2011

Прямо сейчас, когда я начинаю свою игру, я делаю в C ++, я иду влево вправо вверх или вниз ... Но персонаж просто скользит, не похоже, что он идет ... И у меня есть все картинки, уже загруженные в мою игру, и ониработают .. Но я не знаю, как бы я решил это .. То, что я не могу понять, это как изменить изображение, когда вы удерживаете кнопку ..

Это в аллегроway ..

Вот мой код для рисования игрока:

void Player::Draw(BITMAP *Buffer){
    draw_sprite(Buffer, Oskar[picNumber], x, y);
}

Oskar [] это имя массива со всеми картинками ..

Вотчто меняет картинку для персонажа, когда вы нажимаете кнопки:

void Player::Controls(){

if(key[KEY_RIGHT]){
    velocityX = speed;
    picNumber = 6;
}

else if(key [KEY_LEFT]){
    velocityX = -speed;
    picNumber = 9;
}

else{
    velocityX = 0;
}

if(key [KEY_UP]){
    velocityY = -speed;
    picNumber = 3;
}
else if(key [KEY_DOWN]){
    velocityY = speed;
    picNumber = 0;
}
else{
    velocityY = 0;
}

x += velocityX;
y += velocityY;
}

Все дело в переменной, которую я создал. picNumber .. Все мои изображения находятся в массиве, а picNumber представляет, какую картинку рисовать... Было бы неплохо получить некоторую помощь по этому вопросу .. Я думал об этом весь день ..

РЕДАКТИРОВАТЬ

#include "Player.h"
#include "Global.h"
#include <allegro.h>


Player::Player(){

}


Player::~Player(){

}

void Player::Init(){
        x = 10;
        y = 10;
        velocityX = 0;
        velocityY = 0;
        speed = 1;
        picNumber = x % MAXPICS;

        OskarFront[0] = load_bitmap("Character\\OskarFront.bmp", NULL);
        OskarFront[1] = load_bitmap("Character\\OskarStanding.bmp", NULL);
        OskarFront[2] = load_bitmap("Character\\OskarFront2.bmp", NULL);

        OskarBack[0] = load_bitmap("Character\\OskarBack.bmp", NULL);
        OskarBack[1] = load_bitmap("Character\\OskarStandingBack.bmp", NULL);
        OskarBack[2] = load_bitmap("Character\\OskarBack2.bmp", NULL);

        OskarRight[0] = load_bitmap("Character\\Oskar1.bmp", NULL);
        OskarRight[1] = load_bitmap("Character\\Oskar.bmp", NULL);
        OskarRight[2] = load_bitmap("Character\\Oskar2.bmp", NULL);

        OskarLeft[0] = load_bitmap("Character\\OskarLeft.bmp", NULL);
        OskarLeft[1] = load_bitmap("Character\\OskarLeftStand.bmp", NULL);
        OskarLeft[2] = load_bitmap("Character\\OskarLeft2.bmp", NULL);
}

void Player::Update(){
        Player::Controls();
}

void Player::Draw(BITMAP *Buffer){

        if(walkingRight == true){
                draw_sprite(Buffer, OskarRight[picNumber], x, y);
        }

        else if(walkingLeft == true){
                draw_sprite(Buffer, OskarLeft[picNumber], x, y);
        }

        else if(walkingFront == true){
                draw_sprite(Buffer, OskarFront[picNumber], x, y);
        }

        else if(walkingBack == true){
                draw_sprite(Buffer, OskarBack[picNumber], x, y);
        }

        else{
                draw_sprite(Buffer, OskarFront[1], x, y);
        }
}

void Player::Controls(){

        if(key[KEY_RIGHT]){
                velocityX = speed;
                walkingRight = true;
        }

        else if(key [KEY_LEFT]){
                velocityX = -speed;
                walkingLeft = true;
        }

        else{
                walkingRight = false;
                walkingLeft = false;
                velocityX = 0;
        }

        if(key [KEY_UP]){
                velocityY = -speed;
                walkingFront = true;
        }
        else if(key [KEY_DOWN]){
                velocityY = speed;
                walkingBack = true;
        }
        else{
                velocityY = 0;
                walkingFront = false;
                walkingBack = false;
        }

        x += velocityX;
        y += velocityY;
}

вот теперь новый полный код, который я набрал послеполучить помощь здесь .. Его теперь не работает, когда я иду вверхкак передняя картинка, и я иду вниз, вверх показывает изображение .. Но работает влево и вправо .. Также это не меняется изображение, как анимация ..

Ответы [ 3 ]

3 голосов
/ 23 августа 2011

У вас есть только один указатель для каждого направления движения!

Предполагая, что вы нарисовали около 3 (левая нога вперед, перекрытие, правая нога вперед), вам нужно будет увеличить индекс со временем или движением какМарш продвигается.

Интересно, как далеко продвинулся Allegro - десять лет назад это была в основном графика DOS (я использовал ее с DJGPP) и была записка от автора, живущего в лондонской квартире. Как сурово я думал, только теперь я вижу, как далеко от лондонских цен мы, провинциалы.

В ответ на ваш комментарий попробуйте что-то вроде:

#define MAXPICS 3
BITMAP *OskarWalksLeft[MAXPICS];
BITMAP *OskarWalksRight[MAXPICS];
picNumber = x % MAXPICS;
if (facingLeft) {
    draw_sprite(Buffer, OskarWalksLeft[picNumber], x, y);
} else //facingRight
    draw_sprite(Buffer, OskarWalksRight[picNumber], x, y);

или если вам не нужен новый кадр на пиксель, но каждые 3 или около того попробуйте заменить

picNumber = x % MAXPICS;

на

picNumber = (x / 3)  % MAXPICS;

Я попытался немного привести в порядок ваш код ипридумайте это, у меня нет allegro, поэтому я не смог проверить это:

#include "Player.h"
#include "Global.h"
#include <allegro.h>

Player::Player(){}

Player::~Player(){}

enum playerDir {left, right, front, back, stationary} direction;
BITMAP *Oskar[stationary][3];

void Player::Init(){
    x = 10;
    y = 10;
    velocityX = 0;
    velocityY = 0;
    speed = 1;
    picNumber = x % MAXPICS;

    char filename[256];
    const char *dirStrs[] = {"left","right","front","back"};
    for (playerDir i = left; i < stationary; (int)i = (int)i + 1)
        for (j = 0; j < 3; ++j) {
            strcpy(filename, "Character\\Oskar");
            strcat(filename, dirStrs[i]);
            strcat(filename, itoa(j));
            strcat(filename, ".bmp");
            Oskar[i][j] = load_bitmap(filename, NULL);
        }
}

void Player::Update(){Player::Controls();}
void Player::Draw(BITMAP *Buffer){
    switch (direction) {
        case left :
                draw_sprite(Buffer, OskarLeft[picNumber], x, y);
                break;
        case right :
                draw_sprite(Buffer, OskarRight[picNumber], x, y);
                break;
        case front :
                draw_sprite(Buffer, OskarFront[picNumber], x, y);
                break;
        case back :
                draw_sprite(Buffer, OskarBack[picNumber], x, y);
                break;
        default:
                draw_sprite(Buffer, OskarFront[1], x, y);
        }
}

void Player::Controls(){
    direction = stationary;
    if(key[KEY_RIGHT]){
        velocityX = speed;
        direction = right;
    } else if(key [KEY_LEFT]){
        velocityX = -speed;
        direction = left;
    } else velocityX = 0;

    if(key [KEY_UP]){
        velocityY = -speed;
        direction = front;
    } else if(key [KEY_DOWN]){
        velocityY = speed;
        direction = back;
    } else velocityY = 0;

    x += velocityX;
    y += velocityY;
 }
0 голосов
/ 23 августа 2011

В ответ на ваши комментарии к двум другим ответам вы, похоже, не знаете, как не указывать конкретное значение.

Для этого (например, вы хотите что-то в диапазоне [0,2] + c, где c - некоторая константа, определяющая начало вашего индекса. Так, например, вы можете сделать следующее:

void Player::nextFrame( int startIndex /* Changes based on your direction */) {
      static unsigned short iIndex = 0;

      // Increment and map value to the range [0, 2]
      ++iIndex;
      iIndex %= 3;


      // Note: this assumes that picNumber is a member function, else you
      // will have to pass it by reference to this function.
      picNumber = iIndex + startIndex;
}

Это должно делать то, что вы хотите (т.е. в зависимости от направления, которое вы меняетеподходящий стартовый индекс, а затем он увеличивается, отображая значение в диапазон [0, 2].

Надеюсь, это поможет!

0 голосов
/ 23 августа 2011

Вы, кажется, не делаете никакой анимации.Кажется, вы просто устанавливаете конкретный кадр на основе клавиши направления, которую нажимает пользователь.Вам нужна функция, которая делает что-то вроде этого:

void Player::updateFrame(float time_delta)
{
    time_to_next_frame -= time_delta;
    while (time_to_next_frame <= 0.0f)
    {
        nextFrame();
        time_to_next_frame += time_per_frame;
    }
}

Вызывайте ее каждый кадр, передавая количество времени, прошедшее с последнего кадра.

...