1

現在、C++ で作成しているゲームを開始すると、左右上下に歩きます..しかし、キャラクターがスライドするだけで、彼が歩いているようには見えません..そして、すべての写真が既にゲームにロードされており、それらは機能しています. .しかし、私はそれを解決する方法がわかりません..私が理解できないことは、ボタンを押したときに画像を変更する方法です..

ちなみにこれはアレグロです。

描画プレーヤーのコードは次のとおりです。

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

ここでヘルプを取得した後に入力した新しい完全なコードを次に示します..前の写真を表示して上に歩いているときに機能しなくなり、上の写真が表示されている..しかし、左と右は機能します..アニメーションのような絵..

4

3 に答える 3

3

移動方向ごとに 1 つのインデックスしかありません。

約 3 つ (左脚を前方、オーバーラップ、右脚を前方) に描画したと仮定すると、行進の進行に合わせて、時間または動きに応じてインデックスをインクリメントする必要があります。

Allegro がどこまで進歩したか興味深い. 私がどれだけ厳格に考えていたかは、今になって初めて、私たちの地方の価格がロンドンの価格からどれだけ離れているかがわかります.

あなたのコメントに答えて、次のようなことを試してください:

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

私はあなたのコードを少し整理しようとしましたが、これを思いつきました.私はアレグロを持っていないので、テストできませんでした:

#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;
 }
于 2011-08-23T15:32:24.063 に答える
0

他の2つの回答に対するあなたのコメントに応えて、特定の値を超えないようにする方法がわからないようです.

これを行うには (たとえば、[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]にマッピングします。

お役に立てれば!

于 2011-08-23T15:52:10.007 に答える
0

アニメ化はしていないようです。ユーザーが押している方向キーに基づいて特定のフレームを設定しているようです。次のような関数が必要です。

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

フレームごとに呼び出し、最後のフレームから経過した時間を渡します。

于 2011-08-23T15:33:41.583 に答える