Build a Football Game in ZapWorks Studio

Print out the target image above, hit preview in the top left of the screen and hold your phone over the target image to see how this experience is going to look.

Difficulty Level: Intermediate

Coding Knowledge Required: Beginner (at least some familiarity)

Time to Complete: 45 - 60 minutes

In this step-by-step tutorial, we will be creating a simple penalty shoot-out game. Using Bezier curves, 3D models, timelines, and scripting, this is the most advanced (and rewarding) tutorial that we have developed so far. We expect that users following along will have watched all the getting started videos and completed at least a few of the other step by step tutorials.

Working through this will introduce multiple functionalities of ZapWorks Studio, showing off the vast potential of the tool and giving you the confidence to start building out even more complex experiences of your own. Best of luck!


##Part 1: Setting up the scene


  1. Open up Studio and start a New Blank Project, giving it a name and hitting create.

Note: If you haven’t got Studio installed on this computer, you can download it here: my.zap.works/studio.

  1. Download the following assets.

  2. Import all assets from the ‘2D images’ and ‘3D models’ folders from the downloaded assets into the Studio Media Library. With the 3D models, you’ll have to import the POD files one by one and then drag in the associated textures when the import dialog asks for them.

Note: You do not need to do anything with the animations at this point.

  1. Train the tracking image “target-image.jpg” by clicking the plus icon (+) at the top of the Media Library, selecting ‘Train Image File’ and then locating the tracking image within the downloaded assets folder. It should be located BezierFootballAssets > target-image.jpg. The file will now appear in your Media Library as “target-image.jpg.zpt”.

  2. Drag the tracking image “target-image.jpg” onto the root node in the Hierarchy from the Media Library.

Note: It will be helpful to switch the view from Upright to Flat (in the top right of the 3D View). Setting this camera view mimics how you would rotate the real target flat on a table. Using the middle widget in the bottom right of the scene, rotate the scene towards you so that the pitch is once again in view.

  1. Drag the pitch image “pitch.png” as a child to the tracking image from the Media Library.

Note - The tracking image acts as a group.

  1. You will now create a new group within the target to contain all the assets for the goal. Right click on the target node and select New > Group and call it “Goal”. Make sure this group is positioned below the pitch.

  2. Drag the goalpost 3D model from the Symbol Definitions panel into the Goal group. Within the Properties Panel set the transforms of the goalpost to:

    0.02 | -0.06 | 0.03
    0.88 | 0.88 | 0.88
    90 | 0 | 0

Note: Make sure that you are changing the transforms of the goalpost 3D model and not the Goal group.

  1. Drag the “Goalkeeper” 3D model from the Symbol Definitions panel in to the “Goal” group, make sure that it is placed above the goalpost 3D model. Set the transforms to:

    0 | 0.1 | 0
    0.7| 0.7 | 0.7
    90 | 0 | 0


##Part 2: Adding and animating the football


  1. Create a new group “Football” within the target image node. Make sure it is placed above the “Goal” group in the Hierarchy.

  2. Drag the football 3D model from the Symbol Definition panel into the Football group. Set the transforms of the football 3D model to:

    0 | 0 | 0
    0.08 | 0.08 | 0.08
    0 | 0 | 0

Note: This is not the final position of the football.

  1. Right click on the Football group. Select New > Transforms > Bezier. Name the Bezier “leftKickBezier”.

  2. Select the leftKickBezier node in the Hierarchy and in the Properties Panel navigate to Bezier > Points and select “Add”. Fill in these point values below:

    0 | -0.6 | 0.05
    -0.31 | -0.5 | 0.07
    -0.53 | -0.24| 0.14
    -0.54 | 0.56 | 0.06

More information on Bezier Curves.

  1. Select the football 3D model in the Hierarchy. In the Properties Panel head to the Transforms section and set RelativeTo to “leftKickBezier”.

