Du bist nicht angemeldet.

#1 23.07.2014 20:34

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Monkey X - Tutorial 2

Monkey X - Tutorial 2


Vorbetrachtung:

Falls noch keine Grundlagen in der Programmierung bestehen, bitte Tutorial 1 durchlesen.

Bevor wir uns nun ins Getuemmel muessen noch ein paar Dinge geklaert werden.
Ihr koennt Euch ja sicher vorstellen, dass der Quellcode im Laufe der Entwicklung immer groesser wird. Immer mehr Funktionen, Variablen und hoffentlich auch Kommentare (dies hilft ungemein!).
Damit man aber Dinge voneinander abkapseln kann, also "logisch trennen", bietet Monkey eine Importfunktion an. Mit dem Schluesselwort import kann man dem Compiler mitteilen, dass Code von anderer Stelle nachgeladen werden soll.

Dies koennte im Code so aussehen:

Import mojo
Import meine_andere_datei

Hmm, was ist dieses mojo? Mojo ist Modul was von Monkey bereitgestellt wird, es bietet Dinge wie Zeichenfunktionen und anderes. "meine_andere_datei" hingegen besagt, dass entweder ein Modul "meine_andere_datei" bereitstuende - oder aber im gleichen Verzeichnis wie unser Quellcode eine Datei "meine_andere_datei.monkey" herumliegt. Das System ist nicht ganz eindeutig geloest und bedarf etwas mehr Gewoehnung als es bei BlitzMax der Fall war (da gibt es Module und Dateien die man importieren kann, hier ist alles das Gleiche: eine Importierte Datei).
Fuer den Anfang reicht es, wenn wir uns merken: Import mojo brauchen wir, sobald wir eine grafische App entwickeln wollen.


Neben der Importfunktion, beschaeftigt sich dieses Tutorial auch mit Klassen. Klassen sind das was Funktionen fuer Anweisungen sind: eine Gruppierung. Eine Klasse beherbergt aber nicht nur verschiedene Funktionen, nein sie kann auch Variablen speichern. Das Besondere an Klassen ist aber nun, dass Instanzen dieser Klassen erzeugt werden koennen. Waere "Tagebuch" eine Klasse, dann waere "Maries Tagebuch" aber auch "Pauls Tagebuch" (der sicher nicht will, dass jeder weiss, dass er ein Tagebuch schreibt ;D) waeren Instanzen. Klassen koennen Variablen so einrichten, dass sie sowohl von Paul als auch von Marie abgerufen werden koennen, aber auch, dass jeder seine eigen Variablen besitzt. Und was fuer Variablen geht, das klappt auch mit Funktionen. Diese instanzbezogenen Funktionen heissen Methoden - prima, da laesst sich sowas ja gut auseinanderhalten. Wichtig ist hier nun: wenn etwas instanzbezogen ist, kann es auf die allgemeinen Variablen zugreifen, etwas allgemeines aber nicht auf instanzbezogene Daten.


Ein kleines Beispiel gefaellig?

Class Tagebuch
	Field besitzer:String

	Method New(besitzer:String = "")
		Self.besitzer = besitzer
	End Method
	
	Method gehoert:String()
		Return besitzer
	End Method
End


Function Main()
	Local MariesTagebuch:Tagebuch = New Tagebuch("Marie")
	Local PaulsTagebuch:Tagebuch = New Tagebuch("Susi")
	'hab mich geirrt, es gehoert Paul
	PaulsTagebuch.besitzer = "Paul"

	Print "Maries Tagebuch gehoert "+MariesTagebuch.gehoert()
	Print "Pauls Tagebuch gehoert "+PaulsTagebuch.gehoert()
End Function

Statt "local" fuer eine lokale Variable, definieren wir die Instanzeneigenschaften als "Field". Interessant ist hier noch die Method New, die kann prima genutzt werden, um neue Instanzen einer Klasse anzulegen. Monkey ruft diese Methode automatisch auf, versucht man mit New Klassenname eine neue Instanz zu erzeugen. Weiterhin gibt es die Method gehoert, sie liefert an den Nachfrager einen Text zurueck (string) und erwartet als Aufrufparameter einen Text. Gibt man diesen nicht an, wird ein leerer Text ("") angenommen, dass schimpft sich dann Standardwert.
Will man auf eine Eigenschaft einer Instanz von aussen zugreifen, so macht man dies mittels dem Variablennamen der die Instanz beherbergt, und dem mittels "." (Punkt) verknuepften Namen des "Fields". Gleichermassen verfaehrt man, will man Funktionen/Methoden einer Klasse aufrufen.

Genug geplaudert...



Los gehts:
Fangt im Editor eine neue Datei an: Schritt2.monkey und fuegt folgenden Inhalt ein:

Import mojo
Class MyApp Extends App
    Method OnCreate()
        'wird aufgerufen sobald die App fertiggeladen hat
    
        'Setzt die UpdateRate auf 15 Hertz.
        '15x pro Sekunde wird dadurch OnUpdate() aufgerufen
        'Diese muss unbedingt gesetzt werden, sonst passiert nix
        SetUpdateRate(15)
    End
        
    Method OnRender()
        'Einsprungspunkt für alle Darstellungen (zeichnen)
    End
    
    Method OnUpdate()
        'wird aller "UpdateRate"-Hertz aufgerufen
        '(in unserem Fall aller 15x pro Sek)
    End
