Skip to content

[game] User Guide

Gokul Rajiv edited this page Oct 3, 2023 · 5 revisions

Game Module

Documentation

Check out the module's documentation for more information on specifications of exposed functions.

Game Lifecycle Functions

The Source Academy game module, is a wrapper of Phaser 3 API, which the Source Academy game uses.

It is first important to understand the 3 functions preload(), create(), and update() that Phaser uses for defining behaviour at different stages of a game scene's lifecycle:

  • Preload: Used to load game assets before Create
  • Create: Used to create your game objects (and add them to the scene) after the game scene starts
  • Update: Used to update game object states, and called once every game step while the scene is running

You will be defining these 3 functions for modifying your room's behaviour.

Writing your room code

To customize your room with your own room code:

  1. Navigate to the room customization assessment (usually in the Others section).
  2. Open the room in-game on a separate tab (Go to My Room in the game component).
  3. As you write and save your room code, you can refresh your room and view the changes.

Tips:

  • Run your program in the editor first as a sanity check to catch basic syntax errors. As a second check, you can refresh your in-game room. If that doesn't work, you can try refreshing the whole page. If none of these work, then there might be something wrong with your program.
  • Game module functions won't work outside of the game, as they are converted to nullary functions. So, don't be surprised that they don't work in the editor (you might get an error message about wrong arguments if you do). Usually, we'll wrap game module functions in other functions (like the lifecycle functions), so that they won't be applied when we press run.

Source Academy assets

You can make use of the following Source Academy room assets to kickstart your room customization process. Of course, you can also use your own.

Source Academy assets can be found at https://source-academy-assets.s3-ap-southeast-1.amazonaws.com/{postpend}.

e.g: https://source-academy-assets.s3-ap-southeast-1.amazonaws.com/objects/cmr/alienCat.png

You can also use the prepend_remote_url module function for Source Academy assets (as shown in the later examples).

e.g: prepend_remote_url("objects/cmr/alienCat.png")

postpend asset
objects/cmr/alienCat.png alienCat
objects/cmr/catPlushie.png catPlushie
objects/cmr/emoGhost.png emoGhost
objects/cmr/lavaLamp_blue.png lavaLamp_blue
objects/cmr/lavaLamp_orange.png lavaLamp_orange
objects/cmr/lavaLamp_purple.png lavaLamp_purple
objects/cmr/plant01.png plant01
objects/cmr/plant02.png plant02
objects/cmr/plant03.png plant03
objects/cmr/plant04.png plant04
objects/cmr/splendall.png splendall

Examples

Example 1: Moving In

In this example, we'll be adding some objects to our room to make it our own.

import { 
    add,
    create_image, 
    get_screen_height,
    get_screen_width, 
    load_image,
    prepend_remote_url,
    set_display_size
} from 'game';

function preload() {
    // load background
    load_image("room", prepend_remote_url("locations/preview/[email protected]"));
    
    // load objects
    load_image("cat", prepend_remote_url("objects/cmr/alienCat.png"));
    load_image("plushie", prepend_remote_url("objects/cmr/catPlushie.png"));
    load_image("lavaLamp", prepend_remote_url("objects/cmr/lavaLamp_blue.png"));
    load_image("plant", prepend_remote_url("objects/cmr/plant04.png"));
    load_image("splendall", prepend_remote_url("objects/cmr/splendall.png"));
}

function create() {
    // Useful constants
    const width = get_screen_width();
    const height = get_screen_height();
    const center_x = width / 2;
    const center_y = height / 2;
    
    // Create background 
    const image = create_image(center_x, center_y, "room");
    const image_resized = set_display_size(image, width, height);

    // Objects
    const cat = create_image(1.1*center_x, 1.8*center_y, "cat");
    const plushie = create_image(0.15*center_x, 1.5*center_y, "plushie");
    const lavaLamp = create_image(0.7*center_x, 1.15*center_y, "lavaLamp");
    const plant = create_image(1.9*center_x, 1.3*center_y, "plant");
    const splendall = create_image(1.3*center_x, 1.15*center_y, "splendall");
    
    // Add background and objects to scene
    add(image_resized);
    add(cat);
    add(plushie);
    add(lavaLamp);
    add(plant);
    add(splendall);
}

function update() {
    // Your code here
}

In this simple example, we first load our image assets in the preload function. Then in the create function we create and add the images to the scene.

image

Example 2: Fireworks Clicker

