Diskuze: Jak na 2D animaci pohybu?

C# .NET .NET (C# a Visual Basic) Jak na 2D animaci pohybu? American English version English version

Avatar
enes.vint
Člen
Avatar
enes.vint:

Ahoj,

potykam se s problemem. Mam postavu, ktera chodi do 4 smeru (klasicky WSAD) a nasledne 3 dalsi obrazky postavy (ke kazdemu smeru), ktere by meli tvorit animaci, ja vsak za boha nevim, jak na to.

tl;dr Potrebuju pri zmacknuti klavesy pohybu rozjet animaci 3 obrazku. Jsem zacatecnik, tudiz zadne krkolomnosti prosim, radsi budu mit o par radku vice...

Predem dekuji za vase napady!

 
Odpovědět 28.4.2014 19:22
Avatar
Jiří Gracík
Redaktor
Avatar
Odpovídá na enes.vint
Jiří Gracík:

A co ti na tom přijde těžkého? Prostě jenom budeš měnit obrázky při vykreslování pořád dokola.

Nahoru Odpovědět 28.4.2014 19:27
Creating websites is awesome till you see the result in another browser ...
Avatar
Odpovídá na enes.vint
Luboš Běhounek (Satik):

Do nejake promenne si ulozis fazi animace, tu fazi budes jednou za cas (podle rychlosti animace) zvysovat a pri vykreslovani vzdy vykreslis tu cast podle faze animace.

Nahoru Odpovědět  +1 28.4.2014 19:30
:)
Avatar
enes.vint
Člen
Avatar
Odpovídá na Jiří Gracík
enes.vint:

Presne to mi prijde tezke. Nemam tuseni, jak zacit, tudiz bych opravdu ocenil aspon nejake postrceni ke spravnemu reseni.

 
Nahoru Odpovědět 28.4.2014 19:31
Avatar
Jiří Gracík
Redaktor
Avatar
Nahoru Odpovědět 28.4.2014 19:35
Creating websites is awesome till you see the result in another browser ...
Avatar
enes.vint
Člen
Avatar
Odpovídá na Jiří Gracík
enes.vint:

Mam vykresleny zakladni obrazek, tzn. stojici postavu. Potrebuji na stisk tlacitka posouvat postavu (mam) a zaroven menit obrazek.

 
Nahoru Odpovědět 28.4.2014 19:37
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na enes.vint
Ondrca:

a přes co to děláš? WF?

Nahoru Odpovědět 28.4.2014 19:39
Zase jsem o něco chytřejší
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na enes.vint
Ondrca:

Pokud to děláš přes WF, tak si zavolej na Form metodu onkeypress, zjisti která klávesa to je, to hoď do podmínky, jestli je to W A S nebo D a tam změň obrázek.

Nahoru Odpovědět 28.4.2014 19:41
Zase jsem o něco chytřejší
Avatar
enes.vint
Člen
Avatar
Odpovídá na Ondrca
enes.vint:

Prijimam titul nooba, ale netusim, co je to WF. Do okna programu vykresluju panacka, chci s nim hybat (to uz mam), akorat mu jeste potrebuji pridat animaci pohybu. Nepouzivam zadne pluginy ani frameworky.

 
Nahoru Odpovědět 28.4.2014 19:43
Avatar
Ondrca
Redaktor
Avatar
Nahoru Odpovědět 28.4.2014 19:43
Zase jsem o něco chytřejší
Avatar
enes.vint
Člen
Avatar
Odpovídá na Ondrca
enes.vint:

V tom pripade ano, pouzivam Windows Form. Rozpoznavani klaves mam na KeyDown a pohyb funguje (rozpozna WASD).Netusim, jak mam udelat animaci a jak na pohyb tou animaci navazat.

 
Nahoru Odpovědět 28.4.2014 19:48
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na enes.vint
Ondrca:

No, tak určitě máš daný nějaký posun po tom stisku wasd, tak u toho vždycky změníš obrázek.

Nahoru Odpovědět 28.4.2014 19:56
Zase jsem o něco chytřejší
Avatar
enes.vint
Člen
Avatar
Odpovídá na Ondrca
enes.vint:

To samozrejme mam, pohybuji po pixelech. Mam ale 3 obrazky pro kazdy pohyb (1. obrazek - leva noha vpred, 2. obrazek - prava noha vpred atd.) a nemuzu zmenit obrazek pri pohybu, musim zacit animaci pri zacatku pohybu.

 
Nahoru Odpovědět 28.4.2014 20:00
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na enes.vint
Ondrca:

