Luigi Posted December 6, 2014 Share Posted December 6, 2014 (edited) This is a little toy, maybe in the future is a small game... A block move between walls. Features: -colision with wall; -does not pass the limits (lower, upper, left, right); -horizontal and vertical movement; -diagonal movement; -movement speed in the horizontal and vertical is x; -the moving speed in the diagonal is smaller than the horizontal or vertical movement speed new version with GDI; grid gdi3.au3 old version without GDI: grid 00.au3 New version: 15/12/2014 read/work (only) json file created by Tiled Map Editor as background gui zoom improve of moviment in all directions grid_move.au3 images.zip Example: expandcollapse popup#include <Array.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <grid_move.au3> Local $sGuiLabel = "Detefon Grid" ; label of gui Local $sJSONMap = "map2.json" ; "map.json", "map1.json", "map2.json", "map3.json", "mapa_teste.json" ; map to open Local $iZoom = 1 ; zoom of gui ; 1 = 100% ; 1.1 = 110% ; 1.5 = 150% ; 2 = 200% Local $iTime = 20 ; the gui is update in 20 ms Grid_Create($sGuiLabel, $sJSONMap, $iZoom, $iTime) If @error Then ConsoleWrite("@error[ " & @error & " ]" & @LF) Local $iActorX = 64 Local $iActorY = 32 Local $iActorWidth = 32 Local $iActorHeight = 32 Local $iActorSpeed = 3 Local $iActorColor = 0xFF0000FF Grid_AddActor($iActorX, $iActorY, $iActorWidth, $iActorHeight, $iActorSpeed, $iActorColor) grid_add_wall(20, 20, 2, 40, 0xFF00FF00) ;~ grid_add_wall(22, 20, 6, 2, 0xFF00FF00) ;~ grid_add_wall(36, 20, 6, 2, 0xFF00FF00) ;~ grid_add_wall(42, 20, 2, 40, 0xFF00FF00) ;~ grid_add_wall(22, 36, 12, 2, 0xFF00FF00) ;~ grid_add_wall(50, 20, 2, 20, 0xFF00FF88) ;~ grid_add_wall(50, 48, 2, 12, 0xFF00FF88) ;~ grid_add_wall(52, 58, 12, 2, 0xFF00FF88) ;~ grid_add_wall(64, 20, 2, 40, 0xFF00FF88) ;~ grid_add_wall(72, 20, 16, 2, 0xFF6699EE) ;~ grid_add_wall(79, 20, 2, 40, 0xFF6699EE) ;~ grid_add_wall(94, 20, 16, 2, 0xFFFF0000) ;~ grid_add_wall(94, 58, 16, 2, 0xFFFF0000) ;~ grid_add_wall(94, 27, 2, 26, 0xFFFF0000) ;~ grid_add_wall(108, 27, 2, 31, 0xFFFF0000) While Sleep(20) WEnd Func _exit() Exit EndFunc ;==>_exit Edited December 15, 2014 by Detefon Visit my repository Link to comment Share on other sites More sharing options...
JohnOne Posted December 6, 2014 Share Posted December 6, 2014 _EXIT_BEFORE function is flawed. It's parameter is never declared because it is only ever called via OnAutoItExitRegister which passes no params Fix = remove the line and param altogether or If @NumParams Then ConsoleWrite("_exit[ " & $sInput & " ]" & @LF) AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Luigi Posted December 6, 2014 Author Share Posted December 6, 2014 Thank you John, fixed. Visit my repository Link to comment Share on other sites More sharing options...
Luigi Posted December 6, 2014 Author Share Posted December 6, 2014 (edited) The same idea, with GDI. Have some bugs yet... grid gdi.au3 New version (movement fixed) grid gdi3.au3 Edited December 7, 2014 by Detefon Visit my repository Link to comment Share on other sites More sharing options...
Gianni Posted December 7, 2014 Share Posted December 7, 2014 (edited) A possible use for a game "escape from the maze" edit: the exit is in the lower right expandcollapse popup;#AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 ;#Tidy_Parameters=/sf #include-once #include <Array.au3> #include <Misc.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> OnAutoItExitRegister("on_exit") Opt("GUIOnEventMode", 1) Opt("GUIEventOptions", 1) Opt("MustDeclareVars", 1) Global $aGuiSize[2] = [670, 700] Global $sGuiTitle = "Detefons's grid" Global $hGui ; $aBox[0] size of box ; $aBox[1] horizontal space between boxes ; $aBox[2] vertical space between boxes ; $aBox[3] grid's left position ; $aBox[4] grid's top position Global $aBox[5] = [10, 1, 1, 5, 5] ; used to store the pressed keys Global $aPress[6] = [False, False, False, False, False, False] ; $aKeys[0] ctrl ; $aKeys[1] space ; $aKeys[2] left ; $aKeys[3] up ; $aKeys[4] right ; $aKeys[5] down Global $aKeys[6] = [11, 20, 25, 26, 27, 28] ; store old values from x and y Global $iox, $ioy Global $hLabelX, $hLabelY Global $mx, $my ; used to calc a movement's diagonal Global Const $ROOT = Round(Sqrt(2) / 2, 3) Global $aGrid[($aGuiSize[0] - $aBox[3]) / ($aBox[0] + $aBox[1])][($aGuiSize[1] - $aBox[4] - 30) / ($aBox[0] + $aBox[2])] ; $aPos is a shadow array, if a pos[x][y] have no value, is possible walk here ; if have a some value, this is not possible Global $aPos[UBound($aGrid, 1)][UBound($aGrid, 2)] ; limits Global $aLim[4] = [0, 0, UBound($aGrid, 1) - 1, UBound($aGrid, 2) - 1] Global $oActor = ObjCreate("Scripting.Dictionary") $oActor.Add(1, ObjCreate("Scripting.Dictionary")) $oActor.Item(1).Add("x", 1) ; 4) ; start x position $oActor.Item(1).Add("y", 1) ; 10) ; start y position $oActor.Item(1).Add("s", 0.5) ; speed horizontal and vertical $oActor.Item(1).Add("ss", $oActor.Item(1).Item("s") * $ROOT) ; speed diagonal $hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1], -1, -1, $WS_POPUPWINDOW, $WS_EX_COMPOSITED) GUISetOnEvent($GUI_EVENT_CLOSE, "_quit") ; make the maze --------------------------------------------------------------------- ; portions of code from the following topic: ; http://www.autoitscript.com/forum/topic/141892-maze-generator/ ; ----------------------------------------------------------------------------------- Local $maze = _MyMaze(20, 20) ; generate maze Local $aiSize[2] = [20, 20] Local $aXY Local $color[2] = ["", "0x00AA00"]; [0] = Path ; [1] = Wall ([0] = path must stay empty) ; (see in Grid() function for path color) For $i = 0 To UBound($maze) - 1 $aXY = _GetCellPos($aiSize, $i) $aXY[0] *= 3 $aXY[1] *= 3 add_wall($aXY[1] + 1, $aXY[0] + 0, 1, 1, $color[StringMid($maze[$i], 1, 1)]) ; 10 add_wall($aXY[1] + 2, $aXY[0] + 1, 1, 1, $color[StringMid($maze[$i], 2, 1)]) ; 21 add_wall($aXY[1] + 1, $aXY[0] + 2, 1, 1, $color[StringMid($maze[$i], 3, 1)]) ; 12 add_wall($aXY[1] + 0, $aXY[0] + 1, 1, 1, $color[StringMid($maze[$i], 4, 1)]) ; 01 add_wall($aXY[1] + 0, $aXY[0] + 0, 1, 1, $color[1]) ; 00 add_wall($aXY[1] + 2, $aXY[0] + 0, 1, 1, $color[1]) ; 20 add_wall($aXY[1] + 1, $aXY[0] + 1, 1, 1, $color[0]) ; 11 add_wall($aXY[1] + 0, $aXY[0] + 2, 1, 1, $color[1]) ; 02 add_wall($aXY[1] + 2, $aXY[0] + 2, 1, 1, $color[1]) ; 22 Next ; ----------------------------------------------------------------------------------- $hLabelX = GUICtrlCreateLabel("x " & $oActor.Item(1).Item("x"), 10, 665, 600, 20) $hLabelY = GUICtrlCreateLabel("y " & $oActor.Item(1).Item("y"), 10, 685, 600, 20) grid() GUISetState(@SW_SHOW, $hGui) While Sleep(20) keyboard() If move() Then MsgBox(0, "End of game", "Great! did you find the exit!") Exit EndIf WEnd Func keyboard() For $ii = 0 To 5 If _IsPressed($aKeys[$ii]) And Not $aPress[$ii] Then $aPress[$ii] = True If Not _IsPressed($aKeys[$ii]) And $aPress[$ii] Then $aPress[$ii] = False Next EndFunc ;==>keyboard Func mov_vh($each, $dir, $speed, $sig = 1) ; movement vertical and horizontal Local $iTry = $oActor.Item($each).Item($dir) + $oActor.Item($each).Item($speed) * $sig Switch $dir Case "x" $mx = Round($iTry) $my = Round($oActor.Item($each).Item("y")) Switch $sig Case -1 If $iTry < $aLim[0] Then Return $aLim[0] Case 1 If $iTry > $aLim[2] Then Return $aLim[2] EndSwitch If ($aPos[$mx][$my]) Then Return $oActor.Item($each).Item("x") Case "y" $mx = Round($oActor.Item($each).Item("x")) $my = Round($iTry) Switch $sig Case -1 If $iTry < $aLim[1] Then Return $aLim[1] Case 1 If $iTry > $aLim[3] Then Return $aLim[3] EndSwitch If ($aPos[$mx][$my]) Then Return $oActor.Item($each).Item("y") EndSwitch Return $iTry EndFunc ;==>mov_vh Func move_d($each, $id) ; movement diagonal Switch $id Case 1 $oActor.Item($each).Item("x") = mov_vh($each, "x", "ss") $oActor.Item($each).Item("y") = mov_vh($each, "y", "ss", -1) Case 2 $oActor.Item($each).Item("x") = mov_vh($each, "x", "ss") $oActor.Item($each).Item("y") = mov_vh($each, "y", "ss") Case 3 $oActor.Item($each).Item("x") = mov_vh($each, "x", "ss", -1) $oActor.Item($each).Item("y") = mov_vh($each, "y", "ss") Case 4 $oActor.Item($each).Item("x") = mov_vh($each, "x", "ss", -1) $oActor.Item($each).Item("y") = mov_vh($each, "y", "ss", -1) EndSwitch EndFunc ;==>move_d Func move() For $each In $oActor $iox = $oActor.Item($each).Item("x") $ioy = $oActor.Item($each).Item("y") If $aPress[2] And Not $aPress[3] And Not $aPress[4] And Not $aPress[5] Then $oActor.Item($each).Item("x") = mov_vh($each, "x", "s", -1) If $aPress[4] And Not $aPress[2] And Not $aPress[3] And Not $aPress[5] Then $oActor.Item($each).Item("x") = mov_vh($each, "x", "s") If $aPress[3] And Not $aPress[2] And Not $aPress[4] And Not $aPress[5] Then $oActor.Item($each).Item("y") = mov_vh($each, "y", "s", -1) If $aPress[5] And Not $aPress[2] And Not $aPress[3] And Not $aPress[4] Then $oActor.Item($each).Item("y") = mov_vh($each, "y", "s") If $aPress[3] And $aPress[4] And Not $aPress[2] And Not $aPress[5] Then move_d($each, 1) If $aPress[4] And $aPress[5] And Not $aPress[2] And Not $aPress[3] Then move_d($each, 2) If $aPress[2] And $aPress[5] And Not $aPress[3] And Not $aPress[4] Then move_d($each, 3) If $aPress[2] And $aPress[3] And Not $aPress[4] And Not $aPress[5] Then move_d($each, 4) GUICtrlSetBkColor($aGrid[Round($iox)][Round($ioy)], 0xFFFFFF) GUICtrlSetBkColor($aGrid[Round($oActor.Item($each).Item("x"))][Round($oActor.Item($each).Item("y"))], 0x000000) Next GUICtrlSetData($hLabelX, "$x[" & Round($oActor.Item(1).Item("x")) & "]") GUICtrlSetData($hLabelY, "$y[" & Round($oActor.Item(1).Item("y")) & "]") Return ((Round($oActor.Item(1).Item("x")) = 58) And (Round($oActor.Item(1).Item("y")) = 58)) ; reached the exit of the maze EndFunc ;==>move Func grid() $mx = UBound($aGrid, 1) - 1 $my = UBound($aGrid, 2) - 1 For $ii = 0 To $mx For $jj = 0 To $my $aGrid[$ii][$jj] = GUICtrlCreateLabel("", $aBox[3] + $ii * ($aBox[0] + $aBox[1]), $aBox[4] + $jj * ($aBox[0] + $aBox[2]), $aBox[0], $aBox[0]) If $aPos[$ii][$jj] Then GUICtrlSetBkColor($aGrid[$ii][$jj], $aPos[$ii][$jj]) Else GUICtrlSetBkColor($aGrid[$ii][$jj], 0xDDDDDD) ; <-- Path color EndIf Next Next EndFunc ;==>grid Func _quit() Exit EndFunc ;==>_quit Func on_exit() GUIDelete($hGui) EndFunc ;==>on_exit Func add_wall($iXX, $iYY, $iWW, $iHH, $iColor) For $ii = $iXX To $iXX + $iWW - 1 For $jj = $iYY To $iYY + $iHH - 1 $aPos[$ii][$jj] = $iColor Next Next EndFunc ;==>add_wall ; make the maze --------------------------------------------------------------------- ; portions of code from the following topic: ; http://www.autoitscript.com/forum/topic/141892-maze-generator/ ; ----------------------------------------------------------------------------------- Func _MyMaze($iMazeX, $iMazeY) ; , $iRndSeed = Default, $bShow = True) Local $bShow = False Local $iRndSeed = Random(0, SRandom(@SEC * @MIN), 1) ; 1% of progress Local $aiSize[2] = [$iMazeX, $iMazeY] ;$aiSize[0] Equals Number of Rows in each colum and $aiSize[1] equals number of Colums ;Generate the maze it will be stored in $aCells Local $aCells = Generate_Maze($aiSize) ; This is where the maze will be stored ; It will store witch walls are intact Return $aCells EndFunc ;==>_MyMaze Func Generate_Maze(Const ByRef $aiSize) Local Const $iTotalCells = $aiSize[0] * $aiSize[1] Local $iMoveToCell ; What cell to move to Local $aCellstack[$iTotalCells][2];This stores with sequnce the cell got generated in. used for backtracing. First dimension is Row. Second is Colum Local $iCurrentCellStackNumber = 0 ; Current subscript number to write to in $aCellstack Local $aCurrentCellStack[2] ; USed as a temp storage of a bit of cellstack. First dimension is Row. Second is Colum Local $iUnvisitedCells = $iTotalCells ; Number of cell that are unvisited Local $sNeighbours = '' Local $sNeighbourOk Local $iRndDirection Local $aCurrentCellRowColum ;; setup cell array. Local $aCells[$iTotalCells];This is where the maze will be stored ; It will store witch walls are intact Local $aVisitedCells[$iTotalCells] Local $iCurrentCell = Random(0, $iTotalCells - 1, 1) ;; set random start point/cell ;Make all walls be intact by filling the cells array with 1111 For $i = 0 To $iTotalCells - 1 $aCells[$i] = "1111" $aVisitedCells[$i] = False Next While 1 ;Mark as visited and add to the cell stack $aCurrentCellRowColum = AddToCellStack($iCurrentCell, $iCurrentCellStackNumber, $aCellstack, $aiSize) ;; $iCurrentCell not used in function. ;Check to see if it sould stop createing the maze If $iUnvisitedCells <> 0 Then ;Check to see if the current cell has any neighbours there are unvisited $sNeighbours = _Neighbours($aCurrentCellRowColum, $iCurrentCell, $aVisitedCells, $aiSize) If $sNeighbours <> "0000" Then ;Choose a random unvisited Neighbour Do $iRndDirection = Random(0, 3, 1) $sNeighbourOk = StringMid($sNeighbours, $iRndDirection + 1, 1) Until $sNeighbourOk = "1" Switch $iRndDirection ;Witch side to move to Case 0 ; Move Up $iMoveToCell = $iCurrentCell - $aiSize[1] Case 1 ; Move Right $iMoveToCell = $iCurrentCell + 1 Case 2 ; Move Down $iMoveToCell = $iCurrentCell + $aiSize[1] Case 3 ; Move Left $iMoveToCell = $iCurrentCell - 1 EndSwitch BustWall($iCurrentCell, $iMoveToCell, $iRndDirection, $aCells) $iCurrentCell = $iMoveToCell ;Make the current cell visited $aVisitedCells[$iCurrentCell] = True $iUnvisitedCells -= 1 Else $aCurrentCellStack[0] = $aCellstack[$iCurrentCellStackNumber - 2][0] ; Get row of last item in cellstack $aCurrentCellStack[1] = $aCellstack[$iCurrentCellStackNumber - 2][1] ; Get colum of last item in cellstack $iCurrentCell = _GetCellPos($aiSize, $aCurrentCellStack) ; Combine row and colum to get pos $iCurrentCellStackNumber -= 2 ; This will ensure that the used cell from the cellstack will be overwritten EndIf Else ExitLoop EndIf WEnd Return $aCells EndFunc ;==>Generate_Maze #Region Maze generation functions Func BustWall($Cell1, $Cell2, $iDirection, ByRef $aCells) ; This function will remove the walls in two adjacent cells. Direction is from first cell to second. Direction can be from 0 - 3. 0 = Up, 1 = Right, 2 = Down, 3 = Left $aCells[$Cell1] = StringReplace($aCells[$Cell1], $iDirection + 1, "0", 1, 2) ; Bust the wall between cell1 and cell2 in cell1 FlipDirection_br($iDirection) $aCells[$Cell2] = StringReplace($aCells[$Cell2], $iDirection + 1, "0", 1, 2) ; Bust the wall between cell1 and cell2 in cell2 EndFunc ;==>BustWall Func AddToCellStack($iCurrentCell, ByRef $iCurrentCellStackNumber, ByRef $aCellstack, Const ByRef $aiSize); This function will add the $Cell to the $aCellstack at the subscript of $CurretCellStackNumber ;Convert to Rows and colums Local $aCurrentCellRowColum = _GetCellPos($aiSize, $iCurrentCell) ;Add cell to the cell stack $aCellstack[$iCurrentCellStackNumber][0] = $aCurrentCellRowColum[0] $aCellstack[$iCurrentCellStackNumber][1] = $aCurrentCellRowColum[1] ;Add one to $iCurrentCellStackNumber $iCurrentCellStackNumber += 1 Return $aCurrentCellRowColum EndFunc ;==>AddToCellStack Func _Neighbours(Const ByRef $aCurrentCellRowColum, $Cell, ByRef Const $aVisitedCells, Const ByRef $aiSize) ; Check for Neighbours and store them in a string an 1 means that the neighbour has not been visited and an 0 means the neighbour has been visited it also checks for the edge of the maze. Local $NeighbourRowColum, $sNeighbours = '' Local Const $iTotalCells = $aiSize[0] * $aiSize[1] ;Check Clockwise ;Check Above cell If ($Cell - $aiSize[1] >= 0) And ($aVisitedCells[$Cell - $aiSize[1]] = False) Then $sNeighbours &= "1" Else $sNeighbours &= "0" EndIf ;Check Right Cell $NeighbourRowColum = _GetCellPos($aiSize, $Cell + 1) If ($aCurrentCellRowColum[0] >= $NeighbourRowColum[0]) And ($Cell + 1 < $iTotalCells) And ($aVisitedCells[$Cell + 1] = False) Then $sNeighbours &= "1" Else $sNeighbours &= "0" EndIf ;Check Buttom Cell If ($Cell + $aiSize[1] < $iTotalCells) And ($aVisitedCells[$Cell + $aiSize[1]] = False) Then $sNeighbours &= "1" Else $sNeighbours &= "0" EndIf ;Check Left Cell $NeighbourRowColum = _GetCellPos($aiSize, $Cell - 1) If ($aCurrentCellRowColum[0] <= $NeighbourRowColum[0]) And ($Cell - 1 >= 0) And ($aVisitedCells[$Cell - 1] = False) Then $sNeighbours &= "1" Else $sNeighbours &= "0" EndIf Return $sNeighbours EndFunc ;==>_Neighbours #EndRegion Maze generation functions #Region Global Functions Func _GetCellPos(Const ByRef $aiSize, $vFind) ; This function will make a row and a colum into a Pos to be used with $aCells or $aCellstack, Or it will Make a Pos into an array with row and colum If IsArray($vFind) Then Local $CellPos = $vFind[0] * $aiSize[1] + $vFind[1] Return $CellPos Else Local $aCellRowColum[2] ; Will be used in the _GetCellPos function to temp.. store an array $aCellRowColum[0] = Int($vFind / $aiSize[1]) $aCellRowColum[1] = $vFind - ($aCellRowColum[0] * $aiSize[1]) Return $aCellRowColum EndIf EndFunc ;==>_GetCellPos Func FlipDirection_br(ByRef $iDirection) ; Flips the direction If $iDirection > 1 Then $iDirection -= 2 Else $iDirection += 2 EndIf EndFunc ;==>FlipDirection_br #EndRegion Global Functions Edited December 8, 2014 by Chimp UEZ and Luigi 2 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
lorenkinzel Posted December 8, 2014 Share Posted December 8, 2014 Pretty cool; especially with the "maze" alternate added. Downside being: will affect my productivity for a few days. Link to comment Share on other sites More sharing options...
Luigi Posted December 8, 2014 Author Share Posted December 8, 2014 @Chimp; cool the maze alternative! ^^ Visit my repository 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