GDI+ 2D Game Demo

Urmatorul tutorial a fost gandit pentru incepatori, pentru a intelege cum se creaza un joc simplu 2D, folosind GDI+. In acest tutorial nu veti intalni optimizari, trebuie sa tineti cont ca este un joc demonstrativ.

De preferat este sa fiti familiarizati cu tutorialele Interfata personalizata cu WinAPI, Double Buffering si Coliziunea Obiectelor pentru o mai buna intelegere a acestui tutorial.
 
Pentru inceput o sa avem nevoie de doua fisiere antet pentru a putea accesa functiile GDI+ si cele pentru managementul sunetelor.

#include <GDIPlus.au3>
#include <Sound.au3>

Mai avem nevoie de cateva variabile cu scop global, pe care le vom folosi in diverse functii:

Global $hMain, $hWall, $hPlayer, $hMob, $hGate, $hGraphics, $hClone, $hBackBuffer
Global $GameOver = False, $GameFinish = False, $Pause = False, $Sound

$hMain este handle-ul ferestrei principale
$hWall este handle-ul imaginii pentru zid
$hPlayer este handle-ul imaginii pentru jucator
$hMob este handle-ul imaginii pentru mob
$hGate este handle-ul imaginii pentru poarta
$hGraphics este handle-ul unui obiect Graphics (suprafata de desenare)
$hClone este handle-ul unei obiect Bitmap (portiunea in care se desfasoara actiunea jocului)
$hBackBuffer este handle-ul unui obiect Graphics (buffer in memorie pentru operatiile de desenare)
$GameOver este o variabila booleana care indica daca jucatorul a pierdut (mancat de mob)
$GameFinish este o variabila booleana care indica daca jucatorul a terminat jocul (a intrat pe poarta)
$Pause este o variabila booleana care indica daca jocul este suspendat(pauza) pentru o perioada de timp
$Sound contine sound ID-ul melodiei de fundal
 
Cream cele 3 obiecte care vor interactiona in joc:

Global $ObjPlayer = CreateObject(30,30,30,30,30,390,30,420)
Global $ObjMob = CreateObject(210,210,30,30,30,390,30,420)
Global $ObjGate = CreateObject(390,420,30,30,30,390,30,420)

 
Incarcam resursele grafice (directorul curent\Gfx):

_GDIPlus_Startup()
$hWall = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Wall.bmp")
$hPlayer = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Player.bmp")
$hMob = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Mob.bmp")
$hGate = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Gate.bmp")

 
Cream fereastra principala, desenam o imagine de fundal si cream butoanele de minimizare si inchidere a programului:

$hMain = GUICreate("GDI+ 2D Game Demo",458,505,-1,-1,0x80000000,0x00000008)
$hBackground = GUICtrlCreatePic(@ScriptDir & "\Gfx\Background.bmp",0,0,458,505)
$hLabel = GUICtrlCreateLabel("GDI+ 2D Game Demo",5,2,150,18)
$hMinimize = GUICtrlCreatePic(@ScriptDir & "\Gfx\Minimize.bmp",415,0,20,20)
$hClose = GUICtrlCreatePic(@ScriptDir & "\Gfx\Close.bmp",435,0,20,20)
GUICtrlSetColor($hLabel,0xFFFFFF)
GUICtrlSetBkColor($hLabel,0x000000)
GUICtrlSetFont($hLabel,10,600,0,"Garamond")
GUICtrlSetState($hBackground,128)
GUISetState(@SW_SHOW,$hMain)

Fereastra principala nu are bara de titlu si butoane de sistem (stilul $WS_POPUP), fapt pentru care cream manual un control Pic pentru imaginea de fundal, un control Label pentru titlu si alte doua controale Pic pentru butoanele de minimizare si inchidere. Pentru controlul care pastreaza titlul se seteaza culoarea textului, a fundalului si fontul, iar controlul care pastreaza imaginea de fundal este dezactivat. In final se seteaza fereastra principala ca fiind vizibila.
 
Urmatorul lucru de care ne vom ocupa este sunetul de fundal:

SoundSetWaveVolume(50)
$Sound = _SoundOpen(@ScriptDir & "\Snd\Medley.wav")
_SoundPlay($Sound)

Initial setam volumul la 50% (depinde de performantele audio de care dispuneti, puteti modifica valoare dupa preferinta), deschidem fisierul care contine melodia de fundal si pornim melodia.
 
In continuare ne vom ocupa de crearea suprafetelor de desenare:

$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hMain)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(458,505,$hGraphics)
$hClone = _GDIPlus_BitmapCloneArea($hBitmap,4,21,450,480,$GDIP_PXF24RGB)
$hBackBuffer = _GDIPlus_ImageGetGraphicsContext($hClone)

Am explicat mai sus ce inseamna fiecare, cu exceptia $hBitmap care este handle-ul unui obiect Bitmap specific pentru intreaga fereastra, dar in cazul nostru nu vrem sa redesenam peste bara de titlu, marginile ferestrei si butoanele de minimizare si inchidere. De aceea suprafata activa va fi cea in care se desfasoara jocul, implicit portiunea clonata din acest $hBitmap.
 
Trebuie sa ne gandim si la cazul in care fereastra este restaurata dupa o minimizare sau daca fereastra este scoasa in afara ecranului si apoi readusa pe ecran, etc. Toate aceste evenimente vor distruge ce a fost desenat cu GDI+. In consecinta, cand unul din aceste evenimente are loc imaginea din buffer trebuie redesenata pe ecran. Pentru a apela functia de redesenare cand aceste evenimente au loc, folosim urmatoarele doua linii:

GUIRegisterMsg(0x85,"REPAINT")
GUIRegisterMsg(0x0F,"REPAINT")

Prima linie apeleaza functia REPAINT cand se intercepteaza mesajul WM_NCPAINT. A doua linie apeleaza functia REPAINT cand se intercepteaza mesajul WM_PAINT.
 
Urmeaza liniile de cod care ii permit userului sa miste jucatorul, sa puna pauza si pe ultima linie se inregistreaza apelul functiei MoveMobRandom la fiecare secunda, pentru a misca mobul:

HotKeySet("{UP}","MoveUp")
HotKeySet("{DOWN}","MoveDown")
HotKeySet("{LEFT}","MoveLeft")
HotKeySet("{RIGHT}","MoveRight")
HotKeySet("{PAUSE}","Pause")
AdlibRegister("MoveMobRandom",1000)

 
Apoi urmeaza bucla principala:

Do
	Switch GUIGetMsg()
		Case -7
			_SendMessage($hMain,0x0112,0xF012,0)
		Case $hMinimize
			GUISetState(@SW_MINIMIZE,$hMain)
		Case $hClose
			ExitLoop
	EndSwitch
	If (_SoundStatus($Sound) <> "playing") And (Not $Pause) Then _SoundPlay($Sound)
	_GDIPlus_GraphicsClear($hBackBuffer,0xFF000000)
	For $X = 0 To 450 Step 30
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,$X,0)
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,$X,450)
	Next
	For $Y = 0 To 480 Step 30
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,0,$Y)
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,420,$Y)
	Next
	If ObjectsOverlap($ObjPlayer,$ObjMob) Then
		AdlibUnRegister("MoveMobRandom")
		$GameOver = True
	EndIf
	If ObjectsOverlap($ObjPlayer,$ObjGate) Then
		AdlibUnRegister("MoveMobRandom")
		$GameFinish = True
	EndIf
	If ObjectsOverlap($ObjMob,$ObjGate) Then
		UpdateObject($ObjMob,$ObjMob[0]-30,$ObjMob[1])
	EndIf
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hPlayer,$ObjPlayer[0],$ObjPlayer[1])
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hMob,$ObjMob[0],$ObjMob[1])
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hGate,$ObjGate[0],$ObjGate[1])
	_GDIPlus_GraphicsDrawImage($hGraphics,$hClone,4,21)
	Sleep(10)
Until $GameOver Or $GameFinish

