Jump to content

GDI problems


Achilles
 Share

Recommended Posts

I am trying to make a screen for when the user completes a game. I planned on combining "#10 Simple Ball Collision Simulation" with some basic text ontop saying "Game over" and the players score. I got the particle explosion organized to where it would be ready to easily insert into code; same with some text. However I am having difficulty combining them.

Here's my attempt at combining them, which currently only shows the particle explosion:

#include-once
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)


Global $ex_width = @DesktopWidth * 0.75
Global $ex_height = @DesktopHeight * 0.75


Global $explosion_step, $explosion_length, $explosion_max_amount, $explosion_max_particle, $explosion_amount, $explosion_coordinate
Global $ex_bitmap, $ex_graphics, $ex_backbuffer, $x_min = -1, $x_max = -1, $y_min = -1, $y_max = -1, $screenDC
Global $hFont, $hFamily, $hFormat, $textBrush, $textHBrush

_InitiateGUI($ex_width, $ex_height, 8)

While 1

    _GDIPlus_GraphicsClear($ex_backbuffer, 0xA0000000)
    If Mod(Random(1, 10, 1), 9) >= 4 Then
        _Explosion_Init(Random($x_min, $x_max, 1), Random($y_min, $y_max, 1))
    EndIf
    _Explosion()

    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($ex_bitmap) ;copy drawn image to GUI
    $dc = _WinAPI_CreateCompatibleDC($screenDC)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_DeleteObject($gdibitmap)
    _WinAPI_BitBlt($screenDC, 0, 0, $ex_width, $ex_height, $dc, 0, 0, $srccopy)
    _WinAPI_DeleteDC($dc)


    Sleep(50)
WEnd


Func _InitiateGUI($ex_width, $ex_height, $max)
    
    $explosion_max_amount = $max
    $explosion_step = 8
    $explosion_length = ($ex_width + $ex_height) / 7
    $explosion_max_particle = $max * 2
    Global $explosion_coordinate[$explosion_max_particle][$explosion_step * $explosion_max_amount] ; on/off, x, y, vx, vy, v, brush, color
    
    $hGUI = GUICreate('', $ex_width, $ex_height)
        GUISetOnEvent($GUI_EVENT_CLOSE, '_CleanUp')
    $hWnd = WinGetHandle($hGUI)
    
    _GDIPlus_Startup()
    $ex_graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $ex_bitmap = _GDIPlus_BitmapCreateFromGraphics($ex_width, $ex_height, $ex_graphics)
    $ex_backbuffer = _GDIPlus_ImageGetGraphicsContext($ex_bitmap)
    $screenDC = _WinAPI_GetDC($hGUI)
    _GDIPlus_GraphicsSetSmoothingMode($ex_backbuffer, 2)
    
    
    
    ; all the below is for text
    $textBrush = _GDIPlus_BrushCreateSolid(0x1A000000)
    $textHBrush = _GDIPlus_BrushCreateSolid (0x7FAFAFAF)
    $textFontSize = 36
    $hFormat = _GDIPlus_StringFormatCreate()
        _GDIPlus_StringFormatSetAlign($hFormat, 1)
    $hFamily = _GDIPlus_FontFamilyCreate ("Arial")
    $hFont = _GDIPlus_FontCreate ($hFamily, $textFontSize, 2)
    $text = 'Game Over!' & @LF & @LF & '"Your score was 123'
    _AntiAlias($ex_backbuffer, 4)
    _GDIPlus_GraphicsClear($ex_backbuffer)
    _GDIPlus_GraphicsFillRect($ex_backbuffer, 0, 0, $ex_width, $ex_height, $textBrush)
    $tLayout = _GDIPlus_RectFCreate($ex_width / 2, $ex_height / 4, 0, 0)
    _GDIPlus_GraphicsDrawStringEx ($ex_backbuffer, $text, $hFont, $tLayout, $hFormat, $textHBrush)
    _GDIPlus_GraphicsDrawImageRect($ex_graphics, $ex_bitmap, 0, 0, $ex_width, $ex_height)
    _GDIPlus_GraphicsClear($ex_backbuffer)
    


    ; all the below is for explosions
    $x_min = $explosion_length * 0.75
    $x_max = $ex_width - $x_min
    $y_min = $explosion_length * 0.75
    $y_max = $ex_height - $y_min

    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
        $brush_color = 0; 0xFF000000 + Random(0x400000, 0xFFFFFF, 1)
        For $n = 0 To $explosion_max_particle - 1
            $explosion_coordinate[$n][$o + 6] = _GDIPlus_BrushCreateSolid($brush_color)
        Next
    Next

    GUISetState()
