Codea 1.5 (Beta 11)

.@mpilgrem Nice extension - shall use that for further investigations. I was thinking that blendmode could be very useful in erasing stuff and came up with the following for the rectangle with a hole:

function setup()
    img = image(300,300)
    setContext(img)
    background(34, 34, 34, 255)
    blendMode(NORMAL)
    rectMode(CENTER)
    fill(255, 0, 0, 255)
    rect(150,150,300,300)
    blendMode(
        BLEND_ZERO,BLEND_ONE_MINUS_SRC_ALPHA
        )
    fill(0, 0, 0, 255)
    ellipse(150,150,200,200)
    setContext()
    blendMode(NORMAL)
end

function draw()
    background(34, 34, 34, 255)
    stroke(255, 255, 255, 255)
    strokeWidth(10)
    line(0,0,WIDTH,HEIGHT)
    spriteMode(CENTER)
    sprite(img,WIDTH/2,HEIGHT/2)
end

Here’s my exploration (with a few bits “borrowed” from @mpilgrem’s code!). The output is what I’ve just uploaded to Twitter (somehow I can never get those pictures to embed here). What it does is draw two squares one on top of the other with a specific blend mode. To avoid interaction with the background, it does this in a separate blank image. That image is then drawn in normal blending mode onto the background. The squares are gradients: block colour but with gradient alpha, and in different directions. Then all the different combinations (for the 2-element blendMode function) are displayed in a grid. Took me a while to spot NORMAL amongst them!

--
-- Blend Modes Explorer
--

supportedOrientations(LANDSCAPE_ANY)
function setup()
    print("This demonstrates blending modes. Blend modes determine "..
    "how drawing operations blend together on-screen.")
    mode = {
    BLEND_ZERO, BLEND_ONE,
    BLEND_SRC_COLOR, BLEND_ONE_MINUS_SRC_COLOR,
    BLEND_DST_COLOR, BLEND_ONE_MINUS_DST_COLOR,  
    BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA,
    BLEND_DST_ALPHA, BLEND_ONE_MINUS_DST_ALPHA,
    BLEND_SRC_ALPHA_SATURATE}    
    modeName = {
    "ZERO", "ONE",
    "SRC_COLOR", "ONE_MINUS_SRC_COLOR",
    "DST_COLOR", "ONE_MINUS_DST_COLOR",  
    "SRC_ALPHA", "ONE_MINUS_SRC_ALPHA",
    "DST_ALPHA", "ONE_MINUS_DST_ALPHA",
    "SRC_ALPHA_SATURATE"}
    local n = #mode
    local w = math.floor(math.min(WIDTH,HEIGHT)/n)
    local src = mesh()
    src:addRect(w/2,w/2,w,w)
    src.colors = {
        color(255, 0, 0, 0),
        color(255, 0, 0, 255),
        color(255, 0, 0, 255),
        color(255, 0, 0, 0),
        color(255, 0, 0, 255),
        color(255, 0, 0, 0)
    }
    local dest = mesh()
    dest:addRect(w/2,w/2,w,w)
    dest.colors = {
        color(0, 0, 255, 255),
        color(0, 0, 255, 255),
        color(0, 0, 255, 0),
        color(0, 0, 255, 255),
        color(0, 0, 255, 0),
        color(0, 0, 255, 0),
    }
    im = image(WIDTH,HEIGHT)
    spriteMode(CORNER)
    local imw = image(w,w)
    for i = 1, n do
        print(modeName[n+1-i])
        for j = 1,n do
            setContext(imw)
            dest:draw()
            blendMode(mode[i],mode[j])
            src:draw()
            setContext()
            blendMode(NORMAL)
            setContext(im)
            resetMatrix()
            sprite(imw,(i-1)*w,(j-1)*w)
            setContext()
        end
    end
end

function draw()
    background(255, 255, 255, 255)
    sprite(im,0,0)
end

.@mpilgrim @Jmv38

The coroutine bug has been fixed.

.@John great job! Thanks.

The in-app reference says that tween() returns an ‘int’, but it returns a table.

Below is some short code to explore that and the easing functions:


--
-- Tween Explorer
--