Codul sursa continut in interiorul buclei principala poate fi impartit in 6 parti:
1. Expresia conditionala care gestioneaza mesajele interceptate de fereastra pincipala (Primary Down, Minimize si Close)
2. Linia in care se testeaza daca melodia de fundal continua sa ruleze, in caz contrar (daca nu este in modul pauza) melodia este rulata iar
3. Linia in care se curata bufferul din memorie, in care se deseneaza
4. Cele doua bucle For…Next, in care se deseneaza zidurile marginale in buffer
5. Testarea celor 3 posibile coliziuni: jucator-mob, jucator-poarta sau mob-poarta. In cazul coliziunii jucator-mob, variabila $GameOver este setata ca True, bucla va rula pentru ultima data (pentru desenare). In cazul coliziunii jucator-poarta, variabila $GameFinish este setata ca True, bucla va rula pentru ultima data (pentru desenare). In cazul coliziunii mob-poarta (am vrut ca acest lucru sa fie interzis), pozitia mobului este reactualizata in partea stanga a portii.
6. Desenarea jucatorului, mobului si a portii in buffer, apoi copierea bufferului pe suprafata de desenare.

Iesirea din bucla are loc in 3 cazuri: daca userul apasa butonul Close(x), in cazul in care jucatorul este mancat de mob sau in cazul in care jucatorul intra pe poarta.
 
La iesirea din bucla principala se opreste melodia de fundal si se inchide fisierul care contine melodia:

_SoundStop($Sound)
_SoundClose($Sound)

 
Urmeaza partea in care este tratat finalul jocului (cauza):

If $GameOver Then
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Over.wav")
	TrayTip("Game Over","Mancat de mob",1)
ElseIf $GameFinish Then
	TrayTip("Game Finish","Ajuns la poarta",1)
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Finish.wav")
Else
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Exit.wav")
	TrayTip("Exit","Userul a inchis jocul",1)
EndIf
_SoundPlay($Sound)
Sleep(5000)

Se testeaza daca iesirea din bucla principala s-a datorat faptului ca jucatorul a fost mancat de mob. Daca acesta este motivul se deschide si reda o melodie care indica acest lucru, plus un mesaj vizual care persista 5 secunde.
Daca motivul pentru iesirea din bucla principala s-a datorat faptului ca jucatorul a intrat pe poarta, la fel se deschide si reda o melodie care indica acest lucru, plus un mesaj vizual care persista 5 secunde.
Pentru oricare alt caz (incluzand cazul in care userul inchide aplicatia) se deschide si reda o melodie care indica acest lucru, plus un mesaj vizual care persista 5 secunde.
 
Mai trebuie doar oprita melodia care este redata (pentru unul din cazurile de mai sus) si inchis fisierul care contine melodia.

_SoundStop($Sound)
_SoundClose($Sound)

 
Apoi eliberate resursele folosite:

