Is there a function to generate possible x,y,w,h values for n rectangles to fit on phone screen?

So basically i’m just trying to make a card game. I’ve got the prototype in Codea running on an Ipad in landscape mode, but I’m having difficulty figuring out what the card dimensions should be for an iphone in either landscape or portrait mode. Here is the project that i posted days ago (https://codea.io/talk/discussion/8198/card-game-dropbox-zip-file-no-installer#latest)

What i did do was make a big list by hand of x, y, x2, y2 values for each potential card, but only In ipad Landscape mode.

There are up to 16 cards, as well as one deck. So seventeen tables of x,y,x2, y2 values. REALLY don’t want to rewrite this by hand for each possible screen orientation and device. I thought I could try making a function to generate this automatically, but no luck - is beyond my knowledge. help?

P.s. I haven’t decided what width and height of cards would be good to fit on a phone screen. I was using 140 x 196 on the iPad, but on a phone screen (320x480) that will not fit. Maybe 70 x 98? The hard part is trying to figure out where everything should go. I don’t want to use any magnification or scrolling, rather just have everythiing fit on screen. If not possible, then… well, function first, practicality after, with a function like that it would still make this easier

P.s.s. Do i have to program again for the dimensions of an iphone 6+ screen? Or is it automatically scaled up from a normal iphone screen?

To make the cards scale with the screen size, you could just use the variables WIDTH and HEIGHT. WIDTH/18 could be the width of a card and HEIGHT/16 could be the height of the same card. Just put everything that might change on a different size screen in terms of WIDTH and HEIGHT.

@xThomas See the discussion I show below. I have a program in there that scales the screen for different sizes. You can look at that to see how I did it.

https://codea.io/talk/discussion/8026/best-way-to-scale-ui-elements-for-all-screen-sizes

@xThomas I modified my original code to include the iPad Pro, the 38mm Watch, and the 42mm Watch. Since I don’t have an iPad Pro, the 42mm or 38mm Watch, I’m not sure if this show the correct information for those sizes. If anyone has one of them, let me know if there’s a problem.

displayMode(FULLSCREEN)

function setup()  
    device={"iPad Pro","iPad Air","iPhone7 Plus","iPhone7","iPhone 5","Watch 42mm","Watch 38mm"}
    rectMode(CENTER)
    fontSize(40)
    font("Baskerville-Italic")
    x=300
    y=100
    xv=3
    yv=3
    dev=1
    if WIDTH<HEIGHT then
        tab={vec2(1024,1366),vec2(768,1024),vec2(414,736),
                vec2(375,667),vec2(320,568),vec2(156,195),vec2(136,170)}
    else
        tab={vec2(1366,1024),vec2(1024,768),vec2(736,414),
                vec2(667,375),vec2(568,320),vec2(195,156),vec2(170,136)}
    end 
    wm=WIDTH
    hm=HEIGHT 
end

function orientationChanged()
    setup()
end

function draw()
    background(0)
    fill(255)   
    stroke(255)
    strokeWidth(3)

    -- same code for all devices
    w=tab[dev].x    -- width of device from table
    h=tab[dev].y    -- height of device from table
    mw=wm     -- largest width of all devices
    mh=hm     -- largest height of all devices
    ar=(w/h)/(mw/mh)    -- aspect ratio

    scale(w/mw,h/mh)    -- scale of device to largest screen

    sprite("Planet Cute:Character Pink Girl",x,y,101,171*ar)
    sprite("Planet Cute:Character Cat Girl",100,600,101,171*ar)

    text("Tap screen to show different device sizes.",mw*.38,mh*.25)
    text(device[dev],mw*.2,mh*.45)
    text(tab[dev].x.."  "..tab[dev].y,mw*.2,mh*.4)

    noFill()
    ellipse(mw/2,mh/2,50,50*ar)
    ellipse(mw*.75,mh*.75,100,100*ar)

    line(mw/2,mh/2,0,mh)
    line(mw*.75,mh*.75,200,100)

    rect(mw/2,mh/2,mw,mh)
    rect(200,100,100,100*ar)
    -- end of same code for all devices

    -- calculate motion of sprite
    x=x+xv
    y=y+yv
    if x>=mw or x<=0 then
        xv=-xv
    end
    if y>=mh or y<=0 then
        yv=-yv
    end    
end

function touched(t) -- display different device size
    if t.state==BEGAN then
        dev=dev+1
        if dev>#device then
            dev=1
        end
    end
end

@dave1707 sorry it took so long to get back to u, but cool. Any ideas on how i can improve my own piece of code before i take a longer look at implementing yours? It should be self explanatory, but if it isn’t, and I might not have explained my problem very well, im still trying to make the function that can set the x,y x2 and y2 positions in a table so i draw cards and handle touch. But it’s kind of hard for me, i’m not really used to this math,but i think it is necessary so i can implement it into my card game, where right now it’s all set by hand. I am not good at this :frowning: (to be clear, the problem is that it doesn’t look good right now, but its fully playable)

-- Attempting to make a function for set of playing cards with even spacing in between them. that can auto reaize itself for different orientation changes

-- it kind of works but doesnt work right


playingFields = {}

function setcards()
    print "setting card positions!?"
    local w, h = 180, 240
    local sw, sh = 20, 28
    local x, y, x2, y2
    local j = 0
    local k = 1
    y = HEIGHT - h - sh
    y2 = HEIGHT - sh
    local tx, ty
    local yy, yy2
    local wrapwidth = WIDTH - 20
    local ywrap = 0
    local shy = 1
    for i = 1,16 do
        x = w * j + sw * k
        x2 = w * k + sw * k
        yy = y - (h * ywrap) - (sh * shy)
        yy2 = y2 - (h * ywrap) - (sh * shy)
        if x2 > wrapwidth then
            --print(" exceeded wrapwidth, wrapping to next line ")
            j = 0
            k = 1
            x = w * j + sw * k
            x2 = w * k + sw * k
            ywrap = ywrap + 1
            yy = y - (h * ywrap) - (sh * shy)
            yy2 = y2 - (h * ywrap) - (sh * shy)
            shy = shy + 1
        end
        tx = x + w/2
        ty = yy + h/2
        playingFields[i] = {x = x, x2 = x2, y = yy, y2 = yy2, tx = tx, ty = ty}
        playingFields[i][0] = i
        
        k, j = k + 1, j + 1
        
       -- print("("..x..", "..yy..")", "("..x2..", "..yy2..")")
     --   print("ywrap ="..ywrap)
    end
end

function setup()
    setcards()

end

function orientationChanged( newO )
    setcards()
end
function draw()
    background(40,40,50)
    for i,v in ipairs(playingFields) do
       -- fill(16*i)
        pushStyle()
        rectMode(CORNERS)
        stroke(0,252,0)
        strokeWidth(3)
        fill(168)
        rect(v.x, v.y, v.x2, v.y2)
        popStyle()
        pushStyle()
        fontSize(32)
        font("Arial")
        fill(252,252)
        text(v[0], v.tx, v.ty)
        popStyle()
    end
end

@xThomas How many cards across and down are you trying to fit on the screen.

@xThomas I don’t think my original code would work for cards. Here is a different version to place cards on different size screens. I don’t know how many cards you want on the screen, so I set this so you can change the number of cards across and down. You can also change the spacing size in between the cards. I’m just simulating different screen sizes, but you would have to change some of the code to use the WIDTH and HEIGHT of the actual device screen.

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()  
    rectMode(CENTER)
    dev=1
    device={"iPad Pro","iPad Air","iPhone7 Plus","iPhone7","iPhone 5"}
    tab={vec2(1366,1024),vec2(1024,768),vec2(736,414),vec2(667,375),vec2(568,320)}

    xCards=8    -- number of cards across
    yCards=4    -- number of cards down
    spacing=4   -- spacing between cards
end

function draw()
    background(0)    
    -- set screen size, change code to use actual screen size
    currW=tab[dev].x
    currH=tab[dev].y
    
    -- determine card size based on screen size
    sx=(currW-spacing*(xCards+1))//xCards
    sy=(currH-spacing*(yCards+1))//yCards
    
    drawCards()

    -- draw screen outline, not needed for actual device.
    noFill()
    stroke(255)
    strokeWidth(3)
    rect(currW/2,currH/2,currW,currH)  
      
    -- display text, not needed for actual device 
    fill(255)   
    text(device[dev],WIDTH/2,HEIGHT-25)
    text(tab[dev].x.." x "..tab[dev].y,WIDTH/2,HEIGHT-50)
    text("Cards = "..xCards.." across by "..yCards.." down",WIDTH/2,HEIGHT-75)
    text("Tap screen to change screen size",WIDTH/2,HEIGHT-100)
end

function touched(t) -- display different device size
    if t.state==BEGAN then
        dev=dev+1
        if dev>#device then
            dev=1
        end
    end
end

function drawCards()
    fill(255,255,255,80)
    for x=1,xCards do
        for y=1,yCards do
            rect(x*sx+x*spacing-sx/2,y*sy+y*spacing-sy/2,sx,sy)
        end
    end
end

I have been starting to use a different form for making my apps universal, so I will share my old technique of making any app universal. All you have to do is create an image in the setup(), then setContext() of the entire draw(). Be careful not to use WIDTH and HEIGHT, for they will mess it up. Make variables called WIDTHw and HEIGHTh and make them equal to normal size screen. Here’s an example:

-- Universal
supportedOrientations(CurrentOrientation)
displayMode(OVERLAY)
function setup()
    if CurrentOrientation==LANDSCAPE_LEFT or CurrentOrientation==LANDSCAPE_RIGHT then
        WIDTHw=1024
        HEIGHTh=768
    else
        WIDTHw=768
        HEIGHTh=1024
    end
    output.clear()
    parameter.clear()
    print("This is an example of making an app universal!")
    GIMG=image(WIDTHw,HEIGHTh)
    GSize=vec2(WIDTH,HEIGHT)
    parameter.number("Width of Device",1,WIDTHw,WIDTHw,function(a)
        GSize.x=a
    end)
    parameter.number("Height of Device",1,HEIGHTh,HEIGHTh,function(t)
        GSize.y=t
    end)
    print"Drag the parameters to change the size of the screen."
    print("It looks a bit distorted, but it works for 2D and 3D")
end

-- This function gets called once every frame
function draw()
    background(0)
    setContext(GIMG,true)
    pushMatrix()pushStyle()
    background(255)
    rectMode(CENTER)
    fill(229, 98, 98, 195)
    stroke(167, 223, 137, 202)
    strokeWidth(10)
    rect(WIDTHw/2,HEIGHTh/2,(vec2(WIDTHw,HEIGHTh)*3/4):unpack())
    sprite("SpaceCute:Rocketship",WIDTHw/2,HEIGHTh/2)
    fill(0)
    fontSize(80)
    textAlign(CENTER)
    font("AcademyEngravedLetPlain")
    textMode(CENTER)
    text("Developing\
For Dummies",WIDTHw/2,HEIGHTh*3/4)
    fontSize(30)
    font("Zapfino")
    text("Author\
|Da Baller|",WIDTHw/2,HEIGHTh/4)
    popMatrix()popStyle()
    setContext()
    pushMatrix()pushStyle()
    spriteMode(CENTER)
    sprite(GIMG,GSize.x/2,GSize.y/2,GSize:unpack())
    popMatrix()popStyle()
end

@CamelCoder Does that work if you have a lot of objects moving around the screen.

@dave1707 yeah, in fact, it runs at almost the same FPS, except, 3D buffer will slow it down just a tiny bit, maybe like .5 FPS. If you haven’t downloaded my apps, that’s what I used for it. My app, Mazoo: The Ultimate 3D Maze, is 3D and works on all devices properly. It’s just a bit slow on old devices, but that doesn’t have to do anything with the setContext()

@CamelCoder I tried it with moving sprites and it works fine. Great Job. But like you said, any sprites I use are distorted. There should be a way to calculate an aspect ratio with yours so sprites, circles, or squares remain correct.