Note: The football should now be positioned on the penalty spot.

  1. In the Controllers Panel in the bottom left add a new controller by clicking the plus button (+) and call it “penaltyKick”.

  2. We are now going to start working with timelines. If you have not yet read the Timelines article, we recommend you do this now and come back to the tutorial. Right click on the new “penaltyKick” controller and create a new timeline called “leftKick”.

  3. Select the “leftKick” timeline in the Controllers panel. Click on the leftKickBezier node in the Hierarchy. In the Properties > Distance add the distance value to the controller by clicking the plus button (+) next to it.

  1. In the Timeline panel, change the length of the “leftKick” timeline to 1500. Make sure to hit enter.

Note: It’s advisable to zoom out of the timeline using the zoom slider in the top right of the timeline view so you can see the entire timeline.

  1. Set the time to 1500. This will move the timeline handle. With the leftKickBezier node selected, set the distance value in the Properties panel to 1. This will create a transition block between 0-1.

  1. We are now going to link the two end keyframes. Click and drag to highlight the far end two keyframe diamonds (this should turn them both orange) then right click and select Make Link (L) > With left value.

Note: This will link the two end keyframes. Press play to test how it works.

  1. Right click on the transition block and select Interpolation > Decelerating.

Note: If you play again, you will see that the ball slows down as it heads towards the goal.

  1. We are now going to repeat this process for the right kick. Select the base controller in the Controller panel. Right click on the “Football” group in the Hierarchy and select New > Transforms > Bezier. Name the Bezier “rightKickBezier”.

  2. Select the rightKickBezier node and in the Properties panel select “Add” next to points, filling in the values below:

    0 | -0.6 | 0.05
    0.31 | -0.5 | 0.07
    0.53 | -0.24| 0.14
    0.54 | 0.56 | 0.06

  1. In the Controllers panel, right click on the “penaltyKick” controller, create a new timeline called “rightKick”.

  2. Select the “rightKick” controller in the Controllers panel. Now click on the “rightKickBezier” node in the Hierarchy, in the Properties panel add the distance value by clicking the plus icon (+) .

  3. Change the length of the “rightKick” timeline to 1500.

  4. In the Timeline panel, set the time to 1500. This will move the timeline handle. With the “rightKickBezier” node selected in the Hierarchy, set Properties > Distance to 1. This will create a transition block between 0-1.

  1. Click and drag to highlight the end two keyframes (this should turn them both orange) then right click and select Make Link (L) > With left value.

Note: This won’t play just yet, as we still need to set the relativeTo.

  1. Right click on the transition block of the rightKickBezier distance property and select Interpolation > Decelerating.

  2. Click into the base controller in the Controllers panel. Click on the “Football” 3D model node in the Hierarchy. Within the Properties panel navigate to Properties > Transform > relativeTo and set the second value to “rightKickBezier”. Then set relativeToProp value to [1,0].

  1. Select the “rightKick” timeline in the Controllers panel and the “Football” 3D model node in the Hierarchy. Within the Properties panel, add the relativeToProp property to the timeline by clicking the (+) icon.

  2. In the Timeline panel, set the time to -1. This will move the timeline handle. In the Properties panel, change the relativeToProp value to [0,1] and hit enter.

Note: This moves the football relative to the right bezier curve allowing it to move along the curve. We do not need to change anything in the “leftKick” timeline as this uses the default relativeToProp value.

Note: You can now play left kick and right kick animations by clicking into the different controllers and pressing play in the Timeline panel.


##Part 3: Adding animations to the goalkeeper


  1. We are now going to animate the goalkeeper 3D model. Find and open the file “GK_animation.txt” in the asset folder that you downloaded earlier. It should be located BezierFootballAssets > 3D Models > Goalkeeper > GK_animation.txt. We are looking for the following animation frame references.

    IDLE = 300-335
    R/LOW = 1-60
    L/LOW = 149-207

Note: Animation frame references define the different animations which have been baked into a 3D model.

  1. Right click on the “Goalkeeper” subsymbol in the Symbol Definitions panel. Do not enter the subsymbol. Select “Properties” and navigate to the Animation tab. Expand the dialogue box from the bottom corner so you can see the option (+) or (-) new animations.

