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

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?

I try to make a “connect four” or however you call it :slight_smile: ( 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 :wink:

@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

Oh my god

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

Nice work

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:\
Tap the screen\
to 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\
the WINNER!"
            timer = math.huge --win notification doesnt timeout         
        end
        if ElapsedTime > touchTimer then
            note = "Tap anywhere\
to 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;
}
]]
}

an image

B-)

wonderful and amazing

Awesome work @yojimbo2000