EndFunc


Func _CleanUp()
    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
        For $n = 0 To $explosion_max_particle - 1
            _GDIPlus_BrushDispose($explosion_coordinate[$n][$o + 6])
        Next
    Next
    
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose($textBrush)
    _GDIPlus_BrushDispose($textHBrush)

    _GDIPlus_BitmapDispose($ex_bitmap)
    _GDIPlus_GraphicsDispose($ex_graphics)
    _GDIPlus_GraphicsDispose($ex_backbuffer)
    _GDIPlus_Shutdown()
    
    Exit
EndFunc 

Func _Explosion_Init($ex, $ey)
    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step ;fill array with coordinate of hit object
        If $explosion_coordinate[0][$o] <> 1 Then
            $explosion_coordinate[0][$o] = 1
            $explosion_coordinate[0][$o + 1] = $ex ;save x coordinate
            $explosion_coordinate[0][$o + 2] = $ey ;save y coordinate
            $brush_color = 0xFF000000 + Random(0xF0F0F0, 0xFFFFFF, 1)
            For $n = 0 To $explosion_max_particle - 1
                $explosion_coordinate[$n][$o + 1] = $explosion_coordinate[0][$o + 1] ;duplicate x start position of all explosion particles
                $explosion_coordinate[$n][$o + 2] = $explosion_coordinate[0][$o + 2] ;duplicate y start position of all explosion particles
                $explosion_coordinate[$n][$o + 3] = _Random(-7, 7, 1) ;create random x vector (explosion particle speed)
                $explosion_coordinate[$n][$o + 4] = _Random(-7, 7, 1) ;create random y vector (explosion particle speed)
                $explosion_coordinate[$n][$o + 5] = Abs($explosion_coordinate[$n][3 + $o]) + Abs($explosion_coordinate[$n][4 + $o]) ;add absolute distance of vectors x and y
                $explosion_coordinate[$n][$o + 7] = $brush_color
                _GDIPlus_BrushSetSolidColor($explosion_coordinate[$n][$o + 6], $explosion_coordinate[$n][$o + 7])
            Next
            ExitLoop
        EndIf
    Next
EndFunc   ;==>Explosion_Init

Func _Explosion() ;draw explosions coordinates
    Local $q, $k, $r, $g, $b
    $explosion_amount = 0
    For $k = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
        If $explosion_coordinate[0][$k] = 1 Then ;only draw active explosions
            $explosion_amount += 1
            For $q = 0 To $explosion_max_particle - 1
                $explosion_coordinate[$q][$k + 1] += $explosion_coordinate[$q][$k + 3] ;draw new x coordinate of a particle
                $explosion_coordinate[$q][$k + 2] += $explosion_coordinate[$q][$k + 4] ;draw new y coordinate of a particle
                $explosion_coordinate[$q][$k + 5] += Abs($explosion_coordinate[$q][$k + 3]) + Abs($explosion_coordinate[$q][$k + 4]) ;absolute vector length
                If $explosion_coordinate[$q][$k + 5] <= $explosion_length Then ;draw until max. distance has been reached
                    _GDIPlus_GraphicsFillEllipse($ex_backbuffer, $explosion_coordinate[$q][$k + 1], $explosion_coordinate[$q][$k + 2], 3, 3, $explosion_coordinate[$q][$k + 6])
                    ;fade out colors
                    $r = BitAND($explosion_coordinate[$q][$k + 7], 0x00FF0000) / 0x10000 * 0.925 ;decrease red channel
                    $g = BitAND($explosion_coordinate[$q][$k + 7], 0x0000FF00) / 0x100 * 0.925 ;decrease green channel
                    $b = BitAND($explosion_coordinate[$q][$k + 7], 0x000000FF) * 0.925 ;decrease blue channel
                    $explosion_coordinate[$q][$k + 7] = "0xFF" & Hex($r, 2) & Hex($g, 2) & Hex($b, 2)
                    _GDIPlus_BrushSetSolidColor($explosion_coordinate[$q][$k + 6], $explosion_coordinate[$q][$k + 7]) ;set new color
                Else ;when max. distance has been reached then set x vector and y vector to 0
                    $explosion_coordinate[0][$k] = 0
                EndIf
            Next
        EndIf
    Next
