Computer Science & Software Engineering
Intro to Javascript
JavaScript Overview
JavaScript is the primary programming language students use to move from learning to code to building real software systems. Because it runs directly in the browser and connects naturally with HTML, CSS, APIs, databases, and server-side technologies, it provides a foundation for the Open Coding Society learning progression.
Students begin with games and interactive experiences, progress to projects that address real-world problems, build systems used by people and organizations, and ultimately conduct independent research and development through the Honors Capstone.
Games → Projects → Systems → Research
To support this progression, students will now move from using JavaScript in applications to learning the fundamental concepts of the language itself.
Why JavaScript Is Used
-
Client-Side Interactivity: JavaScript allows web applications to respond immediately to user actions, including input, clicks, keyboard events, animation, and game interactions.
-
Web Integration: JavaScript works with HTML and CSS to create complete interactive experiences. Students will also explore tools such as SASS to support the development of larger and more maintainable interfaces.
-
Full-Stack Development: JavaScript can connect the user interface to APIs, databases, and server-side systems, allowing students to progress from individual applications to complete software systems.
Distinct Properties
- Dynamic Typing: Variables can hold values of different types during program execution.
- Prototype-Based Objects: JavaScript objects can inherit behavior from other objects. Modern JavaScript also provides
classsyntax for organizing object-oriented programs. - Event-Driven Programming: Programs can respond to user actions and other events such as clicks, keyboard input, and game events.
- Asynchronous Programming: Callbacks, promises, and
async/awaitallow programs to handle tasks such as API requests without blocking the application. - First-Class Functions: Functions can be stored in variables, passed as arguments, and returned from other functions.
Core Concepts
-
Variables & Scope: Using
letandconstto store data and control where variables can be accessed. -
Data Types: Working with primitive values such as numbers, strings, booleans,
null, andundefined, as well as objects. -
Control Structures: Using conditionals and loops to make decisions and repeat operations.
-
Functions: Organizing code into reusable units that can receive input and return results.
-
Objects & Object-Oriented Programming: Modeling data and behavior together to create more complex applications and systems.
-
Arrays & Data Structures: Organizing collections of data and processing them with JavaScript methods.
-
DOM Manipulation: Using JavaScript to interact with and modify HTML and CSS in a web page.
-
Events: Responding to user interactions such as clicks, keyboard input, and other events.
-
Asynchronous Programming: Handling operations such as API calls using callbacks, promises, and
async/await. -
Data Exchange with JSON: Using JavaScript Object Notation (JSON) as a common format for exchanging data between applications, APIs, and systems.
These concepts provide the foundation for the next stage of development: using JavaScript not simply to write code, but to build increasingly complex games, projects, systems, and research applications.
Why JavaScript Is Used
To motivate the purpose of learning JavaScript, we need to think about the next stage of development: using JavaScript not simply to write code, but to build increasingly complex games, projects, systems, and research applications.
Use Cases
These are outcomes that describe why we want to learn the JavaScript language.
-
Client-Side Interactivity: JavaScript allows web applications to respond immediately to user actions, including input, clicks, keyboard events, animation, and game interactions.
-
Web Integration: JavaScript works with HTML and CSS to create complete interactive experiences. Students will also explore tools such as SASS to support the development of larger and more maintainable interfaces.
-
Full-Stack Development: JavaScript can connect the user interface to APIs, databases, and server-side systems, allowing students to progress from individual applications to complete software systems.
Distinct Properties
These are properties of the language that make it functional and useful for developers.
-
Dynamic Typing: Variables can hold values of different types during program execution.
-
Prototype-Based Objects: JavaScript objects can inherit behavior from other objects. Modern JavaScript also provides
classsyntax for organizing object-oriented programs. -
Event-Driven Programming: Programs can respond to user actions and other events such as clicks, keyboard input, and game events.
-
Asynchronous Programming: Callbacks, promises, and
async/awaitallow programs to handle tasks such as API requests without blocking the application. -
First-Class Functions: Functions can be stored in variables, passed as arguments, and returned from other functions.
Core Concepts
Understanding core concepts is where we typically start our learning journey.
-
Variables & Scope: Using
letandconstto store data and control where variables can be accessed. -
Data Types: Working with primitive values such as numbers, strings, booleans,
null, andundefined, as well as objects. -
Control Structures: Using conditionals and loops to make decisions and repeat operations.
-
Functions: Organizing code into reusable units that can receive input and return results.
-
Objects & Object-Oriented Programming: Modeling data and behavior together to create more complex applications and systems.
-
Arrays & Data Structures: Organizing collections of data and processing them with JavaScript methods.
-
DOM Manipulation: Using JavaScript to interact with and modify the Document Object Model (DOM), the programmatic representation of the structure and content of a web page.
-
Events: Responding to user interactions such as clicks, keyboard input, and other events.
-
Asynchronous Programming: Handling operations such as API calls using callbacks, promises, and
async/await. -
Data Exchange with JSON: Using JavaScript Object Notation (JSON) as a common format for exchanging data between applications, APIs, and systems.
Learning JavaScript
Pretty much anyone will tell you that learning how to code is best done by having a project. Our first project will be working with the OCS GameBuilder, a tool that uses structured data to configure objects in a 2D game engine.
We will begin our JavaScript journey by learning how to create, read, and modify objects. Objects use key-value pairs to organize information. This structure is closely related to JSON (JavaScript Object Notation), a standard format for exchanging data between applications and systems.
The progression will be:
Objects → JSON → Game Data → 2D Game Engine
Person Object
Let’s start with a basic person object. Notice how we use keys (like “name”, “age”) to access values.
Code Runner Challenge
Build a personalized version of your own student record.
View IPYNB Source
%%js
// CODE_RUNNER: Build a personalized version of your own student record.
// Simple person object with key-value pairs
const person = {
name: "Jane",
age: 16,
grade: "11th",
favoriteSubject: "Computer Science"
};
// Access values using keys
console.log("Name:", person.name);
console.log("Age:", person.age);
console.log("Favorite Subject:", person.favoriteSubject);
// Add a new key-value pair
person.school = "Del Norte High School";
console.log("After adding school:");
console.log(person);
Database Collections
A key concept is that the structure of your data can change according to your needs. A collection of related objects can be used to represent an information database such as infoDb.
This type of structured data can have multiple uses:
- Collections of data transmitted between systems, such as APIs.
- Data received by a backend application to move information into and out of persistent storage, such as a database.
- Data used to configure applications, games, and other software systems.
Code Runner Challenge
Define your records for the infoDB. One record for you and another for your table partner. Pretend data is fine. Make sure to include a hobby or collection for each person.
View IPYNB Source
%%js
// CODE_RUNNER: Define your records for the infoDB. One record for you and another for your table partner. Pretend data is fine. Make sure to include a hobby or collection for each person.
// infoDB is a JavaScript object with Keys and Values
const infoDb = {}
infoDb.id_0001 = {
"FirstName": "John",
"LastName": "Mortensen",
"DOB": "October 21",
"Residence": "San Diego",
"Email": "jmortensen@powayusd.com",
"OwnsCars": ["2015-Fusion", "2011-Ranger", "2003-Excursion", "1997-F350", "1969-Cadillac"]
};
console.log(infoDb);
Game Object
Now we can apply the same concepts to the OCS GameBuilder.
A game object contains properties that describe how a GameObject should behave and appear in the 2D game engine. For example, playerData contains information about the player’s image, size, position, animation, movement, and collision behavior.
The playerData object demonstrates how a relatively complex system can be described using nested key-value pairs. Each property represents a decision about the game object:
- Identity: What is this object called?
- Source: What image or asset should it use?
- Position: Where should it begin?
- Size: How large should it appear?
- Animation: How should its sprite sheet be interpreted?
- Movement: How should the player respond to keyboard input?
- Collision: What part of the object should be considered its hitbox?
Code Runner Challenge
Define the player data using GameBuilder. Customize data for the player's sprite, movement, and controls. Adjust the path to your image location on your machine.
View IPYNB Source
%%js
// CODE_RUNNER: Define the player data using GameBuilder. Customize data for the player's sprite, movement, and controls. Adjust the path to your image location on your machine.
const path = "/Users/johnmortensen/opencs/pages";
const playerData = {
id: 'playerData',
src: path + "/images/gamebuilder/sprites/chillguy.png",
SCALE_FACTOR: 5,
STEP_FACTOR: 1000,
ANIMATION_RATE: 50,
INIT_POSITION: { x: 100, y: 300 },
pixels: { height: 512, width: 384 },
orientation: { rows: 4, columns: 3 },
down: { row: 0, start: 0, columns: 3 },
downRight: { row: 1, start: 0, columns: 3, rotate: Math.PI/16 },
downLeft: { row: 0, start: 0, columns: 3, rotate: -Math.PI/16 },
left: { row: 2, start: 0, columns: 3 },
right: { row: 1, start: 0, columns: 3 },
up: { row: 3, start: 0, columns: 3 },
upLeft: { row: 2, start: 0, columns: 3, rotate: Math.PI/16 },
upRight: { row: 3, start: 0, columns: 3, rotate: -Math.PI/16 },
hitbox: { widthPercentage: 0, heightPercentage: 0 },
keypress: { up: 87, left: 65, down: 83, right: 68 }
};
console.log(
playerData
);
Summary
The playerData object demonstrates how structured data can describe a complex system. The GameBuilder uses data like this to create a playable game object.
Objects are the beginning. The goal is to use JavaScript code to turn structured data into working games.
Ongoing Hack
Use the OCS GameBuilder to begin your journey into JavaScript code and structured data.
Start by creating and modifying the game objects. Change values, observe the results, and experiment with how the data affects the game.
Be patient. Give yourself permission to be confused. Learning to program is not about understanding everything immediately. It is about experimenting, asking questions, observing what happens, and gradually building a mental model of how the system works.
GameBuilder will be the beginning of your JavaScript journey.
Code Runner Challenge
GameBuilder storage. Save your GameBuilder code here, describe what you did in code comments.
View IPYNB Source
%%js
// CODE_RUNNER: GameBuilder storage. Save your GameBuilder code here, describe what you did in code comments.
import GameEnvBackground from '/assets/js/GameEnginev1/essentials/GameEnvBackground.js';
import Player from '/assets/js/GameEnginev1/essentials/Player.js';
import Npc from '/assets/js/GameEnginev1/essentials/Npc.js';
import Barrier from '/assets/js/GameEnginev1/essentials/Barrier.js';
class GameLevelCustom {
constructor(gameEnv) {
const path = gameEnv.path;
const width = gameEnv.innerWidth;
const height = gameEnv.innerHeight;
// Definitions will be added here per step
this.classes = [
// Step 1: add GameEnvBackground
// Step 2: add Player
// Step 3: add Npc
];
/* BUILDER_ONLY_START */
// Post object summary to builder (debugging visibility of NPCs/walls)
try {
setTimeout(() => {
try {
const objs = Array.isArray(gameEnv?.gameObjects) ? gameEnv.gameObjects : [];
const summary = objs.map(o => ({ cls: o?.constructor?.name || 'Unknown', id: o?.canvas?.id || '', z: o?.canvas?.style?.zIndex || '' }));
if (window && window.parent) window.parent.postMessage({ type: 'rpg:objects', summary }, '*');
} catch (_) {}
}, 250);
} catch (_) {}
// Report environment metrics (like top offset) to builder
try {
if (window && window.parent) {
try {
const rect = (gameEnv && gameEnv.container && gameEnv.container.getBoundingClientRect) ? gameEnv.container.getBoundingClientRect() : { top: gameEnv.top || 0, left: 0 };
window.parent.postMessage({ type: 'rpg:env-metrics', top: rect.top, left: rect.left }, '*');
} catch (_) {
try { window.parent.postMessage({ type: 'rpg:env-metrics', top: gameEnv.top, left: 0 }, '*'); } catch (__){ }
}
}
} catch (_) {}
// Listen for in-game wall visibility toggles from builder
try {
window.addEventListener('message', (e) => {
if (!e || !e.data) return;
if (e.data.type === 'rpg:toggle-walls') {
const show = !!e.data.visible;
if (Array.isArray(gameEnv?.gameObjects)) {
for (const obj of gameEnv.gameObjects) {
if (obj instanceof Barrier) {
obj.visible = show;
}
}
}
} else if (e.data.type === 'rpg:set-drawn-barriers') {
const arr = Array.isArray(e.data.barriers) ? e.data.barriers : [];
// Track overlay barriers locally so we can remove/replace
window.__overlayBarriers = window.__overlayBarriers || [];
// Remove previous overlay barriers
try {
for (const ob of window.__overlayBarriers) {
if (ob && typeof ob.destroy === 'function') ob.destroy();
}
} catch (_) {}
window.__overlayBarriers = [];
// Add new overlay barriers
for (const bd of arr) {
try {
const data = {
id: bd.id,
x: bd.x,
y: bd.y,
width: bd.width,
height: bd.height,
visible: !!bd.visible,
hitbox: { widthPercentage: 0.0, heightPercentage: 0.0 },
fromOverlay: true
};
const bobj = new Barrier(data, gameEnv);
gameEnv.gameObjects.push(bobj);
window.__overlayBarriers.push(bobj);
} catch (_) {}
}
}
});
} catch (_) {}
/* BUILDER_ONLY_END */
}
}
export const gameLevelClasses = [GameLevelCustom];
Submit Assignment
Need to update a submission later? Open the submissions dashboard.