Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Aligning right hand side of scaled sprite with right of window? — Gideros Forum

Aligning right hand side of scaled sprite with right of window?

snookssnooks Member
edited August 2017 in General questions
I'm having a bit of difficulty aligning the right hand side of a scaled sprite with the right hand side of the device screen/window. The example code below works perfectly for aligning to the left and works for the right when scale=1, but it breaks when scaling for aligning right. I haven't put any code to deal with scaling in the r.h.s. calculation but I've tried a bunch of stuff with no success.

What is the correct formula to replace "rhs=" in function boundX below?
application:setScaleMode("letterbox")
 
contentWidth = application:getContentWidth()
contentHeight = application:getContentHeight()
logicalTranslateX = application:getLogicalTranslateX()
logicalTranslateY = application:getLogicalTranslateY()
logicalScaleX = application:getLogicalScaleX()
logicalScaleY = application:getLogicalScaleY()
 
 
logicalScreenLeft = -logicalTranslateX / logicalScaleX
logicalScreenTop = -logicalTranslateY / logicalScaleY
logicalScreenWidth = contentWidth + logicalTranslateX / logicalScaleX * 2
logicalScreenHeight = contentHeight + logicalTranslateY / logicalScaleY * 2
 
 
print("logicalScreenHeight    =", logicalScreenHeight)
print("logicalScreenWidth    =", logicalScreenWidth)
 
worldWidth = logicalScreenWidth * 1.4
local size = logicalScreenHeight * 0.5
 
local myWindow = Shape.new()
myWindow:setLineStyle(2)
myWindow:setFillStyle(Shape.SOLID, 0xff00ff)
myWindow:beginPath()
myWindow:moveTo(logicalScreenLeft,logicalScreenTop)
myWindow:lineTo(worldWidth,logicalScreenTop)
myWindow:lineTo(worldWidth,logicalScreenHeight)
myWindow:lineTo(logicalScreenLeft,logicalScreenHeight)
myWindow:lineTo(logicalScreenLeft,logicalScreenTop)
myWindow:endPath()
stage:addChild(myWindow)
myWindow:setPosition(0,0)
 
-- left hand guide triangle
local myShape = Shape.new()
myShape:setLineStyle(2)
myShape:setFillStyle(Shape.SOLID, 0x0000ff)
myShape:beginPath()
myShape:moveTo(logicalScreenLeft,logicalScreenTop)
myShape:lineTo(size,logicalScreenTop)
myShape:lineTo(logicalScreenLeft,size)
myShape:lineTo(logicalScreenLeft, logicalScreenTop)
 
myShape:endPath()
myWindow:addChild(myShape)
 
-- right hand guide triangle
local myShape2 = Shape.new()
myShape2:setLineStyle(2)
myShape2:setFillStyle(Shape.SOLID, 0x0000ff)
myShape2:beginPath()
myShape2:moveTo(worldWidth-size,logicalScreenTop)
myShape2:lineTo(worldWidth,logicalScreenTop)
myShape2:lineTo(worldWidth,logicalScreenTop+size)
myShape2:lineTo(worldWidth-size,logicalScreenTop)
myShape2:endPath()
myWindow:addChild(myShape2)
 
-- guide line to show whether full triangle is in view
local myLine = Shape.new()
myLine:setLineStyle(2)
myLine:setFillStyle(Shape.SOLID, 0x0000ff)
myLine:beginPath()
myLine:moveTo(logicalScreenLeft, size)
myLine:lineTo(worldWidth, size)
myLine:endPath()
myWindow:addChild(myLine)
myWindow:setScale(0.9) -- change this to see right hand align breaking
 
 
local function boundX(x)
  local scale = myWindow:getScaleX()
  local lhs = (1 - scale) * logicalScreenLeft -- this works to bound x value to lhs 
 
  --TODO: fix right hand side bounds to work with scaling (perfect at 1)
  local rhs = -(worldWidth - logicalScreenWidth - logicalScreenLeft)
 
  x = math.max(x, rhs)
  x = math.min(x, lhs) -- bounds to left side of screen at all scales
  print("bounded x   =", x)
 
  return x
end
 
local function setPosition(x)
	myWindow:setX(boundX(x))
end
 
-- now moving the sprite show that right hand side doesn't work at scales other than one
-- positive value for left hand align, high negative for right hand
setPosition(-10000) -- positve correctly bounds to left hand side at all scale levels
                   -- negative only works to bound right hand side at scale = 1

Comments

  • antixantix Member
    edited August 2017
    Here's a small example that uses getWidth() and getHeight() to get the scaled dimensions of the shape...
    application:setScaleMode("letterbox")
     
    contentWidth = application:getContentWidth()
    contentHeight = application:getContentHeight()
    logicalTranslateX = application:getLogicalTranslateX()
    logicalTranslateY = application:getLogicalTranslateY()
    logicalScaleX = application:getLogicalScaleX()
    logicalScaleY = application:getLogicalScaleY()
     
    logicalScreenLeft = -logicalTranslateX / logicalScaleX
    logicalScreenTop = -logicalTranslateY / logicalScaleY
    logicalScreenWidth = contentWidth + logicalTranslateX / logicalScaleX * 2
    logicalScreenHeight = contentHeight + logicalTranslateY / logicalScaleY * 2
     
    local function newRect(w, h, color, style) -- draw a rectangle
      local rect = Shape.new()
      rect:setLineStyle(style)
      rect:setFillStyle(Shape.SOLID, color)
      rect:beginPath()
      rect:moveTo(0, 0)
      rect:lineTo(w, 0)
      rect:lineTo(w, h)
      rect:lineTo(0, h)
      rect:closePath()
      rect:endPath()
      return rect
    end
     
    local function alignRect(rect, p)
      local w, h = rect:getWidth(), rect:getHeight()
      local l, t = 0, 0 -- default is top left
     
      if p == "middle left" then
        t = (logicalScreenHeight * 0.5) -(h * 0.5)
      elseif p == "middle right" then
        l = logicalScreenWidth - w
        t = (logicalScreenHeight * 0.5) -(h * 0.5)
      elseif p == "topright" then
        l = logicalScreenWidth - w
      elseif p == "bottom middle" then
        l = (logicalScreenWidth * 0.5) -(w * 0.5)
        t = logicalScreenHeight - h
      elseif p == "bottom left" then
        t = logicalScreenHeight - h
      elseif p == "bottom right" then
        l = logicalScreenWidth - w
        t = logicalScreenHeight - h
      elseif p == "middle" then
        l = (logicalScreenWidth * 0.5) -(w * 0.5)
        t = (logicalScreenHeight * 0.5) -(h * 0.5)
      end
     
      rect:setPosition(l, t)
    end
     
    local r = newRect(64, 32, 0x008800, 0)
    stage:addChild(r)
    r:setScale(1.5)
     
    alignRect(r, "bottom middle")
    Hopefully that helps :)

    Likes: snooks

    +1 -1 (+1 / -0 )Share on Facebook
  • snookssnooks Member
    edited August 2017
    Thanks very much for your help! Unfortunately that was one of the things I'd tried already. You inspired me to rule some things out for sure though and clear my head and the solution is...
    local rhs = -(((worldWidth * scale) - logicalScreenWidth) - (1-scale) * logicalScreenLeft)
    ... which seems a bit obvious now, considering that the lhs was solved with the last half of that. :)
    local rhs = -(((worldWidth * scale) - logicalScreenWidth) - lhs)
    Thanks again!

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.