supportedOrientations(LANDSCAPE_ANY)
function setup()
    easingType = {
        "Quad", "Cubic", "Quart", "Quint",
        "Expo", "Sine",
        "Back", "Bounce", "Elastic"}
    inOutType = {"in", "out", "inOut", "outIn"}
    duration = 3
    dim = math.min(WIDTH, HEIGHT)
    offset = dim / 4
    margin = dim / 20
    width = margin / 10
    dim = dim - offset * 2 - margin - width
    easingFunction = 1
    inOutFunction = 1
    parameter.integer("easingFunction", 1, #easingType, 1, reset)
    parameter.watch("easingType[easingFunction]")
    parameter.integer("inOutFunction", 1, #inOutType, 1, reset)
    parameter.watch("inOutType[inOutFunction]")
    reset()
    elaborate("tweenId", tweenId)
    local col = color(255, 255, 0)
    fill(col)
    stroke(col.r * 0.5, col.g * 0.5, col.b * 0.5, 255)
    rectMode(CORNER)
    spriteMode(CORNER)
    ellipseMode(CORNER)
    noSmooth()
    fontSize(32)
end

function elaborate(k, v)
    local typeV = type(v)
    if typeV == "table" then
        print(k.." is a table")
        for k1, v1 in pairs(v) do
            elaborate(k.."."..k1, v1)
        end
    elseif typeV == "function" then
        print(k.." is a function")
    else
        print(k.." = "..v)
    end
end

function draw()
    background(64)
    text(easingString..": touch Viewer to rerun.",
        WIDTH / 2, HEIGHT - 50)
    strokeWidth(5)
    line(offset, offset + margin,
        offset + margin + dim + width, offset + margin)
    line(offset + margin, offset,
        offset + margin, offset + margin + dim + width)
    noStroke()
    rect(offset, subjectY.y + offset + margin, margin, width)
    rect(subjectX.x + offset + margin, offset, width, margin)
    setContext(img)
    ellipse(subjectX.x, subjectY.y + offset + margin, width)
    setContext()
    sprite(img, offset + margin, 1)
end

function touched(touch)
    if touch.state == BEGAN then reset() end
end

function reset()
    easingString = inOutType[inOutFunction]..easingType[easingFunction]
    img = image(dim + width, dim + width + offset * 2)
    subjectX = {x = 1}
    local targetX = {x = dim}
    tween(duration, subjectX, targetX)
    subjectY = {y = 1}
    local targetY = {y = dim}
    tweenId = tween(duration, subjectY, targetY, easingString,
        nil, "arg1", "arg2")
end

Running tween() creates (update) global variables easing and loop that reference functions. Is that the intention? For example:


function setup()
    print(easing) -- Output: nil
    tween(1, {x=0}, {x=1})
    print(easing) -- Output: function 0x????????
end

function draw() background(0) end

I’m seeing some odd behavior in the editor when hitting the backspace button. Not always, but with regularity, there’s a long delay between using the backspace button and text actually going away. This is particularly true when an area if text is selected and I hit the backspace to delete.

It is not yet in the in-app reference, but I believe easing functions for tween() have this form (at least, for the first four arguments):


-- t is the current time
-- d is the duration of the animation
-- b is the initial animated value
-- c is the change in the animated value by the end of the animation
function myEasing(t, b, c, d)
    t = t / d
    return b + c * math.pow(math.sin(t * math.pi * 2.5), 2)
end

Hello @Simeon. Like @Mark, I am also experiencing Editor misbehaviour. Try this:

  1. Create a new project.

  2. Double tap the Viewer to select the word function.

  3. Press the backspace key.

The deletion of the text selected this way is not rendered until the cursor is moved to a new line.

I still have these problems:

Cannot move to or select the very last character of an editor window with the special keys.

Cannot get saveProjectTab() to work. The only reference I found about this is a comment by toadkick back in November where it worked for him. Here’s the link, since the vanilla forums are inherently unsearchable and Google doesn’t see the beta threads:

http://twolivesleft.com/Codea/Talk/discussion/comment/15423#Comment_15423

I’ve also got a strange effect with the GraphicsStyle example. No code is being run at all.

Thanks @mpilgrem and @Codeslinger.

.@mpilgrem

I can reproduce that. Looking into it.

.@Codeslinger

• I’ve fixed the move/select so that it works up to the last character in the next build.

• Looking into saveProjectTab() — it seems to work for me, try the following in a test project:

function setup()
    saveProjectTab( "TestTab", "-- Blah blah blah")
end

This creates a tab named “TestTab” in the current project with the contents when leaving the viewer.

• I am unable to reproduce Graphics Style example not rendering on iOS 5 or 6. If you have any further detail on this it would be appreciated.

.@Codeslinger it seems that the saveProjectTab issue occurs when you attempt to explicitly save into the current project by name.

So if my current project is named “Foo”, then saveProjectTab(“Foo:MyTab”, “Contents…”) doesn’t appear to work. saveProjectTab(“Some Other Project:MyTab”, “Contents…”) does work, however (provided “Some Other Project” is not an example). And saveProjectTab(“MyTab”, “Contents…”) also works for saving into the current project.

I’ll fix this issue.

.@Mark @mpilgrem thank you for reporting the editor bugs, they should be fixed in the next build.