Sikke en overskrift...
Jeg får lidt data omkring hvilke personer der er i hvilke rum i en bygning.
Jeg skal så, fra et fugleperspektiv, simulere de går rundt som lysende pletter i en
tegning af bygningen. (tænk GPS og Die Hard, James Bond, Hackers ...indsæt selv flere film med skurke, gadgets og helte i ventilationssystemer)
Jeg har en del mennesker og rum at holde styr på og som altid et minimum af system ressourcer
til rådighed.
Jeg har lavet en løsning der benytter tilfældig tal. dvs:
newX = Math.random()*room.width;
newY = Math.random()*room.height;
Jeg tweener personerne til dette koordinat (newX, newY) med en event
der "trickler" ned gennem de forskellige bygninger, etager og rum og beder mine person objekter om at udregne
deres næste destination og flytte sig dertil.
Det er i og for sig fint, det ser dog ikke specielt ud som mennesker der bevæger sig.
En anden bivirkning ved dette er at "folk" kan finde på at tage nogle gevaldige ryk fra den ene ende af rummet
til en anden, hvis tallene der kommer ud af random metoden er langt fra den nuværende position.
Det gode ved denne løsning er dog at jeg ikke ender i noget form for collisionDetection for at sikre mig
at en person bliver inde for rammerne af rummet (det ville få selv den største octocore til at bryde sammen da jeg har mange mennesker i spil)
Ressource spørgsmålet fik mig også til at droppe ting som Brownian motion osv. da de er ret beregningskrævende.
For at kompensere for den bivirkning med folk der flytter sig for langt på en "opdaterings cycle" (1 sek.)
så prøvede jeg at udregne den rette linie mellem den nuværende position og den tilfældigt genererede position.
Det gav mig så mulighed for at lade en person gemme sin egen velocity/fart internt i person objektet og så bruge
denne værdi til at bevæge personen ud af den rette linie vha. af sin egen fart.
Dette er godt da jeg så ved oprettelse af en person kan lade vedkommne være mere eller mindre aktiv (større mindre fart)
og blive ved med at følge det mønster. Så jeg ikke har mennesker der bevæger sig hurtigt, langsomt, hurtigt, men istedet
benytter det samme tempo (og nogle endda står stille hvis farten er 0)
Men igen, bevægelsesmønstret ligner ikke noget et mennesker ville følge og det giver uheldige bivirkninger med masser
af "if" sætninger når personer skal tildeles negative hastigheder for at kunne komme rundt i rummet og ikke smutte ud over kanten af rummet
fordi farten er større end afstanden til slutpunktet. Feks:
Personen står i punktet 2, 2 og får som det nye koordinat 0,0. Personens fart er 3 pixel per sek. ud mod punktet 0,0 ... dvs. næste skridt er
ligger i -0.2 , -0.2 og er så udenfor rummet og beregningen bryder sammen.
Så ville høre om der er nogle idéer derude til at få disser pletter til at opføre sig "ordentligt" og menneskeligt.
Samtidigt blive inden for grænserne af deres rum og på en måde der skåner CPU'en når den skal flytte mellem 0 - 1000 af disse
rundt på skærmen.
Tak for input og go weekend.
2 kommentarer
En optimeringsmulighed ligger i selve den måde mennesker plejer at bevæge sig på i bygninger:
Det meste af tiden står/sidder man stille og laver et eller andet. Kun sjældent har man brug for at bevæge sig rundt i samme rum, og det er endnu sjældnere at man bevæger sig fra rum til rum! Det vil altså se mere realistisk ud, hvis du nøjes med at bede dine prikker om at bevæge sig med mellemrum.
Selve bevægelseshastigheden får du ikke ret meget ud af at variere- de fleste går rundt med ca. 3-4 km/t med mindre de er stressede
Konklusionen er, at du kan optimere din kode ved at opdele prikkerne i to arrays; en aktiv og en inaktiv. For hvert "tick"/update kan du flytte x antal tilfældige emner mellem de to arrays, og nøjes med at animere emner på den aktive liste. Du kan optimere endnu mere ved kun at veksle elementer mellem arrays når et aktivt emne når sin destination. Du skal i dette tilfælde sikre allerede når du sætter et element i gang, at destinationen er gyldig.
Med ovenstående optimeringer vil jeg gætte på, at du kan nøjes med at lave collision detection beregninger på måske 10-20 emner i sekundet ud af 1000 ialt. Resten er enten animationer som stadig tweener, eller emner som er inaktive og står stille.
Håber du kan bruge inputtet.
Hej Sugekoppen (noget jeg aldrig troede jeg skulle skrive..)
Jeg har løst problemet i mellemtiden, men jeg er stadig
taknemmelig for dit input.
Jeg ledte som sådan ikke efter en måde at gøre collision detection løsningen brugbar.
Systemet vil sikkert, som systemer gør, på et tidspunkt skulle holde styr på mange flere mennesker, så
vil helst ikke ligge mig op af en løsning der bygger på noget der potentielt er meget CPU krævende.
En anden ting der er lidt uheldig ved collision detection er at de mønstre der kommer ud af det bliver
meget ligende "Pong", det gør at øjet opfatter "menneskerne" som noget kunstigt der hopper rundt på væggene.
Jeg løste "udfordringen" ved at gøre person objekterne mere autonome. Så via et composite pattern kører room objektet en
update på alle de personer der er i rummet.
Person objektet har så muligheder for at ignorere updaten eller eksekvere kode der sætter en ny destination inden for
væggene i rummet og begynder at bevæge sig derhen.
Dvs. at med en READY = true/false bestemmer personen om der skal bruges kræfter/CPU på at udregne en
ny destination eller ej.
Person objektet bliver oprettet med en velocitet, denne er vægtet så den i 60% af tilfældene er =0, altså de står/sidder stille.
Der er 3 hastigheder, 0, 3 og 5 px/sek.
Så når en person har bevæget sig til sit mål sætter den READY = true, der kommer så en update hvert sek. fra room objektet, personen udregner sin nye destination, sætter READY = false og begynder at bevæge sig mod målet.
Det gør at personerne giver en illusion om at have et mål og at de opdaterer og ændrer retning på forskellige tidspunkter.
Så hvis en person har velociteten 5 px/s og bliver bedt om at gå en distance på 50 px. så vil den person igonerere update i 50/5 = 10 sekunder
mens de finder vej og derefter tage en ny destination ind. En anden person skal måske kun tilbagelægge 10 px og vil så være klar igen efter 2 sek.
forudsat de også har velociteten 5 px/s.
Det bruger et minimum af CPU og gør at jeg kan køre update hver sek. uden at det kræver nogen udregninger for alle der ikke
er i rummet, er i gang med at bevæge sig eller sidder stille. Så på det område bruger jeg dit princip med at sortere i hvad der er nødvendigt at
bruger CPU tid på
Tak igen, Hygge
Mvh. Ricki
AS1 < AS2 < AS3