Hello and maze?

Here is my code.

Collision detection is working (thanks dave) but the tilt y direction is not working and I don’t know why.



-- Maze Test

function setup()
    displayMode(FULLSCREEN)
    e1=physics.body(EDGE,vec2(100,100),vec2(100,700))  --physics for walls
    e2=physics.body(EDGE,vec2(100,100),vec2(700,100))
    e3=physics.body(EDGE,vec2(100,700),vec2(700,700))
    e4=physics.body(EDGE,vec2(700,100),vec2(700,700))
    player=physics.body(CIRCLE,40) --player collision detection
    player.x=WIDTH/2 --start in center (just for testing)
    player.y=HEIGHT/2
    player.restitution=0.5
    player.sleepingAllowed=false
end

function draw()
    background(40, 40, 50)
    fill(0, 51, 255, 255)
    strokeWidth(5)
    line (100,100,100,700) --Drawing walls
    line (100,100,700,100)
    line (100,700,700,700)
    line (700,100,700,700)
    player.x=player.x+Gravity.x*10 --tilt x
    player.y=player.y+Gravity.y*10 --tilt y
    sprite("Planet Cute:Star",player.x,player.y) --draw player
end

I added supportedOrientations and player.gravityScale. You can tilt it in any direction.


-- Maze Test

function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(PORTRAIT)
    e1=physics.body(EDGE,vec2(100,100),vec2(100,700))  --physics for walls
    e2=physics.body(EDGE,vec2(100,100),vec2(700,100))
    e3=physics.body(EDGE,vec2(100,700),vec2(700,700))
    e4=physics.body(EDGE,vec2(700,100),vec2(700,700))
    player=physics.body(CIRCLE,40) --player collision detection
    player.x=WIDTH/2 --start in center (just for testing)
    player.y=HEIGHT/2
    player.restitution=0.5
    player.sleepingAllowed=false
    player.gravityScale=0
end

function draw()
    background(40, 40, 50)
    fill(0, 51, 255, 255)
    strokeWidth(5)
    line (100,100,100,700) --Drawing walls
    line (100,100,700,100)
    line (100,700,700,700)
    line (700,100,700,700)
    player.x=player.x+Gravity.x*10 --tilt x
    player.y=player.y+Gravity.y*10 --tilt y
    sprite("Planet Cute:Star",player.x,player.y) --draw player
end

@Mene I hope you don’t mind, but I took your code and added a small maze to give you an idea of what is involved in creating a maze manually. I used the CHAIN command to define the edges. Also, I’m not sure what you were going to do, but hold the iPad flat and work the ball thru the maze without touching the edges by tilting the iPad. Hope this gives you enough of an example to continue with your code.


-- Maze Test

displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT)

function setup()
    str=""
    tab={}
    tab[1]=physics.body(CHAIN,false,vec2(100,100),vec2(600,100),vec2(600,700))
    tab[2]=physics.body(CHAIN,false,vec2(500,700),vec2(100,700),vec2(100,200),
        vec2(400,200),vec2(400,300)) 
    tab[3]=physics.body(CHAIN,false,vec2(200,300),vec2(500,300),vec2(500,200))
    tab[4]=physics.body(CHAIN,false,vec2(200,700),vec2(200,400),
        vec2(400,400),vec2(400,500))
    tab[5]=physics.body(CHAIN,false,vec2(300,500),vec2(300,600),vec2(600,600))
    tab[6]=physics.body(CHAIN,false,vec2(500,600),vec2(500,400))

    player=physics.body(CIRCLE,20)
    player.x=WIDTH/2
    player.y=900
    player.restitution=0.5
    player.sleepingAllowed=false
    player.gravityScale=0
end

function draw()
    background(40, 40, 50)
    fill(0, 51, 255, 255)
    strokeWidth(5)

    -- draw maze lines from physics.body vec2’s
    for z=1,#tab do
        for y=2,#tab[z].points do
            line(tab[z].points[y-1].x,tab[z].points[y-1].y,   
                tab[z].points[y].x,tab[z].points[y].y)       
        end
    end

    player.x=player.x+Gravity.x*5  -- move player based on tilt
    player.y=player.y+Gravity.y*5

    ellipse(player.x,player.y,40)  -- draw a circle instead of a sprite

    fill(255)
    text(str,WIDTH/2,HEIGHT-200)  -- display text if circle touches maze edges
