Navigation

    CreatiCode Scratch Forum

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • CreatiCode

    Multi-player 2D game <Candy Truck Battle> - Difficulty 6

    Tutorials
    1
    1
    22
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • info-creaticode
      CreatiCode last edited by

       

      Introduction

       

      In this tutorial, you’ll build a 2-player game called Candy Truck Battle, where two candy trucks collect rewards and fire donuts at each other. Each player controls one truck on their own computer, but they’ll both see the full game scene on their screens.

      To connect the two players across computers, we’ll use the enhanced cloud variables provided by CreatiCode. Here’s a quick preview of the final result:

      finaldemo.gif

       
       
       
       

      Module 1 - Setting Up the Game Session

       

      In this section, you’ll set up a game session that connects two players running the same project on different computers. We’ll use widgets for the user interface, and cloud variables for real-time communication between the two players.

       
       

      Step 1 - Remix the Starter Project

       

      Start by remixing this project:

      play.creaticode.com/projects/68543e0c23ae1eb9ca386f59

       
      It contains everything you’ll need: trucks, trees, donuts, rewards, and other assets.

       
       

      Step 2 - Display the Game Name Input

       

      Open the “Setup” sprite, which manages the connection between two players.

      Create a new custom block called show setup screen and run it when the green flag is clicked:

      c84d3e16-232a-4353-9eea-465b711736d7-image.png
       

      Inside this block, start by displaying a label and an input box:

      6bf5c536-45f9-4c6e-9ee4-0f02c503228c-image.png

       
      The label has a fully transparent background and 0 border, so we directly see the white text over the green stage. The input box has a default value of 1234 as an example.

      This game name will be used later as a “session ID” to create a new game session. Each pair of players will share a common session ID, so that the cloud variables will only be kept in sync between them. This way, players in different sessions won’t interfere with each other.
       
      Here’s what it looks like:

      d06b0b8a-d4ec-406a-98f8-e524d520a37e-image.png

       
       

      Step 3 - Show 2 Action Buttons

       

      To connect just these two players using cloud variables, one player needs to create the session and the other must join it using the same session ID.

      Under the input box, add a label and two buttons:

      97f1210a-f1c5-4be8-a781-9f2f5da27a2a-image.png

       
      Here are the blocks you’ll add inside the show setup screen block:

      8a3775a1-d738-4602-b67d-fd4bbc4a3891-image.png

       
       

      Step 4 - Handle the “Create Session” Button

       

      When the “create session” button (“button1”) is clicked, we will first set a few key variables:

      1762b11d-8f2d-4604-a3da-0542f6c24eaf-image.png

       

      • Player 1 sets my team = 1 and opponent team = 2.
      • Store the session ID in a variable like session input.

       
       

      Step 5 - Create the Session and Handle Errors

       

      Use the create cloud session block. If it fails (usually because that session ID already exists), show an error and let the player try a different ID.

      5f9a234b-ed1e-42ce-8cbe-01ea925cc7b6-image.png
       
      Here’s the error message shown to the user:

      bb2e38bc-3cf4-490f-8fb8-32e73c4104b1-image.png

       
       

      Step 6 - Show a waiting message

       

      If player 1 successfully creates the session, they’ll wait for the second player to join.

      975c5066-aa8b-4d9e-82f4-38e540b43d3a-image.png

       
      The message looks like this:

      62027797-0808-4fa8-8b64-cab54fe2af30-image.png

       
       

      Step 7 - Wait for ☁ ready2 from Player 2

       

      We’ll use the cloud variable ☁ ready2 to let player 1 know when player 2 has joined. Initially, set it to 0.

      Once player 2 joins, they’ll set ☁ ready2 = 1, and player 1 will detect this change.

      2e26f356-7a3c-410b-a0c8-3c6c5b1ac7b5-image.png

       
      2681b78e-f496-4af3-842b-4aabf26d32f8-image.png

       
       

      Step 8 - Handle Player 2 Joining the Session

       

      When the second player clicks Button 2 (“Join Session”):

      • Set my team = 2 and opponent team = 1
      • Save the session ID
      • Try to join the existing cloud session

      If successful:

      • Show a “Waiting for player 1…” message
      • Set ☁ ready2 = 1 (this triggers player 1’s next step)

      If it fails, player 2 probably used the wrong ID or the session isn’t created yet.

       
      ecea004a-9699-443b-901c-7f95988cbcaf-image.png

       
       

      Step 9 - Show “Start Game” Button for Player 1

       

      Once ☁ ready2 = 1 is detected on player 1’s side, we hide the setup screen and show a new “Start Game” button.

      bfb57002-a68e-44f9-b2e9-653b5d9b71d3-image.png

       
       

      Step 10 - Start the Game

       

      When player 1 clicks “Start Game,” set the cloud variable ☁ game state = 1 to let both players know the game has started.

      Start with ☁ game state = 0 when the project loads:

      1a5818e5-b4c1-4571-801d-45a88bc618cd-image.png

       
      Then update it when the button is clicked:

      3d591b58-9c4f-4cc4-97c9-8da9517c5bd0-image.png

       
       

      Step 11 - Wait for ☁ game state = 1

       

      Once ☁ game state = 1, both players proceed.

      For player 1:

      1c28f136-528f-4164-b8d1-c37791f5e95e-image.png

       
      And for player 2:

      d2286f7d-bd46-4591-b6d8-f2a02a23ee94-image.png

       
       

      Step 12 - Show Life Count

       

      After the game begins, show each player’s life count, starting at 3. Create a block called show life count:

      9a99bf8d-4348-422d-90b0-ecfea1ca4fad-image.png

       

      • Use lives_1 and lives_2 as label names for updates.

      Call this block for both players:

      2f432994-d3f6-4135-b6a6-14b10d54c012-image.png

       
      eb9d5444-49c0-4b2e-a68c-a940563e5520-image.png

       
       

      Step 13 - Recap

       

      Let’s walk through the full connection process:

      1. Player 1 enters a unique session ID (like “1234”) and creates a cloud session. They wait for ☁ ready2 = 1.
      2. Player 2 uses the same session ID to join. If successful, they set ☁ ready2 = 1 and wait for the game to start.
      3. When player 1 sees ☁ ready2 = 1, they get a “Start Game” button. Clicking it sets ☁ game state = 1.
      4. When both players see ☁ game state = 1, they clear the setup screen and display lives.

      To test the setup on one computer:

      1. Save and share the project.
      2. Open a new incognito window, log in to creaticode.com, and open the project link.
      3. Arrange the two windows side by side.

      Or test with a friend on a different device.

       
      Here is what it looks like on 2 browsers:

      setupsession.gif

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

      Module 2 - Adding Game Objects

       

      In this module, we’ll add the main objects to the game scene, starting with the trucks and trees. To keep both players’ views identical, we’ll rely on cloud variables to make sure these objects are created in exactly the same way on both computers.

       
       

      Step 1 - Broadcast the “add trucks” message

       

      After the life count is displayed on both computers, we broadcast a message called “add trucks”:

      ec50b2dc-4ab9-40d7-a791-1ac8701ce5c2-image.png

       
      484bc863-b60b-4491-8425-56a342499f04-image.png

       
       

      Step 2 - Create Truck Clones

       
      Switch to the Truck sprite.

      Since we only use clones for gameplay, hide the original sprite when the green flag is clicked. When the sprite receives the "add trucks" message, it will create two clones, one for each player:

      43d93ad4-a13e-4bf6-a05d-5f4556771446-image.png

       
      Each clone has a unique clone ID:

      • 1 represents Player 1’s truck
      • 2 represents Player 2’s truck

      In total, there are 4 clones running across both computers: each player controls their own truck locally, and the other player sees a “mirror” clone of that truck on their computer.

       
       

      Step 3 - Initialize the Truck Clone State

       

      Every truck clone will start with a ☁ my state variable with a value of 0. This value indicates which direction the truck is moving:

      • 0: Not moving
      • 1: Moving up
      • 2: Moving down
      • 3: Moving left
      • 4: Moving right

      e907c86f-297a-4f5c-a510-598b575370dd-image.png

       
      Note that the ☁ my state variable is a cloud variable, and each truck clone has its own ☁ my state variable. The value of this variable is synchronized between the 2 clones with the same ID on the 2 computers. For example:

      If Player 1 sets clone 1’s state to 3 on their computer, the state of clone 1’s mirror on Player 2’s computer is also updated to 3, so the clone 1 truck will start moving left on both computers. Meanwhile, clone 2’s state is unaffected.

       
       

      Step 4 - Additional Truck Initialization

       

      Each truck clone should also be initialized with:

      • A life count of 3
      • A speed of 40 (feel free to change the speed)
      • A costume based on its ID (1 for yellow, 2 for red)
      • And it should be shown, since the original Truck sprite stays hidden

      bd3d5356-86db-42fa-9387-c2cb0b6f5337-image.png

       
       

      Step 5 - Set Starting Positions

       

      Now place the two truck clones in opposite corners:

      6ec4b79a-a6e9-417e-ad27-6588a8a67b0c-image.png

       
      After running the project, you’ll see the two trucks appear like this:

      07fe0e07-97e0-4d66-b65d-4b6c3ffb0855-image.png

       
       

      Step 6 - Broadcast the “add objects” message from “Setup”

       

      Back in the Setup sprite, after the trucks are added (on Player 1’s computer only), we send the "add objects" broadcast:

      f5437ada-b0b5-4b21-9c35-08898f321269-image.png

       
      Only Player 1 sends this message. Player 1’s program will decide when and where to add the objects, and then share those details with Player 2 using cloud variables.

       
       

      Step 7 - Configure the Tree Count

       

      Trees are static obstacles that block both trucks and the donuts they shoot. Use the variable tree count to define how many trees to add.

      Set this value in the Setup sprite:

      d07b4906-39d1-44f2-ad5b-3db0a6763287-image.png

       
      Then, in the Tree sprite, when it receives the "add objects" message, it checks if tree count > 0:

      aac7c68b-01a6-4f95-836a-52dc0ee02fb3-image.png

       
      Again, this part of the code runs only on Player 1’s computer after the “Start Game” button is clicked.

       
       

      Step 8 - Generate a Tree List

       

      To ensure trees appear in the same places for both players, we generate their positions on Player 1’s computer, then share them using a cloud variable.

      We use the format "x_y" for each position. A list of 2 tree positions might look like:

      120_-23_100_70
      

      Here’s how to build that list step by step:

      fad951e8-dfb4-4e92-98fd-914c6fecaefc-image.png

       
      The tree list variable starts as empty, and then we repeatedly append a random x position and a random y position to it, all using the “_” separator.

       
       

      Step 9 - Share the List Using ☁ all trees

       

      Once Player 1 has the full list, assign it to the cloud variable ☁ all trees.
      Then both computers will extract the same data and generate trees accordingly:

      2da8c79b-82f0-4f42-9669-8754be44bc89-image.png

       
       

      Step 10 - Create Tree Clones

       

      To create each clone:

      1. Extract the x and y positions from the list using the "part of by" block
      2. Move the Tree sprite to that location
      3. Create the clone

      Each tree takes up 2 entries in the list (x and y). So tree #1 uses part 1 and 2, tree #2 uses part 3 and 4, and so on.

      154735de-dd3e-4c0f-924d-65b936531c69-image.png

      4f58af6c-7060-485f-ae93-4dbd5192a4c0-image.png

       

      Use a loop to process each tree:

      5c5daf47-07c1-4284-a559-e2572533ef01-image.png

       
       

      Step 11 - Hide the Original Tree Sprite

       

      We’ll only use clones for the trees. Hide the original sprite and show each clone when it’s created:

      hide-tree-original.png

      Now, test the game—you should see identical trees on both screens:

      trees-both-sides.png

       
       

      Step 12 - Add Sugar objects

       

      Sugar objects restore a truck’s life when collected.

      Unlike trees, Sugars appear dynamically during gameplay, and may also disappear if not collected. So they’re handled differently.

      In the Sugar sprite, when "add objects" is received:

      • Start a loop to randomly generate Sugar positions
      • Each Sugar gets a unique ID
      • A cloud variable ☁ new sugar info stores "ID_x_y" for the next clone

      sugar-gen-code.png

      Key points:

      • IDs start at 1 and increment
      • Wait a random 30–90 seconds between Sugars
      • This loop runs only on Player 1’s computer

       
       

      Step 13 - Create Sugar Clones

       

      On both computers, whenever ☁ new sugar info changes, split it to get the ID and coordinates, then create a clone.

      69e6217b-8bde-49ff-91de-a34ec224fa30-image.png

       
      Before cloning, check the clone ID is “originalsprite” to avoid duplicate clones from existing ones.

      Use the first part (ID) to uniquely identify each clone.

       
       

      Step 14 - Hide the Original Sugar Sprite

       

      Just like with trees, hide the original Sugar sprite and show only its clones:

      hide-tree-original.png

       
       

      Step 15 - Auto-Delete Sugar Clones

       

      Each Sugar clone will wait 15–25 seconds. If it’s not collected, it deletes itself:

      74fca837-90a1-4927-b23a-b740087c11f7-image.png

       
       

      Step 16 - Add Gas Objects (Speed Boosts)

       

      The Gas sprite works just like Sugar, but boosts the truck’s speed instead of restoring life.

      Just duplicate the Sugar sprite’s code and adjust the variables:

      • next gas ID
      • new gas info
      • Any references to “Sugar” should be changed to “Gas”

      112d7dd6-db6d-4168-90ce-e1ae88d64e3b-image.png

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

      Module 3 - Keyboard Control of the Trucks

       

      Now that the game world is set up, it’s time to let players control their trucks using the keyboard. But remember, this is a two-player online game. That means when a player presses a key to move their truck, the same movement must happen in real-time on both computers.

      We’ll accomplish this using cloud variables to send and sync movement commands.

       
       

      Step 1 - Broadcast the “start game” Message

       

      Once all objects are added and the game is ready, we need to let both players begin controlling their trucks. In the Setup sprite, broadcast the "start game" message on both computers:

      For Player 1:

      startgame-player1.png

      For Player 2:

      startgame-player2.png

      In the Controller sprite, we’ll listen for this message and begin a forever loop to handle keyboard inputs:

      controller-loop.png

       
       

      Step 2 - Detect Key Press and Set Command

       

      Within the loop, check which arrow key the player is pressing:

      • 1: Up
      • 2: Down
      • 3: Left
      • 4: Right
      • 0: No key is pressed (stay still)

      key-detection.png

      This value is stored in the new command variable.

       
       

      Step 3 - Send the Command Only If It Changes

       

      Since this loop runs continuously (many times per second), it could end up sending the same command over and over. That’s unnecessary and wasteful. So we’ll compare the current command to the last command sent, and only send a new command when it actually changes.

      First, store the command 0 in a current command variable initially:

      set-current-command.png
       
      Then, compare it with the new command. If different, save this new command:

      compare-command.png

       
       

      Step 4 - Send the Command to the Correct Truck

       

      Each player controls one of the two trucks. Player 1 controls truck 1, and player 2 controls truck 2. On both computers, both trucks exist, so we need to ensure that only the correct truck clone receives the command from the player.

      Here’s how we’ll do it:

      • Use the my team variable (1 or 2) to send a message with that same number
      • Attach the new command as the parameter (we have made sure this is different from before)

      So Player 1 will send message "1" with the command, and Player 2 will send "2":

      c49bb7cd-1aaf-4c14-9a8c-a82769961baa-image.png

       
       

      Step 5 - Let the Correct Truck Handle the Command

       

      Switch to the Truck sprite.

      All truck clones (ID 1 and ID 2) will receive the message "1" or "2", but only the clone with the matching ID should actually respond. Use an if block to check the clone ID.

      Then define a custom block called handle command that will process the movement:

      handlecommand-block.png

      So if Player 1 presses a key:

      • On Player 1’s computer, Truck 1 responds and updates its state.
      • On Player 2’s computer, Truck 1’s mirror will also update its state.

      This keeps both trucks behaving identically on both screens.

       
       

      Step 6 - Set ☁ my state Cloud Variable

       

      Inside the handle command block, set the cloud variable ☁ my state to the command value:

      set-my-state.png

      Each truck clone owns its own cloud variable. This variable is not visible to other clones or sprites locally—but because it’s a cloud variable, the value is automatically shared with the other player’s computer.

      So the state of a truck is immediately synced across both computers. That’s how both players see the exact same movement for the same truck.

       
       

      Step 7 - Calculate Travel Duration and Distance

       

      Now we’ll build the movement loop. To ensure that truck speed is consistent across fast and slow computers, calculate how much time has passed between iterations of the loop using the timer.

      Use that to determine how far the truck should travel:

      calculate-timer-distance.png

      For example:

      • On a fast computer, the loop might run 40 times/sec, so travel duration ≈ 0.025
      • On a slower one, maybe 20 times/sec, so travel duration ≈ 0.05

      Multiply speed by time to get consistent movement regardless of computer speed.

       
       

      Step 8 - Move the Truck Up (State = 1)

       

      Now use that travel distance to move the truck in the right direction. Start by handling state 1 (move up)

      391fc6b3-60db-4cce-b52f-980d9651ad12-image.png

       
       

      Step 9 - Move in the Other Directions (States 2–4)

       

      Repeat this logic for states 2 (down), 3 (left), and 4 (right):

      move-234.png

      No need to handle state 0 directly—if no key is pressed, the truck simply doesn’t move.

       
       

      Step 10 - Undo Movement if Hitting a Tree or Edge

       

      If the truck hits a tree or touches the edge, immediately reverse the last movement:

      reverse-hit.png
       
      Put this logic at the top level inside the loop, so it always runs on every frame, regardless of what state the truck is in.

       
       

      Step 11 - Sync Position When Truck is Idle (Command = 0)

       

      Even with identical movement commands, trucks can drift out of sync over time due to slight timing delays. Here’s why:

      Imagine Player 1 moves the yellow truck up, then presses right. The command is instantly executed on Player 1’s computer. But there’s a small delay (maybe 0.1 seconds) before that command reaches Player 2. So on Player 2’s screen, the yellow truck moves slightly farther up before turning.

      To fix this, whenever a truck receives command 0 (no movement), we broadcast its exact position to the other computer using a cloud variable ☁ my x y (formatted like "x_y"😞

      sync-on-idle.png
       
      Then, when the other computer receives this update, the matching truck clone updates its position smoothly:

      receive-sync.png

      This ensures both versions of the truck stay visually aligned.

       
       

      Step 12 - Sync Position When Truck Hits Obstacle

       

      When a truck hits a tree or an edge, it should stop moving—and sync its corrected position to the other computer. You can reuse the handle command block by calling it with command 0.

      But only the truck being controlled locally by the player should do this, because only that version has the accurate position. Add this logic inside the collision detection block, not at the top level:

      sync-on-stuck.png

      Now, both players will always see exactly the same movement, even when a truck hits trees or stop moving.

      Here’s a demo of it in action:

      insync.gif

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

      Module 4 - Collecting Items

       

      In this module, we’ll enable the trucks to collect Sugar and Gas items, which can increase the truck’s life or boost its speed. When a truck picks up one of these items, we need to make sure the effect happens only once, and that it syncs across both computers.

      This means the item should disappear at the same time on both screens, and the truck’s speed or life must update only on the player’s own truck (not the mirrored one).

      Let’s go step by step.

       
       

      Step 1 - Detect Touching the Sugar

       

      Start in the Truck sprite.

      We’ll use the “when touching [object]” block to detect when the truck touches a Sugar clone. But there’s an important detail: each computer has two trucks (clone ID 1 and 2), and we only want the truck controlled by the local player to handle the collection.

      So first, check that my team matches the truck’s clone ID. That ensures only the player’s truck reacts:

      truck-touch-sugar.png

      If you don’t do this check, both the original truck and its remote mirror might react, and the item could be collected twice incorrectly.

       
       

      Step 2 - Notify Which Sugar Was Collected

       

      When a Sugar item is collected, we want both computers to delete that Sugar clone. Since each Sugar clone has a unique ID, we can use a cloud variable to broadcast that ID.

      Set ☁ sugar being collected to the ID of the clone that was touched:

      set-sugar-being-collected.png

      Once this variable changes, every copy of the Sugar sprite (on both computers) will be notified.

       
       

      Step 3 - Increase Truck’s Life (Max 3)

       

      After collecting a Sugar item, the player’s truck should gain one life—but only if its current life is less than 3.

      Here’s the code to do that:

      increase-life.png
       
      This check prevents the truck from going above the max life limit.

       
       

      Step 4 - Delete the Correct Sugar Clone

       

      Now switch to the Sugar sprite.

      We want only the clone with the matching ID to delete itself when ☁ sugar being collected changes. Use the when [cloud variable] changes hat block, and compare the clone’s ID with the new value:

      delete-sugar-clone.png
       
      This event runs on both computers, but only the matching clone actually deletes itself.

      To make this detection work reliably, set ☁ sugar being collected to an invalid ID at the beginning of the game, like -1 or "none":

      init-sugar-variable.png
       
      If you skip this step, the first clone might mistakenly delete itself before anything has been collected.

      Now test it out: try adjusting the Sugar spawn delay to appear more frequently so you can quickly see the effect during testing:
       
      sugarcollect.gif

       
       

      Step 5 - Handle Touching Gas Objects

       

      Back in the Truck sprite, we’ll use similar logic to handle collecting Gas objects. These do not increase life—they increase the truck’s speed instead.

      Duplicate the Sugar collection code and change it to work with Gas. When touched, increase the speed variable of the truck:

      touch-gas.png
       
      Again, remember to only allow the local player’s truck to trigger the collection.

       
       

      Step 6 - Delete the Gas Clone

       

      In the Gas sprite, add logic similar to Sugar. When the cloud variable ☁ gas being collected changes, compare its value to each clone’s ID. If it matches, delete the clone:

      delete-gas.png
       
      And just like with Sugar, initialize this variable to an invalid value at the start:

      init-gas-variable.png
       
      This avoids accidental deletions or unexpected behavior.

      Once you’ve added this code, try testing the collection of both Sugar and Gas. Make sure:

      • Only one truck can collect the item (not the mirror)
      • The effect applies only to that truck
      • The item disappears on both screens

      This logic is essential for keeping both players’ games perfectly in sync.

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

      Module 5 - Shooting Donuts

       

      In this module, we’ll let players shoot donuts from their trucks. Donuts travel in a straight line and disappear when they hit a tree, the edge of the stage, or the opponent truck. If a donut hits the opponent’s truck, it will lose a life. As always, everything must stay synchronized between both players’ computers.

      Let’s walk through each part of the shooting mechanic.

       
       

      Step 1 - Detect SPACE Key to Fire

       

      In the Controller sprite, add a condition to detect when the player presses the SPACE key. When that happens, broadcast a "shoot donut" message.

      ca2b8092-5090-4b15-909b-b736e2739c68-image.png

       
       

      Step 2 - Only Original Donut Handles the Message

       

      Switch to the Donut sprite. When the "shoot donut" message is sent out, it will be received by both the original Donut and all its clones. So, add a check to make sure only the original sprite handles it:

      a863f526-6d52-4546-98c2-96f02939cc71-image.png

       
       

      Step 3 - Limit Shooting Frequency

       

      To prevent players from spamming the SPACE key, introduce a cooldown. Create two variables:

      • donut_time: last time a donut was fired
      • donut_interval: minimum wait time between shots (e.g., 1 second)

      Initialize them like this:

      donut-time-init.png
       
      And check the current timer value before allowing a new shot:

      7db53c54-f190-4c4a-bfc2-b9f77239f0e7-image.png

       
       

      Step 4 - Get truck position and direction

       

      A donut should appear at the front of the truck, facing the same direction. Use the sensing blocks to get the x/y position and direction of the truck the player is controlling:

      get-truck-position.png
       
      Use my team to access the truck clone ID that matches the player.

       
       

      Step 5 - Track Donut ID

       

      Each donut clone should have a unique ID. Use a variable next donut ID, initialized to 0:

      init-donut-id.png

      Increase it by 1 with each new shot:

      7925599a-d71d-4c97-a97e-9d27534d9a8a-image.png

       
       

      Step 6 - Create ☁ new donut command

       

      Use a cloud variable ☁ new donut command to let both computers know a new donut was fired.

      Its format will be:

      playerID_direction_x_y_donutID

      Start with the direction 90 (right). Offset the x-position by 35 so the donut doesn’t touch the truck that fired it:

      8b2df66f-6d40-4f73-a2da-5d0189496cbe-image.png

       
       

      Step 7 - New donut commands for the other three directions

       

      Repeat the same logic for directions:

      • 0 (up): adjust y
      • 180 (down): adjust y
      • 270 (left): adjust x

      b11bf926-5d97-4fc4-8539-e5f35880a2dc-image.png

       
       

      Step 8 - Handle updates in ☁ new donut command

       

      When the cloud variable ☁ new donut command changes, both computers will create a new donut clone.

      Make sure only the original Donut sprite handles this:

      c414302c-3fe0-4f77-8ea1-fc07a72bb8d3-image.png

       
       

      Step 9 - Extract Donut Info

       

      Split the command string into 2 parts and store them:

      • owner team: the shooting player
      • my direction: the direction the donut should move in

      c7d9a2d3-551a-4934-a574-abdca16d07d8-image.png

       
       

      Step 10 - Move Donut to Position and Set Angle

       

      Move the original Donut sprite to the target position and direction. The clone will inherit this when it’s created:

      a0e3f559-856b-45f0-808f-962cc39111f4-image.png

       
       

      Step 11 - Create the Donut Clone

       

      Now create the donut clone. Its ID will be a combo of the player’s ID and the sequence number:

      c80015ee-0406-4755-a88d-ec1761887c06-image.png

       
       

      Step 12 - Set Costume by Team

       

      Set the donut costume based on the player who fired it:

      ff0b0c44-15f0-4727-8309-b05718c2078d-image.png

       
       

      Step 13 - Hide the Original Donut Sprite

       

      Only clones should be visible. The original Donut stays hidden:

      fcefe505-18da-4679-93ee-73c26a4ff6cf-image.png

      16aad3ca-23c6-46ef-9a7d-ba7776735fc5-image.png

       
       

      Step 14 - Calculate Travel Distance Based on Timer

       

      Just like trucks, donuts should move consistently across fast and slow computers. Use the timer and a constant speed (e.g. 150) to calculate how far each donut moves every frame:

      donut-travel-distance.png

      Each clone tracks its own prev time and travel distance.

       
       

      Step 15 - Move the Donut

       

      Move the donut in its set direction using the calculated distance:

      e00ba132-02f3-4bb0-8e93-dc61fea43c64-image.png

       
       

      Step 16 - Delete on Tree or Edge (Only on Owner’s Side)

       

      Only the player who owns the donut should check for collisions (to avoid false positives due to lag). If a donut touches a tree or the edge:

      • Set ☁ donut to delete to its ID
      • Both computers delete the clone when this variable updates

      0ab2eef4-235d-496b-8513-303c10da800a-image.png

       
       

      Step 17 - Detect Hitting the Opponent

       

      If the donut hits the opponent truck, do the same thing: set a cloud variable ☁ donut hitting target to the donut’s ID:

      6835d348-d1aa-4586-baf9-d1383f1ebd90-image.png

       
       

      Step 18 - Delete the Donut

       

      In the Donut sprite, when ☁ donut to delete updates, each clone compares its ID and deletes itself if it matches:

      aaa08493-cff5-4532-a8d4-b1230d40729b-image.png

       
       

      Step 19 - Handle Opponent Hit

       

      Similarly, when ☁ donut hitting target changes, the matching clone:

      1. Sends a truck hit message with the opponent truck’s ID. For example, if this clone’s team is 1, then the opponent team’s ID is 2 (3 - 1).
      2. Deletes itself

      99bfd34d-57ce-4346-855a-9ac03c501ac3-image.png

       
       

      Step 20 - Truck Handles “truck hit”

       

      In the Truck sprite, handle this message carefully:

      Only the truck that got hit, and only on its own player’s computer, should reduce its life by 1.

      Use two checks:

      • clone ID = truck being hit
      • my team = owner of this truck

      truck-hit-checks.png
       
      Then update ☁ my lives, which is mirrored on both computers.

       
       

      Step 21 - React to Changes in ☁ my lives

       

      Each truck that shares that cloud variable will react when ☁ my lives is updated.

      Make sure the game has started (game state is 1):

      52292a20-0798-4591-9b81-108863d8ea51-image.png

       
       

      Step 22 - Compare Life Count

       

      Use a separate variable prev my lives (initially 3) to compare the new life count to the previous one:

      5cc07434-3c0a-4e68-8523-ae922d7efbb6-image.png

       

      dfde5a30-496f-4f1f-b4bd-98a0ba752c48-image.png

       
       

      Step 23 - Play Sound Effect

       

      Play different sounds for gaining vs. losing lives:

      93767c74-c89b-47e9-82e8-4fffe51029f2-image.png

       
       

      Step 24 - End the Game if Lives = 0

       

      If the truck’s life count drops to zero, end the game. This check happens on both computers:

      8018a2f8-a3c6-4462-9999-ca5be2402b16-image.png

       
       

      Step 25 - Show the Winner

       

      Before stopping the game, show a message announcing who won:

      If truck ID = 1, then player 2 wins. If it’s 2, then player 1 wins:

      show-winner.png

       
      Here is a full demo of the game:

      finaldemo.gif

       
       
       
       
       
       
       
       
       
       

      Additional Challenges

       

      The game you’ve built so far is a fully functional 2-player battle, but there’s plenty of room to expand and experiment. The main goal of this project was to demonstrate how cloud variables and clones can be used to build a multiplayer game where each player runs the same project on their own computer, and everything stays in sync.

      Once you’ve got the basic mechanics working, here are some ways you can extend and improve the game. These ideas range from simple tweaks to major redesigns—try one or try them all.


      🔹 Firepower Reward

      You’ve already added Sugar and Gas as collectible items. Now try adding a third type of reward that affects the player’s shooting ability.

      What to do:

      • Create a new sprite for a Firepower item
      • When collected, reduce the cooldown time between donuts (e.g., from 1 second to 0.5 seconds)
      • Use a new cloud variable to sync this change across both computers
      • Maybe even show a temporary fire effect or shooting animation

      This reward adds more strategy and makes collecting items more impactful.


      🔹 Shrinking Arena

      To prevent players from hiding or running away forever, you can create a shrinking play area—similar to battle royale games.

      How it works:

      • Add invisible wall sprites that slowly move inward from the edges of the stage
      • These walls can appear every 10 seconds or after a certain time has passed
      • If a truck touches a wall, it loses a life or takes damage

      This forces players toward the center of the stage over time, making the game more intense and guaranteed to end eventually.


      🔹 2 vs. 2 Team Game

      This is a major upgrade: turn your 2-player battle into a 4-player team battle, with two players on each team.

      What changes:

      • Four players will join the same cloud session, each with their own truck (clone IDs 1 to 4)
      • Players 1 and 2 are on Team Yellow, and Players 3 and 4 are on Team Red
      • Each player only controls their own truck, but it has 3 mirror trucks on the other 3 computers
      • Donuts can damage players from the opposite team, but not teammates
      • The game ends when both trucks from one team have lost all their lives

      What you’ll need to update:

      • Session setup screen to support 4 unique player IDs
      • Truck spawning logic to handle 4 clones and assign them to teams
      • Donut logic to check for friendly fire and block it
      • Life tracking and win condition logic to check if both teammates are eliminated
      • Display a win message like “Red Team Wins!” when the condition is met
      1 Reply Last reply Reply Quote 0
      • Pinned by  info-creaticode info-creaticode 
      • First post
        Last post