Hier wird der Code des Maple Desktops zur Verfügung gestellt
und auf die Programmierung weiterer Mobs eingegangen. Es werden
Kenntnisse in der Scriptsprache "AutoIt" vorrausgesetzt.
Dieser Code beinhaltet noch keine Include-Funktionen und ist so
für das erstellen eines neuen Maple Desktop gut geeignet.
Hier wird ein wenig auf den Programmaufbau eingegangen und einige
Codeschnipsel erklärt.
Mit diesen Zeilen beginnt das Programm:
#Region Data
#Endregion
Data
In der Region stehen später die Ressource-Includes und eine
Array, die die Frames (Bilderabfolge) festlegt. Ohne diese Zeilen
würde das Script nich funktionieren.
(Siehe dazu auch: Tutorial
zum erstellen
eines eigenen Mobs.)
Folgende Zeilen binden die GDI+-Library und einige weitere Funktionen
und Konstanten ein.
Alle Bibliotheken werden bei der Installation von AutoIt mitinstalliert.
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <Memory.au3>
#include <Array.au3>
#Include <Timers.au3>
#include <GuiMenu.au3>
#include <StaticConstants.au3>
Nun werden alle Bilder mit der Funktion "_ResourceLoadImage"
aus der Exe direkt in den Ram geladen.
Es wirden 2 Handles mit der Funktion "_GDIPlus_BitmapCreateHBITMAPFromBitmap"
erstellt und eines davon gespiegelt. Dieser Befehl lautet
"_GDIplus_ImageRotateFlip".
; Daten laden!
for
$n = 0 to UBound($hBitmap)-1 step 1
for $m = 1 to $hBitmap[$n][0][0] step 1
;Bitmaps:
$hBitmap[$n][$m][0] =
_ResourceLoadImage($hBitmap[$n][$m][0])
$sSave = $hBitmap[$n][$m][0]
$hBitmap[$n][$m][0] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($sSave)
_GDIplus_ImageRotateFlip($sSave,4)
$hBitmap[$n][$m][1] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($sSave)
_GDIPlus_ImageDispose($sSave)
Next
$sLMH[$hBitmap[$n][0][1]][0] += 1
$sLMH[$hBitmap[$n][0][1]][$sLMH[$hBitmap[$n][0][1]][0]] = $n
Next
Nun wird ein Fenster mit der
Größe 100x100
Pixel erstellt. Sollte schon ein Maple Desktop Anwendung existieren,
dann wird dieses Fenster ein "Kind" (Child) von diesem.
$hWnd = GUICreate("Maple
Desktop", 100,100, $nPos[0],$nPos[1], $WS_POPUP, BitOr( $WS_EX_LAYERED,$WS_EX_TOPMOST,$WS_EX_TOOLWINDOW),WinGetHandle("Maple
Desktop"))
Um später mit der Funktion _WinAPI_UpdateLayeredWindow das
Fenster zu erneuern müssen wir noch davor einen
Speicherkontext und 2 DllStrukturen erstellen. In dennen wir die
Größe des aktuellen Frames und die Transparens
festlegen können.
$hScrDC
= _WinAPI_GetDC(0)
$hMemDC
= _WinAPI_CreateCompatibleDC($hScrDC)
$tSize
= DllStructCreate($tagSIZE)
$pSize
= DllStructGetPtr($tSize )
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend
= DllStructCreate($tagBLENDFUNCTION)
$pBlend
= DllStructGetPtr($tBlend)
DllStructSetData($tBlend, "Format", 1)
Mit dem folgenden Code wird die Y-Position der Taskbar ermittelt. Wenn
die Taskbar nicht unten angeordnet ist, dann ist die Höhe,
welche in der Variable $hTask gespeichert
wird, gleich der Desktophöhe.
;Taskleistenposition
festlegen!
$tRect = DllStructCreate("long;long;long;long")
$ret
= DllCall("user32.dll", 'long', "FindWindowA", 'str', "Shell_traywnd", 'str', "")
DllCall("User32.dll", "int", "GetWindowRect", "hwnd", $ret[0], "ptr", DllStructGetPtr($tRect))
$top
= DllStructGetData($tRect, 2)
$hTask = _IIf(DllStructGetData($tRect, 1) < 1 and $top > 0,$top,@DesktopHeight)
Jetzt wird die Animation der Bilder/Frames gestartet. Der Befehl "_Timer_SetTimer"
ruft die Funktion "_RedrawObjekt" in
bestimmten Zeitabständen, die in den
Arrayeinträgen "$hBitmap[$hMovement][$hFrame][6]"
stehen auf.
;Starte Animation des Objekts
$hTimer = _Timer_SetTimer($hWnd,$hBitmap[$hMovement][$hFrame][6], "_RedrawObjekt")
Die Mainloop, beginnt mit folgenden Codezeilen:
$dWindow
= WinGetHandle("[active]")
If
not _CheckList() then
$hWindow
= $dWindow
$hPos = WinGetPos("[active]")
endif
In diesen wird kontrolliert, ob ein anderer Maple Desktop gerade aktiv
und im Vordergrund ist, den dann darf dieser nicht als Fenster erkannt
werden.
Nun wird noch überprüft ob ein anderes Fenster im
Vordergrund ist. Falls dies der Fall ist, dann wird mit der Funktion "_SetControllGround()"
, die die Array "$hGround" neu definiert. In
dieser Array sind alle Controlls des aktuellen Fensters aufgelistet,
aufgebaut ist sie so:
$hGround[$i][0] = X-Position des
Controlls
$hGround[$i][1] = Y-Position des
Controlls
$hGround[$i][2] = Weite des Controlls
;Controllgrounds neu setzen,
falls nötig!
If $hWindow
<> $aWindow or $aPos[0] <>
$hPos[2] or $aPos[1] <> $hPos[3] then
$aWindow = $hWindow
$aPos[0] = $hPos[2]
$aPos[1] = $hPos[3]
_SetControllGround()
$dList = WinList("Maple
Desktop")
$aNow = RandomEx(0,UBound($hGround)-1,1)
endif
In den folgenden 60 Zeilen werden die Kollisionsabfragen mit den
Controlls,dem Fenster und der Taskleiste abgearbeitet. Dies ist
eigentlich das interresanteste an dem ganzen Script, jedoch ist es zu
schwierig und zu viel Variablen, als das man es verständlich
erklären könnte.
In diesen Zeilen werden nur folgende 2 Funktionen verwendet.
Die 1. Funktion, lautet "_SetMovement". Diese wird verwendet, wenn das
Monster zum Beispiel am Rand eines Controlls steht und nun eine
Hupf-Bewegung ausgeführt werden soll.
Die 2.
Funktion lautet "_Movement" und wird mindestens 1x in dem
Schleifendurchgang ausgeführt. In dieser Funktion wird mit
folgender Bedingung:
_IIf($hBitmap[$hMovement][0][1] = 2, $hState
, $hDelay-TimerDiff($hState) ) >
0
endschieden, ob die aktuelle Bewegung weitergeführt wird:
Switch
$hBitmap[$hMovement][0][1]
Case 1
;laufen
$nPos[0] += _Iif($hView
= 0,-$hSpeed,$hSpeed)
Case 2
;jumpen
$hState -= $hWidth*0.0666
$nState = Round(@DesktopHeight-$hState)
If $nState > $hWidth/2 then $hFall = 1
$nPos[0] = $nState*_Iif($hView
<> 0,1,-1)+$nX
$nPos[1] = $nY-(-$hHeight/($hWidth*$hWidth)*($nState-$hWidth)^2+$hHeight*2)
EndSwitch
oder eine neue Bewegung ausgewählt werden sollte:
;Neue Bewegung
wählen:
Local $sCaller,$sRandom = RandomEx(1,$hGroup,1)
for
$sVar = 0 to UBound($hBitmap)-1 step 1
If $hBitmap[$sVar][0][1] = 0 or $hBitmap[$sVar][0][1] = 4 then ContinueLoop
$sCaller
+= $hBitmap[$sVar][0][4]
If $sCaller
>= $sRandom then ExitLoop
Next
Dann muss jedoch auch eine neue Zeitspanne für die
Bewegung,die Sichtrichtung und einige Variablen neu festgelegt
werden:
$hMovement
= $sVar
$hFrame = 1
$hFall = 0
$hDelay = RandomEx($hBitmap[$hMovement][0][7],$hBitmap[$hMovement][0][8],1)
Switch $hBitmap[$hMovement][0][1]
Case 1
;laufen
$hState = TimerInit()
$hView = RandomEx(0,1,1)
Case 2
;jumpen
$hState = @DesktopHeight
$hView = RandomEx(0,1,1)
$nX = $nPos[0]
$nY = $nPos[1]
Case Else
$hState = TimerInit()
EndSwitch
Mit der Funktion "_UpdateObjekt"
wird die Größe,Position und das Bild des Fensters
aktuellisiert.
Falls ein Sound für die neue Bewegung festgelegt ist, dann
wird dieser Mithilfe der Dll "winnmm.dll" abgespielt.
Nun wird mit der Funktion "_GetOpacity()" noch Transparens
ermittelt, die proportional zur Urzeit ist. Der zurückgegebene
Wert wird nun in die Dll Struktur, die am Anfang erstellt wurde,
eingetragen.
;neu zeichnen:
_UpdateObjekt()
;Sound starten:
If
$hBitmap[$hMovement][0][2] <>
"" and $hSound = 1 then DllCall("winmm.dll", "int", "PlaySound", "str", $hBitmap[$hMovement][0][2], "hwnd", 0, "int", _IIf($hBitmap[$hMovement][0][3] = 1,BitOR(0x00040004, 1,8),BitOR(0x00040004, 1)))
;Opacity neu setzen!
$hOpacity = _GetOpacity()
DllStructSetData($tBlend, "Alpha"
, $hOpacity )
DllStructSetData($tBlend, "Format", 1)
Ich hoffe, ich hab mit diesem kleinen Einblick euch den Aufbau des
Programms näher bringen können.
Um das ganze noch überschaubar zu halten, hab ich nicht alle
Funktionen vorgestellt, wenn also noch Fragen oder Unklarheiten gibt,
dann dürft ihr selbstverständlich mich in ICQ oder
per E-Mail kontaktieren.
Hier wird in Kürze ein Tutorial zum erstellen eines eigenen
Mobs entstehen!
|