[SOLVED] Show newRect on top of Qiso map

I’m using Qisoto render a map and I have a newRect and native text field showing up when the user clicks on a button. The text field is properly shown in front of all the other layer but the rectangle is rendered behind the map.

I added 

myRectangle:toFront() 

but it doesn’t change anything.

How can I put the overlay (white rectangle in the attached snapshot) on top of the map?

If possible, I also would like to change the opacity of the map (any layer).

Thanks

Qiso creates a display group on initiation and all rendering is done to that group, so as long as you initiate before creating other display groups, those groups should naturally sit on top and adding your UI elements to those groups should in turn sit them on top of Qiso.

That said, from your screenshot it looks like those icons are already sitting on top so it might be that you’ve already created the groups properly but found a bug specifically with newRect… could you post the related code please?

Regarding layer opacities… Qiso does already incorporate this to some extent, but it’s centred around character movement. You could technically still use it by adding dummy characters (transparent sprites perhaps) to one of the layers tiles and then using the opacityLayerOnEnter() function to set the transparency that layer should drop to when a character is on it, buts that’s a messy approach. Leave it with me - I’ll get a couple of new functions added in for you.

Indeed, the buttons are still active, which I do not want to.

Here is my pause.lua:

local composer = require( "composer" ) local scene = composer.newScene() local globalData = require( "globalData" ) local databaseModuleVar = require("databaseModule") function saveGame(saveName) -- handle DB backup return true end -- "scene:create()" function scene:create( event ) local sceneGroup = self.view end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then local overlayWidth = display.contentWidth local overlayHeight = display.contentHeight local myRectangle = display.newRect( overlayWidth/2, overlayHeight/2, overlayWidth, overlayHeight ) myRectangle:setFillColor( 1, 1, 1, 1, 0.5 ) --myRectangle:toFront() sceneGroup:insert( myRectangle ) local filenameField local function textListener( event ) if ( event.phase == "began" ) then -- User begins editing "filenameField" elseif ( event.phase == "ended" or event.phase == "submitted" ) then local result = saveGame(event.target.text) composer.hideOverlay() sceneGroup:remove(filenameField) elseif ( event.phase == "editing" ) then end end filenameField = native.newTextField( overlayWidth/2, overlayHeight/2, 800, 200 ) native.setKeyboardFocus( filenameField ) filenameField:addEventListener( "userInput", textListener ) sceneGroup:insert(filenameField) end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase local parent = event.parent -- Reference to the parent scene object if ( phase == "will" ) then -- Call the "resumeGame()" function in the parent scene parent:resumeGame() end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

And part of my game.lua (parent scene) :

-- Enable zooming when the screen is pinched qiso.enablePinchZoom() -- Enable camera panning when the screen is dragged qiso.enableCameraPan() -- Enable the main Qiso loop to render/update our world qiso.activate() -- Load and show the toolbar local toolbar = require("toolbar") toolbar.loadBottomToolbar() function scene:resumeGame () local sceneGroup = self.view local gameSavedConfirmation = display.newText( "Game saved as "..globalData.currentGameName, 300, 200, native.systemFont, 0, left ) gameSavedConfirmation.x = gameSavedConfirmation.width/2 -- set offset of half the width of the text area gameSavedConfirmation.y = gameSavedConfirmation.height\*2 -- set offset of half the height of the text area gameSavedConfirmation:setFillColor( 1, 1, 1 ) sceneGroup:insert( gameSavedConfirmation ) transition.fadeOut( gameSavedConfirmation, { time=6000 } ) end function overLay () local options = { isModal = true, effect = "fade", params = { sampleVar = "my sample variable" } } composer.showOverlay("pause", options) end globalData.saveButton:addEventListener("tap", overLay)

Finally, my toolbar module:

local M = {} globalData.buildingBarGroup = display.newGroup() -- Create a new display group for the building bar icons function M.loadBottomToolbar() -- Menu bar at the bottom, containing different modes local widget = require("widget") globalData.toolbarGroup = display.newGroup() -- Create a new display group for the toolbar bar icons globalData.toolbarGroup.alpha = 1 -- Display the toolbar globalData.deleteButton = widget.newButton( { width = 150, height = 150, defaultFile = "delete.png" } ) globalData.deleteButton.x = 75 globalData.deleteButton.y = display.contentHeight-75 globalData.toolbarGroup:insert( globalData.deleteButton ) -- insert button into toolbar group -- More buttons here... end return M

Thanks for the work on the opacity functions :slight_smile:

I’m afraid I can’t seem to replicate your newRect issue. Even without using display groups, so long as newRect is called after the local qiso = require “plugin.qisoengine” line, it should be rendered above the map.

In your code though, I notice you have 5 paramerts here:

myRectangle:setFillColor(  1, 1, 1, 1, 0.5 )

setFillColor only expects 4 params so effectively you’re creating a fully opaque rectangle with this as I believe the 0.5 will be ignored, but from my own testing even this shouldn’t prevent the rect from actually showing up.

I’m wondering if there’s an issue somehow with your sceneGroup. Does the rectangle show if you comment out the sceneGroup:insert part?

In better news - Qiso now has a opacityLayer() function and the Tiled map import will bring in any layer opacities you set through Tiled too.

https://qiso.qweb.co.uk/documentation/graphics/rendering/functions/opacitylayer

It can take some time for the Corona build servers to synchronise so the new function might not work for you yet, but as far as I’m aware synchronisation usually takes less than 1 hour.

I corrected the extra parameter in myRectangle:setFillColor

I’m wondering if there’s an issue somehow with your sceneGroup. Does the rectangle show if you comment out the sceneGroup:insert part?

I’ve changed that and the overlay is now on top of the map and of the buttons! The map cannot be dragged & dropped, which is expected, unfortunately the buttons are still active. I think the problem is the same as this post and Rob actually mentioned:

Display objects that are not part of the parent scene or part of the overlay scene (i.e. you did not insert them into the scene group) are always on top of composer managed objects.

In my case, the buttons are inserted in a new display group, in my toolbar module, which is not written using Composer. Do I need to use Composer there as well, and add a sceneGroup? (See come in my original post)

In better news - Qiso now has a opacityLayer() function and the Tiled map import will bring in any layer opacities you set through Tiled too.

https://qiso.qweb.co.uk/documentation/graphics/rendering/functions/opacitylayer

Wow that was fast! Will test the new function really soon :slight_smile:

From Rob’s response, it sounds like composer always sits behind other display objects, so if those icons aren’t part of a composer group then their rendering will always be foreground.

What I would do is create two functions - one to set the opacity of everything within your toolbar group to 0 and remove the tap/touch event binds, and the other to set those items to opacity 1 and add the event binds. Display groups are basically just tables so you can iterate their contents like regular tables. That way whenever you need to toggle the display of your toolbar, just call the appropriate function.

That worked! For reference, my functions look like this sample:

function disableToolbar () globalData.toolbarGroup.alpha = 0.3 globalData.exitButton:removeEventListener("tap", modeModules.exitMode) globalData.moveButton:removeEventListener("tap", modeModules.moveMode) globalData.deleteButton:removeEventListener("tap", modeModules.deleteMode) globalData.buildButton:removeEventListener("tap", buildMenuModules.createBuildBar) end

Regarding opacityLayer I’m trying to change it manually before using it in loadTiledMap but I don’t see any effect. I tried, for example:

qiso.opacityLayer(1, 5)

But I’m not sure how to define the layer as an integer. I usually use their name.

Hmm… Actually I think that’s the documentation that’s wrong, sorry. You should be able to reference by the usual layer name!

Not quite sure how that’s happened since the documentation pages are constructed automatically from the source code, but there you go! Will fix in the morning.

Yep, sorry, the documentation was wrong. showLayerTileOnEnter(), hideLayerOnEnter(), showLayerOnEnter(), opacityLayerOnEnter(), and opacityLayer() all incorrectly referenced layer as an integer instead of a string. Now fixed.

Works like a charm! Thanks again for the help!