_GDIPlus_ImageDispose($hGate)
_GDIPlus_ImageDispose($hMob)
_GDIPlus_ImageDispose($hPlayer)
_GDIPlus_ImageDispose($hWall)
_GDIPlus_BitmapDispose($hClone)
_GDIPlus_GraphicsDispose($hBackBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

 
Functiile apelate pentru miscarea jucatorului:

Func MoveUp()
	UpdateObject($ObjPlayer,$ObjPlayer[0],$ObjPlayer[1]-30)
EndFunc
 
Func MoveDown()
	UpdateObject($ObjPlayer,$ObjPlayer[0],$ObjPlayer[1]+30)
EndFunc
 
Func MoveLeft()
	UpdateObject($ObjPlayer,$ObjPlayer[0]-30,$ObjPlayer[1])
EndFunc
 
Func MoveRight()
	UpdateObject($ObjPlayer,$ObjPlayer[0]+30,$ObjPlayer[1])
EndFunc

In fond, pentru fiecare directie noua este reactualizata pozitia obiectului asociat jucatorului, cu 30 pixeli, plus sau minus.
 
Functia care misca mobul:

Func MoveMobRandom()
	Switch Random(1,4,1)
		Case 1
			UpdateObject($ObjMob,$ObjMob[0],$ObjMob[1]-30)
		Case 2
			UpdateObject($ObjMob,$ObjMob[0],$ObjMob[1]+30)
		Case 3
			UpdateObject($ObjMob,$ObjMob[0]-30,$ObjMob[1])
		Case 4
			UpdateObject($ObjMob,$ObjMob[0]+30,$ObjMob[1])
	EndSwitch
EndFunc

Se genereaza un numar aleator intre 1-4, fiecare corespunzator unei directii. Pentru fiecare directie se reactualizeaza pozitia obiectului asociat mobului cu 30 pixeli, plus sau minus.
 
Functia care trateaza suspendarea/redarea actiunilor:

Func Pause()
	$Pause = Not $Pause
	If $Pause Then
		AdlibUnRegister("MoveMobRandom")
		HotKeySet("{UP}")
		HotKeySet("{DOWN}")
		HotKeySet("{LEFT}")
		HotKeySet("{RIGHT}")
		_SoundPause($Sound)
	Else
		AdlibRegister("MoveMobRandom",1000)
		HotKeySet("{UP}","MoveUp")
		HotKeySet("{DOWN}","MoveDown")
		HotKeySet("{LEFT}","MoveLeft")
		HotKeySet("{RIGHT}","MoveRight")
		_SoundResume($Sound)
	EndIf
EndFunc

In prima linie se trece din starea intial in alta stare (True->False sau False->True).
Daca valoarea curenta este True(pauza) atunci se dezactiveaza apelarea functiei care misca mobul, se dezactiveaza tastele asociate pentru miscarea jucatorului si melodia de fundal este pusa pe pauza.
Daca valoarea curenta este False(iesire din modul pauza) se reactiveaza apelarea functiei care misca mobul, se reactiveaza tastele asociate pentru miscarea jucatorului si melodia de fundal este reluata.
 
Functia pentru redesenare (WM_PAINT si WM_NCPAINT):

Func REPAINT($hWnd,$msg,$wParam,$lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics,$hClone,4,21)
    Return _WinAPI_DefWindowProc($hWnd,$msg,$wParam,$lParam)
EndFunc

Se copiaza bufferul din memorie pe suprafata de desenare.
 
Functiile pentru lucrul cu obiecte (identice cu cele descrise in tutorialul Coliziunea Obiectelor):

Func CreateObject($X,$Y,$W,$H,$MinX,$MaxX,$MinY,$MaxY)
	Local $Object[8] = [$X,$Y,$W,$H,$MinX,$MaxX,$MinY,$MaxY]
	Return $Object
EndFunc
 
Func UpdateObject(ByRef $Obj,$X,$Y)
	If $X < $Obj[4] Then $X = $Obj[4]
   	If $X > $Obj[5] Then $X = $Obj[5]
	If $Y < $Obj[6] Then $Y = $Obj[6]
   	If $Y > $Obj[7] Then $Y = $Obj[7]
	$Obj[0] = $X
	$Obj[1] = $Y
EndFunc
 
Func ObjectsOverlap($Obj1,$Obj2)
    Local $SX = Abs($Obj2[0] - $Obj1[0]) + $Obj2[2]
    Local $SY = Abs($Obj2[1] - $Obj1[1]) + $Obj2[3]
    Return ($SX < $Obj1[2] + $Obj2[2] And $SY < $Obj1[3] + $Obj2[3])
EndFunc

 
 
Daca asamblati toate portiunile de cod sursa de mai sus, scriptul arata asa:

#include <GDIPlus.au3>
#include <Sound.au3>
 
Global $hMain, $hWall, $hPlayer, $hMob, $hGate, $hGraphics, $hClone, $hBackBuffer
Global $GameOver = False, $GameFinish = False, $Pause = False, $Sound
 
Global $ObjPlayer = CreateObject(30,30,30,30,30,390,30,420)
Global $ObjMob = CreateObject(210,210,30,30,30,390,30,420)
Global $ObjGate = CreateObject(390,420,30,30,30,390,30,420)
 
_GDIPlus_Startup()
$hWall = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Wall.bmp")
$hPlayer = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Player.bmp")
$hMob = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Mob.bmp")
$hGate = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Gfx\Gate.bmp")
 
$hMain = GUICreate("GDI+ 2D Game Demo",458,505,-1,-1,0x80000000,0x00000008)
$hBackground = GUICtrlCreatePic(@ScriptDir & "\Gfx\Background.bmp",0,0,458,505)
$hLabel = GUICtrlCreateLabel("GDI+ 2D Game Demo",5,2,150,18)
$hMinimize = GUICtrlCreatePic(@ScriptDir & "\Gfx\Minimize.bmp",415,0,20,20)
$hClose = GUICtrlCreatePic(@ScriptDir & "\Gfx\Close.bmp",435,0,20,20)
GUICtrlSetColor($hLabel,0xFFFFFF)
GUICtrlSetBkColor($hLabel,0x000000)
GUICtrlSetFont($hLabel,10,600,0,"Garamond")
GUICtrlSetState($hBackground,128)
GUISetState(@SW_SHOW,$hMain)
 
SoundSetWaveVolume(50)
$Sound = _SoundOpen(@ScriptDir & "\Snd\Medley.wav")
_SoundPlay($Sound)
 
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hMain)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(458,505,$hGraphics)
$hClone = _GDIPlus_BitmapCloneArea($hBitmap,4,21,450,480,$GDIP_PXF24RGB)
$hBackBuffer = _GDIPlus_ImageGetGraphicsContext($hClone)
 
