[Multimedia][tutorial] Map Bewegen

Ich würde gerne in einem Tutorial zeigen wie man auf einem Spiel die Mapbewegen kann, sobald sich der Spieler dem Rand des Formes nährt.
Zu Beginn nenne ich mal die Klassen die in euerem Projekt vorhanden Sein Sollten

[ul]
[li]Game
[/li][li]Sprite
[/li][li]World
[/li][li]Render
[/li][li]Moving
[/li][/ul]

World Klasse

In dieser Klasse legen wir die Eigenschaften Unserer Map fest. Unter anderem die Größe, den Offset Wert und auch die Textur. In dieser Klasse finden sich nur eigenschaften. Folgende eigenschaften sind Erforederlich. Der Offset wert Verschieb die Textur anhand des Wertes.

[CSHARP]
class World
{

    public Bitmap map { get; set; }
    public int OffsetX { get; set; }
    public int OffsetY { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }

}

[/CSHARP]

Sprite Klasse

Die Sprite Klasse Beinhaltet alle Eigenschaften zu unserem Spieler. In dieser Klasse finden Sich auch nun wieder nur Eigenschaften. Es werden hier die Eigenschaften NowX und NowY (Diese Eigenschaften sind im Späteren Spielverlauf für Quests z.b. Wichtig. Sie Erhöhen sich beim Bewegen in der Moving Klasse, in diesem Tutorial werden diese erstmal nicht benötigt), PosX und PosY ( Anhand dieser Werte werden wir die Figur (Spieler) auf Unsere Form Zeichnen), SpriteNorth, SpriteSouth, SpriteWest und SpriteEast (Dies Sind die Bilder des Spielers ich habe dafür die 4 Eigenschaften festgelegt das man wenn man nach norden Läuft ein Bild der Figur hat die nach norden läuft. etc) und Width und Height ist die Größe der Textur.

[CSHARP]
public class Sprite
{

    public String SpriteName { get; set; }
    public int PosX { get; set; }
    public int PosY { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public int NowX { get; set; }
    public int NowY { get; set; }
    public Bitmap SpriteNorth { get; set; }
    public Bitmap SpriteSouth { get; set; }
    public Bitmap SpriteWest { get; set; }
    public Bitmap SpriteEast { get; set; }

}

[/CSHARP]

Klasse Game

Diese Klasse ist ein Form auf der wir das Spiel Ausgeben. hier finden wir folgenden Code. Wichtig wir Brauchen einen Timer !

[CSHARP]
// Lokale Variabeln
Public static Sprite sprite;
Public static World map;

    private void GamePanel_Load(object sender, EventArgs e)
    {
        this.DoubleBuffered = true;
        sprite = new Sprite();
        setSprite(sprite);
        map = new World();
        setMap(map);
        timer1.Start();
    }

[/CSHARP]

Hier wird das Spiel Initialisiert

[CSHARP]
private void setSprite(Sprite s)
{
// Hier Ihre Eigenschaften
}

     private void setMap(World map)
     {
         // Hier Ihre Eigenschaften
     }

[/CSHARP]

Hier werden die Eigenschaften der Klassen Definiert.

[CSHARP]
private void GamePanel_KeyDown(object sender, KeyEventArgs e)
{

        if (e.KeyData == Keys.Up) Moving.moveUp(sprite);
        if (e.KeyData == Keys.Down) Moving.moveDown(sprite);
        if (e.KeyData == Keys.Left) Moving.moveLeft(sprite);
        if (e.KeyData == Keys.Right) Moving.moveRight(sprite);

    }

[/CSHARP]

Dies ist unsere Bewegungs Steuerung, die Klasse Moving wird im Späteren erläutert.

[CSHARP]
private void GamePanel_Paint(object sender, PaintEventArgs e)
{
render.moveMap(e);
render.dorender(e);

    }

[/CSHARP]

Hier die Zeichen Methode des Formes, die Klasse render wird im Späteren erläutert.

[CSHARP]
private void timer1_Tick(object sender, EventArgs e)
{
this.Invalidate();
}
[/CSHARP]

Hier wird die Welt automatisch neu Gezeichnet. Invalidate() ruft die Methode Paint auf und es wird neu Gezeichnet.

Klasse Moving

Diese Klasse ist unsere Bewegungs Steuerung. Hier wird nichts Anderes gemacht als die Koordianten Berechnet. Es giebt nur 4 Methoden.

[CSHARP]
class Moving
{

