tisdag 4 januari 2011

Relationer mellan objekt

Det finns två typer av relationer (i dagsläget): referenspunker (objekt kretsar kring andra objekt) och gravitation. Bara spelaren påverkas av gravitation! Andra rörelser är t ex cirkulära eller elliptiska (eller fyrkantiga för den delen).

Det är den första typen av relationer som detta inlägg handlar om. Det finns olika varianter (se diskussionen nedan), till att börja med ska variant nummer 1 prövas.

Under tiden som leveln skapas kommer alltså GameObjectRelationSystem att spara alla objekt som agerar referenspunkter i en hashmap:
<int, GameObject> där int är referensobjektets ID och den andra är pekaren till objektet.

Så när referensobjektet skapas (se separat inlägg) måste den alltså ange att den är ett referensobjekt, samt uppge ett ID. På samma sätt måste de som rör sig kring en referenspunkt få en komponent PositionReferenceComponent som håller pekaren till referensobjektet, och som uppdateras som bland de första komponenterna. Det innebär självklart att referenspunkter måste komma före i GameObject-trädet.

Till en början tillåter vi bara cirkulära rörelser - det blir lättast så...

Dessutom: Det här innebär att vår player, the dude, kommer att behöva byta plats i trädet beroende på om han befinner sig på en planet eller ute i rymden!

Alternativ till utformning av systemet
Det ska gärna vara "lättvikt" eftersom beräkningar görs i varje frame, och inte för rörigt (dumt, men snabbt, att objekt har pekare direkt till andra objekt).

Exempel på alternativ 1: Pekare direkt till referensobjektet.

Detta system kommer inte ha ett globalt system för att handskas med relationer under spelets gång, men likväl måste det finnas för att kunna koppla samman objekten när leveln skapas.


Exempel på alternativ 2: Pekare hanteras av globalt system.

söndag 2 januari 2011

Översikt: de olika delsystemen


Att arbeta på:

Game state, results, save/load

OpenGL

Rendering

Kollisionshantering (Replica Island har två: "background collisions", som vi tar bort helt, och GameObject Collisions, som vi kan återanvända tills vidare iallafall).

Texture preloading. Flyttas från GameObjectFactory till LevelSystem? Hur ska bilderna refereras i level-filerna? Numreringen i R.java är ju godtycklig.

Säljupplägg - finansiering, reklam, Lite/Full version.
...

lördag 1 januari 2011

Dagbok

21/1: Finally, a functioning demo where the dude floats around until he's colliding with a planet. The collision detection is super light weight, the dude has a public field radiusLightWeightCollision and so does all the planets.

So... what will happen at collision? Well, the dude's state will be "running" or "attached" or something similar, the physics will be replaced with the behavior of running about on a planet, so why not change the components to reflect that? Which components will be necessary? Firstly, user input takes a very different form: an arrow will be painted on top of the dude, starting in his center and pointing towards the point where the finger is on the screen. Secondly, the dude will have an elaborate way of moving, which must be calculated. Hmmm....
1) Extract the point where the finger is, and deal with multiple points of contact.
2) Calculate the distance to the point, translate that to a force.
3) project that force onto the tangent that is defined by the circle of the planet and the point on the circumference where the dude is.
4) Calculate the resulting angular velocity, and from that the resulting position.
5) Propagate the dude.
6) Draw the arrow, proportional to the non-projected force.

14/1: I almost have a player floating around, there's just one problem: how should I work with physics? In Replica Island he's using stuff like impulse, acceleration and stuff but it might be overkill.

9/1: Ok nu finns ett referenssystem, så målet är uppnått. Nu har jag börjat lägga till en player. Det rör upp en massa frågor. Hur ska vi lösa gravitationsfrågan? Det är ju inte spikat hur det ska fungera med fysiken. ObjectRelationSystem får hjälpa till här med men jag vet inte riktigt hur ännu.
Kollision och animation: Ska vi ta hela systemet med RenderComponent, AnimationComponent och SpriteComponent med hull och hår? Hur löser vi faktumet att bilder ska rotera i spelet? Så är det ju inte i Replica Island.
Hm. Så här måste det nog bli tills vi har bilder att animera: Låt dude bestå av en enda animation frame, med sfärisk kollisionsvolym. Ge planeterna sfäriska kollisionsvolymer de med. Det blir en bra början!

