Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Animate an Object to x- y- coordinate

Hey guys,
I've got a question for a school project i'm just working on.
I've already created an object ( rect ) and I want that rect to moves to an given coordinate with an animation.
Is there a way to do that?
Thank you :)

Comments

  • Posts: 2,020

    There are lots of different ways to do that, depending on what you are trying to model. Is the rect meant to represent a physical body with mass, momentum, velocity? Do you want it to speed up and slow down smoothly at the beginning and end of the movement? Does it have a maximum speed? Can you show us what you have so far?

  • Posts: 27

    I try to make a "connect four" or however you call it :) ( four in a row ) game where the stones should fall down in the row you tap on. The game is closely done, so I don't want to add physics now XD.
    Right now the stones just appear in the row you tap on and I want that they fall down with an animation to an x- and y- coordinate .just in the simplest way of animating ;)

  • dave1707dave1707 Mod
    Posts: 7,909

    @hallomio77 Look at what I have here and find what you need.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        pl={"Players 1 turn","Players 2 turn"}
        col={color(255,0,0),color(0,255,0)}
        bt,e,nbr={},{},{2,1}
        for z=1,8 do
            table.insert(e,physics.body(EDGE,vec2(z*80+150,100),vec2(z*80+150,550)))
        end
        e1=physics.body(EDGE,vec2(250,100),vec2(750,100))
        player=1
    end
    
    function draw()
        background(0)
        noStroke()
        for a,b in pairs(bt) do
            fill(b.c)
            ellipse(b.x,b.y,78)
        end
        stroke(255)
        strokeWidth(6)
        for z=1,8 do
            line(z*80+150,100,z*80+150,568)
        end
        for z=0,6 do
            line(230,z*78+100,790,z*78+100)
        end
        fill(col[player])
        text(pl[player]..", tap white line.",WIDTH/2,HEIGHT-50)
        line(230,630,790,630)
    end
    
    function touched(t)
        if t.state==BEGAN and t.y>600 and t.y<660 then
            b=physics.body(CIRCLE,39)
            b.x,b.y=t.x,t.y
            b.c=col[player]
            table.insert(bt,b)
            player=nbr[player]
        end
    end
    
  • Posts: 27

    Oh my god

  • Posts: 27

    Thank you very much for that code;) its much more better than my project XD

  • Posts: 27

    Nice work

  • edited June 2015 Posts: 2,020

    I must confess I got a bit carried away here. I have my procrastination hat on. Here is a complete connect4 game, pass-and-play, with realistic animation, game state management, a win animation, a notification system, and recursive win-state checking that can detect even if the winning tile is placed in the middle of the line. And all in just 210 lines! Man I love Codea. Anyone want to add AI to this?

    --# Main
    -- pass-and-play connect4 in 210 lines! by Yojimbo2000
    displayMode(FULLSCREEN)
    local terminal = 24 --terminal velocity
    local restitution = 0.3 --bounciness
    size = 100 --size of each space on board
    
    function setup()
        font("DINAlternate-Bold")
        fontSize(50)
        textAlign(CENTER)
        cm = mesh() --coin mesh
        cm.texture = "Platformer Art:Coin"
        w,h = size * 0.7, size * 0.7
        cols = {color(255, 0, 60, 255), color(255, 223, 0, 255)} --player colours
        colNames = {"Red", "Yellow"}
        col = 1 --current player
        start()
    end
    
    function start()
        win = nil --reset states
        clearTiles = true
        cm:clear() --clear mesh
        coin = {} --clear board
        board.init()
        note = "Pass and play:\nTap the screen\nto place your pieces" --new game notification
        fill(0, 169, 255, 255)
        timer = ElapsedTime + 2.3
        touchTimer = ElapsedTime + 2.5
        tween.delay(2.5, playerNote)
    end
    
    function playerNote()
        fill(cols[col])
        note=colNames[col].." to play"
        timer = ElapsedTime + 2
    end
    
    function draw()
        --update
        for i=1,#coin do
            local v = coin[i]
            if not v.atRest then
                if v.pos.y > v.tar.y + 0.5 then --above target
                    v.vel = math.max(v.vel - 0.5, -terminal) --increase velocity up until terminal velocity
                elseif v.pos.y < v.tar.y - 0.5 then --below target
                    if v.vel < 0 then --and heading down
                        v.vel = math.abs(v.vel * restitution) --bounce
                        v.angleVel = v.angleVel * restitution
                    end
                else --on target
                    if math.abs(v.vel)<0.5 then --bring coin to rest
                        v.atRest=true
                        v.vel=0
                    end
                end
                v.pos.y = v.pos.y + v.vel --update position and angle
                v.angle = v.angle + v.angleVel
                cm:setRect(i,v.pos.x,v.pos.y,w,h,v.angle) --update rect
            end
        end
        --winning condition
        if win and coin[win].atRest then --if winning coin has come to rest    
            if clearTiles then --do this once
                clearTiles = false
                for i,v in ipairs(coin) do
                    if not v.winningTile then --clear all tiles except the winning ones
                        v.tar.y = -HEIGHT * 0.5
                        v.atRest = false
                    end
                end
                touchTimer = ElapsedTime + 1 --prevent player from accidentally tapping past win screen
                local c = coin[win].col --notification
                fill(cols[c])
                note = colNames[c].." is\nthe WINNER!"
                timer = math.huge --win notification doesnt timeout         
            end
            if ElapsedTime > touchTimer then
                note = "Tap anywhere\nto restart"
            end
        end
        --drawing
        background(40, 40, 50)
        cm:draw() --draw coin mesh
        board.m:draw() --draw board mesh  
        --notifications
        if note then
            text(note, WIDTH*0.5,HEIGHT*0.8)
            if ElapsedTime > timer then note=nil end
        end
    end
    
    function touched(touch)
        if touch.state==ENDED and ElapsedTime>touchTimer then  --ensure only 1 token created per touch
            if win then --win state
                start() --restart
            else --normal play
                local bx, by = math.ceil(touch.x/size) --board x
                local column = board.b[bx] --find column of board
                if #column < board.h then --check there's room on board
                    by = #column+1
                    local x,y = (bx-0.5)*size, (by-0.55)*size --work out screen x and y
    
                    local r = cm:addRect(0,0,w,h) --add rect
                    cm:setRectColor(r, cols[col]) --set to red or yellow
    
                    coin[#coin+1] = { --add coin object
                    pos = vec2(x, HEIGHT+size), tar=vec2(x,y), vel=0, --set position and target
                    angle = math.random() * math.pi, angleVel = math.random() - 0.5, --angle and angular velocity
                    rec = r, col=col, atRest=false --rect number (for win anim), colour
                    }
                    column[by]=coin[#coin] --add piece to board     
                    check4(1,col,r,{column[by]},vec2(bx,by))  --check for win
                    if not win then
                        col = 3 - col --alternate between player 1 and 2
                        tween.delay(0.3, playerNote)
                        touchTimer = ElapsedTime + 0.3
                    end
                else
                    sound(SOUND_POWERUP, 21188) --error noise; move elsewhere
                end
            end
        end
    end
    
    local dir = {vec2(-1,-1),vec2(-1,0),vec2(-1,1),vec2(0,1)} --half of the 8 compass points, starting lower left and moving clockwise (only need half of them cos of reversing algorithm 
    
    function check4(lev,col,piece,manifest,pos,vel) --level of iteration, colour we're checking, last piece played, manifest of tiles found, current position, direction
        if lev==1 then --first iteration?
            for i=1,#dir do --fire out compass points
                check4(2,col,piece,manifest,pos + dir[i],dir[i])
            end
        elseif lev==5 or lev==15 then --4 in a row
            win=piece --set the win flag to the wimning piece
            for i,v in ipairs(manifest) do
                v.winningTile=true --set all the other winning pieces
            end
        else
            if board.b[pos.x] and board.b[pos.x][pos.y] and board.b[pos.x][pos.y].col==col then --if valid square, and same colour then
                manifest[#manifest+1]=board.b[pos.x][pos.y]--update manifest
                check4(lev+1,col,piece,manifest,pos+vel,vel) --check next tile
            elseif lev<10 then --reverse direction (once only). This is to catch cases where a line of 4 is completed by a tile in the middle of the line. Not the most efficient way to do this, but the easiest to code.
                local p = pos-vel --back up to prev square
                manifest={board.b[p.x][p.y]} --reset manifest
                check4(12,col,piece,manifest,p-vel,-vel) --set reverse direction with double digit iteration level to prevent endless reversing
            end
        end
    end
    --# Board
    board = {}
    
    function board.init()
        board.w, board.h = math.ceil(WIDTH/size), math.ceil(HEIGHT/size) --width and height in number of cells
        board.b = {} --array for actual board
    
        local img = image(size,size) --image of blue with a hole
        setContext(img)
        background(47, 61, 132, 255)
        stroke(55, 62, 98, 255)
        strokeWidth(5)
        fill(0, 0, 0, 255)
        ellipse(size*0.5, size*0.5, size*0.9)
        setContext()
    
        board.m=mesh() 
        board.m.shader=shader(cookieCutter.vert, cookieCutter.frag)
        board.m.texture=img    
    
        for x=1, board.w do
            board.b[x]={} --initialise the array
            for y=1, board.h do
                board.m:addRect((x-0.5)*size,(y-0.5)*size,size,size) --fill mesh with holes
            end
        end
    end
    cookieCutter={ --a shader that sets the alpha of black pixels to zero. solves problem of not being able to draw zero alpha primitives
    vert=[[
    uniform mat4 modelViewProjection;
    
    attribute vec4 position;
    attribute vec4 color;
    attribute vec2 texCoord;
    
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    
    void main()
    {
        vColor = color;
        vTexCoord = texCoord;
    
        gl_Position = modelViewProjection * position;
    }
    ]],
    frag=[[
    precision highp float;
    
    uniform lowp sampler2D texture;
    
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    
    void main()
    {
        mediump vec4 col = texture2D( texture, vTexCoord ) * vColor;
        col.a = smoothstep(0.,0.1, (col.r + col.g + col.b)); //set alpha to zero for black
        gl_FragColor = col;
    }
    ]]
    }
    
  • edited June 2015 Posts: 2,020

    an image

  • IgnatzIgnatz Mod
    Posts: 5,396

    B-)

  • Posts: 289

    wonderful and amazing

  • Posts: 745

    Awesome work @yojimbo2000

Sign In or Register to comment.