End


'die Main() wird automatisch aufgerufen - hier definieren wir was 
'beim Ausfuehren des Programmes gemacht wird
'"App" definiert, dass OnRender/OnUpdate usw ausgefuehrt werden - da 
'wir unsere MyApp von "App" erweitern, uebernehmen wir dieses Verhalten
Function Main()
        New MyApp
End Function

Puhh, wenigstens unsere alte bekannte Funktion "Main()" ist noch dabei (ganz unten), aber was ist da nun der Inhalt?
Statt irgendwelcher If-then-Bedingungen steht da New MyApp. Wir wissen ja nun, dass damit eine neue Instanz der Klasse "MyApp" erzeugt wird. Warum diese nicht in einer Variable gespeichert wird? Hmm, da wir MyApp selbst nicht verwenden oder irgendwie von aussen darauf zugreifen, ist dies einfach in dem Moment nicht noetig. MyApp hat aber doch gar keine New-Methode? Hat sie doch! Denn mittels dem Schluesselwort "extends" haben wir in der Klassendefinition festgelegt, dass "MyApp" alle Eigenschaften, Funktionen usw. von der Klasse "App" erbt. Diese App-Klasse wird von Monkey bereitgestellt. Die New-Methode von App kuemmert sich darum, dass bestimmte Methoden aufgerufen werden (beispielsweise "OnRender()" -damit auch immer fein der Bildschirm unserer App gezeichnet wird, oder "OnCreate()" sobald alles notwendige geladen worden ist).

Jetzt, wo sicher so mancher schon die Rakete gestartet hat: zu sehen ist hier ersteinmal noch nix, auch wenn die Funktionen "OnRender()" und "OnUpdate()" ja schonmal da sind. Aber wofuer ist denn "OnUpdate()"? Wie es sich fuer ordentliche Programmierer gehoert, trennen wir "Logik" und "Grafik". Das Zeichnen eines Autos ist also an anderer Stelle zu realisieren, als die Bewegung dieses (und vorallem die Kontrolle, ob er gegen eine Wand gefahren ist). Warum? Zeichnen ist oft um Welten langsamer als das die Spiellogik (Schach ausgenommen!).
Da alte Hardware nicht soviele Zeichnungen pro Sekunde fertigstellen kann, wir aber sicherstellen muessen, dass uns zwischen den Zeichnungen kein Autocrash durch die Lappen geht, koennen wir auf diese Art die Logik haeufiger pro Sekunde Berechnungen durchfuehren lassen, als Zeichnungen. So kann es sein, dass 10x pro Sekunde das Auto gezeichnet wird (nach 1m, nach 3, nach 7, nach 11m), aber 40x pro Sekunde bewegt (1, 1.1, 1.2, ... 11m).


So, nun wollen wir aber was zeichnen, weg von diesem ganzen Theoriekram: das Aequivalent zur Konsolenausgabe mittels "Print" ist "DrawText". Da wir nun aber nicht mehr einfach Zeile fuer Zeile ausgeben koennen, bedarf es noch einer Koordinatenangabe. Waehrend Systeme wie OpenGL die verfuegbare Zeichenflaeche in 0,0-1,1 aufteilen (0.5, 0.5 waere also die Mitte) ist Monkey da netter (was nicht gleichzusetzen mit "besser" ist!) und erwartet Pixelangaben: ein 10,10 sagt also, von oben links gehst du 10 pixel nach rechts und 10 nach unten.

Worauf wartest Du noch? Hier ist der naechste Code (ueberschreibe ruhig den alten)

Import mojo
Class MyApp Extends App
	Field meinName:String = "Paul"
	'die derzeitige Position unseres "Mein Name ist"-Textes
	Field ausgabeX:Int = 0

    Method OnCreate()
        'wird aufgerufen sobald die App fertiggeladen hat
    
        'Setzt die UpdateRate auf 15 Hertz.
        '15x pro Sekunde wird dadurch OnUpdate() aufgerufen
        'Diese muss unbedingt gesetzt werden, sonst passiert nix
        SetUpdateRate(15)
    End Method
        
    Method OnRender()
        'Bildschirm leeren, einfarbige Flaeche
        Cls

        'Farbe setzen
        SetColor(0, 0, 255)

        DrawText("Hello World!", 0, 0)
        DrawText("Mein Name ist:" + Self.meinName, ausgabeX, 15)
    End Method
    
    Method OnUpdate()
        'wird aller "UpdateRate"-Hertz aufgerufen
        '(in unserem Fall aller 15x pro Sek)

		'pro UpdateRate erhoehen wir um 1, macht 15 Pixel pro Sekunde
        ausgabeX = ausgabeX + 1

        'nach 100 Pixeln wieder nach 0
        If ausgabeX >= 100 Then ausgabeX = 0
    End Method
End Class


'die Main() wird automatisch aufgerufen - hier definieren wir was 
'beim Ausfuehren des Programmes gemacht wird
'"App" definiert, dass OnRender/OnUpdate usw ausgefuehrt werden - da 
'wir unsere MyApp von "App" erweitern, uebernehmen wir dieses Verhalten
Function Main()
        New MyApp