EndFunc   ;==>Explosion

Func _Random($w1, $w2, $w3 = 0) ;just to avoid 0 as random number
    Local $x = 0, $l1 = 0.50
    While $x = 0
        $x = Random($w1, $w2, $w3)
        If $x < $l1 And $x >= 0 Then $x += $l1
        If $x > -$l1 And $x <= 0 Then $x -= $l1
    WEnd
    Return $x
EndFunc   ;==>_Random

Func _GDIPlus_BrushSetSolidColorEx($hBrush, $iARGB = 0xFF000000)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "hwnd", $hBrush, "int", $iARGB)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_BrushSetSolidColor

Func _AntiAlias($hGraphics, $mode)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", $mode)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_AntiAlias

This is the basic text part I had working. Basically I want this text overlay ontop of the particle explosions:

#include <GUIConstantsEx.au3>
#include <GDIplus.au3>

Global Const $width = 600
Global Const $height = 400
;~ Global Const $pi = 3.14159265358979323
;~ Global $title = "GDI+"
;~ Global $aPoints[4][2]


; Build your GUI here
Opt("GUIOnEventMode", 1)

$hwnd = GUICreate('dd', $width, $height)
GUISetOnEvent($GUI_EVENT_CLOSE, "close")
GUISetState()

; Load your GDI+ resources here:
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)

$textBrush = _GDIPlus_BrushCreateSolid(0x1A000000)
$textHBrush = _GDIPlus_BrushCreateSolid (0x7FAFAFAF)


$textFontSize = 36
$hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
$hFamily = _GDIPlus_FontFamilyCreate ("Arial")
$hFont = _GDIPlus_FontCreate ($hFamily, $textFontSize, 2)

$text = "Game Over!" & @LF & @LF & "Your score was 123"


_AntiAlias($backbuffer, 4)


_GDIPlus_GraphicsClear($backbuffer)

_GDIPlus_GraphicsFillRect($backbuffer, 0, 0, $width, $height, $textBrush)

$tLayout = _GDIPlus_RectFCreate($width / 2, $height / 4, 0, 0)
_GDIPlus_GraphicsDrawStringEx ($backbuffer, $text, $hFont, $tLayout, $hFormat, $textHBrush)

_GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)


While 1 
    Sleep(200) 
WEnd

close()

Func close()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose($textBrush)
    _GDIPlus_BrushDispose($textHBrush)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc ;==>close

Func _AntiAlias($hGraphics, $mode)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", $mode)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_AntiAlias
Edited by Achilles
My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

Try this:

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)


Global $ex_width = @DesktopWidth * 0.75
Global $ex_height = @DesktopHeight * 0.75


Global $explosion_step, $explosion_length, $explosion_max_amount, $explosion_max_particle, $explosion_amount, $explosion_coordinate
Global $ex_bitmap, $ex_graphics, $ex_backbuffer, $x_min = -1, $x_max = -1, $y_min = -1, $y_max = -1, $screenDC
Global $hFont, $hFamily, $hFormat, $textBrush, $textHBrush, $text, $tLayout

