Jump to content
gottygolly

Collision detection with gdi

Recommended Posts

gottygolly

I asked about this before but last time it was with controls and i've been told that I should do it with gdi instead. Well I tried and got stuck on the collision part of it.

I have it to where it will hit the red rectangle and then cut off all movement but I just want to make it so if the top of the white block hits the bottom if the red box, the white box can no longer move up but can still move left, right and down.

#include <gdiplus.au3>
#include <misc.au3>
$gui = GUICreate("", 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$x = 220
$y = 355
$x2 = 200
$y2 = 0
$move = True
GUISetState()
_GDIPlus_Startup()
$hwnd = _GDIPlus_GraphicsCreateFromHWND($gui)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(640, 480, $hwnd)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$brush_c = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$g_hPen_A = _GDIPlus_PenCreate(0xFF00FF00, 4)
$brush_b = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$path = _GDIPlus_PathCreate()
$path2 = _GDIPlus_PathCreate()
$g_path = _GDIPlus_PathAddRectangle($path, $x2, $y2, 300, 50)
$g_path2 = _GDIPlus_PathAddRectangle($path2, $x, $y, 50, 50)

While 1
    _GDIPlus_GraphicsClear($backbuffer)
    $g_path = _GDIPlus_PathAddRectangle($path, $x2, $y2, 300, 50)
$g_path2 = _GDIPlus_PathAddRectangle($path2, $x, $y, 50, 50)
    If $y2 >= 480 Then
        $y2= -50
    EndIf
    $y2 += 1
    _GDIPlus_GraphicsFillRect($backbuffer, $x2, $y2, 300, 50, $brush_c)
    _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
    If $move = True Then
        If _IsPressed("25") Then
            $x -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("27") Then
            $x += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("26") Then
            $y -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("28") Then
            $y += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        EndIf
        _GDIPlus_GraphicsDrawImageRect($hwnd, $bitmap, 0, 0, 640, 480)
        $cp = GUIGetCursorInfo($gui)
        Select
        Case _GDIPlus_PathIsOutlineVisiblePoint($path, $x, $y)
            $move = False
        EndSelect
    Sleep(10)
WEnd

Func _Exit()
    _GDIPlus_PathDispose($path)
    _GDIPlus_PathDispose($path2)
    _GDIPlus_BrushDispose($brush_c)
    _GDIPlus_BrushDispose($brush_b)
    _GDIPlus_PenDispose($g_hPen_A)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($hwnd)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

Any help will go a long way. Thanks in advance!

Share this post


Link to post
Share on other sites
Danyfirex

I'm sure UEZ has an example here.

Another examples here and here.

 

Saludos

Share this post


Link to post
Share on other sites
UEZ

What should happen when a collision is detected exactly? I mean I can move the white square around the red rectangle and hit it from the top! A little more precise definition what should happen after collision please.

If you objects are simple objects as rectangles you can use also _WinAPI_PtInRect() to check for collision.


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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
gottygolly

I may have asked it wrong but I want it to simulate hitting a wall. Like in the code below when moving down.

#include<misc.au3>
#include<windowsconstants.au3>
#include<guiconstants.au3>
$gui = GUICreate("Gui", 300, 300, -1, -1, BitOR($WS_EX_WINDOWEDGE, $WS_POPUP))
$pic = GUICtrlCreateInput("", 50, 50, 36, 36)
GUICtrlSetState($pic, $GUI_DISABLE)
GUICtrlSetBkColor($pic, 0xFF0000)
GUISetBkColor(0x000000)
$inp = GUICtrlCreateInput("", 200, 200, 50, 50)
GUICtrlSetState($inp, $GUI_DISABLE)
GUISetState()

While 1
    If _IsPressed("25") Then
        $cp = ControlGetPos($gui, "", $pic)
        $cpx = $cp[0] - 1
        GUICtrlSetPos($pic, $cpx, $cp[1])
    EndIf
    If _IsPressed("28") Then
        $cp = ControlGetPos($gui, "", $pic)
        If _CanMoveDown($cp) Then
            $cpy = $cp[1] + 1
            GUICtrlSetPos($pic, $cp[0], $cpy)
        EndIf

    EndIf
    If _IsPressed("27") Then
        $cp = ControlGetPos($gui, "", $pic)
        $cpx = $cp[0] + 1
        GUICtrlSetPos($pic, $cpx, $cp[1])
    EndIf
    If _IsPressed("26") Then
        $cp = ControlGetPos($gui, "", $pic)

        $cpy = $cp[1] - 1
        GUICtrlSetPos($pic, $cp[0], $cpy)

    EndIf
    $msg = GUIGetMsg(1)
    Switch $msg[1]
        Case $gui
            Switch $msg[0]
                Case -3
                    Exit
            EndSwitch
    EndSwitch
WEnd

Func _CanMoveDown($cp)
    $red_B = $cp[1] + $cp[3]
    $red_R = $cp[0] + $cp[2]
    $red_L = $cp[0]
    If $red_B >= 200 And ($red_R >= 200 And $red_L <= 250) Then
        Return False
    EndIf
    Return True
EndFunc   ;==>_CanMoveDown

 

Edited by gottygolly

Share this post


Link to post
Share on other sites
gottygolly

Wasn't sure if I should edit the last post or make a new one but I made a new one to get help a little faster.

I figured out a way to do what I intended on doing from the stop but now I ran into another problem.

If the white box hits the left side of the box then it can't move right but can move up/down. Same with all sides, if it hits the bottom for the red box then it can't move down but can move left/right.

There must be an easier way of doing this, thanks in advance.

#include <gdiplus.au3>
#include <misc.au3>
$gui = GUICreate("", 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$x = 220
$y = 355
$x2 = 200
$y2 = 200
$move = True
GUISetState()
_GDIPlus_Startup()
$hwnd = _GDIPlus_GraphicsCreateFromHWND($gui)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(640, 480, $hwnd)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$brush_c = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$g_hPen_A = _GDIPlus_PenCreate(0xFF00FF00, 4)
$brush_b = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$path = _GDIPlus_PathCreate()
$path2 = _GDIPlus_PathCreate()
$g_path = _GDIPlus_PathAddRectangle($path, $x2, $y2, 300, 50)
$g_path2 = _GDIPlus_PathAddRectangle($path2, $x, $y, 50, 50)

While 1
    _GDIPlus_GraphicsClear($backbuffer)
    _GDIPlus_GraphicsFillRect($backbuffer, $x2, $y2, 300, 50, $brush_c)
    _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        If _IsPressed("25") Then
            If $x <= $x2 + 305 And $y >= $y2 And $y <= $y2 + 50 Or $y+50 <= $y2 + 50 and $y+50 >= $y2 And $x <= $x2+305 Then
                Else
            $x -= 5
            EndIf
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("27") Then
            If $x+50 >= $x2-5 And $y >= $y2 And $y <= $y2 + 50 Or $y+50 <= $y2 + 50 and $y+50 >= $y2 And $x+50 >= $x2-5 Then
                Else
            $x += 5
            EndIf
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("26") Then
            If $y <= $y2+55 And $x <= $x2+300 And $x+50 >= $x2 Then
                Else
            $y -= 5
            EndIf
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        If _IsPressed("28") Then
            If $y+50 >= $y2-5 And $x <= $x2+300 And $x+50 >= $x2 Then
                Else
            $y += 5
            EndIf
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
        _GDIPlus_GraphicsDrawImageRect($hwnd, $bitmap, 0, 0, 640, 480)
        $cp = GUIGetCursorInfo($gui)
        Select
        Case _GDIPlus_PathIsOutlineVisiblePoint($path, $x, $y)
            $move = False
        EndSelect
    Sleep(10)
WEnd

Func _Exit()
    _GDIPlus_PathDispose($path)
    _GDIPlus_PathDispose($path2)
    _GDIPlus_BrushDispose($brush_c)
    _GDIPlus_BrushDispose($brush_b)
    _GDIPlus_PenDispose($g_hPen_A)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($hwnd)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

 

Share this post


Link to post
Share on other sites
gottygolly

Double posted for some reason, delete this one please.

Edited by gottygolly

Share this post


Link to post
Share on other sites
UEZ

Try this:

#include <gdiplus.au3>
#include <misc.au3>
$gui = GUICreate("", 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$x = 220
$y = 355
GUISetState()
_GDIPlus_Startup()
$hwnd = _GDIPlus_GraphicsCreateFromHWND($gui)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(640, 480, $hwnd)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$brush_c = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$g_hPen_A = _GDIPlus_PenCreate(0xFF00FF00, 4)
$brush_b = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$path = _GDIPlus_PathCreate()
_GDIPlus_PathAddRectangle($path, 200, 155, 200, 50) ;red rectangle

While 1
    _GDIPlus_GraphicsClear($backbuffer)
    _GDIPlus_GraphicsFillPath($backbuffer, $path, $brush_c)
    _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)

    If _IsPressed("25") Then ;left
        If _GDIPlus_PathIsVisiblePoint($path, $x - 5, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x - 5, $y + 50, $backbuffer) Then
            ContinueLoop
        Else
            $x -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("27") Then ;right
        If _GDIPlus_PathIsVisiblePoint($path, $x + 55, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 55, $y + 50, $backbuffer) Then
            ContinueLoop
        Else
            $x += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("26") Then ;up
        If _GDIPlus_PathIsVisiblePoint($path, $x, $y - 5, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y - 5, $backbuffer) Then
            ContinueLoop
        Else
            $y -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("28") Then ;down
        If _GDIPlus_PathIsVisiblePoint($path, $x, $y + 55, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y + 5, $backbuffer) Then
            ContinueLoop
        Else
            $y += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf

    _GDIPlus_GraphicsDrawImageRect($hwnd, $bitmap, 0, 0, 640, 480)

    Sleep(10)
WEnd

Func _Exit()
    _GDIPlus_PathDispose($path)
    _GDIPlus_BrushDispose($brush_c)
    _GDIPlus_BrushDispose($brush_b)
    _GDIPlus_PenDispose($g_hPen_A)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($hwnd)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

 

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
gottygolly

Thanks for the reply UEZ, it's a little buggy but I think I can work off of this. :thumbsup:

Edit: This one works a bit better for me.

#include <gdiplus.au3>
#include <misc.au3>
$gui = GUICreate("", 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$x = 220
$y = 355
GUISetState()
_GDIPlus_Startup()
$hwnd = _GDIPlus_GraphicsCreateFromHWND($gui)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(640, 480, $hwnd)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$brush_c = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$g_hPen_A = _GDIPlus_PenCreate(0xFF00FF00, 4)
$brush_b = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$path = _GDIPlus_PathCreate()
_GDIPlus_PathAddRectangle($path, 200, 155, 200, 50) ;red rectangle

While 1
    _GDIPlus_GraphicsClear($backbuffer)
    _GDIPlus_GraphicsFillPath($backbuffer, $path, $brush_c)
    _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)

    If _IsPressed("25") Then ;left
        If _GDIPlus_PathIsVisiblePoint($path, $x -10, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x - 10, $y + 50, $backbuffer) Then

        Else
            $x -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("27") Then ;right
        If _GDIPlus_PathIsVisiblePoint($path, $x + 55, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 55, $y + 50, $backbuffer) Then

        Else
            $x += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("26") Then ;up
        If _GDIPlus_PathIsVisiblePoint($path, $x, $y-10, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y-10, $backbuffer) Then

        Else
            $y -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("28") Then ;down
        If _GDIPlus_PathIsVisiblePoint($path, $x, $y + 55, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y + 55, $backbuffer) Then

        Else
            $y += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf

    _GDIPlus_GraphicsDrawImageRect($hwnd, $bitmap, 0, 0, 640, 480)

    Sleep(10)
WEnd

Func _Exit()
    _GDIPlus_PathDispose($path)
    _GDIPlus_BrushDispose($brush_c)
    _GDIPlus_BrushDispose($brush_b)
    _GDIPlus_PenDispose($g_hPen_A)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($hwnd)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

 

Edited by gottygolly

Share this post


Link to post
Share on other sites
UEZ

Yes, you are right when moving diagonally it much better now.
Btw, I shorten the If/Then code a little bit.

#include <gdiplus.au3>
#include <misc.au3>
$gui = GUICreate("", 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$x = 220
$y = 355
GUISetState()
_GDIPlus_Startup()
$hwnd = _GDIPlus_GraphicsCreateFromHWND($gui)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(640, 480, $hwnd)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$brush_c = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$g_hPen_A = _GDIPlus_PenCreate(0xFF00FF00, 4)
$brush_b = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$path = _GDIPlus_PathCreate()
_GDIPlus_PathAddRectangle($path, 200, 155, 200, 50) ;red rectangle

While 1
    _GDIPlus_GraphicsClear($backbuffer)
    _GDIPlus_GraphicsFillPath($backbuffer, $path, $brush_c)
    _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)

    If _IsPressed("25") Then ;left
        If Not (_GDIPlus_PathIsVisiblePoint($path, $x -10, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x - 10, $y + 50, $backbuffer)) Then
            $x -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("27") Then ;right
        If Not (_GDIPlus_PathIsVisiblePoint($path, $x + 55, $y, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 55, $y + 50, $backbuffer)) Then
            $x += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("26") Then ;up
        If Not (_GDIPlus_PathIsVisiblePoint($path, $x, $y-10, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y-10, $backbuffer)) Then
            $y -= 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf
    If _IsPressed("28") Then ;down
        If Not (_GDIPlus_PathIsVisiblePoint($path, $x, $y + 55, $backbuffer) Or _GDIPlus_PathIsVisiblePoint($path, $x + 50, $y + 55, $backbuffer)) Then
            $y += 5
            _GDIPlus_GraphicsFillRect($backbuffer, $x, $y, 50, 50, $brush_b)
        EndIf
    EndIf

    _GDIPlus_GraphicsDrawImageRect($hwnd, $bitmap, 0, 0, 640, 480)

    Sleep(10)
WEnd

Func _Exit()
    _GDIPlus_PathDispose($path)
    _GDIPlus_BrushDispose($brush_c)
    _GDIPlus_BrushDispose($brush_b)
    _GDIPlus_PenDispose($g_hPen_A)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($hwnd)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

 


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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
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

×