End Function

Nun sind OnRender() und OnUpdate() endlich mit Inhalt gefuellt. Mittels Cls loeschen wir etwaigen Datenmuell vom Grafikspeicher (malen eine leere Flaeche ueber Pixelmuell) und dann geben wir auch schon den Text aus. Schoen ist hier auch zu sehen, wie wir Logik (Bewegung des Textes) und Grafik (Zeichnen des Textes) trennen. Ach und eine Kleinigkeit habe ich noch geaendert: statt alle Methoden, Klassen immer mit "End" abzuschliessen, bevorzuge ich es, etwas aussagekraeftigere Varianten zu nutzen (End Class, End Method, ...).


Wer nun noch weiter ueben will: Es gibt noch andere "Primitive" zum Zeichnen:
DrawRect(x,y,w,h)
DrawOval(x,y,w,h)


Uebung: Damit (und mit SetColor) muesste sich doch ein "blockiges Auto" zeichnen lassen oder?

bye
Ron


sigimg2.php?id=1

Offline

#2 24.07.2014 02:53

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Hier mein erstes Auto:

Import mojo
Class MyApp Extends App
   
    Method OnCreate()
        'wird aufgerufen sobald die App fertiggeladen hat
    
        'Setzt die UpdateRate auf 15 Hertz.
        '15x pro Sekunde wird dadurch OnUpdate() aufgerufen
        'Diese muss unbedingt gesetzt werden, sonst passiert nix
        SetUpdateRate(15)
    End Method
        
    Method OnRender()
        'Bildschirm leeren, einfarbige Flaeche
        Cls

        'Farbe setzen
        SetColor(0, 0, 255)
        
        'Karosse
        DrawRect(160, 170, 180, 50)
        DrawRect(210, 130, 100, 40)  
        
        'Räder
        SetColor(0, 0, 388)
        DrawOval(180, 200, 40, 40)
        DrawOval(290, 200, 40, 40)
        
        SetColor(0, 0, 588)
        DrawOval(185, 205, 30, 30)
        DrawOval(295, 205, 30, 30)
        
        
              
    End Method
End Class


'die Main() wird automatisch aufgerufen - hier definieren wir was 
'beim Ausfuehren des Programmes gemacht wird
'"App" definiert, dass OnRender/OnUpdate usw ausgefuehrt werden - da 
'wir unsere MyApp von "App" erweitern, uebernehmen wir dieses Verhalten
Function Main()
        New MyApp
End Function



Eigentlich habe ich versucht, das Teil auch noch zu bewegen. ähnlich der Schrift.
Wußte aber nicht, wie ich das definieren sollte.
Bis Field bin ich noch gekommen...

Beitrag geändert von Gast2 (24.07.2014 03:33)

Offline

#3 24.07.2014 08:09

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Zum Bewegen:

In dem Beispiel mit dem bewegenden Text benutze ich eine Variable um den Text versetzt zu positionieren. Wir haben also ein eine dynamische Koordinate, statt "10" nutzen wir die Variable "ausgabeX".

Jederzeit koennten wir aber auch beim Zeichnen hinschreiben "ausgabe X + 10", dass nenne ich dann "lokalen Offset" (also eine Verschiebung).

Du zeichnest deine schicke Karre aber immer an fixen Punkten (x = 160, x = 210, ...) besser waere es aber, wenn sich diese Zahlen veraendern wuerden -> Stichwort: Variable.
Eventuell denkst Du nun, fuer jedes Bauteil eine Variable zu nutzen, aber nein, alle koennen die gleiche Variable nutzen - bspweise den "linkesten Punkt". Die Reifen sind dann "linkerPunkt + 100" oder "linkerPunkt + 200" versetzt.

Stell Dir einfach vor, Du hast dir aus Papier was gebaut und zusammengeheftet - nun verschiebst du einfach mit dem Zeigefinger auf einem Teil des Autos alle Teile in einem Rutsch - so aehnlich laeuft es hier ab.


Da ich nun aber schon viel erklaert habe eine neue Uebung: Das Auto soll aus dem Bildschirm herausfahren und dann auf der anderen Seite wieder herauskommen:

- finde durch probieren heraus wie breit der Bildschirm ist (dafuer gibt es eine Funktion, aber finde die Zahl halt raus)
- lasse die Autoposition bis zu dieser Zahl erhoehen, setze sie dann so ins negative, dass die andere Seite des Autos noch nicht auf der anderen Seite zu sehen waere (- Autobreite)

Damit muesste dein Auto schoen von links nach rechts tuckern.

Wenn Du willst kannst du Dir auch ueberlegen, wie man es machen muesste, dass das Auto nicht erst verschwindet und dann auf der anderen Seite auftaucht, sondern die verschwindende Spitze bereits auf der anderen Seite wieder zu sehen ist.


bye
Ron


sigimg2.php?id=1

Offline

#4 25.07.2014 21:23

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Mal eine Zwischenfrage:

Ich wollte heute weitermachen. Habe hier den Schritt eins im Monkey geöffnet und der Funktioniert, wie es soll.