_InitiateGUI($ex_width, $ex_height, 8)

While 1

    _GDIPlus_GraphicsClear($ex_backbuffer, 0xA0000000)
    If Mod(Random(1, 10, 1), 9) >= 4 Then
    _Explosion_Init(Random($x_min, $x_max, 1), Random($y_min, $y_max, 1))
    EndIf
    _Explosion()
    _GDIPlus_GraphicsDrawStringEx ($ex_backbuffer, $text, $hFont, $tLayout, $hFormat, $textHBrush)

    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($ex_bitmap) ;copy drawn image to GUI
    $dc = _WinAPI_CreateCompatibleDC($screenDC)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_DeleteObject($gdibitmap)
    _WinAPI_BitBlt($screenDC, 0, 0, $ex_width, $ex_height, $dc, 0, 0, $srccopy)
    _WinAPI_DeleteDC($dc)


    Sleep(50)
WEnd

Func _InitiateGUI($ex_width, $ex_height, $max)

    $explosion_max_amount = $max
    $explosion_step = 8
    $explosion_length = ($ex_width + $ex_height) / 7
    $explosion_max_particle = $max * 2
    Global $explosion_coordinate[$explosion_max_particle][$explosion_step * $explosion_max_amount] ; on/off, x, y, vx, vy, v, brush, color

    $hGUI = GUICreate('', $ex_width, $ex_height)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_CleanUp')
    $hWnd = WinGetHandle($hGUI)

    _GDIPlus_Startup()
    $ex_graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $ex_bitmap = _GDIPlus_BitmapCreateFromGraphics($ex_width, $ex_height, $ex_graphics)
    $ex_backbuffer = _GDIPlus_ImageGetGraphicsContext($ex_bitmap)
    $screenDC = _WinAPI_GetDC($hGUI)
    _GDIPlus_GraphicsSetSmoothingMode($ex_backbuffer, 2)



    ; all the below is for text
    $textBrush = _GDIPlus_BrushCreateSolid(0x1A000000)
    $textHBrush = _GDIPlus_BrushCreateSolid (0x7FAFAFAF)


    $textFontSize = 36
    $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
    $hFamily = _GDIPlus_FontFamilyCreate ("Arial")
    $hFont = _GDIPlus_FontCreate ($hFamily, $textFontSize, 2)

    $text = "Game Over!" & @LF & @LF & "Your score was 123"

    $tLayout = _GDIPlus_RectFCreate($ex_width / 2, $ex_height / 4, 0, 0)




    ; all the below is for explosions
    $x_min = $explosion_length * 0.75
    $x_max = $ex_width - $x_min
    $y_min = $explosion_length * 0.75
    $y_max = $ex_height - $y_min

    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
    $brush_color = 0; 0xFF000000 + Random(0x400000, 0xFFFFFF, 1)
    For $n = 0 To $explosion_max_particle - 1
    $explosion_coordinate[$n][$o + 6] = _GDIPlus_BrushCreateSolid($brush_color)
    Next
    Next

    GUISetState()
EndFunc


Func _CleanUp()
    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
    For $n = 0 To $explosion_max_particle - 1
    _GDIPlus_BrushDispose($explosion_coordinate[$n][$o + 6])
    Next
    Next

    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose($textBrush)
    _GDIPlus_BrushDispose($textHBrush)

    _GDIPlus_BitmapDispose($ex_bitmap)
    _GDIPlus_GraphicsDispose($ex_graphics)
    _GDIPlus_GraphicsDispose($ex_backbuffer)
    _GDIPlus_Shutdown()

    Exit
EndFunc

