[GELÖST] TButton Create Funk. durch eine Extend Create Funk.

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Neoxit

Betreff: [GELÖST] TButton Create Funk. durch eine Extend Create Funk.

BeitragSo, Jul 08, 2012 20:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bins mal wieder mit meinen Types.
Also ich habe mir hier mal zum training 2 Types zur erstellung von Buttons gemacht.

Da haben wir einmal den SuperType (TButton) und den ExtendType (TTitlescreenbutton).
Ich habe in der TButton eine Create Funktion geschrieben, wodurch ich mir im Programm die entsprechenden Buttons erstellen kann.

Nun gibt es bei mir im Titlescreen bspw. noch die änderung das ein Infotext an der Seite angezeigt wird, wenn man mit der Maus über den Button fährt. Heißt also ich habe den TButton mit einer txt:string variable erweitert und ebenfalls eine Create funktion eingebaut.

Sie sieht wie folgt aus:

BlitzMax: [AUSKLAPPEN]

Type TButton
Field x:Int, y:Int
Field img:TImage
Field id:Int

rem

*Ich musste diese Funktion entfernen, damit es funktioniert. Daher auskommentiert.

Function Create:TButton(x:Int, y:Int, img:String)
Local a:TButton = New TButton
a.x = x
a.y = y
a.img = LoadImage(img)
Return a
End Function
endrem


Method Draw()
DrawImage Self.img, Self.x, Self.y

If ImagesCollide(Self.img, Self.x, Self.y, 0, Img_Cursor, cursor_x, cursor_y, 0)
DrawImage img_wahlbalken, Self.x, Self.y

If MouseDown(1)
Select Self.id
Case 100 ' ID = 100 - Beenden
EndGraphics
End
Case 10 ' ID = 10 - Level
System_Level = 1


End Select
End If

End If

End Method

End Type

Type TTitlescreenbutton Extends TButton
Field txt:String

Function Create:TTitlescreenbutton(x:Int, y:Int, img:String, txt:String, id:Int)
Local b:TTitlescreenbutton = New TTitlescreenbutton
b.x = x
b.y = y
b.img = LoadImage(img)
b.txt = txt
b.id = id
Return b
End Function

Method Draw()
Super.Draw() 'Erstmal die Super-Method ausführen, dann die extend version dranhängen

If ImagesCollide(Self.img, Self.x, Self.y, 0, Img_Cursor, cursor_x, cursor_y, 0)
DrawText Self.txt, 480, 450
End If

End Method

End Type

'. . .

'Buttons Erstellen
Global NeuesSpiel:TTitlescreenbutton = TTitlescreenbutton.Create(270, 450, "gfx\button_neuesspiel.png", "Beginne eine neue Runde Kiozay.", 10)
Global Optionen:TTitlescreenbutton = TTitlescreenbutton.Create(270, 490, "gfx\button_optionen.png", "Hier hast du verschiedene Einstellungsmöglichkeiten für das Spiel.", 50)
Global Credits:TTitlescreenbutton = TTitlescreenbutton.Create(270, 530, "gfx\button_credits.png", "Wenn dich Interessiert, wer bei diesem Spiel mitgewirkt hat, schaue hier rein.", 101)
Global Beenden:TTitlescreenbutton = TTitlescreenbutton.Create(270, 570, "gfx\button_beenden.png", "Hier kannst du Kiozay verlassen.", 100)



Wie ihr seht handelt es sich hierbei nun nur um Buttons, welche sich im TItlescreen befinden.
Das Problem bei der Create funktion ist, das ich beim Compilern eine fehlermeldung bekommen:

Code: [AUSKLAPPEN]
Compile Error: Overriding method differs by type


BLIde schickt mich dann in diese zeile:

BlitzMax: [AUSKLAPPEN]
Function Create:TTitlescreenbutton(x:Int, y:Int, img:String, txt:String, id:Int)


Leider kann ich den Fehler nicht erkennen. Hat jemand eine Universallösung dafür parat geschweige denn eine Ahnung woran es genau liegt? Ursprünglich möchte ich nämlich auch über Create.TButton meine "standardbuttons" anlegen.

