【问题标题】:Sprite doesn't want to cooperate雪碧不想合作
【发布时间】:2018-05-22 17:58:11
【问题描述】:

我正在用 C++ SFML 制作一个项目。下面你可以看到动画“引擎”代码的一小段。这是我的问题:在运动功能中,根据按下的键,方向变量“dir”会发生变化。然后,在 int main() 中,aniamte_char 函数将一个 sprite 作为其参数之一,在本例中,是“ch[]” sprite 数组的一个元素,其 id 为“e.dir”。现在发生了什么 “e.dir=0”工作正常,动画播放正常,但“e.dir=1,2,3,4”没有显示。我试着摆弄来解决这个问题,但似乎没有任何效果,我一无所知;/如果有人知道为什么会这样,请帮忙。

int_main()

#include <SFML/Graphics.hpp>
#include <iostream>
#include <conio.h>
#include <windows.h>

#include "InfiPower.h"

#define WIDTH 1200
#define HEIGHT 800
#define FRQ 10

using namespace std;
using namespace sf;

int main()
{
    RenderWindow win(VideoMode(WIDTH,HEIGHT),"takie cos lol");
    win.setFramerateLimit(60);

    InfiPower e(WIDTH/2-25,HEIGHT/2-25,true,0,0,-1);

    Texture bg_[1];
    bg_[0].loadFromFile("Textures/bg.png");

    Texture ch_[5];
    ch_[0].loadFromFile("Textures/char_idle.png");
    ch_[1].loadFromFile("Textures/char_right.png");
    ch_[2].loadFromFile("Textures/char_up.png");
    ch_[3].loadFromFile("Textures/char_left.png");
    ch_[4].loadFromFile("Textures/char_down.png");
    Sprite ch[5];
    ch[0].setTexture(ch_[0]);
    ch[1].setTexture(ch_[1]);
    ch[2].setTexture(ch_[2]);
    ch[3].setTexture(ch_[3]);
    ch[4].setTexture(ch_[4]);

    e.cur_bg=0;

    while(win.isOpen())
    {
        win.clear();

        e.movement(10,10000,WIDTH);
        e.set_background(win,bg_);
        cout<<e.dir<<endl;
        e.animate_char(win,ch[e.dir],100,FRQ);

        if(Keyboard::isKeyPressed(Keyboard::Escape))
        {
            exit(0);
        }

        win.display();
    }
}

我的动画“引擎”片段:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <conio.h>
#include <windows.h>
#include "InfiPower.h"

using namespace std;
using namespace sf;

void InfiPower::animate_char(RenderWindow & win,Sprite & s,int cell_width,int caf)
{
    s.setPosition(c_xo,c_yo);
    s.setTextureRect(IntRect(state*cell_width,dir*cell_width,cell_width,cell_width));

    if(anim_c==caf)
    {
        state++;
        anim_c=0;
    }
    if(state>=4)
    {
        state=0;
    }

    win.draw(s);
    anim_c++;
}
void InfiPower::movement(int ms,int b,int w)
{
    if(Keyboard::isKeyPressed(Keyboard::D))
    {
        if(bg_x>=((b-w)*(-1)+ms))
        {
            in_motion=true;
            bg_x=bg_x-ms;
        }
        last_dir=1;
        dir=1;
    }
    else if(Keyboard::isKeyPressed(Keyboard::A))
    {
        if(bg_x+ms<=0)
        {
            in_motion=true;
            bg_x=bg_x+ms;
        }
        last_dir=3;
        dir=3;
    }
    else if(Keyboard::isKeyPressed(Keyboard::S))
    {
        if(if_4_dirs==true)
        {
            //if(bg_y-ms>=800)
            //{
                in_motion=true;
                bg_y-=ms;
            //}
            last_dir=4;
            dir=4;
        }
    }
    else if(Keyboard::isKeyPressed(Keyboard::W))
    {
        if(if_4_dirs==true)
        {
            //if(bg_y+ms<=0)
            //{
                in_motion=true;
                bg_y+=ms;
            //}
            last_dir=2;
            dir=2;
        }
    }
    else
    {
        in_motion=false;
        dir=0;
    }
}
void InfiPower::set_background(RenderWindow & win,Texture bg_[])
{
    Sprite bg;
    bg.setPosition(bg_x,bg_y);

    for(int i=0; i>=(-1); i++)
    {
        if(i==cur_bg)
        {
            bg.setTexture(bg_[i]);
            win.draw(bg);
            break;
        }
    }
}

【问题讨论】:

  • 编辑您的问题以包含minimal reproducible example
  • 我不知道如何以更简单的方式解释这个问题,所以我决定提供一点背景知识。反正我做了一些小改动。
  • 弹出一个或两个调试器断点,并逐步执行适当的函数,寻找当 e.dir 不为 0 时它会做什么。
  • 所以发生的情况是,精灵被发送到函数,但在函数中发生了一些事情,导致它无法正确显示。我知道它已正确发送,因为我将其设置为在没有选择 spritesheet 区域的情况下进行绘制。所以它必须与函数中的代码有关。但是什么?在早期的项目中,这个功能没有问题。

标签: c++ sprite sfml


【解决方案1】:

我的猜测是这条线将您的 Y 坐标源矩形设置为下一行。对于 dir=0,这是最上面的一行,可以正常工作:

s.setTextureRect(IntRect(state*cell_width,dir*cell_width,cell_width,cell_width));

如果只有一行,那么应该是:

s.setTextureRect(IntRect(state*cell_width,0,cell_width,cell_width));

我想说点什么,我并不是要刻薄或不尊重他人,但我认为您应该放慢脚步,在继续之前学习更多编码。在当前的项目中,你已经咬得比你能咀嚼的还多。 (基于这个问题和以前的问题)

我担心的是你正在做很多“坏”的事情,这些事情会让你慢下来,直到你学会解决它们。例如。 for(int i=0; i&gt;=(-1); i++) 表示 while(true) until integer overflow。仅仅因为代码“有效”并不意味着它就是您要说的。语义在编程中很重要。

如上所述,您应该学习如何使用调试器并逐步执行代码。这是一项非常基础的技能。

我建议参加编程课程,阅读几本书,研究其他人的代码等......

我还强烈建议通过使用商业引擎来学习游戏引擎编程,并了解他们是如何做到这一点的。这是一种自上而下的方法,可让您在处理低级内容之前学习更抽象的概念。我推荐 Unity 之类的东西。

【讨论】:

  • 非常感谢您的帮助,我完全忽略了这一点。现在问题是我过去用这个引擎做过很多项目。当我年轻得多且编程教育较​​少时,我就制作了这个引擎。因此,您指出的所有小事。我在早期的项目中使用了这个“引擎”,我忘记更改一些东西,比如你幸运地找到的那件事。但无论如何,我非常感谢你的 halp 和编程技巧:D
  • 干杯!编码快乐!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多