Func _Explosion_Init($ex, $ey)
    For $o = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step ;fill array with coordinate of hit object
    If $explosion_coordinate[0][$o] <> 1 Then
    $explosion_coordinate[0][$o] = 1
    $explosion_coordinate[0][$o + 1] = $ex ;save x coordinate
    $explosion_coordinate[0][$o + 2] = $ey ;save y coordinate
    $brush_color = 0xFF000000 + Random(0xF0F0F0, 0xFFFFFF, 1)
    For $n = 0 To $explosion_max_particle - 1
    $explosion_coordinate[$n][$o + 1] = $explosion_coordinate[0][$o + 1] ;duplicate x start position of all explosion particles
    $explosion_coordinate[$n][$o + 2] = $explosion_coordinate[0][$o + 2] ;duplicate y start position of all explosion particles
    $explosion_coordinate[$n][$o + 3] = _Random(-7, 7, 1) ;create random x vector (explosion particle speed)
    $explosion_coordinate[$n][$o + 4] = _Random(-7, 7, 1) ;create random y vector (explosion particle speed)
    $explosion_coordinate[$n][$o + 5] = Abs($explosion_coordinate[$n][3 + $o]) + Abs($explosion_coordinate[$n][4 + $o]) ;add absolute distance of vectors x and y
    $explosion_coordinate[$n][$o + 7] = $brush_color
    _GDIPlus_BrushSetSolidColor($explosion_coordinate[$n][$o + 6], $explosion_coordinate[$n][$o + 7])
    Next
    ExitLoop
    EndIf
    Next
EndFunc ;==>Explosion_Init

Func _Explosion() ;draw explosions coordinates
    Local $q, $k, $r, $g, $b
    $explosion_amount = 0
    For $k = 0 To $explosion_step * ($explosion_max_amount - 1) Step $explosion_step
    If $explosion_coordinate[0][$k] = 1 Then ;only draw active explosions
    $explosion_amount += 1
    For $q = 0 To $explosion_max_particle - 1
    $explosion_coordinate[$q][$k + 1] += $explosion_coordinate[$q][$k + 3] ;draw new x coordinate of a particle
    $explosion_coordinate[$q][$k + 2] += $explosion_coordinate[$q][$k + 4] ;draw new y coordinate of a particle
    $explosion_coordinate[$q][$k + 5] += Abs($explosion_coordinate[$q][$k + 3]) + Abs($explosion_coordinate[$q][$k + 4]) ;absolute vector length
    If $explosion_coordinate[$q][$k + 5] <= $explosion_length Then ;draw until max. distance has been reached
    _GDIPlus_GraphicsFillEllipse($ex_backbuffer, $explosion_coordinate[$q][$k + 1], $explosion_coordinate[$q][$k + 2], 3, 3, $explosion_coordinate[$q][$k + 6])
    ;fade out colors
    $r = BitAND($explosion_coordinate[$q][$k + 7], 0x00FF0000) / 0x10000 * 0.925 ;decrease red channel
    $g = BitAND($explosion_coordinate[$q][$k + 7], 0x0000FF00) / 0x100 * 0.925 ;decrease green channel
    $b = BitAND($explosion_coordinate[$q][$k + 7], 0x000000FF) * 0.925 ;decrease blue channel
    $explosion_coordinate[$q][$k + 7] = "0xFF" & Hex($r, 2) & Hex($g, 2) & Hex($b, 2)
    _GDIPlus_BrushSetSolidColor($explosion_coordinate[$q][$k + 6], $explosion_coordinate[$q][$k + 7]) ;set new color
    Else ;when max. distance has been reached then set x vector and y vector to 0
    $explosion_coordinate[0][$k] = 0
    EndIf
    Next
    EndIf
    Next
EndFunc ;==>Explosion

Func _Random($w1, $w2, $w3 = 0) ;just to avoid 0 as random number
    Local $x = 0, $l1 = 0.50
    While $x = 0
    $x = Random($w1, $w2, $w3)
    If $x < $l1 And $x >= 0 Then $x += $l1
    If $x > -$l1 And $x <= 0 Then $x -= $l1
    WEnd
    Return $x
EndFunc ;==>_Random

Func _GDIPlus_BrushSetSolidColorEx($hBrush, $iARGB = 0xFF000000)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "hwnd", $hBrush, "int", $iARGB)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_BrushSetSolidColor

Regards,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...