Nästa mål, alltså:
Hitta på en enkel lösning för gravitation.
Tillverka dude och planeter med en enda frame och med sfäriska kollisionsvolymer. Utnyttja DynamicCollisionSystem eller vad det heter, och fånga upp eventet att de kolliderar.

6/1: Har fastnat i vinkelvolten. Så många system, nånstans måste jag börja!! Nu finns en blogpost som ska sammanfatta alla delsystem. Idag är målet: Få en planet att stå stilla, en annan att kretsa kring den första, och en tredje att kretsa kring den andra.

4/1: Johan och Bagarn träffades och pratade framtiden. Förslag: skriv en affärsplan och ta med den till Venture Cup, bara för att få lite feedback.

I vilken form vill vi arbeta, hur vill vi tjäna pengar? Samarbeta med t ex Cybercom, som kan ragga stora kunder, och kanske iPhone-app-studios? Dvs agera outsourcing-företag, ta beställningsjobb? Eller vill vi satsa på egna appar och spel helt och hållet?


1/1: Just nu sitter jag och lägger upp ramverket för att läsa fram en level ur en fil. Den stora frågan just nu: Hur får man med bilder på ett snyggt och snabbt sätt?

Under julen städade jag i koden, fick bort en hel del Replica Island-grejer.

torsdag 30 december 2010

Spara och återskapa levels

Levels kommer i grupper. Gruppen kallar vi för en galax och en level är ett solsystem i galaxen. Spelaren väljer vilken level som ska spelas i aktiviteten LevelPicker:



Varje galax har sin "palett", dvs tillhörande rådata som bakgrundsbilder, monster, planeter, ljud mm. Dessa defineras (kommer att defineras) i en xml-fil och förallokeras för att korta ner tiden det tar att starta en level. Varför definera detta i xml-filer? Jo, det är det bästa sättet att peka ut resurser i Android.



Varje level beskrivs i binärfiler. Filen är en serie instruktioner för att skapa en komplett level. Levels och deras tillhörande data kopplas samman i leveltree.xml.

Levelfiler skapas i LevelSerializer (ren java), och packas upp i LevelBuilder (del av Android-koden).

Binärfilens protokoll
Det första som står i filen är dess versionsnummer (en int), som måste vara samma över hela Level-systemet för att fungera. Sedan följer instruktioner i form command-data-command-data osv. Commands är alltid representerade med en Java short, datat på olika form beroende på vad som står där. Instruktionsuppsättningen är självdokumenterande i LevelSerializer.java.

Efter versionsnumret defineras varje GameObject, i den ordning som de ska uppträda under GameObjectManager.

För varje GameObject läses först dess fields in (såsom id, position, hastighet) i valfri ordning. Sedan läses varje GameComponent in i den ordning de ska uppträdai sitt GameObject.

GameObjectManager

GameObjectManager representerar i princip en hel level. Barnen i GOM är GameObjects, som representerar de olika elementen i spelet, typ en planet, en skurk, spelaren, en bakgrundsbild.

GOM är en nod i GameTree naturligtvis. Strukturen ser sedan ut så här:



Mer än så är det inte. GameComponents är det som ger liv till ett GameObject: RenderComponent håller en bild, MovementComponent beräknar rörelse, ja du fattar.

Detta är anledningen till att deserialization av en level-fil inte är rekursiv: trädet har ett fördefinerat djup.

Level system: överblick

Det är så mycket mer än jag trodde!! Detta är en (komplett?) översikt:





GameObjectManager är den nod i Game-trädet som håller alla spelobjekt (GameObjects, som i sin tur har en massa GameComponents som ger den sina egenskaper, typ bild, animation, AI, rörelser, fysik...).

LevelSerializer och LevelBuilder är de som tillverkar respektive packar upp levels från binärfiler.