Tak to vyřeš přes Timer, nastav mu nějaký normální čas a přitom tom to změň

Nahoru Odpovědět 28.4.2014 20:01
Zase jsem o něco chytřejší
Avatar
Jiří Gracík
Redaktor
Avatar
Odpovídá na Ondrca
Jiří Gracík:

Jednodušší by podle mého bylo jen při každém eventu přičítat nějakou proměnou a podle ní vykreslovat správný obrázek. (jak říkal Luboš Běhounek (Satik) )

Nahoru Odpovědět 28.4.2014 20:11
Creating websites is awesome till you see the result in another browser ...
Avatar
enes.vint
Člen
Avatar
Odpovídá na Ondrca
enes.vint:

Dam se do toho, diky za radu. Snad se mi to podari.

 
Nahoru Odpovědět 28.4.2014 20:11
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na Jiří Gracík
Ondrca:

Asi jo, máš pravdu, ale stejně to musí hodit celý i to přičítání do Timeru.

Nahoru Odpovědět 28.4.2014 20:13
Zase jsem o něco chytřejší
Avatar
Jiří Gracík
Redaktor
Avatar
Odpovídá na Ondrca
Jiří Gracík:

Jo to jo, předpokládal jsem, že už tam nějaký má, asi jsem to blbě řekl :)

Nahoru Odpovědět 28.4.2014 20:17
Creating websites is awesome till you see the result in another browser ...
Avatar
Ondrca
Redaktor
Avatar
Nahoru Odpovědět 28.4.2014 20:18
Zase jsem o něco chytřejší
Avatar
Odpovídá na Ondrca
Luboš Běhounek (Satik):

Edit: bylo myšleno na enes.vint

Předpokládám tedy, že máš na Formuláři PictureBox, ve kterém je panáček.

Přidej si tam Timer, vlastnost Enabled mu nastav na true, Interval třeba na 300, dvakrát na ten Timer klikni - tím se ti vytvoří událost OnTick, ve které budeš měnit fázi animace třeba následujícím kódem (musíš někde třeba u formuláře mít proměnnou typu int s názvem fazeAnimace):

fazeAnimace = fazeAnimace % pocetAnimaci;

Za pocetAnimaci si dosadíš 3, tenhle kód ti zajistí, že se ti animace bude opakovat pořád dokola.
hned za tu fázi animace si dáš kód, který bude načítat příslušný obrázek, např něco jako:

PictureBoxPanacek.Load("obrazek"+fazeAnimace+".png");

[me|]13831[/m­e|]enes.vint[me|]­13831[/me|][me|]13831[/m­e|]

Editováno 28.4.2014 20:23
Nahoru Odpovědět  +1 28.4.2014 20:22
:)
Avatar
enes.vint
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
enes.vint:

Do formulare vykresluji pomoci metody Paint. Vykreslim zakladni obrazek a pri pohybu chci zakladni obrazek nahrazovat 3 po sobe jdoucimi obrazky.

 
Nahoru Odpovědět 28.4.2014 20:24
Avatar
Odpovídá na enes.vint
Luboš Běhounek (Satik):

hoď sem ten kousek kódu, kterým to kreslíš

Nahoru Odpovědět 28.4.2014 20:33
:)
Avatar
enes.vint
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
enes.vint:
private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics gameWindow = e.Graphics;
            {
                gameWindow.DrawImage(d_1, xChar, yChar);
            }
        }

Pres toto vykreslim obrazek a pres souradnice v promennych xChar a yChar s obrazkem pohybuji.

 
Nahoru Odpovědět 28.4.2014 20:40
Avatar
Odpovídá na enes.vint
Luboš Běhounek (Satik):

jak nacitas do d1? :)

nacti si vsechny animace do vice image a pak podle te faze je vykresluj.
Pokud by jsi umel s poli nebo s Listem, mel by jsi nejlepsi nacist ty animace do pole/listu a pak pri vykreslovani vykreslit image s indexem fazeAnimace

Nahoru Odpovědět 28.4.2014 21:02
:)
Avatar
enes.vint
Člen
Avatar
enes.vint:

Vice image mam, viz kod:

