Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

Diskuze: XNA - fyzikální model

C# .NET .NET (C# a Visual Basic) XNA - fyzikální model American English version English version

Aktivity (1)
Avatar
matesax
Redaktor
Avatar
matesax:14.10.2012 11:03

Dobrý den,
kamarád mne poprosil o vytvoření fyzikálního modelu pohybu. Jedná se o jednoduchou vesmírnou hru. Ovládáte loď ve formě písmene A a to - UP/DOWN = pohyb - chcete-li plyn, LEFT/RIGHT = točení. Pokud není plyn, loď by měla zachovávat původní směr (i při točení) a rychlost pomalu uvadat. No a při otáčení a plynu dohoromady by neměla ihned zatáčet - ale chovat se podle fyziky - tedy měla by se pohybovat podle výslednice sil - původního směru a směru nového. A to se mi právě nedaří. Vytvořil jsem si na to proměnné - stará rychlost, nová rychlost, starý směr a nový směr:

using System;
using Microsoft.Xna.Framework;

namespace Cunteka
{
    public class Monster
    {
        public float oldDirection = 90, actualDirection = 90, actualSpeed = 0, oldSpeed = 0, x = 40, y = 40;
        public bool who = true;

        public void Move()
        {
            double
                oldX = Math.Sin(oldDirection) * oldSpeed,
                oldY = Math.Cos(oldDirection) * oldSpeed,
                actualX = Math.Sin(actualDirection) * actualSpeed,
                actualY = Math.Cos(actualDirection) * actualSpeed;

            Vector2 position = new Vector2(x + (float)((who ? -1 : 1) * oldX), y + (float)((who ? 1 : -1) * oldY)) - new Vector2(x + (float)((who ? -1 : 1) * actualX), y + (float)((who ? 1 : -1) * actualY));

            oldDirection = (float)Math.Atan2(position.Y, position.X);
            oldSpeed = position.Length();
            x += position.X;
            y += position.Y;
        }
    }
}

Ovládání:

bool up = false;

if ((up = Keyboard.GetState().IsKeyDown(Keys.Up)) || Keyboard.GetState().IsKeyDown(Keys.Down))
{
    if (monster.actualSpeed < 3)
        monster.actualSpeed += 0.01F;

    monster.who = up;
    monster.Move();
}
else
{
    if (monster.actualSpeed > 0)
        monster.actualSpeed -= 0.05F;

    monster.oldSpeed = 0;
    monster.Move();
}

bool left = false;

if ((left = Keyboard.GetState().IsKeyDown(Keys.Left)) || Keyboard.GetState().IsKeyDown(Keys.Right))
    monster.actualDirection += left ? -0.08F : 0.08F;

První problém - když nastavuji starou rychlost:

oldSpeed = position.Length();

Loď se pohybuje šejdrem - když jsem zkusil dát ji na aktuální rychlost, tak se navíc ještě divně klepe... :) Když ji nechám na nule, vše šlape suprově. Jenže loď se otáčí ihned - ne podle výslednice - co mám špatně? Děkuji.

Editováno 14.10.2012 11:05
 
Odpovědět 14.10.2012 11:03
Avatar
matesax
Redaktor
Avatar
Odpovídá na matesax
matesax:14.10.2012 11:40

Teď si uvědomuji, že se mi to takto bude stejně otáčet skoro ihned - chtělo by to jít na to jinak. Před tím jsem dopočítával do nové hodnoty - mělo to 2 problémy - točil-li jsem se dokola, zpožděně to muselo ještě pár kol opsat - i po ukončení tohoto výkonu a zadruhé - nepohybovalo se to plynule...

 
Nahoru Odpovědět 14.10.2012 11:40
Avatar
Kit
Redaktor
Avatar
Odpovídá na matesax
Kit:14.10.2012 11:44

Pracuj nejen se souřadnicemi, ale i s rychlostí a zrychlením jako s vektory. Výpočty budou mnohem jednodušší.

Nahoru Odpovědět 14.10.2012 11:44
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Redaktor
Avatar
Odpovídá na Kit
matesax:14.10.2012 11:48

Jak píši, stejně by toto vedlo do pekel. (Celé otočení bych si akorát rozdrobil do více úseků - ale otáčelo by se to téměř ihned.) Něchtělo se mi bastlit to dopočítávání, ale než dělat list fyzikálních sil a prohánět je cykly, to raději dobastlím to dopočítávání... :)

 
Nahoru Odpovědět 14.10.2012 11:48
Avatar
Kit
Redaktor
Avatar
Odpovídá na matesax
Kit:14.10.2012 12:06

Protože spojuješ otáčení se zrychlením. Natočení lodi ber jako jednotkový vektor, kterým násobíš skalár zrychlení (tah motoru). Tím získáš vektor zrychlení. A pak už jen

speed+=zrychleni
position+=speed

S komplexními čísly by se to dělalo mnohem lépe a přehledněji, ale nemohl bys to dělat ve 3D.

Nahoru Odpovědět 14.10.2012 12:06
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.