Alle Projekte

Frühere Arbeit

AsteroidShooter, mein Abschlussprojekt am Gymnasium

Ein kleiner Weltraum-Shooter, 2018 von Grund auf in C# auf Microsofts XNA-Framework geschrieben, als mein Abschlussprojekt am Gymnasium, mit einer schriftlichen Arbeit, die erklärt, wie er funktioniert.

Rolle
Code, Spieldesign und die schriftliche Arbeit
Stack
C#, XNA 4.0
Kontext
Abschlussprojekt in Informatik, Gimnazija, Mai 2018
Status
Frühere Arbeit

Worum es geht

Man fliegt ein Schiff und schießt mit Lasern auf Asteroiden. Das erste Level ist absichtlich leicht und endet damit, dass das Spiel einem gratuliert, als wäre das schon das ganze Spiel. Dann beginnt es, mit einem zu sprechen, und das zweite Level ist weitaus schwerer als das erste. Wer verliert, bekommt einen Level-Code, den man im Hauptmenü eingeben kann, um direkt zu dem Level zurückzuspringen, an dem man gescheitert ist.

Es ist klein: zwei Level. Ich programmierte damals schon seit über zehn Jahren, deshalb war für mich der interessante Teil, die Struktur ohne Engine aus dem Nichts aufzubauen.

Screenshot folgt in Kürze

Gameplay im zweiten Level.

assets/projects/xna-game/gameplay.png (bereits hinzugefügt)

Das zweite Level: das Schiff, Asteroiden und eine zoombare Kamera.

Screenshot folgt in Kürze

Das Hauptmenü.

assets/projects/xna-game/main-menu.png (bereits hinzugefügt)

Das Hauptmenü, mit seinem farbwechselnden Hintergrund und einem umhertreibenden Schiff.

Screenshot folgt in Kürze

Der Bildschirm nach dem Tod mit dem Level-Code.

assets/projects/xna-game/game-over.png (bereits hinzugefügt)

Beim Tod wird ein Level-Code angezeigt, mit dem man zu diesem Level zurückspringen kann.

Wie es gebaut ist

public void HandleCollisions()
{
    PlayerObject pObj = null;
    List<Vector2> pPoints = null;
    if (PObjRef.IsAlive && (PObjRef.Target as PlayerObject).Scene == this) { pObj = (PlayerObject)PObjRef.Target; pPoints = pObj.BuildCollisionPoints(); }
    if (pObj != null && pPoints.Count < 3) pObj = null;
    List<Tuple<AsteroidObject, List<Vector2>>> Asteroids = new List<Tuple<AsteroidObject, List<Vector2>>>();
    List<Tuple<LaserObject, List<Vector2>>> Lasers = new List<Tuple<LaserObject, List<Vector2>>>();
    foreach (GameObject GObj in GameObjects)
    {
        if (GObj.Scene != this) continue;
        if (GObj is Explosion) continue;
        if (GObj is PlayerObject) continue;
        List<Vector2> CPoints = GObj.BuildCollisionPoints();
        if (CPoints.Count < 3) continue;
        if (GObj is AsteroidObject)
        {
            if (pObj != null) CheckCollision(GObj, CPoints, pObj, pPoints);
            foreach (Tuple<LaserObject, List<Vector2>> tLP in Lasers)
                CheckCollision(GObj, CPoints, tLP.Item1, tLP.Item2);
            Asteroids.Add(new Tuple<AsteroidObject, List<Vector2>>((AsteroidObject)GObj, CPoints));
        }
        else if (GObj is LaserObject)
        {
            foreach (Tuple<AsteroidObject, List<Vector2>> tAP in Asteroids)
                CheckCollision(GObj, CPoints, tAP.Item1, tAP.Item2);
            Lasers.Add(new Tuple<LaserObject, List<Vector2>>((LaserObject)GObj, CPoints));
        }
    }
}
public void CheckCollision(GameObject A, List<Vector2> PointsA, GameObject B, List<Vector2> PointsB)
{
    if (!SATCollisions.CheckSATCollision(PointsA, PointsB)) return;
    OnCollision(A, B);
}
Originalcode von 2018: der Kollisionsdurchlauf, der Objekte nach Typ paart.

Ein kompletter Durchlauf

Das ganze Spiel vom Hauptmenü über das erste Level und den Monolog, bis mich das deutlich schwerere zweite Level geschlagen hat. Ich habe es während der Entwicklung leichter gemacht, und acht Jahre später schaffe ich es immer noch nicht zuverlässig.

Video folgt in Kürze

Ein vollständiger Durchlauf, von Anfang bis Ende.

Paste the YouTube video ID into data-youtube on this figure in work/xna-game.html

Ein kompletter Durchlauf, von mir gespielt.

Rückblick

Es ist ein Schülerprojekt und liest sich stellenweise auch so: Eine globale Klasse hält gemeinsamen Zustand, und die Level-Logik steckt in der Spielszene statt in Daten. Was ich weiterhin verteidigen würde, sind die Trennung von Szenen und Objekten, die Objekterzeugung per Warteschlange und die stabile Sortierung, die aus der Jagd auf einen echten Flacker-Bug entstand und nicht aus einem Tutorial.

Video (optional) folgt in Kürze

Etwa 20 Sekunden des zweiten Levels: fliegen, schießen und die Kamera zoomen.

assets/projects/xna-game/gameplay.mp4 (etwa 20 Sekunden)

Spielszene.