home

Open Source


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. 
File:
SourceCode.zip
Size:
18.4 kp
Version:
4.0
Last Update:
09.09.2010


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!