Habe dann neu geöffnet und schreibe den Kram so rein. Aber erstens verfärbt sich der Text nicht so fein. Und dann wird die Rakete nicht interaktiv.

Habe ich was vergessen?

Ich habe aber auch die Übung mit dem Auto reinkopiert. Da wird Raketchen a net bunt....



Import mojo
Class MyApp Extends App
   
    Method OnCreate()
        'wird aufgerufen sobald die App fertiggeladen hat
    
        'Setzt die UpdateRate auf 15 Hertz.
        '15x pro Sekunde wird dadurch OnUpdate() aufgerufen
        'Diese muss unbedingt gesetzt werden, sonst passiert nix
        SetUpdateRate(15)
    End Method
    
     Method OnRender()
        'Bildschirm leeren, einfarbige Flaeche
        Cls

        'Farbe setzen
        SetColor(0, 0, 255)
        
        'Karosse
        DrawRect(ausgabeX, 170, 180, 50)
        DrawRect(ausgabeX + 50, 130, 100, 40)  
        
        'Räder
        SetColor(0, 0, 388)
        DrawOval(ausgabeX + 20, 200, 40, 40)
        DrawOval(ausgabeX + 130, 200, 40, 40)
        
        SetColor(0, 0, 588)
        DrawOval(ausgabeX + 5, 205, 30, 30)
        DrawOval(ausgabeX + 115, 205, 30, 30)
        
                      
    End Method
End Class    
    
Function Main()
    New MyApp
End Function  

Offline

#5 25.07.2014 21:43

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Hast Du darauf geachtet, die Datei mit der Endung ".monkey" zuspeichern?

Bei Linux kann man Dateien ja nennen wie man will, aber "TED" braucht unbedingt die .monkey-Endung.


PS: eine andere kostenlose IDE fuer Monkey:

https://github.com/engor/Jentos_IDE
http://fingerdev.com/apps/jentos/

brauchst nur diese Datei herunterladen:
https://drive.google.com/uc?id=0Bx2zoIlA6GzKR1JKc0Jpbmpfb0k

Die schiebst Du dann in Dein Monkeyverzeichnis neben die "Monkey"-Datei - und dann haettest Du einen anderen Editor (der meines Erachtens "mehr" kann - hilfreiche Dinge halt).


@Uebung
ja so muesste es geloest werden (freilich konntest Du nun nicht testen und bemerken,dass du "ausgabeX" nicht deklariert hast biggrin) - nun noch ein paar Gedanken dazu, wie man den Teil links sichtbar machen koennte, der rechts schon rausgefahren ist. Nein, ich rede nicht von speziellen Befehlen. Ein ganz einfacher "Trick".


bye
Ron


sigimg2.php?id=1

Offline

#6 25.07.2014 22:19

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

NICHT LESEN
wenn du noch an der "links rein- und rechts noch rausfahrend"-Sache ueberlegst.





Hier nun mal eine erweiterte Fassung - die Dein Auto zeichnet (ich glaube die Radkappen willst du nochmal ueberarbeiten):

Import mojo
Class MyApp Extends App
	Field autoA:TAuto
	Field autoB:TAuto

	Method OnCreate()
		'wird aufgerufen sobald die App fertiggeladen hat

		'Setzt die UpdateRate auf 15 Hertz.
		'15x pro Sekunde wird dadurch OnUpdate() aufgerufen
		'Diese muss unbedingt gesetzt werden, sonst passiert nix
		SetUpdateRate(20)
		
		'erzeuge die Autos
		autoA = New TAuto(-200, 200)
		autoB = New TAuto
	End Method

	Method OnUpdate()
		'Autos bewegen
		autoA.Update()
		autoB.Update()
	End Method

	Method OnRender()
		'Bildschirm leeren, einfarbige Flaeche
		Cls

		'Autos zeichnen
		autoA.Draw()
		autoB.Draw()
	End Method
End Class


