动画问题?

发布于 2024-12-01 03:46:59 字数 3534 浏览 0 评论 0原文

现在,当我开始用 C++ 制作游戏时,我会向左向右向上或向下行走。但是角色只是滑动,看起来不像他在行走。而且我已将所有图片加载到我的游戏中,并且它们正在工作。 .但我不知道如何解决它..我不明白的是当你按住按钮时如何使图片改变..

顺便说一下,这是在allegro中..

这是我的代码绘图玩家:

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;
}

这里现在是我在此处获得帮助后输入的新完整代码。当我走上它显示前面时,它现在不起作用图片,我正在走下去,上面的图片正在显示..但是左右都可以..而且它也不会像动画一样改变图片..

Right now when i start my game am making in C++ i walk left right up or down.. But the character just slides doesn't look like he's walking.. And i have all the pictures already loaded into my game and they are working.. But i don't know how i would solve it.. Thing i can't figure out is how to make the picture change when u hold the button..

This is in allegro by the way..

Here is my code for the drawing player:

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

Oskar[] is the name of the Array with all the pictures..

Here is what changes the picture for the character when u press the buttons:

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;
}

Its all about the variable i created picNumber.. All pictures i have is in an Array and the picNumber is represents what picture to be drawn..
Would be nice to get some help on this.. I've been thinking all day about this..

EDIT

#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;
}

here is now the new full code i typed after getting help here.. Its now not working when am walking up its showing the front picture and am walking down the up picture is showing.. But left and right works.. Also its not changing picture like animation..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叫嚣ゝ 2024-12-08 03:46:59

每个运动方向只有一个索引!

假设您绘制了大约 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;
 }

You only have one index for each direction of movement!

Assuming you have drawn about 3 (left leg forward, overlap, right leg forward) you would need to increment the index with time or movement as the march progresses.

Interesting how far Allegro has progressed- a decade ago it was mainly DOS graphics (I used it with DJGPP) and had a note from the author living in a London flat. How austere I thought, only now do I see how far off of London prices we provincials are.

In answer to your comment, try something like:

#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);

or if you don't want a new frame per pixel but every 3 or so try replacing

picNumber = x % MAXPICS;

with

picNumber = (x / 3)  % MAXPICS;

I've tried tidying up your code a little and come up with this, I don't have allegro so couldn't test it:

#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;
 }
淡淡の花香 2024-12-08 03:46:59

你好像没有做任何动画。看来您只是根据用户按下的方向键设置特定的框架。您需要一个执行以下操作的函数:

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;
    }
}

每帧调用它,并向其传递自上一帧以来经过的时间量。

You don't seem to be doing any animation. It seems you are just setting a specific frame based on the direction key the user is pressing. You need a function that does something like this:

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;
    }
}

Call it every frame, passing it the amount of time that has elapsed since the last frame.

放飞的风筝 2024-12-08 03:46:59

针对您对其他两个答案的评论,您似乎不确定如何不超过特定值。

为此(例如,您想要 [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]

希望这有帮助!

In response to your comments on the other 2 answers, you seem to be unsure of how to not go over a specific value.

To do this (for instance you want something in the range [0, 2] + c, where c is some constant determining the start of your index. So for instance, you could do the following:

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;
}

This should do what you want (i.e. depending on the direction you change the start index to suit, and then it increments, mapping the value to the range [0, 2].

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文