// pohyb vpřed
        Image w_1 = Properties.Resources.w_stall;
        Image w_2 = Properties.Resources.w_1;
        Image w_3 = Properties.Resources.w_2;
        Image w_4 = Properties.Resources.w_finish;
        // pohyb vzad
        Image s_1 = Properties.Resources.s_stall;
        Image s_2 = Properties.Resources.s_1;
        Image s_3 = Properties.Resources.s_2;
        Image s_4 = Properties.Resources.s_finish;
        // pohyb doprava
        Image d_1 = Properties.Resources.d_stall;
        Image d_2 = Properties.Resources.d_1;
        Image d_3 = Properties.Resources.d_2;
        Image d_4 = Properties.Resources.d_finish;
        // pohyb doleva
        Image a_1 = Properties.Resources.a_stall;
        Image a_2 = Properties.Resources.a_1;
        Image a_3 = Properties.Resources.a_2;
        Image a_4 = Properties.Resources.a_finish;

S listem neumim vubec, s poli trochu. Mohl bys to prosim trochu rozvest? Napis to opravdu jak pro postizeneho, jinak to asi nepochopim. :D

 
Nahoru Odpovědět 28.4.2014 21:04
Avatar
Luboš Běhounek (Satik):

treba neco jako

List<Image> animaceW = new List<Image>();
animaceW.Add(Properties.Resources.w_1);
animaceW.Add(Properties.Resources.w_2);
animaceW.Add(Properties.Resources.w_finish);
List<Image> animaceA = new List<Image>();
animaceA.Add(Properties.Resources.a_1);
...

a pak v tom vykreslovani neco jako

gameWindow.DrawImage(animaceW[fazeAnimace], xChar, yChar);

nebo

gameWindow.DrawImage(animaceA[fazeAnimace], xChar, yChar);

apod., podle smeru, kam se diva

Nahoru Odpovědět 28.4.2014 21:31
:)
Avatar
enes.vint
Člen
Avatar
enes.vint:

Povedlo se mi dostat list do kodu, panacek se ovsem nezobrazil a pouze problikaval pri pohybu. Prikladam me reseni vykreslovani, ktere je pravdepodobne chybne:

List<Image> animationW = new List<Image>();
            animationW.Add(w_1);
            animationW.Add(w_2);
            animationW.Add(w_3);
            animationW.Add(w_4);

            List<Image> animationS = new List<Image>();
            animationS.Add(s_1);
            animationS.Add(s_2);
            animationS.Add(s_3);
            animationS.Add(s_4);

            List<Image> animationA = new List<Image>();
            animationA.Add(a_1);
            animationA.Add(a_2);
            animationA.Add(a_3);
            animationA.Add(a_4);

            List<Image> animationD = new List<Image>();
            animationD.Add(d_1);
            animationD.Add(d_2);
            animationD.Add(d_3);
            animationD.Add(d_4);

            Graphics gameWindow = e.Graphics;
            if (direction == 'n')
            {
                gameWindow.DrawImage(s_1, xChar, yChar);
            }
            if (direction == 'w')
            {
                gameWindow.DrawImage(animationA[animPhase], xChar, yChar);
            }
            if (direction == 's')
            {
                gameWindow.DrawImage(animationS[animPhase], xChar, yChar);
            }
            if (direction == 'a')
            {
                gameWindow.DrawImage(animationA[animPhase], xChar, yChar);
            }
            if (direction == 'd')
            {
                gameWindow.DrawImage(animationD[animPhase], xChar, yChar);
            }

S tim, ze po chvilce chozeni "spadne" grafika = objevi se bile preskrtnute pole.

 
Nahoru Odpovědět 28.4.2014 22:13
Avatar
Luboš Běhounek (Satik):

jaky mas ten kod v timeru?

Nahoru Odpovědět 28.4.2014 22:27
:)
Avatar
enes.vint
Člen
Avatar
enes.vint:
private void movement_Tick(object sender, EventArgs e)
        {
            if (animPhase < 4)
            {
                animPhase += 1;
            }
            else
            {
                animPhase = 0;
            }
            Refresh();
        }

Kod z timeru. Mimochodem dekuju za pomoc, tohle bych sam nevymyslel.

 
Nahoru Odpovědět 28.4.2014 22:43
Avatar
Odpovídá na enes.vint
Luboš Běhounek (Satik):

Zkus tohle:

animPhase = (animPhase + 1) % 4;

% je zbytek po deleni

Nahoru Odpovědět 28.4.2014 22:48
:)
Avatar
enes.vint
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
enes.vint:

To opravdu pomohlo, dekuju. Uz vse funguje tak, jak ma, akorat pri pohybu nahoru (sipka nahoru) a pri pohybu doprava (sipka doprava) problikava puvodni obrazek, tzn. obrazek, kterej funguje jako pozice kdyz panacek stoji (ta by se mela objevit pouze, kdyz se nedrzi klavesa pohybu a kdyz promenna direction nabyde 'n').

