Sign in to follow this  
Followers 0
Luigi

movement and colision

7 posts in this topic

#1 ·  Posted (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

post-53968-0-96808200-1418131007_thumb.p

new version with GDI;

grid gdi3.au3

post-53968-0-86838500-1418130779.png

old version without GDI:

grid 00.au3

New version: 15/12/2014

post-53968-0-79830600-1418644796_thumb.j

  • 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:

#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 by Detefon

Visit my repository

Share this post


Link to post
Share on other sites



_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.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

A possible use for a game
"escape from the maze"

edit:

the exit is in the lower right

;#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 by Chimp
2 people like this

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

Pretty cool; especially with the "maze" alternate added.

Downside being: will affect my productivity for a few days.

Share this post


Link to post
Share on other sites

@Chimp; cool the maze alternative! ^^


Visit my repository

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
Sign in to follow this  
Followers 0