Čau všem, určitě spousta z Vás zná hru elastomania. Zajímalo by mě, jak by se taková hra dala naprogramovat, nebo spíš co člověk potřebuje umět, aby takovou hru naprogramoval? Budu rád i za nějaký link, protože jsem nic moc o programování fyziky nenašel.
Fórum › Pascal
Elma
no dobře to znám. takhle, umím v pascalu "naprogramovat" míček (circle), který se odráží od stěn například. a teď hodně zjednodušená elastomania, chci naprogramovat dvě kolečka (nemusí se ani otáčet) spojená nějakou třeba bezhmotnou pevnou tyčí, aby se reálně odrážely od stěn. jak na to?
udelas si objekt z dalsich objektu... treba kolecko, tyc.. pak musis mit nejakej zpusob jak zjistit jestli je treba jeden bod v kolizi, jestli je usecka v kolizi a tak
mozna by stacila ta usecka... a pak jestli se treba nedotykaj dva objekty (ne v ramci jednoho)
aby si zavolal treba kolize( objekt, bod/usecka/objekt ) a ono ti to zkontrolovalo vsechny podobjekty
pak natoceni bude trochu horsi... to se delava pomoci transformacnich matic ale nic ti nebrani to zkusit sam... tam pujde asi hlavne o teziste a tak...
Na Elastomanii potřebuješ zhruba tohle:
1) Definovat prostředí pomocí orientovaných úseček (každá má na jedné straně "venku" a na druhé "uvnitř" - zkus googlit heslo "BSP strom" nebo tak něco).
2) Umět detekovat kolizi kružnice s orientovanou úsečkou (kola vs. objekty na mapě). Zapátrej na síti nebo v nějaké učebnici matematiky, zpaměti tyhle vzorce neznám.
3) Umět detekovat kolizi bodu s orientovanou úsečkou (hlava jezdce vs. objekty na mapě).
4) Motorku zredukovat do hmotného bodu s určitým momentem setrvačnosti.
5) K tomu bodu pružně připojit kola (vztah pro lineární pružinu zobecněný do roviny) a napevno hlavu.
6) Napsat si otáčecí algoritmus (viz např. http://int21h.ic.cz/?id=53).
7) Přes Newtonovy zákony (a=F/m, akce a reakce) napsat algoritmus na pohon zadním kolem a brždění.
8) Složit z toho engine, tj. pohyb, otáčení a gravitaci v diskrétním čase.
Plus ještě pár prkotin typu grafika atd..
Je to velice zajímavá aplikace a dá se na tom hodně naučit. Jestli chceš, zkusím taky po něčem zapátrat - docela mě to zajímá :smile2:
Moje stránka.
To Mircosoft : díky moc za odpověď! programovat se teprve učím, takže BSP stromy a složitější grafiku vynechám (jelikož taky umím jen v pascalu :)) takže zkusím začít s hodně redukovanou "elmou" jak jsem psal jen např. dvě kola bez pružin spojená tyčí, která se odráží od "stěn" obrazovky. začnu si s tím hrát :) to, že tě to také zajímá je super, aspoň nejsem sám :)
To Petr : ale jestli se teprve ucis tak zkus neco jednodussiho nez zrovna hra... vsichni co zacinaj programovat zasadne chtej hnedka moc tezky veci a pak na tom ztroskotaj... obzvlaste hry... tam uz to chce i umelou inteligenci a analytickou geometrii a takovejch veci co se i programujou ne zrovna trivialne...
To KIIV : jasně, já si uvědomuju, že naprogramovat např. kompletní elmu s levely, atd.. je obtížný, aby to bylo hratelný. co mě spíš na elmě zaujalo je to, že ačkoliv je to dost jednoduchá 2D hra, tak je velice hratelná právě kvůli skvěle reálné fyzice. pružiny, brždění atd... takže spíš mě zajímá jak naprogramovat fyzikálně reálné chování objektů a praávě proto chci začít s tím, třeba jen s těmi dvěma koly bez pružin, pak jen třeba objekt na pružině atd. prostě naučit se podstatu částí k elmě potřebných, které vypsal mircosoft a pak až někdy se pokusit vše dát dohromady a zkusit z toho poskládat hru, a to asi ne v pascalu :)
udělal jsem jen první krůček s procedurami na otaceni a posun tech dvou kolecek, ale nevim, proc se pri kazdem otoceni ta tyc o trochu zkrati.. je to kvuli zaokrouhlovani?
program elma;
uses math, crt, graph;
const rad=5;
pol=20;
motox=200;
motoy=100;
type
vektor = record
x,y: integer;
end;
var
Gd, Min, Max, i: integer;
moto, tyc: vektor;
procedure inic_kola;
begin
tyc.x:=pol;
tyc.y:=0;
end;
procedure inic_moto;
begin
moto.x:= motox;
moto.y:= motoy;
end;
procedure otoc(alpha: real);
begin
tyc.x:=round(cos(alpha)*tyc.x - sin(alpha)*tyc.y);
tyc.y:=round(sin(alpha)*tyc.x + cos(alpha)*tyc.y);
end;
procedure posun(x,y: integer);
begin
moto.x:=moto.x+x;
moto.y:=moto.y+x;
end;
procedure vykresli;
var px,py,zx,zy: integer;
begin
px:=moto.x+tyc.x;
py:=moto.y+tyc.y;
zx:=moto.x-tyc.x;
zy:=moto.y-tyc.y;
line(px,py,zx,zy);
circle(px,py,rad);
circle(zx,zy,rad);
end;
begin
Gd:=9;
GetModeRange(Gd, Min, Max);
SetGraphMode(Max);
InitGraph(Gd, Min,'');
inic_moto;
inic_kola;
vykresli;
repeat
otoc(pi/18);
vykresli;
delay(500);
until keypressed;
end.
To Petr : Přesně tak, zkracuje se ti kvůli zaokrouhlování. Souřadnice musíš ukládat reálné a zaokrouhlovat je jenom při kreslení na obrazovku.
P.S.: Objektově to psát určitě nemusíš. V případě jedné motorky to tak imho bude i jednodušší.
Moje stránka.
To Mircosoft : tak jsem to změnil, ale zkracuje se mi to, i když to zaokrouhluju jen při vykreslování... doplnil jsem to kontrolou, jestli se délka zkrátila a v případě že jo, tak to souřadnice podle toho zdelší...
Moment, jak to zaokrouhluješ? Myslel jsem to takhle:
line(round(px),round(py),round(zx),round(zy));
čili souřadnice zůstávají pořád nezaokrouhlené, zaokrouhlují se jenom jejich kopie, co předáváš jako parametry kreslicím procedurám.Moje stránka.
To Mircosoft : ano, i když to zaokrouhlím jen při předání kreslícím procedurám, stejně se to zkracuje
Tak jsem udělal pomocí vektorů a kružnic opravdu mega-jednoduchou reprezentaci motorky a mam zatim jen procedury na pohyb tyhle hybridni "motorky". bude potřeba posunovat celou motorku (proc posun), otacet celou (proc otoc_moto) a otacet s kolem, ktery motorku pohani (otoc_kolo). pro otestování těchto procedur jsem udělal ještě funkci na mačkání kláves. šipkami nahoru a dolu se zrychluje kolo, doleva doprava se zrychluje otaceni cele motorky a klavesami a,s,d,w se motorkou da hybat... kdyz ale chci takto klavesami menit to, co se meni v okne graph, musim mit aktivni okno s programem a okno graph je samostatne, v pripade hry pak tedy budu muset udelat neustale prepinani mezi maximalizovanym graph oknem a "programem"
jinak co na to rikate? ty draty uprostred kola jsou pri zrychlovani a zpomalovani stale mene kolme, ale to zase bude nejake zaokrouhlovani nebo nevim :) ted je na rade fyzika...
Nechápu, co myslíš těmi okny (okno s programem, okno s grafikou a tak). Program normálně jede na celé obrazovce v grafickém režimu; jestli ne, tak je něco špatně (alt+enter jsi zkoušel?). Píšeš to v TP nebo v čem? Jestli v TP a máš dva monitory, tak na jednom máš vývojové prostředí (editor zdrojáku), a na druhém ti běží program se vším všudy, ale o klávesnici by se hádat neměly, ne?
Moje stránka.
To Mircosoft : Mám Freepascal. Příkazem Initgraph se otevře okno s názvem graph window application kde se mi vykresluje ta motorka. Ale zvlášť je okno Freepascalu, kde je textový režim, kde se mi vypisujou věci jako třeba po příkazu writeln atd... no a tohle okno musím mít aktivní, abych mohl Readkeyem načíst nějaké klávesy a aby se třeba mohla změnit úhlová rychlost kola, změna se mi vykreslí ale do toho okna graph window application. Když tohle okno není přes celou obrazovku, tak to není třeba takový problém, ale když je, tak to Freepascalský okno není aktivní... Omlouvám se za laické vysvětlení, co se týče počítačového pozadí jsem celkem lama...
Musíš nastavit pod záložkou "Compile" je napsáno "Destination memory", musíš klepnutím nastavit "Destination disk". Nicméně, jede to přesně tak, jak říkáš.
To Petr : Jj, že ve Freepascalu je to jako externí okno, zatímco v TP to funguje.
-> Petr: Zbastlil jsem něco, co by se ti mohlo hodit: detekce, na které straně dané orientované úsečky se daný bod nachází:
function JeVpravoOd(xb,yb,x1,y1,x2,y2:integer):boolean;
var a,b,c:real;
Begin
if x1=x2 then jevpravood:=(xb-x1)*(sgn(y1-y2))>0 {svisla usecka}
else if y1=y2 then jevpravood:=(yb-y1)*(sgn(x2-x1))>0 {vodorovna usecka}
else begin {obecna usecka}
a:=1/(x2-x1);
b:=1/(y1-y2);
c:=y1*(-b)-x1*a;
jevpravood:=(a*xb+b*yb+c)*sgn((longint(x2)-x1)*(longint(y2)-y1))<0;
end;
End;
Funkce vrací true, pokud je bod [xb,yb] napravo od orientované úsečky z bodu [x1,y1] do bodu [x2,y2], nebo false, pokud je nalevo. Platí pro souřadnicové systémy, kde x přibývá doprava a y dolů (tj. např. obrazovka). Určitě by ještě šla optimalizovat pro rychlost (přepsat do celých čísel a podobně).
Ještě ta funkce Sgn:
function sgn(x:integer):shortint;
Begin
if x<0 then sgn:=-1
else if x>0 then sgn:=1
else sgn:=0;
End;
Vrací znaménko daného čísla.
V Elastomanii byly všechny zdi tvořené mnohoúhelníky, skrz které motorka neprošla. Výše uvedená funkce se pro detekci kolize s mnohoúhelníkem dá použít, stačí zjistit, jestli je motorka vpravo od všech stran daného mnohoúhelníku (když ho bereš po směru hodinových ručiček). Funguje to jenom na konvexní tvary (tj. bez rohů prolomených dovnitř), trojúhelníky jsou bez problémů.
V příloze je ukázka.
Moje stránka.
To Mircosoft : omlouvám se, že píšu až teď. momentálně na tvoření elmy nemám moc čas, ale určitě se k tomu vrátím a jsem rád, že jsi na mě nezapomněl :) já to vidím tak, že pro mě asi největší problém bude fyzika a sestavení nějakého enginu, aby se to jakž takž pohybovalo reálně... přemýšlel jsem nad tou fyzikou, když třeba roztočená motorka narazí jedním kolem do stěny, jaké přesně fyzikální pozadí to má no a moc jsem na nic nepřišel, ale snad to nějak půjde, nicméně zatím se na chvíli odmlčuji, ale já se vrátím :) a se mnou přijde elma :)
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze