Ich hätte heute lieber im Bett bleiben sollen. Wegen der Geburtstagsfeier meines Bruders schon recht wenig Schlaf bekommen, wollte ich den Tag eigentlich eher ruhig angehen. Aber das Schicksal hatte etwas anderes mit mir vor.
Die schon zwei mal erwähnten Probleme mit meinem Rechner nahmen noch vor dem ersten Kaffee des Tages einen dauerhaften Zustand an. Da half kein Auseiander- und wieder Zusammenbauen mehr. Er will einfach nicht mehr. Ab und zu brachte er ja noch den gequälten Ansatz eines Piepens zu stande, das war es dann aber auch schon.
Zum Glück kann ich mich per iPod noch um meine Mails und den (oder schreibt man “das Blog”?) Blog kümmern, ich hoffe aber wirklich das der Eee PC am Dienstag hier eintrudelt! Denn bis ich das Geld für ein neues Mainboard nebst passender Cpu zusammen habe werden wohl 1 – 2 Monate vergehen.
Was habe ich mich heute den ganzen Tag über tot gesucht *Kopf-schüttel*
Rahmen für Menüs und Dialoge wurden ohne Probleme gezeichnet, ok… machen wir noch schnell das Hauptmenü fertig und dann Feierabend. Nix da… Irgendwie passten entweder die Menüpunkte nicht in das Fenster, oder das Fenster war zu groß. Aber was kann man falsch machen, wenn ein Rahmenteil genau 8×10 Pixel groß ist und ein Buchstabe der Schriftart genauso groß ist? Simple Mathematik und doch passt irgendetwas nicht!
Ich musste tatsächlich erst ein paar Buchstaben der Schriftart mitteln Paint einen Rahmen verpassen um den Fehler zu sehen. Bis dahin hatte ich meinen Quellcode sicherlich schon an die tausend Mal ergebnislos korrektur gelesen. Die Standardfunktion von Löve für Bitmapschriftarten fügt (was ich natürlich nicht wusste) immer einen Pixel zwischen zwei Buchstaben ein. Aber zum Glück gab es auch noch eine Funktion, dank der ich diesen dummen Pixel abstellen konnte ;)
Nun gut, ich habe jetzt erst einmal genug vom Programmieren. Das Menü kann jetzt warten, da wird schließlich heute noch wer 18 und ist schon kräftig ohne mich am Feiern.
Vorwort: Mir ist aufgefallen das ich meinen GORC Thread im Game of Robot Forum mittlerweile als Devblog mißbrauche. Dem werd ich jetzt mal dagegen wirken und meine Fortschritte und Gedanken hier im Blog posten… wo sie eigentlich auch hingehören ;)
So… habe die letzte Woche genutzt und alle Spielelemente in Klassen gestopft. Der Inhalt einer Szene steckt nun nicht mehr in einem 2D Array, sondern in zwei Lua Tabellen. Eine für die Roboter, später kommen eventuell auch alle anderen NPCs hier rein. Und in der anderen Tabelle stecken alle weiteren Elemente (Mauern, Gold, etc.).
Sinn und Zweck des ganzen ist es die Spiellogik überschaubarer zu gestalten. Anstelle langer if-then-else Blöcke steckt nun die gesamte Logik für ein bestimmtes Objekt in seiner Klasseninstanz. Mal ein Beispiel:
Isolator = Class("Isolator", Moving)
IsolatorImage = love.graphics.newAnimation(love.graphics.newImage("images/isolator-0.png"), 16, 12, 0.1, 0)
IsolatorImage:setCenter(8, 6)function Isolator:init(x, y, params)
self.super:init(x, y)
self.ani = IsolatorImage
self.speed = spieler.speed
endfunction Isolator:canEnter(obj)local dx, dy
-- kann nur vom Spieler betreten werdenifnot Player:made(obj)thenreturnfalseend-- bewegt sich der Isolator bereits, -- können wir ihn nicht betreten, bzw. in seine Richtung gehen-- da wir sonst durch ihn hindurch laufenif self:isMoving()thenreturnfalseend
dx = self.x - obj.x
dy = self.y - obj.y
return self:canMoveTo(dx, dy)endfunction Isolator:canMoveTo(dx, dy)local feld = Szenen:current():get(self.x + dx, self.y + dy)if #feld ==0then
self:setTarget(dx *16, dy *12)returntrueendfor i, e inpairs(feld)doifnot Isolator:made(e.obj)andnot Barbwire:made(e.obj)thenreturnfalseelseif e.obj:canMoveTo(dx, dy)then
self:setTarget(dx *16, dy *12)returntrueendendendreturnfalseend
Ein anderer positiver Nebeneffekt ist die Möglichkeit nun mehrere Objekte auf dem selben Feld zu haben. Wenn man eine Szene das erste mal betritt, befindet sich im Normalfall nur jeweils ein Objekt auf einem Feld. Wer aber Game of Robot schon gespielt hat, weiss das irgendwann der Zeitpunkt gekommen ist, um sein Inventar auszumisten. Tada! Was liegt da näher als alles was im Moment nicht benötigt wird, einfach auf einen Haufen zu legen? Und wenn man es wieder benötigt, einfach auf das Feld laufen und man sammelt automagisch alles ein.
Leider Gottes kann ich mich nicht so wirklich über meine kleine “Errungenschaft” freuen, denn sie kostet Frames :( Das Intro mit seinen knapp 1000 Mauern ist von 60 FPS auf knapp unter 50 gefallen. In den Szenen hält es sich zwar noch in Grenzen (300 bis 400 Objekte) aber sobald man die Isolatoren herum schubst, kann man auch hier bis zu 10 Frames verschwinden sehen.
Habe zwar noch die ein oder andere Idee, wie ich den Verlust eingrenzen kann. Aber auf lange Sicht, sollte ich doch lieber nach einer etwas performanteren Lösung suchen. Welche aber auf keinen Fall das kompfortable Skripten der Objekte verkompliziert…
Jetzt möchte ich mir aber noch nicht den Kopf darüber zerbrechen, und überlege schon mich der GUI von GORC zu widment. Schliesslich wären das die Spielmenüs, die Messageboxen und vor allem das Inventar. Mal schaun, die Nacht hat ja gerade erst angefangen xD
Diesmal war es nicht das Netzwerkkabel, sondern die Stromzufuhr vom Netzteil zum Mainboard an der ich Hand anlegen musste. Natürlich kam ich genau auf diese Idee erst nachdem ich das ganze Prozedere vom letzten Mal durchgezogen hatte… diesmal vergeblich.
Bleibt die Frage: Warum?
Liegt es vielleicht daran, das ich nachdem der Rechner runtergefahren ist, die Steckdosenleiste ausschalte? Wenn ich das nicht mache bekommen meine USB Geräte noch Saft vom angeblich abgeschalteten PC und leuchten die ganze Nacht fröhlich vor sich her. Und einen Wackelkontakt kann ich mir irgendwie nicht so recht vorstellen, da die Tür geschlossen ist kommt nicht einmal mein Kater in die Nähe des Rechners.
Mußte mich eben mal ein wenig ablenken und habe mich auf die Suche nach einer Freeware zum Bildschirmvideos aufzeichnen gemacht. Sie sollte nicht zu verspielt sein, schließlich will ich doch nur ab und zu was aufzeichnen und vielleicht auf Youtube laden. Gesucht… gefunden :)
Entpackt, Videoformat auf MPG4 gestellt und auf Aufnahme gedrückt. Und schon hatte ich mein erstes Video von GORC:
Wirklich nettes Programm :) Was mir aber noch irgendwie fehlt sind die richtigen Einstellungen zum mitschneiden von Sound und Musik des gefilmten Programmes und die Möglichkeit das zu filmende Fenster direkt auswählen zu können. Bei CamStudio kann ich wie es scheint nur den Bereich auswählen. Dabei nehme ich dann entweder zu viel oder zu wenig vom Fenster auf.
Ich hatte vor ein paar Tagen angefangen flüssige Bewegungen in GORC einzubauen und versucht den Quellcode ein wenig übersichtlicher zu gestalten. Da z.B. Charlie und die Roboter ziemlich ähnlich gestrickt waren, lag nichts näher als beide Objekte auch die gleichen Funktionen (zeichnen, bewegen, …) nutzen zu lassen. Dabei war in etwa folgendes herausgekommen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function movable_create()
m ={}
m.x =0
m.y =0return m
endfunction movable_setPosition(m, x, y)
m.x = x
m.y = y
end-- Beispiel:
spieler = movable_create()
movable_setPosition(spieler, 2, 2)
Funktionierte auch alles ziemlich gut. Aber vorhin wurde ich nachdenklich. Wäre es nicht interessant das ganze objektorientiert aufzubauen? Aber wie stellt man das in Lua an? Nach einer Menge googeln und herumspielen bin ich zu folgendem Ergebnis gekommen:
love.filesystem.require("class.lua")-- Standard Objekt
Object = Class(nil)function Object:init()-- Gridposition
self.x =0
self.y =0-- Sprite / Animation
self.ani =0endfunction Object:setPosition(x, y)
self.x = x
self.y = y
end-- Bewegliche Objekte
Moveable = Class(Object)function Moveable:init()
self.super():init()-- Ziel Gridposition
self.nx =0
self.ny =0-- Bewegungsrichtung (entfernen!)
self.dir =0
self.ani_x =0
self.ani_y =0-- Felder pro Sekunde
self.speed =4
self.last_update =0endfunction Moveable:draw()local x, y
x =(self.x - 1)*16 + self.ani_x
y = self.y *12 + self.ani_y
love.graphics.draw(self.ani, x, y)end
...
-- Beispiel:
mauer = Objekt()
mauer:setPosition(10, 15)
spieler = Movable()
spieler:setPosition(2, 2)
Fragt mich jetzt aber nicht wie genau das ganze funktioniert ;) Für mich zählt DAS es geht. Wer trotzdem an der Funktionsweise interessiert ist, kann sich ja auf folgenden Seiten schlau lesen:
Anfang Dezember hatte herc aus dem Game of Robot Forum ein ca. 8 minütiges Gameplay Video der Robot Junior Episode bei Youtube reingestellt. Vielleicht weckt es ja bei dem ein oder anderen Interesse die Robot Spiele mal auszuprobieren?
Als quasi alter Game of Robot Hase muss ich eingestehen das ich den Trick mit dem Blockieren von Gegnern mittels Säurefläschen noch nicht kannte *lach* Das erleichtert doch gleich viele kniffelige Stellen. Danke herc :)
Bin ja eigentlich eher so der gemütliche, aber Teeworlds hat es mir die letzten zwei Stunden echt angetan :)
Lauter bunte kugelige Kerlchen bekriegen sich in farbenfrohen Karten. Mit den WASD Tasten lenkt man sein Kugelviech und zielt mit der Maus. Linksklick feuert die Waffe ab, Mausrad wechselt diese. Mittels Leerstaste wird gehüpft, gut getimet geht auch ein etwas höherer Sprung. Und das Sahnehäubchen ist der Haken, mittels Rechtsklick, mit dem man nach ein wenig Training in ungeahnte Höhen emporsteigen kann.
Anstelle ins Bett, geh ich mal fleissig weiter Punkten *winke*
Wie jeden Morgen gab ich meinem PC Strom und wanderte weiter Richtung Küche und frischem Kaffee. Nur diesmal wich jegliche Farbe aus meinem noch recht verschlafenem Gesicht, als ich zurück zum Rechner kam. Er summte voller Tatendrang, zeigte aber kein Bild. Für den Stromsparmodus des Monitores war ich nicht lange genug in der Küche. Er ist doch nicht etwa kaputt? Wehe!
In den letzten anderthalb Stunden habe ich meinem armen PC Stück für Stück ausgeschlachtet, um dem Fehler auf die Spur zu kommen. Mehrmals den CMOS gelöscht, alles raus. Nichts :( Lüfter sprangen zwar an, aber es gab nicht einmal das “Kein Speicher” Piepen. Innerlich rechnete ich schon aus wann ich genug für ein neues Mainboard, eine neue CPU oder gar beides zusammen gespart hätte.
Das einzigste das ich bisher noch nicht abgezogen hatte, war das Netzwerkkabel. Und ratet mal was passierte als ich eben jenes im letzten Akt meiner Verzweifelung entfernte? Bieeeeep Bieeeeep, da wollte doch wer Speicher :) :) :) Also Stück für Stück wieder alles rein… Rechner fährt hoch. Netzwerkkabel probeweise auch wieder ran, Rechner fährt trotzdem hoch :)
Stellt euch vor ihr habt gerade ein kleines Spiel fürs iPhone geschrieben und zwar in deutsch. Da ihr aber ein möglichst großes Publikum ansprechen wollt, sollte es auch eine englische Version geben. Wie aber geht man das Problem an? Ich habe mal ein wenig gegoogelt.
In eurem Xcode Projektverzeichnis legt ihr zwei Verzeichnisse an: “de.lproj” und “en.lproj”
Nun fügt ihr eurem Projekt mittels Add -> New File … -> Other -> Strings File zwei neue Dateien “Localizable.strings” hinzu. Eins in das “de.lproj” und die andere in das “en.lproj” Verzeichnis.
Eure Projektansicht sollte nun so aussehen:
Ich habe als Beispiel mal ein Hauptmenü genommen, der Code sieht noch wie folgt aus:
Die Strings “Starte Spiel” und “Hilfe” ersetzen wir nun durch die NSLocalizedString() Funktion. StartGameKey und HelpKey geben an welchen String wir an der besagten Stelle haben möchten, übersetzt natürlich ;)
Noch unsere beiden Localizable.strings Dateien bearbeiten, denn aus diesen holt sich unser Programm später die Übersetzten Strings.
Für Deutsch:
1
2
"StartGameKey"="Starte Spiel";
"HelpKey"="Hilfe";
und Englisch:
1
2
"StartGameKey"="Start Game";
"HelpKey"="Help";
Und schon bekommen wir je nach Spracheinstellung der iPhones die passenden Übersetzungen geliefert :) Sollte eine Sprache eingestellt sein, für die wir keine Übersetzung anbieten wird anscheinend die Englische Übersetzung genommen, was in den meisten Fällen völlig ok ist.