Graphics gameWindow = e.Graphics;
            if (direction == 'w')
            {
                gameWindow.DrawImage(animationW[animPhase], xChar, yChar);
            }
            if (direction == 's')
            {
                gameWindow.DrawImage(animationS[animPhase], xChar, yChar);
            }
            if (direction == 'a')
            {
                gameWindow.DrawImage(animationA[animPhase], xChar, yChar);
            }
            if (direction == 'd')
            {
                gameWindow.DrawImage(animationD[animPhase], xChar, yChar);
            }
            if (direction == 'n')
            {
                gameWindow.DrawImage(s_1, xChar, yChar);
            }

Nepomohlo ani to, ze jsem to trochu upravil. Taky by mohla byt chyba nekde pri zvedani klavesy, ale tam pracuju pouze s timerem... Achjo.

private void Form1_KeyUp(object sender, KeyEventArgs e)
       {
           if (e.KeyCode == Keys.Up)
           {
               movement.Stop();
               Refresh();
           }
           if (e.KeyCode == Keys.Down)
           {
               movement.Stop();
               Refresh();
           }
           if (e.KeyCode == Keys.Right)
           {
               movement.Stop();
               Refresh();
           }
           if (e.KeyCode == Keys.Left)
           {
               movement.Stop();
               Refresh();
           }

Pridavam kod, kdyby te to bilo do oci, tak me prosim upozorni.

 
Nahoru Odpovědět 28.4.2014 23:08
Avatar
Luboš Běhounek (Satik):

Tak ho nepridavej do tech listu a pak zmen to cislo za % na 3

Nahoru Odpovědět 28.4.2014 23:16
:)
Avatar
enes.vint
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
enes.vint:

V listech ten obrazek vubec neni. Jde o ten obrazek s1, ktery ma byt vykresleny pouze, kdyz se panacek nehybe.

Editováno 28.4.2014 23:26
 
Nahoru Odpovědět 28.4.2014 23:24
Avatar
Odpovídá na enes.vint
Luboš Běhounek (Satik):

tak si musis nejak zjistovat, jestli se prave hybe - treba v keydown si to ulozit do nejake bool promenne

a v keyup si nastavit, ze se uz nehybe

a pak vykreslovat jen jedno nebo druhe.

Nahoru Odpovědět 28.4.2014 23:37
:)
Avatar
enes.vint
Člen
Avatar
enes.vint:

Pro dnesek to balim, pujdu se na to vyspat a zitra zkusim to s tim booleanem, taky me to napadlo. Fakt si vazim vasi pomoci a dekuju vam.

 
Nahoru Odpovědět 28.4.2014 23:47
Avatar
enes.vint
Člen
Avatar
enes.vint:

Takze noob reporting in!

Podarilo se mi vyresit predchozi problem s problikavajicim obrazkem. Nahradil jsem podminku switchem (viz kod) a vse funguje tak, jak ma.

switch (e.KeyCode)
            {
                case Keys.Up:
                yChar -= 2;
                movement.Start();
                direction = 'w';
                Refresh();
                break;

                case Keys.Down:
                yChar += 2;
                movement.Start();
                direction = 's';
                Refresh();
                break;

                case Keys.Right:
                xChar += 2;
                movement.Start();
                direction = 'd';
                Refresh();
                break;

                case Keys.Left:
                xChar -= 2;
                movement.Start();
                direction = 'a';
                Refresh();
                break;
            }
  • jsem pridal zmenu obrazku na keyUp, takze postava se diva na hrace (tak, jak to melo byt), kdyz prestaneme chodit.
if (e.KeyCode == Keys.Up)
            {
                movement.Stop();
                direction = 'n';
                Refresh();
            }
            if (e.KeyCode == Keys.Down)
            {
                movement.Stop();
                direction = 'n';
                Refresh();
            }
            if (e.KeyCode == Keys.Right)
            {
                movement.Stop();
                direction = 'n';
                Refresh();
            }
            if (e.KeyCode == Keys.Left)
            {
                movement.Stop();
                direction = 'n';
                Refresh();

Problem je tedy vyresen. Dekuji vam za ochotnou pomoc, opravdu si ji vazim a snad budu priste moct poradit nekomu ja. Diky!

 
Nahoru Odpovědět  +1 29.4.2014 18:04
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 36 zpráv z 36.