Jump to content

movement and colision


Luigi
 Share

Recommended Posts

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

Link to comment
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.

Link to comment
Share on other sites

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

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

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

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