IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: C# Rychlý output / ASCII art / nápad na hru

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Tomas
Člen
Avatar
Tomas:20.1.2017 18:39

Zdravím :-) ,
jsem studentem SŠ a máme zde tzn. Ročníkové práce. Tuto ročníkovou práci musíme naprogramovat v jazyce C# + se musí jednat pouze o konzolovou aplikaci.

Pravděpodobně bych chtěl vytvořit nějakou propracovanější "arkádu".

Ovšem problém bude asi jak měnit output na dané obrazovce. Protože si myslím, že pouze Console.Write nevystačí a output bude strašně pomalý. Pravděpodobně to chce hodit do nějakého bufferu a potom to nějak vypsat (mimo mojí hranici zkušeností). Tudíž jak udělat nejlepší výpis na obrazovku pro pohyb / animaci z "ASCII"?

Možná existuje něco na způsob "enginu", který by dokázal takhle znaky vypisovat např. podle obrázku.

Poslední menší problém je asi nápad - hry typu snake, tetris apod. jsem již dělal. Přemýšlel o hrách jako např. pacman nebo nějaký space shooter. Ale jak říkám, limituje mě zde velmi konzole. Kdyby jste o něčem věděli, tak se podělte.

Děkuji moc za odpověď
(doufám, že to není nějak off topic)

 
Odpovědět
20.1.2017 18:39
Avatar
Petr Šťastný
Tvůrce
Avatar
Odpovídá na Tomas
Petr Šťastný:20.1.2017 20:22

Když já potřebuji udělat něco podobného, nepřekresluji všechno, ale překreslím jenom změněný znak.

Console.SetCursorPosition(x, y);

Příklad:

A B C
D E F
G H I

// Potřebuji překreslit E na @
Console.SetCursorPosition(2, 1);
Console.Write("@");

Zatím jsem nepřišel na lepší způsob, jak něco podobného vyřešit, takže snad ti to pomůže.

// EDIT:
Kdybys nevěděl co udělat, tak já momentálně pracuji na takovém RPG dungeonu. Vygeneruji mapu a nechám hrdinu procházet se po mapě a zabíjet příšery. Nic moc složitého a technika, kterou jsem popsal výše, na to úplně stačí.

Editováno 20.1.2017 20:23
 
Nahoru Odpovědět
20.1.2017 20:22
Avatar
Tomas
Člen
Avatar
Odpovídá na Petr Šťastný
Tomas:20.1.2017 20:28

Díky :) Ale pokud bych měl dejme tomu konzoli ve full screenu a hru ve které se hýbe hodně objektů, tak bude výstup stejně strašně pomalý.

Chtěl jsem zkusit štěstí, jestli náhodou nemá někdo zkušenosti s výstupem pomocí nějakého bufferu.
Samozřejmě jsem googlil, ale nikde jsem nenarazil na plně funkční řešení.

 
Nahoru Odpovědět
20.1.2017 20:28
Avatar
Odpovídá na Tomas
Jiří Hlaváček:21.1.2017 0:03

To řešení co naznačuje Petr je myslím vhodné pro to co se snažíš zrealizovat. Pokud jen přepisuješ jednotlivé znaky v konzoli a nepoužiješ refresh (Console.Clear()), tak ta rychlost je celkem slušná. Viz následující experiment.

class Program
    {
        static Random r = new Random();
        static int[,] body = new int[50,2];

        static void Main(string[] args)
        {
            Console.CursorVisible = false;
            System.Timers.Timer t = new System.Timers.Timer(30);
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_elapse);
            t.Start();
            Console.ReadLine();
        }

        private static void t_elapse(object sender, ElapsedEventArgs e)
        {
            for (int i = 0; i < 50; i++)
            {
                Console.SetCursorPosition(body[i, 0], body[i, 1]);
                Console.Write(" ");
            }

            for (int i = 0; i < 50; i++) {
                body[i, 0] = r.Next(0, 40);
                body[i, 1] = r.Next(0, 20);
                Console.SetCursorPosition(body[i, 0], body[i, 1]);
                Console.Write("*");
            }
        }
    }
 
Nahoru Odpovědět
21.1.2017 0:03
Avatar
Tomas
Člen
Avatar
Odpovídá na Jiří Hlaváček
Tomas:21.1.2017 0:56

Musím říct, že jsi mě překvapil a dokonce i trošku přesvědčil. Na té tvé velikosti obrazovky / vykreslujícího pole je to ideální. Ale stále si nejsem jist, jestli by to nemělo vliv na hratelnost = Pokud plánuji mít danou konzoli ve full screenu, tak přepsání celé konzole trvá asi 0,7s. Samozřejmě bych nepřepisoval celou konzoli, ale pokud bych měl nějaké pozadí ze znaků + nějaké ty pohybující se objekty tak se na nějakou znatelnou hodnotu dostanu.

(Zítra, vlastně dnes :-D, zkusím něco napsat a uvidím)

Díky :-)

 
Nahoru Odpovědět
21.1.2017 0:56
Avatar
Odpovídá na Tomas
Neaktivní uživatel:21.1.2017 8:49

Při hře Pacman se ti přece pohybuje dost málo objektů (pacman + 4 duchové). Tam nebude problém s rychlostí

Nahoru Odpovědět
21.1.2017 8:49
Neaktivní uživatelský účet
Avatar
Odpovídá na Tomas
Luboš Běhounek Satik:21.1.2017 9:46

Konzole se dá překreslit mnohem rychlejc, mě to tu zvládá několiksetkrát za sekundu:

https://drive.google.com/…ZUctOGs/view?…

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
21.1.2017 9:46
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Tomas
Jiří Hlaváček:21.1.2017 9:55

Jde o to nepřepisovat celou stránku, ale jen ty znaky, u kterých dochází k aktivní změně a je pravda, jak píše Lukáš, že u většiny her tohoto typu nepotřebuješ pohybovat stovkami objektů. Zkusil jsem to trochu pozměnit a dal jsem tam 100 měnících se pozic a měření času přepisu a pohybuje se to na úrovni 5-15ms a to mi přijde na konzoli celkem rychlé:

class Program
    {
        static Random r = new Random();
        static int[,] body = new int[100,2];

        static void Main(string[] args)
        {

            Console.CursorVisible = false;
            System.Timers.Timer t = new System.Timers.Timer(30);
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_elapse);
            t.Start();
            Console.ReadLine();
        }

        private static void t_elapse(object sender, ElapsedEventArgs e)
        {
            int c = Environment.TickCount;
            for (int i = 0; i < 100; i++)
            {
                Console.SetCursorPosition(body[i, 0], body[i, 1]);
                Console.Write(" ");
            }

            for (int i = 0; i < 100; i++) {
                body[i, 0] = r.Next(0, 50);
                body[i, 1] = r.Next(0, 30);
                Console.SetCursorPosition(body[i, 0], body[i, 1]);
                Console.Write("*");
            }
            c = Environment.TickCount - c;
            Console.SetCursorPosition(2, 32);
            Console.Write(c);
        }
    }
 
Nahoru Odpovědět
21.1.2017 9:55
Avatar
Tomas
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Tomas:21.1.2017 13:52

Satik: Něco takového jsem hledal, díky :)

Lukas, Jiří: Pacman byl na to vykreslování špatný příklad, ale do nějakého toho "space shooteru" se to určitě hodí.
Ale máš pravdu, že pro většinu her by tato metoda stačila.

Díky všem za čas a rady

:-)
 
Nahoru Odpovědět
21.1.2017 13:52
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 9 zpráv z 9.