Forums

OverviewV-Play 2 Support (Qt 5)Camera movement and zoom › Reply To: Camera movement and zoom

OverviewV-Play 2 Support (Qt 5)Camera movement and zoom › Reply To: Camera movement and zoom
#10449

Alex
V-Play Team

Hi,

I highly recommend not touching the scene too much, it’s automatically positioned to fit in the screen, rather work with the container of your game area.

In the example I posted, this is the part of the code that keeps the player (entityBase) centered in the screen, so to keep another object (entityBase2) centered, it would be the easiest thing just to change this part of the code.

Item {
  id: container
  transformOrigin: Item.Center

  // property binding to update the position and keep the player centered in the screen  
  x: scene.width/2 - entityBase.x
  y: scene.height/2 - entityBase.y

  // ...
}

One solution would be to replace this property binding (a property binding automatically updates and recalculates as soon as one of the involved properties change) with a new one, like this (I just replaced the MouseArea of my own example that I posted):

MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        onEntered: parent.opacity = 0.3
        onExited: parent.opacity = 0.2
        onClicked: {
          // I just commented the zoom part and use the same button as before to switch centered object
          if(!scene.zoomOn){
            //scene.scale = 1.2
            // using entityBase2 here to center that object
            container.x = Qt.binding(function() { return scene.width/2 - entityBase2.x })
            container.y = Qt.binding(function() { return scene.height/2 - entityBase2.y })
          }
          else{
            //scene.scale = 1
            // revert back to the inital binding to center entityBase
            container.x = Qt.binding(function() { return scene.width/2 - entityBase.x })
            container.y = Qt.binding(function() { return scene.height/2 - entityBase.y })
          }
          scene.zoomOn = !scene.zoomOn
        }
      }

A more elegant way would be to introduce a new property which holds the object that should get centered, and benefit from the power of property bindings to handle the rest, here is an example for that:

import QtQuick 2.0
import VPlay 2.0

GameWindow{
  id: window

  // this will be our game scene
  Scene {
    id: scene

    property bool zoomOn: false
    property variant focusedObject: entityBase

    EntityManager {
      id: entityManager
      entityContainer: container // the entityContainer is now our container that will be moving
    }

    // instead of changing the scene position we rather introduce a container that holds the entities, and adepts its position accordingly to the player position to keep the player centered in the screen. Also we are sing a property binding to update the position every frame instead of a timer, this is more reliable to keep in in sync.
    Item {
      id: container
      transformOrigin: Item.Center

      // property binding to update the position and keep the player centered in the screen
      x: scene.width/2 - scene.focusedObject.x
      y: scene.height/2 - scene.focusedObject.y

      // put the physicsworld inside the entitycontainer to have correct debug draw
      PhysicsWorld {
        id: physicsWorld
        gravity: Qt.point(0,0)
      }

      // background
      Grid {
        id: grid
        x: scene.width/2
        y: scene.height/2
        width: 2 * window.width
        height: 2 * window.height
        columns: 8
        rows: columns * window.height / window.width    // make each grid a square
        Repeater {
          model: parent.columns * parent.rows
          Rectangle{
            property int rectangleNumber: index
            width: parent.width / parent.columns
            height: width
            color: "transparent"
            border.color: "black"
            border.width: 3
            Text {
              anchors.centerIn: parent
              text: parent.rectangleNumber + 1
              font.pointSize: parent.height / 3
            }
          }
        }
      }

      // the player
      EntityBase {
        id: entityBase
        x: scene.width / 2
        y: scene.height / 2

        Rectangle {
          id: player
          x: -width / 2
          y: -height / 2
          width: 80
          height: width
          radius: width / 2
          color: "blue"

          // start player moving when clicked, and start the timer to update the camera's position
          MouseArea {
            anchors.fill: parent
            onClicked: {
              //cameraTimer.start()
              collider.linearVelocity = Qt.point(100, 75)
              colliderObstacle.linearVelocity = Qt.point(-100,75)
            }
          }
          Text {
            anchors.centerIn: parent
            font.pixelSize: 15
            text: "click me"
            color: "white"
          }
        }
        CircleCollider {
          id: collider
          radius: player.width / 2
          anchors.centerIn: player
          bodyType: Body.Dynamic
          linearVelocity: Qt.point(0, 0)
          categories: Box.Category1
          collidesWith: Box.Category2
          fixture.onBeginContact: player.opacity = 0.5
        }
      }

      // an obstacle
      EntityBase {
        id: entityBase2
        x: scene.width / 2 + 2*window.width
        y: scene.height / 2

        Rectangle {
          id: obstacle
          x: -width / 2
          y: -height / 2
          width: 80
          height: width
          color: "red"
          Text {
            anchors.centerIn: parent
            font.pixelSize: 15
            text: "obstacle"
            color: "white"
          }
        }
        BoxCollider {
          id: colliderObstacle
          width: player.width
          height: width
          anchors.centerIn: obstacle
          bodyType: Body.Dynamic
          sensor: true
          linearVelocity: Qt.point(0, 0)
          categories: Box.Category2
          collidesWith: Box.Category1
        }
      }
    }
  }

  // to avoid having to recalculate the size and position of the HUD elements, we just introduce a 2nd scene that we put on top of the game scene, to hold the hud elements, this one will stay untouched when we zoom into the game sceen
  Scene {
    id: hudScene
    // button to toggle zoom in
    Rectangle {
      id: zoomButton
      x: 10
      y: 10
      width: 100
      height: 40
      radius: 3
      color: "black"
      opacity: 0.2
      Text {
        anchors.centerIn: parent
        font.pixelSize: 30
        text: "zoom"
      }
      MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        onEntered: parent.opacity = 0.3
        onExited: parent.opacity = 0.2
        onClicked: {
          if(!scene.zoomOn){
            scene.scale = 1.2
          }
          else{
            scene.scale = 1
          }
          scene.zoomOn = !scene.zoomOn
        }
      }
    }

    // button to toggle centered object
    Rectangle {
      id: focusButton
      x: 120
      y: 10
      width: 100
      height: 40
      radius: 3
      color: "black"
      opacity: 0.2
      Text {
        anchors.centerIn: parent
        font.pixelSize: 30
        text: "focus"
      }
      MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        onEntered: parent.opacity = 0.3
        onExited: parent.opacity = 0.2
        onClicked: {
          if(scene.focusedObject === entityBase){
            scene.focusedObject = entityBase2
          }
          else{
            scene.focusedObject = entityBase
          }
        }
      }
    }
  }
}

Cheers,
Alex

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