Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

GameNetworkExample

 import QtQuick 2.0
 import Felgo 3.0

 GameWindow {

   // this will be set when the highscore was received from server, or read from local cache
   property int highscore: gameNetwork.userHighscoreForCurrentActiveLeaderboard

   property bool portrait: false

   title: "Username: " + gameNetwork.user.name + ", UserId: " + gameNetwork.user.userId + ", UDID: " + gameNetwork.user.deviceId

   // the GameNetworkView must be designed for portrait mode, because we then have less space in the header navi
   // in landscape, it shall just add more spacing in between, or the title has more space
   // however, when launching the GameNetworkTestMain it is designed for landscape mode to fit more buttons horizontally on screen
   // so: to design the GameNetworkView change to portrait mode, if running the GameNetworkTest change to landscape mode
   screenWidth: portrait ? 640 : 960
   screenHeight: portrait ? 960 : 640

   color: "black"

   activeScene: scene

   Scene {
     id: scene

     width: portrait ? 320 : 480
     height: portrait ? 480 : 320

     property int testHeight: scene.height - testRow.height - footer.height

     // this can be set to start with a specific test at app launch
     state: "user"
     //state: "gamenetworkview"
     //state: "level"

     Row {
       id: testRow
       spacing: 3
       SimpleButton {
         text: "User"
         onClicked: scene.state = "user"
         color: scene.state ==="user" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "Scores"
         onClicked: scene.state = "scores"
         color: scene.state ==="scores" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "Ach."
         onClicked: scene.state = "achievements"
         color: scene.state ==="achievements" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "Chall."
         onClicked: scene.state = "challenges"
         color: scene.state ==="challenges" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "WebStore"
         onClicked: scene.state = "keyvalue"
         color: scene.state ==="keyvalue" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "Lev"
         onClicked: scene.state = "level"
         color: scene.state ==="level" ? "darkgreen" : "darkblue"
       }

       SimpleButton {
         text: "GNView"
         onClicked: {
           gameNetworkView.initialStateBeforeShow = scene.state
           scene.state = "gamenetworkview"
         }
         color: scene.state ==="gamenetworkview" ? "darkgreen" : "darkblue"
       }
     }

     UserTest {
       id: userTest
       visible: false
     }

     ScoreTest {
       id: scoreTest
       visible: false
     }

     AchievementTest {
       id: achievementTest
       visible: false
     }

     ChallengeTest {
     // do not use the ChallengeTest yet, as the API for the ChallengeView is not good at the moment
     //ChallengeTestInternal {
       id: challengeTest
       visible: false
     }

     KeyValueTest {
       id: keyValueTest
       visible: false
     }

     LevelTest {
       id: levelTest
       visible: false
     }

     /* LeaderboardView and AchievementView can be removed when the gameNetworkView is used; if a custom view is desired, overwrite it and set the achievementDelegate and leaderboardDelegate
     LeaderboardView {
       id: leaderboardView
       //anchors.fill: parent

       width: 400
       height: scene.testHeight - 3 // as 3 is the margin, reduece the available height
       anchors.top: testRow.bottom
       anchors.topMargin: 3

       // only enable in the debug version of GameNetwork - do not set it for real games
       // it disables the close button
       debugMode: true
     }

     AchievementView {
       id: achievementView

       width: 400
       height: scene.testHeight - 3 // as 3 is the margin, reduece the available height
       anchors.top: testRow.bottom
       anchors.topMargin: 3

       // enables the close button
       debugMode: true
     }
     */

     Column {
       id: footer
       anchors.bottom: parent.bottom
       Text {
         text: "lastRequest: " + gameNetwork.lastRequest
         color: "white"
         font.pixelSize: 6
         // wrapmode does not work with cocos renderer yet!
         // set a fixed width so the item's size does not need to change when the text changes
         width: scene.width
         wrapMode: Text.WrapAnywhere
       }
       Text {
         text: "lastResponse: " + gameNetwork.lastResponse
         color: "white"
         font.pixelSize: 6
         width: scene.width
         wrapMode: Text.WrapAnywhere
       }
     }

     // this is put on top of all other views
     GameNetworkView {
       id: gameNetworkView
       // this is not required, if the id gameNetwork is used for the FelgoGameNetwork component
       //gameNetworkItem: gameNetwork

       visible: false
       // fill the whole screen, so match it to GameWindow!
       //anchors.fill: parent
       anchors.fill: scene.gameWindowAnchorItem

       onShowCalled: {
         // onShowCalled is also called internally in the VPGNView - so to make sure we only save it when we come from outside VPGNView, add this check
         if(scene.state !== "gamenetworkview") {
           // to this state we switch back in onBackClicked
           initialStateBeforeShow = scene.state

           scene.state = "gamenetworkview"
         }
       }

       onBackClicked: {

         // switch back to the stored initialStateBeforeShow
         if(initialStateBeforeShow) {
           scene.state = initialStateBeforeShow
         } else {
           // this is valid behavior in this example, because the GNView is shown at app startup where no initialState is set
           //console.debug("ERROR: no initialStateBeforeShow is set - this should never happen, as we call the showXXX() functions also with an intial state")
           scene.state = "user"
         }
       }
     }

     states: [
       State {
         name: "user"
         PropertyChanges { target: userTest; visible: true}
       },
       State {
         name: "scores"
         PropertyChanges { target: scoreTest; visible: true}
       },
       State {
         name: "achievements"
         PropertyChanges { target: achievementTest; visible: true}
       },
       State {
         name: "challenges"
         PropertyChanges { target: challengeTest; visible: true}
       },
       State {
         name: "keyvalue"
         PropertyChanges { target: keyValueTest; visible: true}
       },
       State {
         name: "level"
         PropertyChanges { target: levelTest; visible: true}
       },
       State {
         name: "gamenetworkview"
         PropertyChanges { target: gameNetworkView; visible: true}
       }
     ]

   }// Scene

   GameCenter {
     id: gameCenter

     onPluginLoaded: authenticateLocalPlayer()
   }

   FelgoGameNetwork {
    id: gameNetwork

    // Felgo Test Game has id 3
    // gameId 14 in staging
    // GameId with new fb app has id 108 (both have the same pwd)
    gameId: 108
    secret: "vpgnTest-password"

    facebookItem: facebook
    // support both posting to GameCenter and VPGN
    gameCenterItem: gameCenter

    achievements: [

      Achievement {
        key: "achievement01"
        name: "Achievement 1"
        iconSource: "../assets/img/achievement_default.png"
        target: 10
        points: 10
        description: "description1"
        data: "testData1"
        // this currently does not work on server:
        //registerOnFacebook: true
      },

      Achievement {
        key: "achievement02"
        name: "This is a super-long achievement name. This is a super-long achievement name."
        iconSource: "../assets/img/achievement_default.png"
        target: 15
        points: 15
        // this can be changed when the application gets restarted!
        // it is then synced to the server and accessible across all devices
        description: "This is a super-long description. This is a super-long description. This is a super-long description. This is a super-long description. This is a super-long description."
        //data: "testData2"
      },

      Achievement {
        key: "achievement03"
        name: "This is also a very long achievement name."
        iconSource: "../assets/img/achievement_default.png"
        target: 30
        points: 20 // points need not be the same as target!
        description: "Descr3"
      },

      Achievement {
        key: "achievement04"
        name: "Achievement 4"
        description: "A very long description of this achievement, spanning over two lines."
        iconSource: "../assets/img/achievement_default.png"
      },

      Achievement {
        key: "achievement05"
        name: "Achievement 5"
        iconSource: "../assets/img/achievement_default.png"
      }
    ]

    // enable this during testing the faulty fb connection, to avoid endless loops when the app is closed and restarted - instead the request is just skipped
    // problematic is earning an achievement, the other calls work fine without errors
    // TODO: test offline handling more, with wifi completely turned off and then turned on again, from 2 different applications
    //clearOfflineSendingQueueAtStartup: true

    // only set this to true if you have corrupted or faulty data in the user storage, which should be removed
    // you should only set it to true once, if you have faulty data
    //clearAllUserDataAtStartup: true

    onAuthenticatedChanged: {
      console.debug("userAuthenticated changed to:", authenticated)
    }

    // use this instead of defining own delegates
    gameNetworkView: gameNetworkView

    property int defaultPerPageCount: 30 // for testing pagination (in views and in logic), set it to a low value like 1 or 2; default is 30

    // this is useful if you want to define a completely custom view
    // in most cases, using the default skin is fine and the easiest way to use
 //   leaderboardView: leaderboardView
 //   achievementView: achievementView
 //   challengeView: challengeTest.challengeView
 //   friendsView: challengeTest.friendsView

    onAchievementUnlocked: {
      nativeUtils.displayMessageBox("Achievement unlocked with key " + key)
    }
    onAchievementUnlockedAfterServerApproval: {
      nativeUtils.displayMessageBox("Achievement unlocked and approved from server with key " + key)
    }

    onNewHighscore: {
      nativeUtils.displayMessageBox("New highscore reached for leaderboard " + leaderboard + ": " + Math.round(highscore))
    }
    onNewHighscoreAfterServerApproval: {
      nativeUtils.displayMessageBox("New highscore reached and approved from server for leaderboard " + leaderboard + ": " + Math.round(highscore))
    }

    onUserScoreInSync: console.debug("score in leaderboard", leaderboard, "in sync now with score", score)

    // errorReportingLevel is set to 1 (=display gamenetwork errors but no internet connection errors) in release builds
    // and to 2 (Display both gamenetwork errors and connection errors) in debug builds by default
    onError: {
      console.log("A GameNetwork error occured:", JSON.stringify(errorData))

      // if errorReportingLevel is set to 0, you should handle the error by yourself, like in the following code:
      /*
      if(errorData.code === 2) {
        var response = errorData.serverResponse
        console.debug("ERROR: VPGN: error received from GameNetwork Server! \nrequest that failed:", JSON.stringify(request), "\nresponse with error info:", JSON.stringify(response))

        nativeUtils.displayMessageBox(qsTr("GameNetwork Error"), qsTr("An error with code " + response.data.code + " occured when connecting to the GameNetwork Server. Please try again later.\n\nError Message: " + response.data.message))

      } else if(errorData.code === 1) {
        // the request could not be sent, i.e. no internet connection
        nativeUtils.displayMessageBox(qsTr("Connection Error"), qsTr("Could not connect to the internet."))
      }
      */
    }

    onConnectionErrorChanged: {
      console.debug("GameNetworkTestMain: connectionError changed to", connectionError)
      if(!connectionError) {
        nativeUtils.displayMessageBox("Active Connection", "You just got access to internet after previously being disconnected. Your local progress gets now synced with the server.")
      } else {
        nativeUtils.displayMessageBox("Lost Internet Connection", "You just got disconnected from the Internet. Your local progress will be stored for later until you get internet access again.")
      }
    }

    // facebook signal and property handling:
    onFacebookSuccessfullyConnected: nativeUtils.displayMessageBox("Facebook Connected", "You just successfully connected to facebook, congrats!")
    onFacebookSuccessfullyDisconnected: nativeUtils.displayMessageBox("Facebook Disconnected", "You just successfully disconnected from facebook...")
    onFacebookConnectionError: nativeUtils.displayMessageBox("Facebook Error", JSON.stringify(error))
    // also use this properties to check if fb connection was successful in onUserAuthenticated():
    // facebookConnectionSuccessful, facebookWritePermissionsAllowed
    // see the UserTest how to use these properties to connect them with fb connect buttons

   }// FelgoGameNetwork

   Facebook {
     // the user will automatically connect with facebook, once "connect" is pressed in the UserTest
     id: facebook

     // the old fbId (created before new fb update) was 489472511074353
     appId: "714361931969954"

     // old: readPermissions: ["email", "read_friendlists"] read_friendlists is not required - it is sufficient to read the friends who already are using this app! also, the read_friendlists permission requires review!
     // new since 2014-06 and graph api v2 (not used in vplay 1)
     readPermissions: ["email", "user_friends"]
     // for publish_actions permission, the app must be approved & reviewed by Facebook which takes about 7 business days!
     // if your app is not approved yet, set askForWritePermissionsAtFacebookConnect of VPGN to false
     // publish_actions permission is granted for developers of the fb app though (without fb approval)!
     // NOTE: publish_actions is needed to post highscores & achievements
     // fb apps created in the facebook developers dashboard before 2014-06 work just as before, where publish_actions permissions are granted without review and the fbId stays the same
     publishPermissions: ["publish_actions"] // do not request it ATM, until the app is reviewed by fb

 //    publishPermissions: ["publish_stream"]
     // publish_stream should not be used, as it contains a lot of permissions and users might deny it - publish_actions is a part of publish_stream permission ["publish_stream"]
     // NOTE: if posting to a friend's wall secretly, the publish_stream permission is needed! for posting with the dialog, publish_actions is sufficient

     onSessionStateChanged: {
       console.log("New Facebook Session state: ", sessionState, "(0=Null, 1=Opened, 2=Closed, 3=Failed, 4=Opening)");
       console.debug("grantedPermissions:", JSON.stringify(facebook.grantedPermissions))

       if (sessionState === Facebook.SessionOpened) {
         console.debug("Session opened.");
         console.debug("New access token:", facebook.accessToken)

         // once the user opened the session, make sure to initiate a write-request so the publish_action permission is given

       }
       else if (sessionState === Facebook.SessionClosed) {
         console.debug("Session closed. This is expected behavior when the user disconnects from facebook.");
       }
       else if (sessionState === Facebook.SessionFailed) {
         console.debug("ERROR: GameNetworkTestMain: Session failed.");
       }
     }

     onGetGraphRequestFinished: {
       console.debug("GameNetworkTestMain: onGetGraphRequestFinished: graphPath:" + graphPath + ", resultState:" + resultState + ", result:" + result, ", grantedPermissions: " + JSON.stringify(facebook.grantedPermissions));

       // in here it works, but not with the Connections element in FelgoGameNetwork!
       if(resultState === Facebook.ResultOk) {
         console.debug("GameNetworkTestMain: resultState is Ok")
       }
     }

     onPostGraphRequestFinished: {
       console.debug("QML onPostGraphRequestFinished: graphPath:" + graphPath + ", resultState:" + resultState + ", result:" + result + ", grantedPermissions: ", JSON.stringify(facebook.grantedPermissions));
     }

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded