vec2 richtig invertieren (bounce)

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • vec2 richtig invertieren (bounce)

      Hallo zusammen,

      ich habe eine kleine Mod geschrieben und will jetzt das die Projektile abprallen können. Das funktioniert soweit auch ganz gut, bis auf eine kleine Sache und zwar die Richtung in die das Projektil fliegt. Ich mach das ganze folgendermaßen: Zuerst wird geprüft ob das Projektil aufschlägt, dann wird geprüft ob es abprallen darf, wenn ja dann wird das alte Projektil einfach entfernt (bzw. explodiert) und ein neues Projektil wird erzeugt das einfach die Daten vom alten bekommt (Owner, Type, ...). Die Startposition ist also die Endposition des alten Projektils und die Richtung (und hier leigt das Problem) entnehme ich der alten Richtung, nur leider weiß ich nicht wie ich prüfen kann ob das Projektil gegen eine Wand oder gegen Boden/Decke fliegt und daher auch nicht bestimmen kann ob ich die x oder y Koordinate der Richtung invertieren muss. Gibt es einen einfachen Weg das zu prüfen oder eine andere Möglichkeit?

      Wenn dieser Post eine Kartoffel wäre, dann wäre es eine gute Kartoffel.
      Join pLevel!
    • Am Einfachsten ist, die Bounce-Funktion des Lasers anzuschauen bzw. auf die anderen Projektile anzuwenden. (Zumal das Objekt zu zerstören und dann wieder zu generieren nicht sehr sinnvoll ist)
      Du musst wissen ob die Gerade eine Vertikale oder eine Horizontale schneidet um den Richtungsverktor über die Normale zu refelktieren. Da du vermutlich eh überpüfen musst in der Collision ob es ein Tile schneidet, sollte man eh anhand des Collisionspunktes schnell sehen können ob Horizontale oder Vertikale(Vielfache von 32 imho). (Hab mir Tw-Physic nie angeschaut aber vom Prinzip sollte es dasgleiche sein.)
      kawaii

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von BeaR ()

    • Das ist eigentlich ganz einfach^^

      Code den du brauchst mit versuchter erklärung^^

      [cpp]
      CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
      int Damage, bool Explosive, float Force, int SoundImpact, int Weapon)
      : CEntity(pGameWorld, CGameWorld::ENTTYPE_PROJECTILE)
      {
      m_Type = Type;
      m_Pos = Pos;
      m_Direction = Dir;
      m_LifeSpan = Span;
      m_Owner = Owner;
      m_Force = Force;
      m_Damage = Damage;
      m_SoundImpact = SoundImpact;
      m_Weapon = Weapon;
      m_StartTick = Server()->Tick();
      m_Explosive = Explosive;
      m_Bounce = 1;

      GameWorld()->InsertEntity(this);
      }

      void CProjectile::Tick()
      {
      float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed();
      float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
      vec2 PrevPos = GetPos(Pt);
      vec2 CurPos = GetPos(Ct);
      int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &CurPos, 0);
      CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
      CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, CurPos, 6.0f, CurPos, OwnerChar);

      m_LifeSpan--;

      if(TargetChr || Collide || m_LifeSpan < 0 || GameLayerClipped(CurPos))
      {
      if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE)
      GameServer()->CreateSound(CurPos, m_SoundImpact);


      if(m_Weapon == WEAPON_GRENADE && !m_Explosive && m_Bounce > 0 && Collide && (!OwnerChar || distance(CurPos, OwnerChar->m_Pos) > 45.0f)) //rocketjump ohne bounce
      {
      // hier wird die derzeitigePos minus die endpos gerechnet
      // das ergebnis dann mal 1.5 (f)
      vec2 Dir = (CurPos-PrevPos)*1.5f;
      // hier wird "gebouncet"
      GameServer()->Collision()->MovePoint(&PrevPos, &Dir, 1.f, 0);
      // hier wird die direction ausgerechnet
      m_Direction = normalize(Dir)*10f; //0.7f ist die elastizitäts-konstante
      // startpos = endpos
      m_Pos = PrevPos;
      // starttick
      m_StartTick = Server()->Tick();
      // sound
      GameServer()->CreateSound(CurPos, SOUND_GRENADE_FIRE);
      }
      else
      {
      if(m_Explosive)
      GameServer()->CreateExplosion(CurPos, m_Owner, m_Weapon, false);

      else if(TargetChr)
      TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon);

      GameServer()->m_World.DestroyEntity(this);
      }
      }
      }
      [/cpp]
    • Toast schrieb:

      Das ist eigentlich ganz einfach^^

      Code den du brauchst mit versuchter erklärung^^

      [cpp]
      CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
      int Damage, bool Explosive, float Force, int SoundImpact, int Weapon)
      : CEntity(pGameWorld, CGameWorld::ENTTYPE_PROJECTILE)
      {
      m_Type = Type;
      m_Pos = Pos;
      m_Direction = Dir;
      m_LifeSpan = Span;
      m_Owner = Owner;
      m_Force = Force;
      m_Damage = Damage;
      m_SoundImpact = SoundImpact;
      m_Weapon = Weapon;
      m_StartTick = Server()->Tick();
      m_Explosive = Explosive;
      m_Bounce = 1;

      GameWorld()->InsertEntity(this);
      }

      void CProjectile::Tick()
      {
      float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed();
      float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
      vec2 PrevPos = GetPos(Pt);
      vec2 CurPos = GetPos(Ct);
      int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &CurPos, 0);
      CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
      CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, CurPos, 6.0f, CurPos, OwnerChar);

      m_LifeSpan--;

      if(TargetChr || Collide || m_LifeSpan < 0 || GameLayerClipped(CurPos))
      {
      if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE)
      GameServer()->CreateSound(CurPos, m_SoundImpact);


      if(m_Weapon == WEAPON_GRENADE && !m_Explosive && m_Bounce > 0 && Collide && (!OwnerChar || distance(CurPos, OwnerChar->m_Pos) > 45.0f)) //rocketjump ohne bounce
      {
      // hier wird die derzeitigePos minus die endpos gerechnet
      // das ergebnis dann mal 1.5 (f)
      vec2 Dir = (CurPos-PrevPos)*1.5f;
      // hier wird "gebouncet"
      GameServer()->Collision()->MovePoint(&PrevPos, &Dir, 1.f, 0);
      // hier wird die direction ausgerechnet
      m_Direction = normalize(Dir)*10f; //0.7f ist die elastizitäts-konstante
      // startpos = endpos
      m_Pos = PrevPos;
      // starttick
      m_StartTick = Server()->Tick();
      // sound
      GameServer()->CreateSound(CurPos, SOUND_GRENADE_FIRE);
      }
      else
      {
      if(m_Explosive)
      GameServer()->CreateExplosion(CurPos, m_Owner, m_Weapon, false);

      else if(TargetChr)
      TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon);

      GameServer()->m_World.DestroyEntity(this);
      }
      }
      }
      [/cpp]

      Oh mein Gott was für Scheiße du laberst... Ich kotze gleich.
      Schau dir das Thema nächstes mal an bevor du hier irgendwelche Erklärungen postest.
      Um die Normale eines Richtungsvektors zu bekommen einfach eines der beiden Werte (x, y) mal -1 und die zwei vertauschen.
      Das was du da oben versucht zu erklären hast ist Collision. Und intern wird dort der Punkt schon verschoben und zwar um 2 Units gegen die Wand. Eine Unit rein und eine raus. Tada bounce via Collision.
    • BotoX schrieb:

      Um die Normale eines Richtungsvektors zu bekommen einfach eines der beiden Werte (x, y) mal -1 und die zwei vertauschen.

      Das mit dem mal -1 einer der beiden Variablen habe ich ja auch schon gehabt, aber eben nur eine und deshalb ist das Projektil immer nur an Decke/Boden oder an den Wänden abgeprallt. Und was genau meinst du mit "die Normale" und "die zwei vertauschen"? Könntest du eventuell einen kleinen Code posten?

      Wenn dieser Post eine Kartoffel wäre, dann wäre es eine gute Kartoffel.
      Join pLevel!