Variables

Variables are storage containers for data values used within a programming language. Variables can be useful when changing preferences, selecting a background, creating animations, and changing assets in game programming.

Variable Inputs

To obtain data from user and save into a JavaScript variable requires the use of HTML.

The <input> HTML element is used to create interactive controls for web-based forms in order to receive data from the user.

  • Geeks for Geeks Referece on input tag
  • Remember in Jupyter Notebooks and in GitHub Pages we do not use <head> and <body> tags.
  • Additionally, we prefer using SASS for <style> in GitHub Pages.

Variable Outputs

To output a variable in JavaScript it works in combination with HTML as well. To output the variable game_speed or any errors it requires that outputs to be placed in the Document Object Model (DOM).

Additionally, it is common practice in debugging a program to output to console.log.

To view DOM and Developer Outputs

  • Open Help -> Toggle Developer Tools
  • Go to Console menu, you can clear console to view outputs from console comands in this cell
  • To see DOM go to Elements tab and use selector and click on output in this window.
%%html 

<!-- Input definitions -->
<div>
  <label for="speed">Adjust Speed (1-5):</label>
  <input type="number" id="speed" name="speed" min="1" max="5" value="2">
  <button onclick="submitSpeed()">Submit</button>
</div>

<!-- Document Object Model (DOM) output locations -->
<div id="output"></div>
<div id="error"></div>

<script>
  // Function to validate and output the game speed value
  function submitSpeed() {
    let gameSpeed = document.getElementById('speed').value;
    
    // Ensure the value is within the allowed range
    if (gameSpeed < 1 || gameSpeed > 5) {
      // Set/clear output messages when there is an error
      document.getElementById('output').innerHTML = "";
      // Output an error message to the console
      console.error("Invalid game speed value:", gameSpeed);
      // Output an error message to the HTML page
      document.getElementById('error').innerHTML = "Invalid game speed value: " + gameSpeed;
    } else {
      // Set/clear error messages when the value is valid
      document.getElementById('error').innerHTML = "";
      // Output the game speed value to the console
      console.log("Game speed set to:", gameSpeed);
      // Output the game speed value to the HTML page
      document.getElementById('output').innerHTML = "Game speed set to: " + gameSpeed;
    }
  }
</script>

Variable Naming Conventions

  • camelCase In camel case, the first word is lowercase, and the first letter of the remaining words are uppercase: gameSpeed
  • snake_case In snake casse, the words in variables are all lowercase and are separated by a underbar: game_speed
  • PascalCase In PascalCase, the first letter in the word is capitalized: GameSpeed

In JavaScript, there will be usage of all three types in the RPG project.

Variables containing Variables (Reference Types)

There are variables that contain other variables. These are called reference types.

  • JSON Objects: These variables contain key names and associated values (key-value pairs). The key is used for reference and the value contains the data.
    • Key: This is similar to a variable name. The key describes the value and is followed by a colon.
    • Value: The value is associated with the key.
    • Sample Definition: let gameAttribute = {"Speed": 3, "Avatar": "Mario"}
    • Sample Reference: gameAttribute["Speed"]
    • Sample Output from Reference: 3
  • JSON Arrays: These variables contain a sequence of values.
    • Sample Definition: let scoreHistory = [50, 75, 66, 80, 100, 85]
    • Sample Reference: scoreHistory[2]
    • Sample Output from Reference: 66
%%js

// Reference Type example
// Open VSCode Help -> Toggle Developer Tools -> Console

// JSON Object
let gameAttribute = {
    "Speed": 3,
    "Avatar": "Mario"
};

// Accessing JSON Object values
console.log("Speed:", gameAttribute["Speed"]); // Output: Speed: 3
console.log("Avatar:", gameAttribute["Avatar"]); // Output: Avatar: Mario

// JSON Array
let scoreHistory = [50, 75, 66, 80, 100, 85];

// Accessing JSON Array values
console.log("Score at index 2:", scoreHistory[2]); // Output: Score at index 2: 66
<IPython.core.display.Javascript object>

Variable Naming Convention Hack

Search up naming convention for JavaScript. Conventions are important to easily recognize purpose of definitions.

  1. Usage of camelCase. What is standard?
  2. Usage of UPPER_CASE snake_case. What is standard?
  3. Usage of PascalCase. What is standard?

Variable Naming Convention Hack Response

In JavaScript, different naming conventions typically indicate the intended use of variables, functions, and classes. Here’s how camelCase, snake_case, PascalCase, and UPPER_SNAKE_CASE are generally used:

1. camelCase:

  • Usage: Used for variables, function names, and object properties.
  • Example: myVariable, doSomething(), imageHeight
  • Indicates: This is the most common naming convention for variables and functions in JavaScript, and it suggests that the value or function can be modified.

2. snake_case:

  • Usage: Less common in JavaScript but can sometimes be used for constants or keys in objects, especially in configurations or when interacting with non-JS systems (e.g., databases).
  • Example: api_response, user_id
  • Indicates: Used for readability in contexts like JSON data or configuration files, but generally avoided in native JavaScript code for variables and functions.

3. PascalCase:

  • Usage: Typically used for class names and constructors.
  • Example: GameControl, MyClass, AppController
  • Indicates: A PascalCase name suggests that the item is a constructor function or class, representing an entity that can be instantiated (i.e., new MyClass()).

4. UPPER_SNAKE_CASE (also known as CONSTANT_CASE):

  • Usage: Used for constants that do not change during the execution of the program.
  • Example: MAX_HEIGHT, API_KEY
  • Indicates: This is meant to convey that the value is a constant, and changing it in the code would be unexpected.

