Zurück zur Übersicht

Einführung

Bearbeiten

Dieses Tutorial richtet sich an alle Personen, die bereits Erfahrung mit anderen Programmiersprachen gesammelt haben. Vor allem, wenn man von Blitz3D auf BlitzMax umsteigen will, ist dieses Tutorial das richtige. Für Nichtprogrammierer folgt eine kurze Einführung in die Programmierung. Programmierer, die bereits Erfahrung haben, können den folgenden Abschnitt überspringen.

Einführung in die Programmierung

Bearbeiten

Ein Programm besteht aus mehreren Zeilen Code, die ein Programmierer schreiben muss. Dieser Programmcode wird anschließend in eine dem Computer verständliche Sprache kompiliert. Das Schreiben des Codes unterliegt den Regeln einer Programmiersprache, Syntax genannt. Die Syntax einer Sprache kann man mit der Grammatik von "normalen" Sprachen wie Deutsch, Englisch usw. vergleichen.

Bestandteile einer Programmiersprache

Bearbeiten

Eine Programmiersprache besitzt einen Befehlssatz, welcher die Fähigkeiten einer Programmiersprache repräsentiert. Ein einzelner Befehl wird Keyword (Schlüsselwort) genannt. Ein Keyword entspricht den Wörtern einer "normalen" Sprache. Bei der Programmierung gibt es verschiedene Unterteilungen des Codes, z.B. einen Hauptteil (Main) und einen Funktionsteil.

Funktionen

Bearbeiten

Eine Funktion fasst mehrere Zeilen Code zusammen und wird meistens nur dann erstellt, wenn derselbe Programmcode mehrmals aufgerufen werden soll. Eine Funktion liefert einen Wert zurück, den man in einer Variablen speichern kann. Eine Variable ist ein Objekt, welches eine Zahl oder eine Zeichenkette (Strings) speichern kann. Wenn eine Funktion keinen Wert zurückliefert, spricht man häufig von einer Prozedur.

Variablen

Bearbeiten

Variablen werden mit dem Schlüsselwort Local deklariert, wenn sie global sein sollen (z.B. in Funktionen), dann nimmt man Global.

Local Variable
Global GlobaleVariable

Wenn man den Typ der Variablen kennzeichnen will, fügt man einen Doppelpunkt und den Namen der Klasse hinzu.

Local Variable:Int
Global Bild:TImage

Lokale Variablen sind nur in dem Abschnitt gültig, in dem sie definiert wurden. Sie können somit mehrmals mit demselben Namen vorkommen und trotzdem andere Werte besitzen. Wenn eine lokale Variable in einer Funktion definiert wurde, dann ist sie auch nur innerhalb dieser Funktion gültig. Wird eine lokale Variable flach in einer Quelldatei (.bmx) definiert, so ist sie auch nur innerhalb dieser Quelle gültig.

Eine globale Variable kann nur einmal im Quelltext mit diesem Namen vorkommen. Globale Variablen sind auch in Funktionen gültig. In einer Funktion können allerdings nur lokale Variablen definiert werden.

Variablentypen

Bearbeiten

Eine Variable ist ein Platz im Speicher wo wir einen Wert oder einen Text speichern können. Es gibt verschiedene Arten von Variablen, je nachdem wofür sie genutzt werden. Eine Variable kann entweder eine Zahl oder eine Zeichenkette (String) speichern. Je nachdem, welche Zahlen in der Variable gespeichert werden sollen, wählt man einen anderen Typ für die Variable.

Local Zahl:Int
Local Wort:String

Es gibt 4 Typen von Variablen, die Zahlen speichern können.

  • Byte
  • Short
  • Int
  • Long

2 weitere Typen von Variablen, die Fließkommazahlen speichern können:

  • Float
  • Double

Bei Zahlen, wo es nicht so sehr auf Genauigkeit, sondern vielmehr auf Geschwindigkeit ankommt sollte man den Typ Float wählen. Bei komplexen 3D-Berechnungen und Demos etc. wo man exakte Ergebnisse und gut aussehende Effekte haben möchte, nimmt man den Typ Double, wobei der Unterschied nur sehr gering ist.

Um eine Zeichenkette zu speichern, wählt man den Typ String.

  • String

Eine Variable kann auch ein Bild (Image) speichern, welches später auf den Bildschirm gezeichnet werden kann. Die dafür zuständige Klasse heisst TImage.

  • TImage

In Blitz3D war es möglich in einer Int-Variable ein Bild zu speichern und damit zu konvertieren. In BMax muss man den Variablentyp bei der Variablendefinition mit angeben, wenn es nicht der Typ Int ist.

