Forums

OverviewV-Play 1 Support › Change Z-Position of QML Items at run time

Viewing 15 posts - 1 through 15 (of 18 total)
  • Author
    Posts
  • #3991

    Christian
    V-Play Team

    Hi,

    I’ve got a problem with V-Play: It seems, that with the cocos renderer, the z-position of items can’t be changed at run time.

    For example, when i add a lot of items with images, and with pre-defined z-position, everything works fine, but when i start to move them around on the screen and update the z-position accordingly, it doesn’t work.
    However, when i enable the QML renderer, it works perfectly fine.

    Is this a known issue with V-Play?

    If you don’t get what I want to say, I’ll provide some screenshots.

    Cheers,
    Christian

    #4046

    Christian
    V-Play Team

    Hi Christian,
    thanks for your request!

    There is a reason why changing the z-order is not supported with cocos renderer: in Cocos, changing the z order is a very complex operation and is not supposed to be publicly available. The reason why it’s complex, is that the scene graph is stored as a z-ordered list, which would need to be re-sorted during runtime which is not efficient.

    If you provide details what you are trying to achieve, I could point you to other approaches to meet your desired goals. In general, you could add some parent items with different z orders and add the children to the z-order where you would want it to be.

    Cheers,
    Chris

    #4047

    Christian
    V-Play Team

    OK I see the problem…maybe you would have an idea how to accomplish the following:

    What I’m trying to do, is kind of a 2.5D game.
    All set up it currently looks like this:

    Here everything’s fine with the z-order.
    But when you move the boxes around, the ones on the bottom would need to be on top of the ones with lower y-values, otherwise it looks like this:

    #4048

    Christian
    V-Play Team

    Hi Christian,
    I guess you are creating your entities dynamically with the EntityManager?
    The z-ordering depends on the order of which the elements were added to the Scene: if they do not have any explicit z order set, it defaults to 0 and items added at a later time are drawn on top of the previous ones.

    In your case, I would recommend 3 layers:
    – a floor layer with z=0 , which holds the floor images
    – a boxes layer with z=1, which holds the brown images
    – a gems layer with z=2, which holds the crystals
    – a player layer with z=3, which guarantees the player is always drawn on top.

    When you create the entities dynamically, you can specify the parent item where the newly created entity will be added.

    So in QML code it would look like the following:

    
    function createFloor() {
      entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("pathToFloorEntity.qml"), {"z": 0})
    }
    function createBox() {
      entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("pathToBoxEntity.qml"), {"z": 1})
    }
    function createCrystal() {
      entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("pathToCrystalEntity.qml"), {"z": 2})
    }
    function createPlayer() {
      entityManager.createEntityFromUrlWithProperties(Qt.resolvedUrl("pathToPlayerEntity.qml"), {"z": 3})
    }
    

    Does this solve your problem?

    Cheers,
    Chris

    #4049

    Christian
    V-Play Team

    Hi Chris,

    thanks for your answer.

    I didn’t really create the items dynamically, they are all created in declarative QML, the grid is done via a Repeater-element, and the other items are in LevelXX.qml files, which are loaded by a Loader-element

    Actually, the z-ordering works fine when i just specify the “z” property of all my entities.

    But the problem is: because of the 2.5D-look, items in the lowest row have to be drawn above items in the second row from the bottom, and so on. If you look closely at the player, the wall beneath him overlaps him, which is intentional.

    So the z-order formula is this:

    z: row * 10 + level

    Which works fine to build up the level. (“row” is the y value in the grid, so 0,1,…4 and “level” is the vertical position on an imaginary axis pointing out of the screen, which can be 0,1 or 2 right now)

    But when the row-value changes, the ordering needs to change, because then sometimes a box in a lower row has to overlap another box, which previously wasn’t the case.

    #4050

    Christian
    V-Play Team

    Ah I see..

    So you really need to change your z order dynamically in that case. You could use the vertexZ property.
    It is not documented though, because it usually introduces other issues like alpha blending not working correctly, but you could try if it works in your case.

    Add it to any Item/Entity/etc. by adding a float property called vertexZ. It is a float value and you can also see its usage in the Squaby demo by searching the source code for vertexZ.

    Here is an example of adding vertexZ to an Item:

    
    Item {
      property real vertexZ: 1.5
    }
    

    What this property does, is that it modifies the z value of the OpenGL drawing directly. It works best in ranges between -50 and 50, so you might divide your z calculation by 10 to get it working.

    Please let me know if that solved your problem.

    #4051

    Christian
    V-Play Team

    This sounds good, but on first try it did not solve my problem.

    Does vertexZ work with property binding?

    Because generally it works when i use vertexZ instead of z like this:

    property real vertexZ: row + level * 0.1

    But when the value of row changes, this doesn’t seem to change, because the moving blocks move underneath other items.
    So it seems that dynamically changing vertexZ also doesn’t work that easily. (in the Squaby project, they are also always just constants)

    EDIT/PS: I am currently not using an EntityManager / EntityBase objects in my game, only normal Items. Could that be any problem?

    #4053

    Christian
    V-Play Team

    Alright, I found out that we do not support changing vertexZ properties at runtime with the current version. Could you please tell me which operating system you are using for development, so I can send you a version which includes that support?

    If you are using entities or not is not related to this issue. Using the EntityManager & EntityBase is just a convenience function if you want to dynamically create new entities, or store the levels with the entity manager.

    #4054

    Christian
    V-Play Team

    Cool that’s nice!
    I’m currently running Windows 7 64bit, with the newest v-play release.

    #4055

    Christian
    V-Play Team

    Hi again,
    I delved a bit deeper into the z-ordering issue with isometric games.. From what I’ve found out, changing the vertexZ property is one approach to it, as it is used at the TMXTileMap class in cocos renderer to achieve z ordering within sprite sheets. It does have several disadvantages though:

    • If transparent images are used, the alpha test needs to be enabled for all child items of “layers” (which would be the rows in your case). What we found out at internal tests is, that alpha testing is quite expensive even on higher-end devices like the iPhone 4, and is tricky to set the right alpha testing value.
    • By using vertexZ, you override the painters algorithm approach where all items are pre-sorted. So if you use vertexZ for one item and thus overwrite the normal z property, you must use the vertexZ property in all other items as well to avoid z ordering and transparency issues.

    Thus for your use-case, I think it is preferable to change the z property at runtime. I added the support to V-Play and added a test to the basicTests folder which will be available with the next update. Changing z at runtime should be done with respect to its performance penalties: a resorting needs to be done for reordering. This should be fine if you are not using too many siblings where you change the z order, e.g. something below 100 should be reasonable fast. And you should not do this every frame for a game entity obviously. In that case, vertexZ would be preferrable, even with its issues mentioned above.

    Here is its source code of the ZChangingTest.qml, which will be part of V-Play 1.0.1:

    
    import QtQuick 1.1
    
    Rectangle {
      width: 800
      height: 600
      color: "lightgrey"
    
      // tests the changing of z at runtime for cocos renderer - by clicking on the window the z order of rect2 changes from 0 ... 2
      // this test must have the following behavior (for COCOS RENDERER!):
      // initially, rect2 must be below rect1: they have the same z value, but rect2 is defined first so it is rendered first and rect1 will be on top of it
      // with z=0 rect2 must be below rect1, as it has a lower z than the sibling
      // with z=1 rect2 must be on top of rect1, because it has the same z as the sibling, but is put at the end of all same z items
      // with z=2 rect2 must be on top of rect1, as it has a higher z than the sibling
    
      // the difference at QML renderer is, that when rect2 gets z=1, it still says behind rect1 as it was set initially! in cocos that is not easily possible, so mind this different behavior!
      // a workaround for same z values is, to put the items into different layers or just do not set the same z and be explicit about ordering
    
      Rectangle {
        id: rect2
        x: 40
        y: 40
        width: 100
        height: 100
        color: "red"
        z:1
      }
    
      Rectangle {
        id: rect1
        width: 100
        height: 100
        color: "green"
        z: 1
      }
    
      Text {
        text: "green rect z: " + rect1.z + "\nred rect z:" + rect2.z
        anchors.centerIn: parent
      }
    
      MouseArea {
        anchors.fill: parent
        onClicked: {
          // toggles the z order of rect2 from 0 to 2
          if(rect2.z === 2)
            rect2.z=0
          else
            rect2.z++
        }
      }
    }
    
    

    You can find the updated library for windows here, until the update is released: https://dl.dropbox.com/u/13974554/VPlay-libs-windows-zChangeSupport.zip

    Please make a backup of your VPlay.lib and VPlayd.lib in the folder \Desktop\V-PlaySDK\lib and copy the new ones from the zip file which come with support for z changing. Please note, that a clean of your build is required so the new library gets used. With the next engine update, this temporary libraries get replaced from the SDKMaintenance Tool.

    Here are the most useful resources I found on this topic:
    http://www.cocos2d-iphone.org/forum/topic/4348/page/3#post-55439
    http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps
    http://www.learn-cocos2d.com/files/cocos2d-essential-reference-sample/Influencing_the_Draw_Order.html

    Please keep me updated if this solution works now.

    #4056

    Christian
    V-Play Team

    Wow thanks that is awesome.

    I have experienced the issues with vertexZ and alpha in images, so this probably is the perfect solution.
    In my game, the z-order changes when items move around, so I’m sure I can keep this to a minimum.

    I’m downloading the libs at the moment and will try it out and then report back to you.

    Thanks for all the support!

    #4057

    Christian
    V-Play Team

    No worries – looking forward to your game! :)

    #4058

    Christian
    V-Play Team

    So this actually works now! :)

    Thanks for the fast solution.

    BUT there still is a problem – when I start the game in Debug mode I get the error:

    file:///H:/Projects/QT/StoneJumper/GamePrototype-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/qml/main.qml:7:1: GameWindow is not a type 
         GameWindow { 

    –> GameWindow is not a type

    In Release mode, everything works fine, and the z-ordering works and runs without performance issues.

    #4059

    Christian
    V-Play Team

    That is very strange – I tested the library with a clean project and it worked both for debug and release. Are you sure you cleaned your build before? Could you also test it with an Empty V-Play Project from the project wizard please?

    Is there any further information about the error in the log output lines above or below your error message?

    #4060

    Christian
    V-Play Team

    Quote from Christian on December 19, 2012, 13:58
    That is very strange – I tested the library with a clean project and it worked both for debug and release. Are you sure you cleaned your build before? Could you also test it with an Empty V-Play Project from the project wizard please?

    Is there any further information about the error in the log output lines above or below your error message?

    Yes, this also happens on a clean install of the current VPlay release with the following simple example:

    import VPlay 1.0
    import QtQuick 1.1
    
    GameWindow {
       // activeScene: scene
        // the size of the Window can be changed at runtime by pressing the number keys 1-6 with QML window active
        // the content of the logical scene size (480x320) gets scaled to the window size based on the scaleMode
        width: 960
        height: 640
    }

    It also happens on my notebook and on a collegue’s.

    The full log is:

    Starting H:\Projects\QT\VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug\debug\VPlayZOrderingTest.exe...
    m_platform in System set to: 4 , m_isDesktopPlatform: true 
    m_isDebugBuild in System set to: true 
    Load config file from "H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/qml/config.json" , adjustedFileName: "qml/config.json" 
    Setting default orientation to 1 (0=Portrait, 1=LandScape, 2=Auto) 
    VPlayApplication: log messages are enabled by default, because it is a debug build
    VPlayApplication: ...adding this import path for VPlay engine: "D:/__git/VPlayQML/qml" 
    VPlayApplication: adding pluginPathGeneric as importPath: "plugins/generic" 
    VPlayApplication: adding PLATFORM_PLUGIN_PATH as importPath: "plugins/windows" 
    VPlayApplication: importPathList: ("H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/qml", "H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/plugins/windows", "H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/plugins/generic", "D:/__git/VPlayQML/qml", "H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/debug", "G:/QT/VPlay/Desktop/Qt/4.8.1/msvc2010/imports") 
    VPlayApplication: pluginPathList: (".") 
    VPlayApplication:startApplication() 
    VPlayApplication: rootContext of qmlViewer:  QDeclarativeContext(0x2541658) 
    VPlayApplication: using CocosDenshion for audio 
    ...before cocosApplication.run()
    cocos2d: cocos2d-1.0.1-x-0.12.0
    Qml debugging is enabled. Only use this in a safe environment!
    VPlayAppDelegate::applicationDidFinishLaunching()
    cocos2d: GL_VENDOR:     Imagination Technologies (Host GL: `NVIDIA Corporation`)
    cocos2d: GL_RENDERER:   PowerVR PVRVFrame 8.1 SGX (Host GL: `GeForce GTX 460/PCIe/SSE2`) SDK Build: 2.08.28.0607
    cocos2d: GL_VERSION:    OpenGL ES-CM 1.1 
    cocos2d: GL_MAX_TEXTURE_SIZE: 2048
    cocos2d: GL_MAX_MODELVIEW_STACK_DEPTH: 16
    cocos2d: GL supports PVRTC: YES
    cocos2d: GL supports BGRA8888 textures: YES
    cocos2d: GL supports NPOT textures: NO
    cocos2d: GL supports discard_framebuffer: NO
    cocos2d: compiled with NPOT support: NO
    cocos2d: compiled with VBO support in TextureAtlas : NO
    create EngineScene from delegate
    call of EngineScene::scene()
    call of Scene:init()
    Cocos2DWrapper::setTargetScene() called
    Cocos2DWrapper: windowSizeChanged: shift the cocosScene-layer up by its winSize width: 960 , height: 640 
    Cocos2DWrapper: windowSizeChanged: new windowSize:  QPointF(960, 640) , displaySize: QPointF(960, 640) 
    file:///H:/Projects/QT/VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug/qml/main.qml:4:1: GameWindow is not a type 
         GameWindow { 
         ^ 
    WARNING: VPlayApplication: no GameWindow item found, so could not set the rootGameWindow contextProperty as well! 
    Update cocosRenderer size to qmlViewer size: QSize(640, 480) 
    after m_eglView->resize(), size: 640.000000 * 480.000000
    CCDirector::sharedDirector()->getWinSize(): 640.000000 * 480.000000
    Cocos2DWrapper: windowSizeChanged: shift the cocosScene-layer up by its winSize width: 640 , height: 480 
    Cocos2DWrapper: windowSizeChanged: new windowSize:  QPointF(640, 480) , displaySize: QPointF(640, 480) 
    ______________VPlayApplication: cocosWrapper initialized, load QML tree______________ 
    The program has unexpectedly finished.
    H:\Projects\QT\VPlayZOrderingTest-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2010__Qt_SDK__Debug\debug\VPlayZOrderingTest.exe exited with code -1073741819
Viewing 15 posts - 1 through 15 (of 18 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support