GUIRegisterMsg(0x85,"REPAINT")
GUIRegisterMsg(0x0F,"REPAINT")
 
HotKeySet("{UP}","MoveUp")
HotKeySet("{DOWN}","MoveDown")
HotKeySet("{LEFT}","MoveLeft")
HotKeySet("{RIGHT}","MoveRight")
HotKeySet("{PAUSE}","Pause")
AdlibRegister("MoveMobRandom",1000)
 
Do
	Switch GUIGetMsg()
		Case -7
			_SendMessage($hMain,0x0112,0xF012,0)
		Case $hMinimize
			GUISetState(@SW_MINIMIZE,$hMain)
		Case $hClose
			ExitLoop
	EndSwitch
	If (_SoundStatus($Sound) <> "playing") And (Not $Pause) Then _SoundPlay($Sound)
	_GDIPlus_GraphicsClear($hBackBuffer,0xFF000000)
	For $X = 0 To 450 Step 30
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,$X,0)
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,$X,450)
	Next
	For $Y = 0 To 480 Step 30
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,0,$Y)
		_GDIPlus_GraphicsDrawImage($hBackBuffer,$hWall,420,$Y)
	Next
	If ObjectsOverlap($ObjPlayer,$ObjMob) Then
		AdlibUnRegister("MoveMobRandom")
		$GameOver = True
	EndIf
	If ObjectsOverlap($ObjPlayer,$ObjGate) Then
		AdlibUnRegister("MoveMobRandom")
		$GameFinish = True
	EndIf
	If ObjectsOverlap($ObjMob,$ObjGate) Then
		UpdateObject($ObjMob,$ObjMob[0]-30,$ObjMob[1])
	EndIf
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hPlayer,$ObjPlayer[0],$ObjPlayer[1])
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hMob,$ObjMob[0],$ObjMob[1])
	_GDIPlus_GraphicsDrawImage($hBackBuffer,$hGate,$ObjGate[0],$ObjGate[1])
	_GDIPlus_GraphicsDrawImage($hGraphics,$hClone,4,21)
	Sleep(10)
Until $GameOver Or $GameFinish
 
_SoundStop($Sound)
_SoundClose($Sound)
 
If $GameOver Then
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Over.wav")
	TrayTip("Game Over","Mancat de mob",1)
ElseIf $GameFinish Then
	TrayTip("Game Finish","Ajuns la poarta",1)
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Finish.wav")
Else
	$Sound = _SoundOpen(@ScriptDir & "\Snd\Exit.wav")
	TrayTip("Exit","Userul a inchis jocul",1)