    public static void moveUp(Sprite Sprite)
    {
        Sprite.PosY -= 5;                                       // Y-Achsen Position um 5 Veringern
        Sprite.NowY -= 5;                                       // NowY um 5 Veringern
        Declaration.Walk = Declaration.WalkWorldMap.North;      // Deklarieren das sich nach Norden Bewegt wird
        GamePanel.ActiveForm.Invalidate();
        GamePanel.ActiveForm.Text = Sprite.NowY + "," + Sprite.NowX + ";" + GamePanel.ActiveForm.Width + "," + GamePanel.ActiveForm.Height;

        
        
    }

    public static void moveDown(Sprite Sprite)
    {
        Sprite.PosY += 5;                                       // Y-Achse Um 5 erhöhen
        Sprite.NowY += 5;                                       // NowY um 5 erhöhen
        Declaration.Walk = Declaration.WalkWorldMap.South;      // Nach Unten laufen
        GamePanel.ActiveForm.Invalidate();
        GamePanel.ActiveForm.Text = Sprite.NowY + "," + Sprite.NowX + ";" + GamePanel.ActiveForm.Width + "," + GamePanel.ActiveForm.Height;

       
    }

    public static void moveLeft(Sprite Sprite)
    {
        Sprite.PosX -= 5;                                       // X-Achse um 5 veringern
        Sprite.NowX -= 5;                                       // NowX um 5 veringern
        Declaration.Walk = Declaration.WalkWorldMap.West;       // Nach Links Laufen
        GamePanel.ActiveForm.Invalidate();
        GamePanel.ActiveForm.Text = Sprite.NowY + "," + Sprite.NowX + ";" + GamePanel.ActiveForm.Width + "," + GamePanel.ActiveForm.Height;

       
    }

    public static void moveRight(Sprite Sprite)
    {
        Sprite.PosX += 5;                                       // X-Achse um 5 erhöhen
        Sprite.NowX += 5;                                       // NowX um 5 erhöhen
        Declaration.Walk = Declaration.WalkWorldMap.East;       // Nach Rechts Laufen
        GamePanel.ActiveForm.Invalidate();
        GamePanel.ActiveForm.Text = Sprite.NowY + "," + Sprite.NowX + ";" + GamePanel.ActiveForm.Width + "," + GamePanel.ActiveForm.Height;

       
    }

}

[/CSHARP]

Klasse Render

In dieser Klasse wird nur Gezeichnet !

[CSHARP]
public class render
{

    /*
     * Hier wird die Map Gezeichnet
     * und in dem Puffer Gespeichert 
     */
    
    public static void drawmap()
    {
     
        System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(Game.map.map());      // Neues Graphics Element Hinzufügen

        g.DrawImage(Game.map.map, Game.map.LocationX, Game.map.LocationY, Game.map.Width, Game.map.Height);        // Textur wird Gezeichnet

            
        
    }

    /*
     * Hier wird die Welt auf das Form
     * Gezeichnet. 
     */

    public static void moveMap(System.Windows.Forms.PaintEventArgs e)
    {

        CheckPosition(Game.sprite());
                                     
        int WorldOffsetX = -Game.map.map.OffsetX;
        int WorldOffsetY = -Game.map.map.OffsetY;
        
        e.Graphics.DrawImage(Declaration.map.map,WorldOffsetX,WorldOffsetY,Declaration.map.Width,Declaration.map.Height);
    }

   

    
    /*
     * Hier wird der Spieler auf die Welt
     * Gezeichnet 
     */

    public static void dorender(System.Windows.Forms.PaintEventArgs e)
    {

        Sprite item = Game.sprite();
        

            if (Declaration.Walk == Declaration.WalkWorldMap.North) e.Graphics.DrawImage(item.SpriteNorth, item.PosX, item.PosY, item.Width, item.Height);     // Wenn Laufrichtung Norden = NordSprite
            if (Declaration.Walk == Declaration.WalkWorldMap.South) e.Graphics.DrawImage(item.SpriteSouth, item.PosX, item.PosY, item.Width, item.Height);     // Wenn Laufrichtung Süden = SouthSprite
            if (Declaration.Walk == Declaration.WalkWorldMap.West) e.Graphics.DrawImage(item.SpriteWest, item.PosX, item.PosY, item.Width, item.Height);       // Wenn Laufrichtung West = WestSprite
            if (Declaration.Walk == Declaration.WalkWorldMap.East) e.Graphics.DrawImage(item.SpriteEast, item.PosX, item.PosY, item.Width, item.Height);       // Wenn Laufrichtung Osten = East Sprite

        }
    }