Class TAuto
	'Eigenschaften einer jeden Instanz von TAuto
	Field x:Int, y:Int
	Field breite:Int = 180
 	'Geschwindigkeit horizontal/vertikal
	Field dx:Int = 3, dy:Int = 0
	Field farbeR:Int, farbeG:Int, farbeB:Int

	'wenn man "new TAuto(x,y)" aufruft:
	Method New(x:Int, y:Int)
		Self.x = x
		Self.y = y
		'setze die farben jeweils zufaellig rot = 100-255, gruen ... blau ...
		SetzeFarbe(Rnd(100, 255), Rnd(100, 255), Rnd(100, 255))
	End Method
	

	'wenn man "new TAuto()" aufruft:
	Method New()
		x = 0
		'eine zufaellige Zahl raussuchen
		y = Rnd(100, 200)

		'setze die farben jeweils zufaellig rot = 100-255, gruen ... blau ...
		SetzeFarbe(Rnd(100, 255), Rnd(100, 255), Rnd(100, 255))
	End Method


	Method SetzeFarbe(r:Int, g:Int, b:Int)
		Self.farbeR = r
		Self.farbeG = g
		Self.farbeB = b
	End Method
	
	
	Method Update()
		'um die geschwindigkeit "pro update" erhoehen
		x = x + dx
		y = y + dy
		
		'links wieder anfangen wenn komplett verschwunden
		'da wir das "zweite Stueck" Auto schon zeichnen, koennen
		'wir direkt bei 0 anfangen
		If x > DeviceWidth() Then x = 0
	End Method
	
		
	'allgemeine Zeichenmethode
	Method Draw()
		DrawCar(x, y)
		'falls das Auto schon rechts raus verschwindet, zeichnen
		'wir es links schon ein wenig neu
		If x + breite > DeviceWidth()
			'800 - x = der schon nicht mehr sichtbare teil
			DrawCar (-(DeviceWidth()-x), y)
		Endif
	End Method

	
	'unsere spezielle Zeichenmethode
	'dadurch koennen wir prima "halbe Autos" zeichnen	
	Method DrawCar(x:Int, y:Int)
		'Farbe setzen - Werte gehen von 0-255
		SetColor(farbeR, farbeG, farbeB)
		
		'Karosse
		DrawRect(x, y + 40, 180, 50)
		DrawRect(x + 50, y, 100, 40)
		
		'Räder
		SetColor(farbeR - 50, farbeG - 50, farbeB - 50)
		DrawOval(x + 20, y + 70, 40, 40)
		DrawOval(x + 130, y + 70, 40, 40)
		
		SetColor(farbeR - 80, farbeG - 80, farbeB - 80)
		DrawOval(x + 5, y + 75, 30, 30)
		DrawOval(x + 115, y + 75, 30, 30)
	End Method
	
End Class

	
Function Main()
	New MyApp
End Function

Neu ist hier "Rnd" - fuer "Random", also Zufall, die Parameter die wir nutzen sind "Minima" und "Maxima" des Zufallswertes.

Des Weiteren nutzen wir "DeviceWidth()" um die Bildschirmbreite zurueckgeben zu lassen.

Auch zeigt sich hier schon wie man mit Monkey Funktionen "ueberlaedt" (mehrere Varianten mit abweichenden Parametern ...das geht mit BlitzMax noch nicht). Dazu sage ich aber spaeter noch was.


Viel Spass beim anpassen und herumbasteln.


bye
Ron


sigimg2.php?id=1

Offline

#7 25.07.2014 22:26

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Nein, freilich habe ich das monkey vergessen. Das war noch voll unfertig. Wunderte mich nur, warum da nix passierte.

.monkey, .monkey, punktmonkey -> merken gw_smiley_zwinkern

Danke. Kann ich weiterwurschteln.
Hab auch nicht weitergelesen.

Offline

#8 26.07.2014 12:47

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

So, hier mein fahrendes Auto;)



Import mojo
Class MyApp Extends App
   Field ausgabeX:Int = 100
    Method OnCreate()
        'wird aufgerufen sobald die App fertiggeladen hat
    
        'Setzt die UpdateRate auf 15 Hertz.
        '15x pro Sekunde wird dadurch OnUpdate() aufgerufen
        'Diese muss unbedingt gesetzt werden, sonst passiert nix
        SetUpdateRate(15)
    End Method
    
     Method OnRender()
        'Bildschirm leeren, einfarbige Flaeche
        Cls

        'Farbe setzen
        SetColor(0, 0, 255)
        
        'Karosse
        DrawRect(ausgabeX, 170, 180, 50)
        DrawRect(ausgabeX + 50, 130, 100, 40)  
        
        'Räder
        SetColor(0, 0, 388)
        DrawOval(ausgabeX + 20, 200, 40, 40)
        DrawOval(ausgabeX + 130, 200, 40, 40)
        
        SetColor(0, 0, 588)
        DrawOval(ausgabeX + 25, 205, 30, 30)
        DrawOval(ausgabeX + 135, 205, 30, 30)
                              
    End Method
    
    
    Method OnUpdate()
        'wird aller "UpdateRate"-Hertz aufgerufen
        '(in unserem Fall aller 15x pro Sek)

        'pro UpdateRate erhoehen wir um 1, macht 15 Pixel pro Sekunde
        ausgabeX = ausgabeX + 3

        'nach 100 Pixeln wieder nach 0
        If ausgabeX >= 640 Then ausgabeX = -180
    End Method
    
    
End Class    
    
Function Main()
    New MyApp
End Function   Ich habe mal kopiert, was mit dem Installationswerkzeug entfernt, aufgefrischt und zugefügt wird:



@andere kostenlose IDE fuer Monkey

Ich habe die angegebene Datei ins Verzeichnis kopiert.
Was nun?

Muß ich das öffnen? Nutzt monkey das einfach mit?

Beitrag geändert von Gast2 (26.07.2014 12:50)

Offline

#9 27.07.2014 09:32

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

das ist eine andere ausfuehrbare Datei ... halt eine andere ".exe" sozusagen.

Function Main()
    New MyApp
End Function   Ich habe mal kopiert, was mit dem Installationswerkzeug entfernt, aufgefrischt und zugefügt wird:

?? wie meinen?


bye
Ron


sigimg2.php?id=1

Offline

#10 27.07.2014 12:03

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Tschuldigung. Wurmfortsatz;)


Die andere IDE startet nicht.

Beitrag geändert von Gast2 (27.07.2014 12:04)

