Forums

OverviewV-Play 2 Support (Qt 5) › Particle Effect Problems

Tagged: 

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #13503

    Darren

    I am having problems with ParticleVPlay:

    1. I have attached a ParticleVPlay to a moving entity.  When the entity first begins moving, some of the particles are generated in the top left of the screen and not in the location of my entity.  This only happens the first time the entity moves and only for a few particles.  The rest of the particles then behave correctly and emit from my entity.
    2. When the entity is moving, if I rotate it the particles that have already been emitted also move according to the rotation.  I have the positionType set to ParticleVPlayBase.Free.  This movement is not desired – the emitted particles are supposed to be smoke and need to move independently of my entity after they have been emitted.
    3. Sometimes the ParticleVPlay component causes my game to crash.  When I launch it on the desktop I get the following error:

    ASSERT: “i sDouble()” in file ..\..\include\QtQml\5.6.0\QtQml/private/../../../../../src/qml/jsruntime/qv4value_p.h, line 252

    E:\Qt\QTPROJECTS\build-Tankz-Desktop_Qt_5_6_0_MinGW_32bit-Debug\debug\Tankz.exe exited with code 3

    When I launch it on my phone, it does not crash, but the particles do not start.  This error seems to occur most often when I have just updated / changed my code.

     

    I have shown my code below (I have removed parts that I think are not necessary to show the problem)

     

    Thanks in advance for your help guys…

     

    Darren.

     

     

    import QtQuick 2.0
    import VPlay 2.0
    import QtMultimedia 5.0 // required for SoundEffect.Infinite enum value for infinite looping
    
    
    EntityBase {
        id: tank
        entityId: "tankEntity"
        entityType: "playerTankEntity"
        width: 90
        height: 34
    
        property real turretController: 0 //controls rotation of turret
        property point startPoint: Qt.point(0,0)  //used for checking distance tank has travelled, to decide when to drop a tank track
        property alias body: baseCollider.body
        property alias tankBodyPoints: baseImage.imagePoints
    
        // gets accessed to insert the input when touching the HUDController
        property alias controller: twoAxisController
    
        readonly property real forwardForce: 8000 * world.pixelsPerMeter
    
        TwoAxisController {id: twoAxisController}
    
        BoxCollider {id: baseCollider}   
    
        TexturePackerAnimatedSpriteVPlay {id: baseImage}
    
        TexturePackerAnimatedSpriteVPlay {id: turretImage}
        
        ParticleVPlay {
             id: exhaustParticle
             z:4000
    
             // Particle location properties
             anchors.top: parent.bottom
             anchors.topMargin: -18
             anchors.right: parent.left
             anchors.rightMargin: -20
             rotation: 180
    
             duration: ParticleVPlayBase.Infinite
             positionType: ParticleVPlayBase.Free
    
             //More exhaust particles are emitted as the tank moves faster
             maxParticles: 5 + Math.round(40 * Math.abs(twoAxisController.yAxis))
    
             // particle file
             fileName: "../TankExhaustParticle.json"
    
             // start when finished loading
             autoStart: true
           }
    }

     

    import QtQuick 2.0
    import VPlay 2.0
    import "entities"
    
    Item {
        id: level
        width: parent.width
        height: parent.height
    
       
    
        Tank {
            id: tankPlayer
            objectName: "tankPlayer"
            variationType: "tankPlayer"
            x: 120
            y: 200
            rotation: 0
    
        }
    }

     

    import QtQuick 2.0
    import VPlay 2.0
    import "entities"
    
    GameWindow {
        id: window
        screenWidth: 720
        screenHeight: 1280
    
        Rectangle{
            width: parent.width
            height: parent.height
            color: "white"
        }
    
        
        EntityManager {
            id: entityManager
            entityContainer: level
        }   
    
        Scene {
            id: scene
            width: 320
            height: 480
            scaleMode: "letterbox"
    
      
            Rectangle {
                        id: background
                        width: parent.width //*1.8
                        height: parent.height //*1.8
                        color: "white"
                        anchors.centerIn: parent
                    }
    
            // use a physics world because we need collision detection
            PhysicsWorld {
                id: world
                updatesPerSecondForPhysics: 60
    
                debugDrawVisible : true
            }
    
            Level {
                // this gets accessed by its id from JoystickControllerHUD below
                id: level
    
            }
    
           
            focus: true
      
        }
    
    
        HorizontalAxisController{
            id: turretController
            anchors.bottom: parent.bottom
            anchors.right: parent.right
            anchors.bottomMargin: 50
           // property variant playerTurretController: level.tank_player.getComponent("TurretController")
            onPositionChanged: level.tank_player.turretController = turretController.position
        }
    
        JoystickControllerHUD {
            anchors.bottom: parent.bottom
    
            // the joystick width is the space from the left to the start of the logical scene, so the radius is its half
            joystickRadius: 100 //scene.x/2
    
            // this allows setting custom images for the JoystickControllerHUD component
            source: "../assets/img/joystick_background.png"
            thumbSource: "../assets/img/joystick_thumb.png"
    
            // this is the mapping between the output of the JoystickControllerHUD to the input of the player's TwoAxisController
            // this is a performance improvement, to not have to bind every time the position changes
            property variant playerTwoxisController: level.tank_player.getComponent("TwoAxisController")
            onControllerXPositionChanged: playerTwoxisController.xAxis = controllerXPosition
            onControllerYPositionChanged: playerTwoxisController.yAxis = controllerYPosition;
    
    
        }
    }

     

    • This topic was modified 2 years, 6 months ago.
    #13517

    Günther
    V-Play Team

    Hi Darren!

    The positionType: ParticleVPlayBase.Free setting affects how the particles behave when the emitter position changes. When moving the entity, the emitter position changes, but the particles do not move along.

    A set rotation for the whole Particle item or a parent item then applies to all visible elements / particles. This happens after the relative positions to the emitter are calculated and can lead to unwanted effects. To change the angle of the emitter (thus only affecting the direction of the emitted particles), the angle property can be used instead.

    So for your problem, It might help to change the tank rotation independently from the angle of the particle emitter.

     

    As for the errors:
    Can you create a small particle example where these errors occur and send it to us via email?
    I will have a look if I can reproduce the issue – it’s possible that they come from the Qt Quick Particle System, which we use internally. In that case we can report the error to Qt so they can have a look.

     

    Best,
    Günther

     

    • This reply was modified 2 years, 6 months ago by  GT.
    #13519

    Alex
    V-Play Team

    Hi Darren,

    please try setting the target property of the particle to tank.parent

    This property is unfortunately not yet documented, but it is used to use a different relative target to calculate the positional changes for Free particles.

    As Günther already pointed out, the emitter does not move relative to it’s parent, the entity, that’s why you can use the target property to specify another item to calculate the relative movement.

    Cheers,
    Alex

    #13522

    Darren

    Hi guys,

    Thank you for your help as always!

    Just to recap, the problem is that when I rotate my tank, the smoke particles that have already been emitted also move according to the rotation.  If I just move the tank forward or backward, the particles behave correctly and leave a trail behind the tank.

    I have the positionType set at ParticleVPlayBase.Free.

     

    As suggested I have tried the following:

    1. I set the emitter angle independent of the tank – I actually made it bind to the rotation of the tank’s parent (level).  So the emitter angle remained at 0. This had no effect on the problem.
    2. I set the emitter angle to various other angles – eg. tank.rotation, tank.rotation + 90 etc.  Again, it had no effect.
    3. I tried changing the rotation of the particlevplay – this had no effect either
    4. I tried setting the target property of the particle to tank.parent – which is ‘level’. This had the effect of making the smoke particles stick to the back of the tank as it moved and not being left behind.  I imagine this is because the target (tank.parent) is not moving therefore the particles will not move.
    5. I tried creating an invisible item independent of the tank and bound it’s x and y properties to the same as the tank, whilst leaving the rotation static. I then used this item as the target for the particle. This produced some really strange effects with the smoke moving in nice patterns, but not at all as required.

    Am I not understanding your explanations?

    I’m still stuck, although I have made the particles only last a short time so the effect is less noticeable unless you are looking for it.  I guess it will be ok, though I still can’t stop my particles moving sideways when I rotate the tank.

    In terms of reproducing the crash – the code above shows my particle – do you need something different or does this work for you?

     

    Thank you both again for your help.

     

    Darren.

    #13526

    Günther
    V-Play Team

    Hi Darren!

    I just had a closer look:
    The main problem is, that the rotation of the particle target / tank also affects the particle. So the last solution you tried should be the way to go:
    – Make the Tank and the Particle item independent.
    – Add a new parent item for the Particle and use it as the target.
    – Only update the position of the new parent, but do not apply any rotation.

    The only issue that remains, is that the origin point of the particles (the new parent) also needs to consider the Tank rotation. While the position of the tank itself might not change, the emitter position for the particles is still different depending on the rotation.
    That’s also where it gets a bit tricky. I used the mapFromItem function to convert the relative emitter position within the tank to absolute coordinates within the level. If this is done whenever the tank position or rotation changes, the emitter position updates correctly.

     

    Tank / Particle code within Level.qml:

    // the tank
      Tank {
        id: tankPlayer
        objectName: "tankPlayer"
        variationType: "tankPlayer"
        x: 120
        y: 200
      }
    
      // the particle
      Item {
        id: tankParticle
    
        // set initial position
        Component.onCompleted: reposition()
    
        // when tank rotation or position changes -> update particle position
        Connections {
          target: tankPlayer
          onRotationChanged: tankParticle.reposition()
          onXChanged: tankParticle.reposition()
          onYChanged: tankParticle.reposition()
        }
    
        // set up particle
        ParticleVPlay {
          id: exhaustParticle
          z:4000
    
          duration: ParticleVPlayBase.Infinite
          positionType: ParticleVPlayBase.Free
    
          // emitter angle depends on rotation of tank
          angle: tankPlayer.rotation + 180
    
          // target to consider for free particles is set to parent
          // the parent uses the emitter position specified for the tank, but doesn't apply any rotation
          target: parent
    
          // particle file
          fileName: "particles/TestSmokeParticle.json"
    
          // start when finished loading
          autoStart: true
        }
    
        // function to reposition particle
        function reposition() {
          // map emitter coordinates within tank to level coordinates
          var position = level.mapFromItem(tankPlayer, tankPlayer.particleEmitterPosition.x, tankPlayer.particleEmitterPosition.y)
          tankParticle.x = position.x
          tankParticle.y = position.y
        }
      }

     

    Tank.qml:

    import QtQuick 2.0
    import VPlay 2.0
    import QtMultimedia 5.0 // required for SoundEffect.Infinite enum value for infinite looping
    
    
    EntityBase {
      id: tank
      entityId: "tankEntity"
      entityType: "playerTankEntity"
      width: 90
      height: 34
    
      // ... tank properties
    
      // particle emitter position is public
      readonly property alias particleEmitterPosition: particleEmitterPosition
    
     // ... tank items
    
      // dummy item that allows to access the emitter position within the tank
      Item {
        id: particleEmitterPosition
    
        // Particle location properties
        anchors.top: parent.bottom
        anchors.topMargin: -18
        anchors.right: parent.left
        anchors.rightMargin: -20
      }
    }
    

     

    Hope this helps. I’ll also send you my test project via email so you can have a look.

    Best,
    Günther

     

     

     

     

     

     

    • This reply was modified 2 years, 6 months ago by  GT.
    #13531

    Darren

    Günther,

    That works PERFECTLY! 

    Thank you!
    I’ll study the WHY of it working but I think I’ve mostly got it.
    My tank exhaust now behaves like smoke and doesn’t rotate with the tank.

    Same for the damage smoke that I also created….
    I really appreciate your help.

    Thank you
    Darren.

Viewing 6 posts - 1 through 6 (of 6 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