Click (+) to create 3 new rows and add in the start and end frames for the IDLE, R/LOW and L/LOW animations and click finish.

  1. You can now test that the animations have been uploaded. Double click on the goalkeeper subsymbol to enter it. Go into the Controllers panel and your animations should appear. Press play on each individually to preview.

Note: To make sure these animations play at the correct speed in the parent symbol, we will use their length as it appears in the subsymbol. We will use 2500 for the left and right dive and 1500 for the idle.

  1. Return to the parent subsymbol by clicking the cog in the top left of the screen, above the Hierarchy. We are now going to add those goalkeeper animations to our existing timelines: leftKick and rightKick.

Note: We are going to make the goalkeeper dive the wrong way each time.

  1. Select the “leftKick” timeline in the Controllers panel. Set the time to -1 and change the length of the timeline to 2500. This will make it match the length of the goalkeeper dive animation.

With the “goalkeeper” node selected in the Hierarchy, in Properties > References > Animations panel add the animations property to the timeline by clicking the plus icon (+). In the animations dropdown select “R/LOW”. Next change the value to 0 and hit enter.

  1. In the Timeline panel set the time to 2500. In Properties > Animations set R/LOW to 2499 and hit enter. Back in the Timeline panel, click and drag over the final two diamonds. Right click and select Make Link (L) > with left value.

Note: Creating a link between the final 2 keyframes prevents the timeline jumping back to the default value at the end of the time period.

  1. Select the “rightKick” timeline in the Controllers panel. In the Timeline panel, set the time to -1. Change the length of the timeline to 2500.

With the goalkeeper node selected in the Hierarchy set the animations dropdown to L/LOW and change the value to 0.

  1. Set the time to 2500. In Properties > Animations set L/LOW to 2457 and hit enter. Click and drag over the final two diamonds. Right click and select Make Link (L) > with left value.

  1. We will now add a new timeline for the goalkeeper being idle. In the Hierarchy, select the Goalkeeper node. In the Controllers panel right click on the Penalty Kick controller and add a new timeline called “idle”.

  2. Set the length of the timeline to 1500. Set the time to -1. Select the idle animation from the dropdown in the Properties panel and set it to 0.

  3. Set the time to 1500. Set idle animation to 1499. Highlight the two end keyframes, right click and select Make Left Link (L) > with left value.

  4. Click the loop button (the one to the right of the length value) to ensure goalkeeper idle animation loops.


##Part 4: Creating buttons to play the experience


  1. We are now going to create buttons which will allow our player to trigger the animations. Add a new Group to the target image. Name it “Buttons”. Make sure the Buttons group is below the Goal group in the Hierarchy.

  1. In the Controllers panel, make sure the base controller is selected. Drag the left-icon and right-icon buttons from the Media Library into the Buttons group.

  2. Select the left button in the Hierarchy and set its transforms to:

    position -0.3 | -0.85 | 0.15
    scale 0.2 | 0.2 | 1
    rotation 45 | 0 | 0

  3. Select the right button in the Hierarchy and set its transforms to:

    position 0.3 | -0.85 | 0.15
    scale 0.2 | 0.2 | 1
    rotation 45 | 0 | 0

  1. Select the “show” script in the Hierarchy. Click and drag the “idle” timeline from the Controllers panel into the show script. Make sure that you have placed the timeline within the parent show function. When letting go, select “play” from the dropdown menu.

Note: We do this so the idle animation plays from the animation.

  1. Create pointerdown scripts on both the left icon and right icon by right clicking on the node and selecting New > Script > pointerdown.

  2. With the left icon pointerdown script selected, drag the left kick timeline from the controllers panel and into the left icon pointerdown script inside the function and set it to play.

  3. Drag the “leftkick” timeline into the left icon pointerdown script again but this time place it outside of the function and select add event handler > Complete.

  4. Drag the “leftkick” timeline into the left icon pointerdown script for a 3rd time, this time within the complete function. Set it to reset.

  5. Drag in the “idle” timeline within the complete function below the reset line and select “play”.