Offline

#11 27.07.2014 16:16

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

starte es mal von der Konsole aus...so zwecks Fehlermeldungen, wenns ne geht, auch kein Beinbruch biggrin


bye
Ron


sigimg2.php?id=1

Offline

#12 27.07.2014 16:24

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Ich hab's schon versucht über Terminal zu starten (Wird immer angeboten "ausführen", "im Terminal ausführen", "abbrechen". Geht auch nicht.

Offline

#13 27.07.2014 16:48

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Keine Fehlermeldung?

fuehre im dortigen Verzeichnis mal aus "ldd dateiname", dann zeigt es dir, ob irgend eine der "Bibliotheken"fehlt (sicher was QT-maessiges).


bye
Ron


sigimg2.php?id=1

Offline

#14 27.07.2014 18:10

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Keine Fehlermeldung

bei Ausführung "Idd jentos_v1.1_linux"


knoppix@Microknoppix:/media/sdb8/Monkey/MonkeyX77a$ Idd jentos_v1.1_linux
bash: Idd: Kommando nicht gefunden.

Offline

#15 28.07.2014 13:53

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

LDD ... linked ... nicht I/i.

$ ldd jentos_v1.1_linux

bye
Ron


sigimg2.php?id=1

Offline

#16 28.07.2014 14:09

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Das klingt doch schon besser:


knoppix@Microknoppix:/media/sdb8/Monkey/MonkeyX77a$ ldd jentos_v1.1_linux
\tdas Programm ist nicht dynamisch gelinkt

Offline

#17 28.07.2014 18:05

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Hmmm

ronny@RonnyPC ~/Arbeit/Programmieren/MonkeyX77a $ ldd jentos_v1.1_linux 
	linux-vdso.so.1 =>  (0x00007fff653fe000)
	libQt5WebKitWidgets.so.5 => /usr/lib/x86_64-linux-gnu/libQt5WebKitWidgets.so.5 (0x00007f8578597000)
	libQt5WebKit.so.5 => /usr/lib/x86_64-linux-gnu/libQt5WebKit.so.5 (0x00007f85762cc000)
	libQt5Widgets.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 (0x00007f8575ac4000)
	libQt5Network.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007f8575782000)
	libQt5Gui.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 (0x00007f85751b5000)
	libQt5Core.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007f8574ba1000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8574984000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8574680000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8574469000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f85740a1000)
	libQt5OpenGL.so.5 => /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so.5 (0x00007f8573e37000)
	libQt5PrintSupport.so.5 => /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5 (0x00007f8573be0000)
	libQt5Sensors.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Sensors.so.5 (0x00007f85739a7000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f857379f000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f8573585000)
	libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f857337b000)
	libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f8573178000)
	libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f8572f22000)
	libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f8572cfc000)
	libicui18n.so.48 => /usr/lib/x86_64-linux-gnu/libicui18n.so.48 (0x00007f8572934000)
	libicuuc.so.48 => /usr/lib/x86_64-linux-gnu/libicuuc.so.48 (0x00007f85725c7000)
	libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f8572292000)
	libxslt.so.1 => /usr/lib/x86_64-linux-gnu/libxslt.so.1 (0x00007f8572055000)
	libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f8571cee000)
	libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f85719ed000)
	libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f857179c000)
	libgstreamer-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0 (0x00007f8571499000)
	libgstapp-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstapp-1.0.so.0 (0x00007f857128d000)
	libgstbase-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0 (0x00007f8571036000)
	libgstpbutils-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstpbutils-1.0.so.0 (0x00007f8570e0f000)
	libgstvideo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0 (0x00007f8570bcd000)
	libgstaudio-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0 (0x00007f8570987000)
	libsqlite3.so.0 => /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007f85706d3000)
	libQt5Quick.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5 (0x00007f8570178000)
	libQt5Qml.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5 (0x00007f856fd3b000)
	libQt5Sql.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Sql.so.5 (0x00007f856fafc000)
	libQt5Location.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Location.so.5 (0x00007f856f85a000)
	libGL.so.1 => /usr/lib/fglrx/libGL.so.1 (0x00007f856f64e000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f856f349000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f856f145000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f8578801000)
	libicudata.so.48 => /usr/lib/x86_64-linux-gnu/libicudata.so.48 (0x00007f856ddd4000)
	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f856dbb6000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f856d993000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f856d754000)
	libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f856d54c000)
	libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f856d347000)
	libgsttag-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libgsttag-1.0.so.0 (0x00007f856d10f000)
	libQt5V8.so.5 => /usr/lib/x86_64-linux-gnu/libQt5V8.so.5 (0x00007f856cac4000)
	libQt53D.so.5 => /usr/lib/x86_64-linux-gnu/libQt53D.so.5 (0x00007f856c588000)
	libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f856c375000)
	libatiuki.so.1 => /usr/lib/fglrx/libatiuki.so.1 (0x00007f856c25a000)
	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f856c056000)
	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f856be4f000)

Klingt nach "es braucht die QT 5 Bibiotheken".

Aaaaber... ich habs jetzt mal bei Knoppix probiert: kann es sein dass Du eine 32Bit-Variante installiert hast - die Binaerdatei ist ja fuer 64Bit gemacht.