Mit freundlichen Grüßen
Neoxit
  • Zuletzt bearbeitet von Neoxit am Mi, Jul 11, 2012 19:41, insgesamt einmal bearbeitet

ToeB

BeitragSo, Jul 08, 2012 21:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde die Button Klasse allgemein halten und die entsprechenden Methoden und Funktionen als "Abstract" markieren. Dann musst du in der abgeleiteten Klasse diese Beiden nur noch definieren.

Code: [AUSKLAPPEN]
Type TButton
   Field x:Int, y:Int
   Field img:TImage
   

   Method Draw( ) Abstract
   Function Create:TButton( x:Int, y:Int, img:TImage ) Abstract
End Type

Type TTitleScreenButton Extends TButton
   Method Draw( )
      DrawImage( img, x, y )
   End Method
   Function Create:TButton( x:Int, y:Int, img:TImage )
      Local but:TButton = New TTitleScreenButton
      but.x = x
      but.y = y
      but.img = img
      Return but
   End Function
End Type


Nur als Beispiel. So würde ich das machen. Ansonsten, wenn man eine Klasse ableitet werden ja in der Abgeleiteten Klasse alle Funktionen und Methoden / Felder der SuperKlasse übernommen, und zwei gleiche Methoden / Funktionen / Felder kann man nicht in einer Klasse Definieren Wink

Lg, Tobias
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

Neoxit

BeitragSo, Jul 08, 2012 22:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Super dein Beispiel habe ich soweit verstanden.

Nur wenn ich nun in der TitlescreenButton Create Funktion z.b. noch txt:string dazu nehmen möchte, aber bspw in einer extend von sagen wir mal IngameButton Create Funktion NICHT, wie gehe ich das dann an?

Ich möchte ja meine Create befehle so kurz wie möglich halten und keine werte zuweisen, welche für andere extends überflüssig wären.

Hoffe man versteht was ich meine.

blackgecko

BeitragMo, Jul 09, 2012 20:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Das geht nicht. Wenn du eine Funktion/Methode in einer abgeleiteten Klasse überschreiben willst, müssen Rückgabewert, Parameterzahl und Parametertypen gleich sein. (oder zumindest ähnlich, d.h. voneinander abgeleitet.)
Zitat:
Ich möchte ja meine Create befehle so kurz wie möglich halten und keine werte zuweisen, welche für andere extends überflüssig wären.
Dann haben sie in der Basisklasse nichts verloren Wink
Ich würd bei deinem Fall hingehen und der Klasse TButton überhaupt keine create-Methode geben. Und auch keine Instanzen davon erstellen. TButton wäre also nur eine Oberklasse die nichts weiter zu tun hat und nur das enthält was wirklich jeder Button braucht. (x/y zum Beispiel)
Von TButton abgeleitet kannst du dann die spezialisierten Klassen erstellen, die wirklich Buttons beherbergen sollen. Die haben dann tatsächlich create-Methoden. (Es sei denn du willst sie nochmals ableiten)
BlitzMax: [AUSKLAPPEN]
Type TButton
Field x:Int, y:Int
Method Draw( ) Abstract
End Type


Type TTitleScreenButton Extends TButton
Field image:TImage
Function Create:TButton( x:Int, y:Int, img:TImage )
'...
End Function
Method Draw( )
DrawImage( img, x, y )
End Method
End Type

Type TRadioButton Extends TButton
Field text:String
Field state:Int
Function Create:TRadioButton(x:Int,y:Int,text:String,state:Int=False)
'...
EndFunction
Method draw()
'...
EndMethod
EndType


Es lohnt sich, über so eine Klassenhierarchie in Ruhe nachzudenken, je nach Komplexität auch auf Papier. Kann eine Menge Arbeit sparen Wink
So long and thanks for all the fish.
Fedora 17 | Windows 7 || BlitzPlus | BlitzMax
Rechtschreibflame GO!!! Deppenapostroph | SeidSeit | Deppenakzent | DassDas | Deppenleerzeichen | TodTot | enzigste.info - Ja, ich sammel die.