Note: This process plays the timeline when you click the button. Then it resets to start from the beginning, returning the model to the idle animation.

  1. We are now going to repeat this process for the right button. With the right icon pointerdown script selected, drag the “rightKick” timeline from the Controllers panel and into the right icon pointerdown script. Place it inside the function and set it to play.

  2. Drag the “rightKick” timeline into the right icon pointerdown script again but this time place it outside of the function and select add event handler > Complete.

  3. Drag the “rightKick” timeline into the right icon pointerdown script for a 3rd time, this time within the complete function and set it to reset.

  4. Drag in the “idle” timeline within the complete function below the reset line and select “play”.

  1. We are now going to hide the buttons when the game is being played.
    Select the “leftKick” timeline in the Controller panel. Set the time handle to -1. Select the buttons group in the Hierarchy. In the Appearance and Behaviour sections of the property panel add Visible and Enabled using the plus icon (+) and then uncheck both tick boxes next to them.

Note: This means the user cannot see or interact with the buttons

  1. Do the same as the step before but this time for the “rightKick” timeline, setting the time handle to -1 and unchecking the visible and enabled checkboxes.


##Part 5: Preview and publish


  1. That’s it! Your experience should now be playable. Print out the target image below, hit preview in the top left of the screen and hold your phone over the target image to see how it looks.

Note: Remember you will need to change the zapcode on your target image. We have included the psd of the target image in the download folder here.

1 Like

Hi Chris, this is a great tutorial! Many thanks! Can you just explain, without showing step by step what to do, how to build the complete game? I’ve loaded the others animations finding them on PVRShaman, and I’m going to make other beziers… but I suppose it needs some more coding.
Marco from Viewtoo Italy :wink:

1 Like

Hey Marco, thanks so much for trying out the tutorial - really pleased that you liked it! Are you a football fan?

This experience was actually custom built by Mark in our support team for the purpose of showcasing bezier curves and how to combine them with 3D animations and scripting to create a rich mini-game experience. So in answer to your question, there isn’t really a “complete game” which we can show.

To take the game further, I would however definitely recommend exploring the goalkeeper animations. As you mentioned I think that there might be 4-5 in total, so you could create additional buttons for different shots that the player can take.

Another idea that might be quite fun would be to play some crowd cheering audio once the goal has been scored. We cover adding audio in a separate step-by-step tutorial in steps 12-16, or you can check out the docs article here.

If you wanted to make the experience a bit more complex, you could even add a photo feature where the player takes a photo with the goalkeeper after completing the game… just an idea!

Please share any additions that you make, I would love to see how you can take the experience on!

Cheers,
Chris

3 Likes

Many thanks Chris!
See you soon…
Cheers,

Marco

Is there a relatively easy way to make the goalkeeper dive random?

Hey Mike, great to hear from you. Have you had a chance to check out the tutorial we published a few weeks ago on using the javascript math library? It covers a function called math.random which should be a good place to start when looking to make the goalkeeper dive randomly.

https://docs.zap.works/studio/tutorials/using-random-to-increase-re-scannability/

Let me know how you get on!

Thanks Chris, I will take a look.

Excellent Tutorial, my only question would be how to hide the bezier curve line?

thanks in advance :slight_smile:

thanks man this is great tutorial :slight_smile:

2 Likes

Thanks for the tutorial, I am currently rebuilding the game but I stuck a little at the point, where I should reduce the timeline time to 1500 (I am following this tuturial: https://docs.zap.works/studio/tutorials/penalty-shootout-game/ - but I cannot add feedback there, so I hope I can ask here.
So my issue is: I shall set the timeline to 1500 for the leftKick, but the number automatically always gets set up to 5000. If I am using a number above 5000, it takes it, but I cannot reduce the time. Thats not a breaking issue, but I am wondering why? Any global setting which cannot be overwritten?
When I add the rightKick timeline, I can set the duration of the timeline to 1500, it only doesn’t work for the leftKick timeline.

1 Like

Very good tutorual.

Thank you for your tutorial, a lot of new things for me and I can say that it is going to be very useful.

Many thanks, great tutorial.