$ objdump -f jentos_v1.1_linux 

jentos_v1.1_linux:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x000000000041b675

Lass dich davon aber nicht abhalten: man kann zwar selbst das Programm kompilieren (Code ist verfuegbar) aber "lerne erstmal" die Grundzuege mit Monkey/Ted.



bye
Ron


sigimg2.php?id=1

Offline

#18 28.07.2014 19:52

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Ronny schrieb:

... aber "lerne erstmal" die Grundzuege mit Monkey/Ted.


Hmm. Halte ich auch für besser;)

Also vorwärts!

Hast Du eigentlich irgendwo eine Tabelle mit den Befehlen verfügbar?

Sonst suche ich mir die selber zusammen, immer so, wie es hier vorwärtsgeht. Ist vielleicht sogar besser wegen der Einprägung.

Offline

#19 28.07.2014 20:18

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Die Befehle sind "Funktionen" von Modulen. Es gibt so Logiksachen wie unsere "if ... then ... else... endif". Dinge wie "Print" sind aber Funktionen die generell zur Verfuegung stehen (also nicht nur innerhalb einer Klasse).


Im naechsten Tutorial geht es dann eh um "LoadImage/DrawImage" und wir nutzen "import" um eine eigene, zweite Datei, zu importieren.


bye
Ron


sigimg2.php?id=1

Offline

#20 29.07.2014 20:18

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Paar Fragen. Mußt sie nicht ausschweifend beantworten, Stichpunkte reichen sicher, da ich glaube, das Prinzip zu verstehen, aber auch Namen dafür möchte;)


    Field autoA:TAuto
    Field autoB:TAuto


Was ist der genaue Prozess, der hier abläuft bzw. beschrieben wird?



       
        'erzeuge die Autos
        autoA = New TAuto(-200, 200)
        autoB = New TAuto

Die vorher im Field benannten Autos werden jetzt erst erzeugt?



    Method OnUpdate()
        'Autos bewegen
        autoA.Update()
        autoB.Update()
    End Method

Warum wird hier nicht gleich die Updaterate eingetragen?
Weil dies eine Klasse für sich ist, die insgesamt beschreibt, was passieren soll? Die genaue Ausführung sind dann eigenen Klassen?





Class TAuto
    'Eigenschaften einer jeden Instanz von TAuto
    Field x:Int, y:Int
    Field breite:Int = 180
        'Geschwindigkeit horizontal/vertikal
    Field dx:Int = 3, dy:Int = 0
    Field farbeR:Int, farbeG:Int, farbeB:Int


Was meint hier jeweils das Int? Initiiere?


    'wenn man "new TAuto(x,y)" aufruft:
    Method New(x:Int, y:Int)
        Self.x = x
        Self.y = y
        'setze die farben jeweils zufaellig rot = 100-255, gruen ... blau ...
        SetzeFarbe(Rnd(100, 255), Rnd(100, 255), Rnd(100, 255))
    End Method

   

Was meint das Self.?
Warum „setze“? Also deutsch? Hast Du das selber definiert?




Alles in allem verstehe ich das.
Aber ob ich das jetzt umsetzen könnte?
Na, vielleicht denke ich mir mal eine Aufgabe aus.
Oder hast Du eine parat?

Offline

#21 29.07.2014 22:16

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Field autoA:TAuto

Hier teilen wir dem Kompiler (und Leser) mit, dass die umstehende Klasse eine Eigenschaft "autoA" hat... und diese ist vom Typ "TAuto" (sie koennte auch vom Typ "Int" oder "String" sein). Dadurch hat dann jede Instanz der Klasse die Eigenschaft "autoA" und kann auf die Eigenschaften von TAuto (und den spezifischen Eigenschaften von autoA) zugreifen.

Wir koennten schon dort die Autos erzeugen, also

Field autoA:TAuto = new TAuto(-200, 00)

Manchmal erzeugt dies auch mehr Uebersicht, manchmal aber ist ein zentraler Ort (vorallem, wenn man von einer anderen Klasse "erbt", also "class TMeinTyp extends TAndererTyp") die bessere Loesung. Notwendig ist es, wenn bei den Parametern Variablen genutzt werden (bspweise "jedes Auto ist 10 Pixel weiter rechts als das zuvor").


Gast2 schrieb:

Warum wird hier nicht gleich die Updaterate eingetragen?

Du meinst, warum ich nicht autoA.Update(x) aufrufe, um der Methode "Update()" von autoA mitzuteilen mit welchem Wert es zu arbeiten hat?

Falls ja:
Man kann alle "Update()"-Methoden so schreiben, dass sie einen "delta"-Parameter erwarten (delta = Zeit seit letztem Update als Bruchteil der Updatefrequenz: 1.0 = eine komplette Zeit zwischen zwei Updates) oder andere Werte. Oder aber man laesst sie - so wie du richtig erkannt hast - "allgemeingefasst" und laesst die Methode selbst Dinge herausfinden.