    // Wichtig mit dieser Methode wird die Map Bewegt

    public static void CheckPosition(Sprite Sprite)
    {

        if (Sprite.PosY <= 50)
        {
            Declaration.map.OffsetY -= 50;
            Sprite.PosY += 55;
            Sprite.NowY += 5;
        }

        if (Sprite.PosY >= GamePanel.ActiveForm.Height - 100)
        {
            Declaration.map.OffsetY += 50;
            Sprite.PosY -= 55;
            Sprite.NowY -= 5;
        }

        if (Sprite.PosX <= 50)
        {
            Declaration.map.OffsetX -= 50;
            Sprite.PosX += 55;
            Sprite.NowX += 5;
        }

        if (Sprite.PosX >= GamePanel.ActiveForm.Width - 100)
        {
            Declaration.map.OffsetX += 50;
            Sprite.PosX -= 55;
            Sprite.NowX -= 5;
        }

    }


}

[/CSHARP]

Hallo Andy,

besonders für Anfänger, die auf so ein „Tutorial“ stoßen, müssen davon ausgehen, dass es korrekte softwaretechnische Aspkete berücksichtigt.

Mal davon abgesehen, dass es hierfür einhundert mal bessere Tutorials gibt, und im speziellen Du, Andy, nicht qualifiziert bist solche anzubieten, sollte man schon drauf achten, dass die grundlegenden Prinzipien der OOP eingehalten werden.

  1. Klassen schreibt man groß, (Auch in C#)

Schön. Wie dieser initialisiert oder benötigt wird, wird hier aber nicht genannt. Gerade Anfäger werden doch an dieser Stelle eher frustriert drauf schauen.

  1. ALLES static?? - Damit verbaut man sich direkt zu beginn ordentliche Möglichkeiten das Spiel zu erweitern.

  2. Klasse Move

Eine Klasse beschreibt ein DING, eben ein Objekt. (Deswegen _Objekt_orientiert). Move ist 1. kein Objekt. Und wird auch niemals sein, da es nur copy paste static methoden beinhaltet.

Wenn ich jetzt schon Kollisionen mit etwas einbauen möchte, dann muss ich in JEDER Methode wieder code ändern. Dieser Code gehört doch in die Sprite Klasse. Und von der Sprite Klasse gehört es ein „Player“ zu erstellen.

Die benennung „Sprite Sprite“ ist auch suboptimal. Man weiß nicht, ob es die Klasse oder der Parameter gemeint ist beim lesen.

  1. Klasse Game:
    Man sieht nicht wo der Paint Event Handler registriert wird. (Ich kann schon C# und ich selber wüste nicht wo ich ihn registrieren soll, wie dann ein Anfänger!?).

Dann ruft dieser etwas auf, dass aussieht wie ein Member der Variable „render“, aber nein es ist eine Klasse und diese ist static ^^ Und implementiert hundert mal den gleichen Code.

  1. Klasse renderer

Die Methoden „Game.sprite()“ und „Game.map()“ sind essentiell, um zu verstehen, wie die Map mitbewegt wird. Aber sie fehlen in dem Tutorial.

(Ahh jetzt sehe ich, die Methode gibt einfach das jeweilige Objekt zurück ^^) Heißt natürlich nicht „getSprite()“. Oder greift direkt auf die Property der Klasse zu, wie es in C# üblich wäre.

  1. Die Klasse Declaration fehlt hier. Und deren Eigenschaften verstoßen auch gegen gängige Code-Conventionen.

Mein Fazit

Für Anfänger unbrauchbar. Grund hierfür sind nicht unerhebliche Auslassungen. Es fehlt das komplette Projekt, dass man hiermit mit hochladen werden könnte. Alles static und so wirklich erkärt, welche Methode dahinter steckt wird auch nicht.


Offtopic: Wie ich bereits mehrfach gesagt habe: Besser auf eins konzentrieren und sich einer größeren Community anschließen als in einem mini Forum ohne Aktivität ein Projekt nach dem anderen versemmeln.

Das gleiche, wie was ich in http://forum.byte-welt.net/threads/5031-Tutorial-Forum?p=28016&viewfull=1#post28016 geschrieben habe. So lange an irgendeinem Code-Snippet rumzufrickeln, bis es macht, was man will, ergibt noch kein Tutorial.