Global Bild:TImage

Konstanten

Bearbeiten

Eine Konstante ist einer Variablen sehr ähnlich und ist trotzdem keine. Der Unterschied liegt darin, dass eine Konstante niemals ihren Wert verändert. Sie wird mit ihrem Wert initialisiert und behaltet diesen Wert für die gesamte Laufzeit des Programms. Eine Konstante definiert man mit Const.

Const SCREEN_WIDTH = 640

Einer Konstante kann selbstverständlich auch einen anderen Variablentyp als Int besitzen:

Const PI:Float = 3.14

Meistens werden Konstanten immer in Großbuchstaben geschrieben, um die Übersichtlichkeit zu erhöhen.

Speichermanagement

Bearbeiten

In Blitz Max geschieht das Speichermanagement nicht auf Benutzerbasis (jedenfalls normalerweise nicht). Es wurde nämlich ein GarbageCollector (kurz: GC) eingebaut, der sich alle Variablen ansieht und prüft, ob sie gleich NULL sind. NULL ist ein Wert, den man einer Variablen zuweisen kann, wenn man dem GC signalisieren will, dass diese Variable beim nächsten Aufruf des GC gelöscht werden soll.

Automatisch

Bearbeiten

Normalerweise achtet Blitz Max selbst auf Variablen, die gelöscht werden sollen. Man kann aber verschiedene Modi für den GC setzen:

  • Modus 1: Automatisch
  • Modus 2: Manuell

Wenn man den Wert auf manuell stellt, dann muss man selber darauf achten, dass man den GC an der richtigen Stelle startet. Den Modus des GarbageCollectors setzt man mit GCSetMode.

GCSetMode( mode:Int )

Den GarbageCollector kann man auch manuell aufrufen:

GCCollect()

Man sollte dies allerdings nicht zu oft tun, es reicht, wenn man ihn einmal in der Hauptschleife aufruft.

Durch die Einführung des neuen Listentyps wurden einige Blitz3D-Entwickler hart auf die Probe gestellt. Plötzlich funktionierte der folgende Code nicht mehr:

Global menu.TMenu
For menu = Each TMenu
 Print menu\caption$
Next

Das Keyword Each wurde entfernt und stattdessen EachIn hinzugefügt. Es ist aber nicht derselbe Befehl, denn EachIn iteriert durch eine Liste, einen Array oder eine Collection:

Global a[] = [1,2,3,4,5]
For Local i = EachIn a
 Print i
Next

Eine solche Schleife geht immer ein Element weiter, bis es schließlich zum Ende kommt.

Die neue Klasse für Listen nennt sich TList. Eine Liste kann beliebige Elemente enthalten, die man nach dem manuellen Hinuzfügen auch wieder entfernen kann. Normalerweise setzt man den Code für das Hinzufügen in eine Liste in den Konstruktor New (genau genommen: nach dem Konstruktor):

Global TMenuList:TList = New TList

Type TMenu
 Field caption$
 
 'Konstruktor
 Method New()
  TMenuList.AddLast(Self)
 End Method
End Type

Das sind insgesamt nur 4 Zeilen Code, die man hinzufügen muss, um durch alle Instanzen dieses Types iterieren zu können. Der nachfolgende Code nutzt die vorher angelegten Liste:

'Konstruktor wird aufgerufen, Element wird zur Liste hinzugefügt
Local filemenu:TMenu = New TMenu
filemenu.caption$ = "Datei"

'Jedes Element in der Liste wird in dieser Schleife erreicht
For Local menu:TMenu = EachIn TMenuList
 Print menu.caption$
Next

Netzwerk

Bearbeiten

Netzwerkprogrammierung gehört zu den komplexeren Gebieten der Spieleentwicklung. Dies liegt hauptsächlich daran, dass, sobald man damit beginnt, die Fehlerzahl und -komplexität immens zunimmt. Bei den meisten Fehlern im Netzwerkbereich ist standardmäßiges Debuggen quasi sinnlos oder gar nicht möglich, da beim Debuggen das Programm angehalten werden muss, während die Gegenstelle noch munter weiterläuft, was leicht Timeouts usw. auslösen kann. Zusätzlich erfordert fortgeschrittenes Netzwerkprogrammieren eine neue Sichtweise. Das Spiel läuf im Mehrspielermodus nicht mehr einfach linear ab. Im Einzelspielermodus weiß man immer, dass man alle nötigen Daten und Informationen über das Spielgeschehen hat. Im Mehrspielermodus kann es passieren, dass irgendwelche Informationen fehlen, wenn sie dringend gebraucht werden.