Bei TVTower bspweise kann man mittels "GetDeltaTimer().GetDelta()" von ueberall den gerade gueltigen Deltawert ermitteln. Ein Vorteil ist es, weil wir nicht immer davon ausgehen koennen, dass wir Methoden veraendern koennen, wenn wir von anderen Klassen vererben. Bei BlitzMax muss die vererbte Klasse den gleichen "Funktionskopf" besitzen wie das Original. Wenn also "Fahrzeug" die Methode "Update(x:int, y:int)" haette, muesste die "Auto extends Fahrzeug"-Klasse auch "Update(x:int, y:int)" haben und duerfte nicht einfach einen neuen Parameter hinzufuegen. Bei Monkey koennte dies dank "Ueberladung" aber funktionieren. Eindeutig macht es dies aber in dem Fall nicht. Ich persoenlich finde die Ueberladung nur bei "Settern" (also Funktionen die Werte setzen) richtig praktisch, da man da bequem fuer Dritte Sachen bereitstellen kann (SetPos(point), SetPos(x,y), SetPos(rect), ...).

-

Falls Du aber meintest, wieso ich dort nicht den Befehl "SetUpdateRate(15)" ausfuehre?
Das jedes mal zu machen, wuerde einen ziemlichen Rattenschwanz mit sich ziehen. Auch wissen wir ja nicht, ob sich da nicht intern ein Zaehler 0 setzt, oder was da noch passiert. Das ist eher ein Befehl um etwas zu Initialisieren, aehnlich einem "StarteGrafikModus()"-Befehl.


@Was meint das Int.

Ich dachte das haette ich erwaehnt. Int steht fuer "Integer".

Int ... Integer, Ganzzahlen (-5, 3, 0 ...)
Float ... Fliesskomma (1.11012, -121.22, 0.0)
Double ... groessere Fliesskommazahlen (13423423432.2342)
Long ... groessere Ganzzahlen
String ... Textzeilen ("abc", "dadgtt r g dfgd~n~n" - letzteres sind zwei "Zeilenumbrueche")

Das sind alles von der Sache her "Klassen" (aber etwas anders umgesetzt, aus Geschwindigkeitsgruenden) die Funktionen haben (strings bspweise "ToInt()" ... ein "5".ToInt() erzeugt einen Integer mit dem Wert 5).


@self
Self sagt (das habe ich auch erklaert), dass die folgende Eigenschaft sich auf die der Instanz bezieht.

Global meineVariable:Int = 5

'ich schreibe immer "T" vor den Typ, auch wenn er hier "Class" heisst
'und man da auch ein "CAuto" drauss machen koennte :p.
'Notwendig ist das nicht.
Class TAuto 
    Field meineVariable:Int = 10


    'Void besagt: es wird nix zurueckgegeben
    Method Run:Void()
       local meineVariable:Int = 20
       Print "meineVariable: " + self.meineVariable
       Print "meineVariable: " + meineVariable
       Print "meineVariable: " + .meineVariable
    End Method
End Class


Function Main()
	Local auto:TAuto = New TAuto()
	auto.Run()
End Function

@Warum "SetzeFarbe"
Ja wir haben ja die Methode "SetzeFarbe" selbst angelegt ... also selber definiert.



@Aufgabe
Erweitere das Autobeispiel um eine Klasse "TStrasse" - die kann sich ja sogar auch bewegen (wenn wir die Strassenmarkierung "bewegen"). also: graues Rechteck von links nach rechts, eigener "abstandX" fuer den Markierungsstart.
Das dient einfach dazu, dass du ein wenig mit den Klassen in Beruehrung kommst.


bye
Ron


sigimg2.php?id=1

Offline

#22 29.07.2014 23:11

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Ups. Tschuldige, wenn ich Sachen frage, die wohl schonmal erklärt waren.

Irgend ist das wie mit Mathetexten, wenn mir die Gleichungen nicht schlüssig waren, verlor sich selbst normaler Text dann im diffusen.
Wenn ich jetzt Deine ersten Beispiele nochmal anschaue, ist mir da manches klarer, als zu Beginn.

Und manches bracuhe ich wohl auch einfach überdeutlich;)

Offline

#23 30.07.2014 07:58

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Dafuer sind Fragen da... also ruhig stellen.


bye
Ron


sigimg2.php?id=1

Offline

#24 30.07.2014 19:17

Gast2
TVT-Roadie
Registriert: 07.06.2013
Beiträge: 4.276

Re: Monkey X - Tutorial 2

Da fällt mir ein: Bin zwar wegen der Spielanleitung nicht mehr zu gekommen. Aber ich werde einfach 2 Bälle machen, die von den Bildschirmrändern zurückprallen und deren Geschwindigkeit sich beim Aufprall ändert.

Offline

#25 30.07.2014 20:48

Ronny
Administrator
Ort: Chemnitz
Registriert: 08.11.2001
Beiträge: 11.709
Webseite

Re: Monkey X - Tutorial 2

Ja... Gerne auch mit "Sin" und "Tan"-Berechnungen (Einfallswinkel und Co tongue)


bye
Ron


sigimg2.php?id=1

Offline

Schnellantwort auf dieses Thema

Schreibe deinen Beitrag und versende ihn
Bist Du ein Mensch oder ein Roboter ?

Verifizierung, dass diese Aktion durch eine reale Person vorgenommen wird und nicht von einem Programm.