import { 
    add,
    add_listener,
    add_tween,
    create_anim,
    create_anim_config,
    create_anim_spritesheet_frame_configs,
    create_config,
    create_image, 
    create_spritesheet_config,
    create_text,
    create_text_config,
    create_tween_config,
    destroy_obj,
    get_screen_height,
    get_screen_width, 
    load_image,
    load_spritesheet,
    play_anim_on_image,
    prepend_remote_url,
    set_display_size,
    set_interactive,
    set_origin,
    set_scale
} from 'game';

// Game module functions should not be evaluated
// directly in the editor when run. So, we wrap
// it in a nullary function.
const scene_text_config = () => 
    create_config(list(["fontFamily", "Arial"],
                       ["fontSize", "60px"],
                       ["backgroundColor", "#000"],
                       ["color", "#fff"],
                       ["align", "center"]));
    
// Adds text with given text string
function set_text(gameObj, text, x, y) {
    destroy_obj(gameObj);
    gameObj = create_text(x, y,
                        text,
                        scene_text_config());
    set_origin(gameObj, 0.5, 0.5);
    add(gameObj);
    return gameObj;
}

function preload() {
    const spritesheet_config = create_spritesheet_config(45, 44, 0, 0, 0);
    load_spritesheet('fireworks', prepend_remote_url("objects/cmr/fireworks.png"), spritesheet_config);
    load_image("galaxy", prepend_remote_url("locations/galaxy/normal.png"));
}

function create() {
    // Useful constants
    const width = get_screen_width();
    const height = get_screen_height();
    const center_x = width / 2;
    const center_y = height / 2;
    
    // Variable to keep track of number of clicks
    let clickCount = 0;
    
    // Create background 
    const image = create_image(center_x, center_y, "galaxy");
    const image_resized = set_display_size(image, width, height);
    set_interactive(image_resized);
    
    // Create animations
    const fireworks_anim_config = create_anim_config(
        'fireworks-explode',
        create_anim_spritesheet_frame_configs('fireworks'),
        24, null, 0, false, true, false
    );
    create_anim(fireworks_anim_config);
    
    // Initialize centre text
    let centre_text = create_text(center_x, center_y,
                         "Click anywhere on the screen!",
                         scene_text_config());
    set_origin(centre_text, 0.5, 0.5);
    
    // Set up pointerdown listener
    add_listener(image_resized, 'pointerdown', (p, x, y, e) => {
        // Create fireworks
        const fireworks = create_image(x, y, 'fireworks');
        set_scale(fireworks, 4, 4);
        const fireworks_tween_config = create_tween_config(
            'alpha',
            0,
            0,
            1000,
            'Power1',
            (tw, tar) => { // tween onEnd callback
                destroy_obj(fireworks);
            });
        add_tween(fireworks, fireworks_tween_config);
        add(fireworks);
        play_anim_on_image(fireworks, 'fireworks-explode');
        
        // Set click count
        clickCount = clickCount + 1;
        centre_text = set_text(centre_text,
            stringify(clickCount),
            center_x,
            center_y);
    });
    
    // Add background and text to scene
    add(image_resized);
    add(centre_text);
}

function update() {
    // Your code here
}

This example is a little (but not much) more complicated than example 1. In this example, we want to keep track of the number of user clicks and display this number. The complexity in this example comes from needing to appropriately respond to user input. Let's take a closer look at some interesting bits from the program above.

Setting up the pointerdown listener: Most of the heavy lifting in this program takes place in the pointerdown listener callback function:

(p, x, y, e) => {
  // Create fireworks
  ...
};

This function is called every time the image is clicked, and is called with the arguments p (pointer), x (x-coord), y (y-coord), and e (event). We're interested in the x, and y coordinates so that we can spawn the fireworks animation at the click point. We also add a tween (short for inbetweening) to the image to fade out the image after 1 second (by reducing the alpha value). At the end of the tween we use a callback function to destroy the image object, since we won't need it anymore. After we add the fireworks to the scene, we increment our counter of user clicks, and update the display text.

create_config: You may have noticed that there exists a create_text_config function from the game module documentation. We can certainly use this function for creating our text configs. However, there could be aspects of the text that this function doesn't allow you to change, like the text background. If you refer to the Phaser text configuration options, you'll find that Phaser does in fact allow you to change background color. create_config allows us to create our ObjectConfigs manually with a list of key-value pairs as shown in the example. You can find officially supported configuration options in the game module documentation.

image

Clone this wiki locally