Hallo zusammen,
aufgrund des Thread von flambert ist mir die Idee gekommen ein kleines Spiel zu programmieren. Es lehnt sich an die "Programming Games" an und hat nun ca. 12 Stunden Arbeit beansprucht.
Ziel des Spiels ist es seinen Explorer auf einer Karte von einer Ecke in die gegenüberliegende Ecke zu bringen. Jedes Feld auf dem der Explorer steht hat eine bestimmte "Strahlung" die seine Lebenspunkte verringern. Verliert der Explorer alle seine Lebenspunkte so ist das Spiel vorrüber.
Damit sich der Explorer bewegen kann hat er Energie zur Verfügung. Bewegung kostet Energie. Jede Runde wird eine bestimmte Menge an Energie wieder hergestellt.
Zusätzlich kann der Explorer, um besonder strahlenden Felder (je mehr Strahlung desto mehr Lebenspunkte gehen verloren) beliebig viele Scans ausführen (ein Explorer kann sich auch beliebig weit bewegen, solange die Energie dazu vorhanden ist). Scans verbrauchen jedoch auch Energie.
Mit Hilfe von Scans kann ein Geländefeld erkundet werden und somit die Strahlung bestimmt werden. Besonders strahlende Felder können somit umfahren werden.
Die Regeln können über die Konfigurationsdatei konfiguriert werden. Die Standardeinstellungen sind:* 1000 ms zwischen den einzelnen Zügen
Im Anhang ist neben den eigentlich Binaries auch ein Beispiel-Explorer zu finden.
Dieser Beispielexplorer sucht mit einfachen Mitteln nach einen begehbaren Weg.
using aiexp.lib;
namespace example
{
class BasicExplorer : ExplorerBase
{
Tile[,] _scanned;
public Tile[,] ScannedTiles
{
get
{
return this._scanned;
}
private set
{
this._scanned = value;
}
}
public BasicExplorer()
{
}
public override void Explore()
{
this.Print("I explore . . .");
// Eigenschaft initiailisieren falls nötig
if (this.ScannedTiles == null)
this.ScannedTiles = new Tile[this.MapSettings.Width, this.MapSettings.Height];
// Nächstes Zielteil innerhalb der Bewegungsreichweite beziehen
Tile next = this.GetNextTile((int)(this.Energy / this.RuleSet.ExplorerEnergyPerMove));
// Bewegen
if (next != null)
this.Move(next.X, next.Y);
}
Tile GetNextTile(int MaxDistance)
{
Tile[] rightTiles = new Tile[MaxDistance];
Tile[] upperTiles = new Tile[MaxDistance];
Tile next = null;
// Die Schleife scannt die Felder rechts und über den Explorer
// Ist keine Energie mehr zum scannen vorhanden, oder wurde ein Feld mit einer
// Strahlung niedriger 0.1 gefunden, so wird das Scannen vorzeitig beendet
for (int i = 0; i < rightTiles.Length; i++)
{
rightTiles[i] = this.Scan(this.X + i + 1, this.Y);
if (rightTiles[i] != null)
if (rightTiles[i].Radiosity < 0.1f)
break;
else
if (this.Energy < this.RuleSet.ExplorerEnergyPerScan)
break;
upperTiles[i] = this.Scan(this.X, this.Y + i + 1);
if (upperTiles[i] != null)
if (upperTiles[i].Radiosity < 0.1f)
break;
else
if (this.Energy < this.RuleSet.ExplorerEnergyPerScan)
break;
}
// Die Schleife ermittelt das Feld mit der niedrigsten Strahlung
for (int i = 0; i < rightTiles.Length; i++)
{
if (next == null)
next = rightTiles[i];
else
if (rightTiles[i] != null)
if (rightTiles[i].Radiosity < next.Radiosity)
next = rightTiles[i];
if (next == null)
next = upperTiles[i];
else
if (upperTiles[i] != null)
if (upperTiles[i].Radiosity < next.Radiosity)
next = upperTiles[i];
}
return next;
}
public override Tile Scan(int X, int Y)
{
this.Print("Scan X={0},Y={1}", X, Y);
// Koordinaten außerhalb der Kartengrenzen
if (X > this.MapSettings.Width - 1 ||
Y > this.MapSettings.Height - 1)
return null;
// Wurde Koordinate bereits gescannt?
if (this.ScannedTiles[X, Y] != null)
return this.ScannedTiles[X, Y];
// Scannen und falls nötig Ergebnis speichern
Tile t = base.Scan(X, Y);
if (t != null)
this.ScannedTiles[X, Y] = t;
return t;
}
}
}
Der Quellcode für den Explorer muss in C# vorliegen und darf nur auf Typen der System.dll und der Artificial Explorer Library.dll zugreifen. Beim Start des Programms wird die CS-Datei abgefragt, die kompiliert werden soll.
Das Programm versucht das Datei zu kompilieren und anschließend kann aus allen Typen die von ExplorerBase ableiten ausgewählt werden und das Spiel beginnt.
Über Verbesserungvorschläge, Wünsche und Fehlerberichte würde ich mich freuen.
Viel Spaß!
Ein Screenshot aus der Version 1.1.0.
In der linken Hälfte befinden sich Nachrichten die entweder vom Spieler oder vom Explorer selbst stammen. Die Nachrichten können mit ENTF gelöscht werden. Oben rechts befindet sich die Anzeige der aktuellen Lebensenergie (rot) und Energie (blau).
Das helle Feld ist das Feld auf dem der Explorer sich momentan befindet. Die Zahlen zeigt die Strahlung auf den einzelnen Feldern an.
In der Version befindliche Tastenkombinationen sind:
gibts cheats? (lach) 😁
sieht ganz nice aus testes am abend (geladen hab ichs shcon ^^)
Wie versprochen gibts den Quellcode des Programms.
Du wirst Lachen king, rein theoretisch wäre es sogar möglich zu "schummeln", in dem man mit Reflection arbeitet und somit somit die Kartenfelder ohne einen Scan einsehen , sich Energie selbst die gewünschte Menge an Energie zuweisen, oder gleich die Koordinaten des Explorers auf das Ziel zu setzen.
Dies wird wohl auf lange Sicht so bleiben 🙂
Als nächstes werde ich die Einstellungen in eine Konfigurationsdatei auslagern, damit die Kartengröße und andere Parameter für das Spiel beeinflusst werden können, ohne den Quellcode neu kompilieren zu müssen.
Gruß
Jens
xD ich werd am wochende wenn ich daheim bin mal ne CheatEngine für die ganzen spiele hier schreiben xD
Eine neue Version ist verfügbar. Die Binaries befinden sich im ersten Post. Die größte Änderung ist der Umstieg von der Konsolendarstellung auf SDL.NET.
Die Sourcen werde ich morgen im Laufe des Tages einstellen.
Viel Spaß!
Beim Programmstart:
An unhandled exception of type 'System.TypeInitializationException' occurred in ArtificialExplorer.exe
Additional information: The type initializer for 'SdlDotNet.Graphics.Video' threw an exception.
Win XP SP3, .NET 2.0
Den Fehler konnte ich zwar nicht auf den Grund gehen, aber versuch es noch einmal mit der aktuellen Version von oben. Zum. wird dann die Ausnahme vom SDL detailliert angezeigt.
Die neuen Sourcen hängen auch an.
Grüße
Jens
Artificial Explorer - Exception
An exception occured while initializing Sdl.Net
TypeInitializationException Der Typeninitialisierer für SdlDotNet.Graphics.Video hat eine Ausnahme verursacht.Source SdlDotNet
Stacktrace bei SdlDotNet.Graphics.Video.get_IsInitialized()
bei aiexp.Program.Main(String[] Args) in J:\Projekte\ArtificialExplorer\ArtificialExplorer\Program.cs:Zeile 33.DllNotFoundException Die DLL SDL.dll: Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.Source Tao.Sdl
Stacktrace bei Tao.Sdl.Sdl.SDL_WasInit(Int32 flags)
bei SdlDotNet.Graphics.Video.Initialize()
bei SdlDotNet.Graphics.Video..cctor()
OK
Damit ist die Fehlerquelle wohl gefunden. Es fehlen noch die SDL-Libraries, die bei mir im System32-Verzeichnis liegen und ich deshalb aus nicht mit gepackt habe. Der Fehler liegt also klar in meiner Bequemlichkeit begraben 😉
Die benötigten Bibliotheken können hier heruntergeladen werden (Das Archiv ist zu groß zum Anhängen).
Es reicht wenn die Dateien im Anwendungsverzeichnis liegen.
Grüße
Jens