Sven-Seyfert Posted November 17, 2017 Share Posted November 17, 2017 (edited) Hi Community, I already created a collision detection system for a GDI+ Game that I will still work on for a while. But I want to replace my own approch (that is to complex and not dynamic) with the possibilities of _GDI_Plus_PathIsVisiblePoint(). I'm was looking around and found an example from @UEZ here that I edited for my needs. Unfortunately there is no collision on a specific height (Y position) for the movement from left --> right or from right <-- left. Why? The backgrounds of the pictures are only for visualization where the boundaries of the rectangles are. The collision refers to the red rectangle. The player shoudn't move into this area (movement stop). Thanks for any suggestion - I'm grateful! SvenThe animated GIF should hopefully explain my problem further: Spoiler [Solved] final solution: Thanks to the Community. Code: Spoiler expandcollapse popup; includes --------------------------------------------------------------------- #include-once #include <GDIPlus.au3> #include <Misc.au3> ; declaration ------------------------------------------------------------------ Global Const $iGuiWidth = 1000 Global Const $iGuiHeight = 690 Global Const $iGuiLeft = 10 Global Const $iGuiTop = 10 Global Const $GUI_EVENT_CLOSE = -3 Global $bExit = False Global Const $iPlayerWidth = 32 Global Const $iPlayerHeight = 48 Global Const $iPlayerStep = 4 Global $iXPosPlayer = 16 Global $iYPosPlayer = 16 Global Const $iTreeWidth = 128 Global Const $iTreeHeight = 160 Global Const $iXPosTree = 100 Global Const $iYPosTree = 100 Global Const $iWidthCollisionBlock = 40 Global Const $iHeightCollisionBlock = 20 Global Const $iXCollisionBlock = 145 Global Const $iYCollisionBlock = 220 Global Const $sPlayerImg = 'player01_01.png' Global Const $sTreeImg = 'tree01_01.png' ; gui -------------------------------------------------------------------------- Global $hMainGui = GUICreate( '', $iGuiWidth, $iGuiHeight, $iGuiLeft, $iGuiTop ) GUISetState( @SW_SHOW, $hMainGui ) ; init ------------------------------------------------------------------------- Opt( 'GUIOnEventMode', 1 ) GUISetOnEvent( $GUI_EVENT_CLOSE, '_exitToggle' ) OnAutoItExitRegister( '_exit' ) _GDIPlus_Startup() Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND( $hMainGui ) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics( $iGuiWidth, $iGuiHeight, $hGraphics ) Global $hBuffer = _GDIPlus_ImageGetGraphicsContext( $hBitmap ) Global $vRed = _GDIPlus_BrushCreateSolid( 0xFFFF0000 ) Global $hPlayerImg = _GDIPlus_ImageLoadFromFile( $sPlayerImg ) Global $hTreeImg = _GDIPlus_ImageLoadFromFile( $sTreeImg ) ; functions -------------------------------------------------------------------- Func _isCollisionRect( $iX, $iY, $iWidth, $iHeight, $iXBlock, $iYBlock, $iWidthBlock, $iHeightBlock ) Return ( $iX + $iWidth > $iXBlock And $iY + $iHeight > $iYBlock And $iX < $iXBlock + $iWidthBlock And $iY < $iYBlock + $iHeightBlock ) EndFunc Func _isCollisionPoint( $iX, $iY, $iXBlock, $iYBlock, $iWidthBlock, $iHeightBlock ) ; currently unused Return ( $iX > $iXBlock And $iY > $iYBlock And $iX < $iXBlock + $iWidthBlock And $iY < $iYBlock + $iHeightBlock ) EndFunc Func _exitToggle() $bExit = True EndFunc Func _exit() _GDIPlus_BrushDispose( $vRed ) _GDIPlus_GraphicsDispose( $hBuffer ) _GDIPlus_BitmapDispose( $hBitmap ) _GDIPlus_GraphicsDispose( $hGraphics ) _GDIPlus_Shutdown() GUIDelete( $hMainGui ) EndFunc ; processing ------------------------------------------------------------------- While Not $bExit And Sleep( 25 ) _GDIPlus_GraphicsClear( $hBuffer ) _GDIPlus_GraphicsDrawImageRect( $hBuffer, $hPlayerImg, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight ) ; draw player _GDIPlus_GraphicsDrawImageRect( $hBuffer, $hTreeImg, $iXPosTree, $iYPosTree, $iTreeWidth, $iTreeHeight ) ; draw tree If $iYPosPlayer >= $iYCollisionBlock Then _GDIPlus_GraphicsDrawImageRect( $hBuffer, $hPlayerImg, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight ) ; draw player in the forground _GDIPlus_GraphicsFillRect( $hBuffer, $iXCollisionBlock, $iYCollisionBlock, $iWidthCollisionBlock, $iHeightCollisionBlock, $vRed ) ; just for visualization purpose If _IsPressed( '25' ) Then ; left If Not _isCollisionRect( $iXPosPlayer - $iPlayerStep, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $iXCollisionBlock, $iYCollisionBlock, $iWidthCollisionBlock, $iHeightCollisionBlock ) Then $iXPosPlayer -= $iPlayerStep EndIf EndIf If _IsPressed( '27' ) Then ; right If Not _isCollisionRect( $iXPosPlayer + $iPlayerStep, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $iXCollisionBlock, $iYCollisionBlock, $iWidthCollisionBlock, $iHeightCollisionBlock ) Then $iXPosPlayer += $iPlayerStep EndIf EndIf If _IsPressed( '26' ) Then ; up If Not _isCollisionRect( $iXPosPlayer, $iYPosPlayer - $iPlayerStep, $iPlayerWidth, $iPlayerHeight, $iXCollisionBlock, $iYCollisionBlock, $iWidthCollisionBlock, $iHeightCollisionBlock ) Then $iYPosPlayer -= $iPlayerStep EndIf EndIf If _IsPressed( '28' ) Then ; down If Not _isCollisionRect( $iXPosPlayer, $iYPosPlayer + $iPlayerStep, $iPlayerWidth, $iPlayerHeight, $iXCollisionBlock, $iYCollisionBlock, $iWidthCollisionBlock, $iHeightCollisionBlock ) Then $iYPosPlayer += $iPlayerStep EndIf EndIf _GDIPlus_GraphicsDrawImageRect( $hGraphics, $hBitmap, 0, 0, $iGuiWidth, $iGuiHeight ) WEnd Edited May 13, 2018 by Sven-Seyfert Link to comment Share on other sites More sharing options...
UEZ Posted November 17, 2017 Share Posted November 17, 2017 You have to add two additional check points otherwise the corner of the player sprite will stay outside the red path object. expandcollapse popup; includes --------------------------------------------------------------------- #include-once #include <GDIPlus.au3> #include <Misc.au3> ; declaration ------------------------------------------------------------------ Local Const $iGuiWidth = 1000 Local Const $iGuiHeight = 690 Local Const $iGuiLeft = 10 Local Const $iGuiTop = 10 Local Const $GUI_EVENT_CLOSE = -3 Local Const $iPlayerHeight = 48 Local Const $iPlayerWidth = 32 Local Const $iPlayerStep = 4 Local $iXPosPlayer = 16 Local $iYPosPlayer = 16 Local Const $iXPosBlueRectangle = 100 Local Const $iYPosBlueRectangle = 100 Local Const $iBlueRectangleWidth = 128 Local Const $iBlueRectangleHeight = 160 Local Const $iXPosTree = 100 Local Const $iYPosTree = 100 Local Const $iTreeWidth = 128 Local Const $iTreeHeight = 160 Local Const $sPlayerImg = 'player01_01.png' Local Const $sTreeImg = 'tree01_01.png' ; gui -------------------------------------------------------------------------- Local $hMainGui = GUICreate( '', $iGuiWidth, $iGuiHeight, $iGuiLeft, $iGuiTop ) GUISetState( @SW_SHOW, $hMainGui ) ; init ------------------------------------------------------------------------- Opt( 'GUIOnEventMode', 1 ) GUISetOnEvent( $GUI_EVENT_CLOSE, '_exit' ) _GDIPlus_Startup() Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND( $hMainGui ) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics( $iGuiWidth, $iGuiHeight, $hGraphics ) Local $hBuffer = _GDIPlus_ImageGetGraphicsContext( $hBitmap ) Local $vWhite = _GDIPlus_BrushCreateSolid( 0xFFFFFFFF ) Local $vBlue = _GDIPlus_BrushCreateSolid( 0xFFABCDEF ) Local $vRed = _GDIPlus_BrushCreateSolid( 0xFFFF0000 ) Local $hGraphicPath = _GDIPlus_PathCreate() _GDIPlus_PathAddRectangle( $hGraphicPath, 130, 215, 70, 35 ) ; set red collision area Local $hImagePlayer = _GDIPlus_ImageLoadFromFile( $sPlayerImg ) Local $hImageThree = _GDIPlus_ImageLoadFromFile( $sTreeImg ) ; functions -------------------------------------------------------------------- Func _exit() _GDIPlus_PathDispose( $hGraphicPath ) _GDIPlus_BrushDispose( $vRed ) _GDIPlus_BrushDispose( $vBlue ) _GDIPlus_BrushDispose( $vWhite ) _GDIPlus_GraphicsDispose( $hBuffer ) _GDIPlus_BitmapDispose( $hBitmap ) _GDIPlus_BitmapDispose( $hImagePlayer ) _GDIPlus_BitmapDispose( $hImageThree ) _GDIPlus_GraphicsDispose( $hGraphics ) _GDIPlus_Shutdown() GUIDelete( $hMainGui ) Exit EndFunc ; processing ------------------------------------------------------------------- While 1 _GDIPlus_GraphicsClear( $hBuffer ) _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $vWhite ) ; draw player background _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosBlueRectangle, $iYPosBlueRectangle, $iBlueRectangleWidth, $iBlueRectangleHeight, $vBlue ) ; draw tree background _GDIPlus_GraphicsDrawImageRect( $hBuffer, $hImagePlayer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight ) ; draw player _GDIPlus_GraphicsDrawImageRect( $hBuffer, $hImageThree, $iXPosTree, $iYPosTree, $iTreeWidth, $iTreeHeight ) ; draw tree _GDIPlus_GraphicsFillPath( $hBuffer, $hGraphicPath, $vRed ) ; draw red collision area If _IsPressed( '25' ) Then ; left If Not Check_for_Collision($iXPosPlayer - $iPlayerStep, $iYPosPlayer, $iXPosPlayer - $iPlayerStep + $iPlayerWidth, $iYPosPlayer, _ $iXPosPlayer - $iPlayerStep, $iYPosPlayer + $iPlayerHeight, $iXPosPlayer - $iPlayerStep + $iPlayerWidth, $iYPosPlayer + $iPlayerHeight, $hGraphicPath) Then $iXPosPlayer -= $iPlayerStep _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $vWhite ) EndIf EndIf If _IsPressed( '27' ) Then ; right If Not Check_for_Collision($iXPosPlayer + $iPlayerStep, $iYPosPlayer, $iXPosPlayer + $iPlayerStep + $iPlayerWidth, $iYPosPlayer, _ $iXPosPlayer + $iPlayerStep, $iYPosPlayer + $iPlayerHeight, $iXPosPlayer + $iPlayerStep + $iPlayerWidth, $iYPosPlayer + $iPlayerHeight, $hGraphicPath) Then $iXPosPlayer += $iPlayerStep _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $vWhite ) EndIf EndIf If _IsPressed( '26' ) Then ; up If Not Check_for_Collision($iXPosPlayer, $iYPosPlayer - $iPlayerStep, $iXPosPlayer + $iPlayerWidth, $iYPosPlayer - $iPlayerStep, _ $iXPosPlayer, $iYPosPlayer - $iPlayerStep + $iPlayerHeight, $iXPosPlayer + $iPlayerWidth, $iYPosPlayer - $iPlayerStep + $iPlayerHeight, $hGraphicPath) Then $iYPosPlayer -= $iPlayerStep _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $vWhite ) EndIf EndIf If _IsPressed( '28' ) Then ; down If Not Check_for_Collision($iXPosPlayer, $iYPosPlayer + $iPlayerStep, $iXPosPlayer + $iPlayerWidth, $iYPosPlayer + $iPlayerStep, _ $iXPosPlayer, $iYPosPlayer + $iPlayerStep + $iPlayerHeight, $iXPosPlayer + $iPlayerWidth, $iYPosPlayer + $iPlayerStep + $iPlayerHeight, $hGraphicPath) Then $iYPosPlayer += $iPlayerStep _GDIPlus_GraphicsFillRect( $hBuffer, $iXPosPlayer, $iYPosPlayer, $iPlayerWidth, $iPlayerHeight, $vWhite ) EndIf EndIf _GDIPlus_GraphicsDrawImageRect( $hGraphics, $hBitmap, 0, 0, $iGuiWidth, $iGuiHeight ) Sleep( 10 ) WEnd Func Check_for_Collision($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4, $hPath) Return BitOR(_GDIPlus_PathIsVisiblePoint($hPath, $x1, $y1), _GDIPlus_PathIsVisiblePoint($hPath, $x2, $y2), _ _GDIPlus_PathIsVisiblePoint($hPath, $x3, $y3), _GDIPlus_PathIsVisiblePoint($hPath, $x4, $y4), _ _GDIPlus_PathIsVisiblePoint($hPath, $x1, ($y1 + $y3) / 2), _GDIPlus_PathIsVisiblePoint($hPath, $x2, ($y2 + $y4) / 2)) EndFunc Further _GDIPlus_ImageLoadFromFile in an endless loop causes a memory leak! 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 More sharing options...
Sven-Seyfert Posted November 17, 2017 Author Share Posted November 17, 2017 Hi @UEZ, thanks a lot for the way to do it right with _GDIPlus_PathIsVisiblePoint(). I edit my post #1 with the final code solution by a other suggestion from Mars (german forum) because it's more easy and shorter. I will not produce any memory leaks in the future . Thanks for your help - I'm grateful! Sven Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now