end

function collide(c)
    if c.state==BEGAN then  -- circle touched the maze edge
        str="You touched a wall"
    end
end

oh wow! colour me impressed!

That is top notch stuff Dave, thank you!

Sorry to ask more questions, this code is really helpful but I have a query.

What is the ‘false’ for in the physics lines?

I haven’t the slightest idea. I looked at the manual for the CHAIN command and it shows “loop” as the 2nd entry, but I didn’t find what “loop” meant. I tried a number in that position, but that crashed Codea. Putting false there worked. Maybe someone else knows.

Thanks

Btw your brain must be like a computer, amazed how fast you worked out those coordinates for the maze walls. :slight_smile:

@Mene I don’t know if you can use this or not, but I found a program that creates random mazes written by @Wildbill posted July 2012. I modified the code to only create a 10 x 10 maze and also to create the physics.body(EDGE lines automatically. I also added a circle to move thru the maze. Start with the iPad flat and move the circle thru the maze by tilting the iPad. For a different maze, just restart the program.


supportedOrientations(PORTRAIT)
displayMode(FULLSCREEN)

function setup()
    c1=physics.body(CIRCLE,10)
    c1.x=700
    c1.y=800
    c1.gravityScale=0
    c1.sleepingAllowed=false
    
    tab1={}
    tab2={}
    
    EAST = 0
    NORTH = 1
    WEST = 2
    SOUTH = 3
    EWALL = 1
    NWALL = 2
    WWALL = 4
    SWALL = 8
    XOFF = 30
    YOFF = 70
    ALLWALLS = EWALL + NWALL + WWALL + SWALL
    VISITED = 16
    NMAX = 40
    N=10  -- maze size
    pN = N
    M = WIDTH
    XYOFF = XOFF
    stack = {}
    startx = 1; starty = 1
    endx  = N; endy = N
    createmaze(N, startx, starty, endx, endy)
    done=false
end

function draw() 
    background(0,0,0)
    translate(0,100)
    fill(255, 0, 0, 255)
    strokeWidth(2)
    ellipse(c1.x,c1.y,20)
    c1.x=c1.x+Gravity.x*10
    c1.y=c1.y+Gravity.y*10
    strokeWidth(5)
    for i=1, N do
        x = XOFF + (i-1)*S
        for j=1, N do
            y = YOFF + (j-1)*S
            c = maze[i][j]
            w = c%VISITED
            we = w%2
            wn = math.floor(w/NWALL)%2
            ww = math.floor(w/WWALL)%2
            ws = math.floor(w/SWALL)
            if we == 1 then
                line(x+S, y, x+S, y-S)
                pb(x+S,y,x+S,y-S)
            end
            if wn == 1 then
                line(x, y, x+S, y)
                pb(x, y, x+S, y)
            end
            if ww == 1 then
                line(x, y, x, y-S)
                pb(x, y, x, y-S)
            end
            if ws == 1 then
                line(x, y-S, x+S, y-S)
                pb(x, y-S, x+S, y-S)
            end
        end
    end
    done=true
end  

function pb(x,y,x1,y1) 
    local z
    if not done then
        for z=1,#tab1 do
            if tab1[z].x==x and tab1[z].y==y and
                tab1[z].z==x1 and tab1[z].w==y1 then
                    return
            end
        end
        table.insert(tab1,vec4(x,y,x1,y1))
        table.insert(tab2,physics.body(EDGE,vec2(x,y),vec2(x1,y1)))
        tab2[#tab2].sleepingAllowed=false
    end
end

function createmaze(n, sx, sy, ex, ey)
    if ex > N then
        ex = N; ey = N
    end
    S = math.floor((M - 2*XYOFF)/N)
    maze = {}
    for i=0, NMAX+1 do
        maze[i] = {}
        for j = 0, NMAX+1 do
            maze[i][j] = ALLWALLS
            if i == 0 or i == N+1 then
                maze[i][j] = maze[i][j] + VISITED
            elseif j == 0 or j == N+1 then
                maze[i][j] = maze[i][j] + VISITED
            end
        end
    end
    x = ex; y = ey
    sp = 1
    setvisited(ex, ey)
    erasewalls(sx-1, sy, sx, sy)
    erasewalls(ex, ey, ex+1, ey)      
    while true do
        nx, ny = getunvisitedneighbor(x, y)
        if nx < 0 then
            x, y = pop()
            if sp == 1 then          
                break
            end
        else 
            setvisited(nx, ny)
            push(x, y)
            erasewalls(x, y, nx, ny)
            x = nx; y = ny
        end
    end
end  

function push(a, b)
    stack[sp]  = a
    stack[sp+1] = b
    sp = sp + 2
end

function pop()
    sp = sp - 1
    b = stack[sp]
    a = stack[sp-1]
    sp = sp - 1
    return a, b
end

function getneighbor(x, y, d)
    if d == EAST then
        x = x + 1
    elseif d == NORTH then
        y = y + 1
    elseif d == WEST then
        x = x -1
    else 
        y = y - 1
    end
    return x, y
end

function notvisited(x, y)
    if x < 1 or x > N then
        return false
    end
    if y < 1 or y > N then
        return false
    end
    v = math.floor(maze[x][y] / VISITED)
    if v >= 1 then
        return false
    else 
        return true
    end
end

function setvisited(x, y)
    maze[x][y] = maze[x][y] + VISITED
end

function getunvisitedneighbor(x, y)
    nu = 0
    uds = {}
    for i=EAST, SOUTH do
        nx, ny = getneighbor(x, y, i)
        if notvisited(nx, ny)then
            nu = nu + 1
            uds[nu] = i
        end
    end
    if nu == 0 then
        return -1, -1
    end
    td = math.random(1, nu)
    nx, ny = getneighbor(x, y, uds[td])
    return nx, ny
end

function getdirection(x, y, nx, ny)
    if nx > x then
        d = EAST
    elseif ny > y then
        d = NORTH
    elseif nx < x then
        d = WEST
    else
        d = SOUTH
    end
    return d
end

function erasewalls(x, y, nx, ny)
    d = getdirection(x, y, nx, ny)
    if d == EAST then
        maze[x][y] = maze[x][y] - EWALL
        maze[nx][ny] = maze[nx][ny] - WWALL
    elseif d == NORTH then
        maze[x][y] = maze[x][y] - NWALL
        maze[nx][ny] = maze[nx][ny] - SWALL
    elseif d == WEST then
        maze[x][y] = maze[x][y] - WWALL
        maze[nx][ny] = maze[nx][ny] - EWALL
    else
        maze[x][y] = maze[x][y] - SWALL
        maze[nx][ny] = maze[nx][ny] - NWALL
    end
end

Awesome, thanks!

Random mazes which generate their own EDGE lines is brilliant although that code scares me to death, it looks very complex indeed, I doubt I’ll ever be able to code something that complex but its really cool.

@dave1707 Remember to put “local” in front of every single variable you globally created in every function. :wink:

I’m not sure why the tilt wasn’t working, but that would have moved the circle through the walls. Try calling physics.gravity(Gravity) in draw().

And… I think the “loop” is for whether or not it should connect the last point on the chain with the first. (i.e to make it a loop.)

I discovered why the y axis tilt wasn’t working and I have no idea why it stopped it working but it did.

Because my original code didn’t have ‘supportedOrientations(x)’, if I remove the line 'supportedOrientations(PORTRAIT) from my code, the y axis tilt doesn’t work.
Add the line and it works fine. Very strange but I guess theres a reason for it. anyway I know now to make sure to add that to my code.

@SkyTheCoder I don’t think “local” is in my vocabulary. For some reason when I’m writing code I never think of using “local”. I know I should, but most of the time I don’t think of it. Maybe things should be changed so that any variable used in a function is automatically “local” unless it’s declared “global”. The majority of the above code is Wildbill’s, and the one function that I did add (pb) does have “local” in it, so I’m learning. As for the “loop”, that sounds reasonable. But if you’re going to connect the last point with the first point, I think POLYGON would be used unless CHAIN was originally being used for POLYGON also.

@dave1707 I’ve seen you use the variable name “tab” a lot for different things in many of the examples you post. Just out of curiosity what exactly is the significance of that name in your code? Is that a type of traditional programming or something unique to your coding?

@matthew tab is just a name I use for a table. If I have multiple tables I might use tab1, tab2, etc. After I get a program working the way I want it to, I’ll rename the tab’s to something more specific. If it’s just an quick example, I’ll leave them as tab’s. I guess it’s more laziness than traditional.

@dave1707 Ah! That makes sense! :slight_smile: