Display APL visuals through a custom handler
The Tic-Tac-Toe skill user must see a screen after the end of each game. The screen informs the user of the game outcome and the overall standings for both the user and Alexa. The following example shows the screen the user should see if they win. Observe that the secondaryText
contains standings for the user and Alexa.
In the overall design, this logic lives in the skill’s Pick Move module. The user’s device must render such screens within the same custom handler, for example CaptureMoveIntentHandler
, every time a game ends (Win, Lose, or Draw).
In terms of the visual design, the differences between screens of these three outcomes (Win, Lose, or Draw) are the following:
- the background image url
- the
primaryText
These differences are minor, so you can still use the same APL document.
Also, to display the secondaryText
string, your skill logic must store the number of wins of the user and the amount of wins for Alexa. You do so in two separate variables by using session attributes. For more details, see the section About session attributes later in this lab. For now, because the focus is on APL, assume that the following code is a part of a CaptureMoveIntentHandler
. This handler already contains the following two variables with the proper values assigned to them:
winsUser
to store user’s number of winswinsAlexa
to store their losses
So, the same mechanism for rendering APL visuals applies here, with the difference being that the string value for secondaryText
depends on the values assigned to these two variables.
Exercise 2
Assume that variables winsUser
and winsAlexa
store the number of games won by the User and Alexa, including the outcome of the game that just ended. (For details about storing these values in sessionAttributes
, see the section About session attributes later in this lab.)
Update the following code below to store the proper string value in the variable gamesText
to display it with secondaryText
.
Tip: Notice the difference between the two screens:
WinScreenHandler.js
winsUser = sessionAttributes.winsUser;
winsAlexa = sessionAttributes.winsAlexa;
var gamesText = `You have ${winsUser} games and I have ${winsAlexa}.`;
if (Alexa.getSupportedInterfaces(handlerInput.requestEnvelope)['Alexa.Presentation.APL']) {
handlerInput.responseBuilder.addDirective({
type: 'Alexa.Presentation.APL.RenderDocument',
document: informationDocument,
datasources: {
information: {
backgroundImage: {
url: "https://d3j5530a0cofat.cloudfront.net/adlc/win.png",
colorOverlay: true
},
logoUrl: "https://d3j5530a0cofat.cloudfront.net/adlc/somelogo.png",
textContent: {
primaryText: "Congrats! You won!",
secondaryText: ,
hintText: "Say your first move to start a new game"
}
}
}
});
}
Solution
winsUser = sessionAttributes.winsUser;
winsAlexa = sessionAttributes.winsAlexa;
var gamesText;
if (winsUser === 1) {
gamesText = `You have ${winsUser} game and I have ${winsAlexa}.`;
}
else {
gamesText = `You have ${winsUser} games and I have ${winsAlexa}.`;
}
if (Alexa.getSupportedInterfaces(handlerInput.requestEnvelope)['Alexa.Presentation.APL']) {
handlerInput.responseBuilder.addDirective({
type: 'Alexa.Presentation.APL.RenderDocument',
document: informationDocument,
datasources: {
information: {
backgroundImage: {
url: "https://d3j5530a0cofat.cloudfront.net/adlc/win.png",
colorOverlay: true
},
logoUrl: "https://d3j5530a0cofat.cloudfront.net/adlc/somelogo.png",
textContent: {
primaryText: "Congrats! You won!",
secondaryText: gamesText,
hintText: "Say your first move to start a new game"
}
}
}
});
}