EndIf
_SoundPlay($Sound)
Sleep(5000)
 
_SoundStop($Sound)
_SoundClose($Sound)
 
_GDIPlus_ImageDispose($hGate)
_GDIPlus_ImageDispose($hMob)
_GDIPlus_ImageDispose($hPlayer)
_GDIPlus_ImageDispose($hWall)
_GDIPlus_BitmapDispose($hClone)
_GDIPlus_GraphicsDispose($hBackBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
 
Func MoveUp()
	UpdateObject($ObjPlayer,$ObjPlayer[0],$ObjPlayer[1]-30)
EndFunc
 
Func MoveDown()
	UpdateObject($ObjPlayer,$ObjPlayer[0],$ObjPlayer[1]+30)
EndFunc
 
Func MoveLeft()
	UpdateObject($ObjPlayer,$ObjPlayer[0]-30,$ObjPlayer[1])
EndFunc
 
Func MoveRight()
	UpdateObject($ObjPlayer,$ObjPlayer[0]+30,$ObjPlayer[1])
EndFunc
 
Func MoveMobRandom()
	Switch Random(1,4,1)
		Case 1
			UpdateObject($ObjMob,$ObjMob[0],$ObjMob[1]-30)
		Case 2
			UpdateObject($ObjMob,$ObjMob[0],$ObjMob[1]+30)
		Case 3
			UpdateObject($ObjMob,$ObjMob[0]-30,$ObjMob[1])
		Case 4
			UpdateObject($ObjMob,$ObjMob[0]+30,$ObjMob[1])
	EndSwitch
EndFunc
 
Func Pause()
	$Pause = Not $Pause
	If $Pause Then
		AdlibUnRegister("MoveMobRandom")
		HotKeySet("{UP}")
		HotKeySet("{DOWN}")
		HotKeySet("{LEFT}")
		HotKeySet("{RIGHT}")
		_SoundPause($Sound)
	Else
		AdlibRegister("MoveMobRandom",1000)
		HotKeySet("{UP}","MoveUp")
		HotKeySet("{DOWN}","MoveDown")
		HotKeySet("{LEFT}","MoveLeft")
		HotKeySet("{RIGHT}","MoveRight")
		_SoundResume($Sound)
	EndIf
EndFunc
 
Func REPAINT($hWnd,$msg,$wParam,$lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics,$hClone,4,21)
    Return _WinAPI_DefWindowProc($hWnd,$msg,$wParam,$lParam)
EndFunc
 
Func CreateObject($X,$Y,$W,$H,$MinX,$MaxX,$MinY,$MaxY)
	Local $Object[8] = [$X,$Y,$W,$H,$MinX,$MaxX,$MinY,$MaxY]
	Return $Object
EndFunc
 
Func UpdateObject(ByRef $Obj,$X,$Y)
	If $X < $Obj[4] Then $X = $Obj[4]
   	If $X > $Obj[5] Then $X = $Obj[5]
	If $Y < $Obj[6] Then $Y = $Obj[6]
   	If $Y > $Obj[7] Then $Y = $Obj[7]
	$Obj[0] = $X
	$Obj[1] = $Y
EndFunc
 
Func ObjectsOverlap($Obj1,$Obj2)
    Local $SX = Abs($Obj2[0] - $Obj1[0]) + $Obj2[2]
    Local $SY = Abs($Obj2[1] - $Obj1[1]) + $Obj2[3]
    Return ($SX < $Obj1[2] + $Obj2[2] And $SY < $Obj1[3] + $Obj2[3])
EndFunc

 
Daca rulati scriptul, fereastra care va aparea o sa fie asemanatoare cu cea de mai jos:

 
Nota: multumiri pentru sunetul de fundal lui Pippo Noviello (aka Kaminari3).
 
Puteti descarca scriptul, resursele si o versiune compilata de aici.


* Pentru orice intrebari sau nelamuriri legate de curs sau limbajul AutoIt accesati sectiunea AutoIt a forumului SkullBox sau platforma de suport tehnic NetHelp.