Summary of Usage:

  • camelCase: Variables, function names, and object properties.
  • snake_case: Rarely used for variables, but common in external systems or configurations.
  • PascalCase: Classes, constructors, or special types of objects.
  • UPPER_SNAKE_CASE: Constants or values that remain unchanged.

These conventions help signal the role and usage of variables and functions within the code, improving readability and maintainability.

RPG Project Hack

Identify naming convention and data type used in this code. Which items would you change according to your research on naming conventions? What are the data types? Change names and provide comments to to describe data types and name convention changes.

  1. Make a new code cell to make it easy to compare before and after.
  2. Figure out naming convention for Key-Values items. Source and share your reference.
import GameControl from '/hamin/assets/js/rpg/GameControl.js';

// Background data
const image_src = "/hamin/images/rpg/water.png";
const image_data = {
    pixels: {height: 580, width: 1038}
};
const image = {src: image_src, data: image_data};

// Sprite data
const sprite_src = "/hamin/images/rpg/turtle.png";
const sprite_data = {
    SCALE_FACTOR: 10,
    STEP_FACTOR: 1000,
    ANIMATION_RATE: 50,
    pixels: {height: 280, width: 256},
    orientation: {rows: 4, columns: 3 },
    down: {row: 0, start: 0, columns: 3 },
    left: {row: 1, start: 0, columns: 3 },
    right: {row: 2, start: 0, columns: 3 },
    up: {row: 3, start: 0, columns: 3 },
};
const sprite = {src: sprite_src, data: sprite_data};

// Assets for game
const assets = {image: image, sprite: sprite}

// Start game engine
GameControl.start(assets);

RPG Game Project Hack Response

import GameControl from '/hamin/assets/js/rpg/GameControl.js';

// Background image data
const BACKGROUND_IMAGE_SOURCE = "/hamin/images/rpg/water.png"; // Constant, UPPER_SNAKE_CASE for unchanging values
const backgroundImageData = { 
    dimensions: {height: 580, width: 1038} // camelCase, as it's variable data
};
const backgroundImage = {src: BACKGROUND_IMAGE_SOURCE, data: backgroundImageData};

// Sprite data
const SPRITE_IMAGE_SOURCE = "/hamin/images/rpg/turtle.png"; // Constant, UPPER_SNAKE_CASE for unchanging values
const spriteDetails = {
    scaleFactor: 10,          // camelCase for variables
    stepIntervalMs: 1000,     // camelCase for time intervals, clearer naming
    animationRateMs: 50,      // camelCase, includes time unit for clarity
    dimensions: {height: 280, width: 256},  // camelCase for object properties
    orientation: {rows: 4, columns: 3 },    // camelCase for multi-value objects
    down: {row: 0, start: 0, columns: 3 },  // directional data remains camelCase
    left: {row: 1, start: 0, columns: 3 },
    right: {row: 2, start: 0, columns: 3 },
    up: {row: 3, start: 0, columns: 3 },
};
const spriteImage = {src: SPRITE_IMAGE_SOURCE, data: spriteDetails};

// Game assets
const gameAssets = {backgroundImage, spriteImage};  // camelCase for variable names

// Start game engine
GameControl.start(gameAssets);

Code Block Hack

Make a new code block for some game elements that you have in your “Ideation”.

Code Block Hack Response

Here’s an idea I had (which does not actually describe the working game environment, but works as a good example):

class Enemy {
    constructor(x, y, speed) {
        this.x = x;                 // Enemy's initial X position
        this.y = y;                 // Enemy's initial Y position
        this.speed = speed;         // Enemy's speed (pixels per frame)
        this.targetX = 0;           // Player's X position (to be updated in real-time)
        this.targetY = 0;           // Player's Y position (to be updated in real-time)
    }

    // Method to update the enemy's target (player's location)
    updateTarget(playerX, playerY) {
        this.targetX = playerX;
        this.targetY = playerY;
    }

    // Method to calculate direction and move the enemy toward the player
    chasePlayer() {
        // Calculate the difference in position between the enemy and the player
        const deltaX = this.targetX - this.x;
        const deltaY = this.targetY - this.y;

        // Calculate the distance between the enemy and the player
        const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2);

        // Normalize the difference and apply speed to move towards the player
        const moveX = (deltaX / distance) * this.speed;
        const moveY = (deltaY / distance) * this.speed;

        // Update enemy's position
        this.x += moveX;
        this.y += moveY;
    }

    // Method to render the enemy on the canvas (if you're using one)
    render(ctx) {
        ctx.fillStyle = 'red';  // Enemy color
        ctx.fillRect(this.x, this.y, 50, 50);  // Example enemy size (50x50)
    }
}

// Example of game loop where the enemy chases the player
function gameLoop(player, enemy, ctx) {
    // Update player's position (assumed player object has x and y coordinates)
    const playerX = player.x;
    const playerY = player.y;

    // Update the enemy's target position (player's location)
    enemy.updateTarget(playerX, playerY);

    // Move the enemy towards the player
    enemy.chasePlayer();

    // Clear the canvas (assuming you're using canvas)
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // Render the player and the enemy (assuming player has a render method)
    player.render(ctx);
    enemy.render(ctx);

    // Loop the game
    requestAnimationFrame(() => gameLoop(player, enemy, ctx));
}

// Initialize the enemy and player (assuming player exists)
const enemy = new Enemy(100, 100, 2);  // Enemy starts at (100, 100) with speed of 2 pixels per frame
const player = new Player(300, 300);   // Player starts at (300, 300)

// Start the game loop (assuming you have a 2D context "ctx" from a canvas)
gameLoop(player, enemy, ctx);