【问题标题】:How to change screen if you're moving forward and see older things if you move backwards?如果你向前移动,如何改变屏幕,如果你向后移动,如何看到旧的东西?
【发布时间】:2019-09-13 13:00:25
【问题描述】:

我正在开发一个游戏项目,但我遇到了一个问题。所以我有一个游戏对象,如果向右移动然后再次进入左边的屏幕(吃豆人效果)有一个新屏幕,我的意思是屏幕是一样的,但应该有新的其他对象,但是如果游戏对象返回,我应该能够在屏幕上看到旧版本的对象。所以我有一个行星列表。我创建了它们,如果向前移动,我想“打印”列表的第一个元素,如果我向后移动,我想看到前一个元素。我确实想过尝试使用循环版本,但我决定我不会那样做。 https://imgur.com/a/vCjk9iW

class planet {
//an shape planet has these charateristics
sf::CircleShape shape;
 //etc
 };

struct nodeplanet 
{
planet Planet;
nodeplanet *planet;
}

typedef nodeplanet *ptr_listplanet;

//here I make a list with planet

 class listofplanets
{
private:
ptr_listplanet head;
public:
listofplanets()
{
head = NULL;
}
ptr_listofplanets create ()
//etc;
};

//then i create a system of planets;

   struct nodeSystem 
  {
 listofplanets ListOfPlanets;
  nodeSystem*next;
  nodeSystem *prev;
  }
  ptr_listSystem GenerateNode()
{
    ptr_listSystem tmp;
    tmp = new nodeSystem;
    tmp->ListOfPlanets = ListOfPlanets();
    tmp->ListOfPlanets.create(randomnumber());
    tmp->prev = NULL;
    tmp->next = NULL;
    return tmp;
}
ptr_listSystem GenerateSystem ()
{

  for (int i=0; i<3; i=i+1){ //just a trial, creating three systems
        ptr_listSistema newNode = GenerateNode();
        newNode->prev = NULL;
        newNode->next = head;
       if (head!=NULL)
        head->prev = newNode;
        head = newNode;
    }
    return this->head;
}
void Visualize(sf::RenderWindow &window, Player player)
{ 
    ptr_listSistema current = this->head;

        float x;
        //while (current!=NULL){
                x = player.shape.getPosition().x;
       current->ListOfPlanet.draw(window);
       //if ((player.shape.getPosition().x > 1269))
       if (x>1269)
      {
          //current = GenerateSystem();
          current = current->next;


            window.clear();
            current->ListaPianeta.draw(window);

      }
       //if ((player.shape.getPosition().x< 3) && (Keyboard::isKeyPressed(Keyboard::Left))) 
      {
          if ((x<3) && (Keyboard::isKeyPressed(Keyboard::Left)))
          //p = current->prev;
          current = current->prev;
          if (current == NULL)
          {
              current = current->next; //in the case I am in the "head" screen, I should see the head screen; 
          }

          window.clear();
          current->ListOfPlanet.draw(window); 
      }

       // }
}

可视化功能是列表的经典打印功能。至少我认为,列表已经生成,如果玩家向前移动我应该能够看到下一个节点中生成的行星,如果玩家向后移动我应该能够看到前一个节点。我尝试使用循环,使用while,但这不是我应该继续“打印”,这取决于。 (不知道我的想法在逻辑上是否正确)

【问题讨论】:

    标签: c++ sfml


    【解决方案1】:

    认为您可以大大简化一切。只需在实际位置绘制所有内容。然后使用sf::View 表示当前可见屏幕并相应地移动它:

    // setup done only once, we'll reposition it later
    sf::View screen(sf::Vector2(0,0), sf::Vector2(screen_width, screen_height));
    
    // before drawing
    screen.setCenter((std::floor(player.shape.getPosition().x / screen_width) + 0.5f) * screen_width, screen_height / 2);
    window.setView(screen);
    

    这基本上是计算屏幕的预期左边框位置(通过除法、舍入,然后乘以屏幕宽度)并使用屏幕中心的偏移量(+ 0.5f)进行调整。

    显然,您也可以复制 X 坐标的代码并将其重新用于 Y,也允许向上/向下转换:

    screen.setCenter((std::floor(player.shape.getPosition().x / screen_width) + 0.5f) * screen_width, (std::floor(player.shape.getPosition().y / screen_height) + 0.5f) * screen_height);
    

    【讨论】:

    • 感谢您的评论;现在屏幕和窗口一样吗?所以在功能视图中,我还应该添加行星系统的“打印”功能; while (current!=NULL) { current->ListOfPlanets.draw(window);当前=当前->下一个; }
    • @throwawayinvisible 有了这个想法,您只需绘制所有内容,即使它在屏幕外(尽管这可以优化)。 sf::View 确定您的“世界”的哪一部分在屏幕上实际可见。其他库和引擎可能将其称为相机。
    • 这个想法是,如果玩家向前移动,则会出现一个“新世界”,如果向后移动,则会显示前一个世界。所以我的想法是让链表的每个节点都有一个“世界”,根据玩家的移动,我可以前进,所以我有新的世界,如果我回去,旧的世界。根据我对视图功能的了解,它似乎是一个相机,我不确定这是否是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多