Neoxit

BeitragDi, Jul 10, 2012 18:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Super verständliche antwort!
Vielen dank euch beiden, genau das meinte ich übrigens.

So hab ich gar nicht gedacht und ja du hast mehr als recht das kann wirklich kompliziert werden.

Aber in dem fall könnte ich doch die gesamte TButton Klasse Abstract machen, sofern es nur verschiedene gibt oder wäre das wieder fehlerhaft? Eigentlich nicht oder?

Vielen Dank! Very Happy

[EDIT]

Wie macht ihr das in dem Fall eigentlich mit den Bildern? Also wie ladet ihr sie? Ladet ihr sie einmal Global und weist sie dann neu zu? Oder wie würde die aufrufende Funktion dann aussehen?

BlitzMax: [AUSKLAPPEN]
Function Create:TButton( x:Int, y:Int, img:TImage )


Ich habe es immer mit img:string gemacht und in der Createfunktion dann "self.img = loadimage(img)"
oder wie ist der speicherschonenste und "beste" weg?

blackgecko

BeitragDi, Jul 10, 2012 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine Klasse, von der du nicht vorhast, Instanzen zu erstellen, kannst du ruhig Abstract machen. Schaden tut es nicht (spart genau genommen sogar ein paar Zeilen Assemblercode). Manchmal benutzt man das auch als eine Art Schutz, damit man nicht "aus Versehen" irgendwas mit einer Klasse anstellt, die dafür gar nicht gedacht war.
Nebenbei: Wenn eine Klasse eine abstrakte Methode hat, ist auch die Klasse als Ganzes automatisch abstrakt. Nochmal dranschreiben kann man es natürlich trotzdem.

Zu den Bildern: Das mit der Pfadangabe als Parameter für die create-Funktion würd ich sein lassen, denn wenn du mal die Dateien umbenennst oder die Ordnerstruktur änderst, musst du dir alle Codestellen zusammensuchen, wo du Buttons erstellst. Das Argument mit dem Speicher kommt dann noch hinzu, wenn mehrere Buttons das selbe Bild haben: Dann wird dieses Bild auch mehrmals geladen, was ja Quatsch ist.
Ich würde sämtliche Button-Bilder als Klassenvariablen definieren (Global innerhalb einer Klasse) und auch gleich laden. Entweder du plazierst sie direkt in TButton oder (was gründlicher wäre) so weit unten in der Klassenhierarchie wie möglich. Sprich so, dass alle Button-Klassen, die Bilder anzeigen sollen, darauf zugreifen können.
So long and thanks for all the fish.
Fedora 17 | Windows 7 || BlitzPlus | BlitzMax
Rechtschreibflame GO!!! Deppenapostroph | SeidSeit | Deppenakzent | DassDas | Deppenleerzeichen | TodTot | enzigste.info - Ja, ich sammel die.

Neoxit

BeitragMi, Jul 11, 2012 18:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Heißt also, das ich in dem Type TButton (oder halt im entsprechenden untertype) globale variablen machen sollte?

BlitzMax: [AUSKLAPPEN]
Type TButton
Global img_01:TImage = LoadImage("1.png")
Global img_02:TImage = LoadImage("2.png")

End Type


So meinst du das doch oder? ^^

BladeRunner

Moderator

BeitragMi, Jul 11, 2012 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Entweder so, oder halt auf eine extra-Klasse zurückgreifen die alle Images/Ressourcen für dich verwaltet.
Bei einem eher kleinen Projekt würde ich es auch direkt in der Buttonklasse verankern.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neoxit

BeitragMi, Jul 11, 2012 19:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok Top klingt simpel, und anscheinend hatte ich mit meiner einen Frage die ich mal bzgl des OOP etc. hatte ja recht das im prinzip seit bmax fast alles ausschließlich in Klassen verwaltet wird.

[GELÖST]

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group