Sanrio
In part a Mario parody, Sanrio is a multilevel sidescrolling platformer where the player aims to reach the end of a level, collecting coins for maximum points, while avoiding or defeating enemy obstacles.
As this project was intended to be built within 5 days, I used an image that I had drawn before as a base wireframe. Having an idea of what assets I needed and the functionality I wanted to create, organizing programming process was far more straightforward than starting from scratch.

I broke the game down into specific features I wanted implement:
- Player creation and movement
- Level generation
- Enemy obstacles
- Player shooting + variants on attacks
- Items and powerups
- Level map
- Enemy projectiles + diversified attacks
- Boss battles
For the controls instruction, I wanted to do something a little different than a literal image diagram. By making an interactive keyboard that instantly reflected the result, I thought learning the controls would come much more intuitively than having to memorize and reference the menu.

I wanted to reflect changes in the keyboard without having to load multiple static images and so ended up generating one in JS. I was able to avoid hard-coding html for each key by creating an array of arrays that represented each row of keys, with each number reflecting a different type of key (ex. 1 = numbers, 2 = letters) and relying on styling to create the correct configuration.
For scene generation, I wanted to be able to quickly generate multiple maps, without having to calculate the positions of each decorative element or platform. Using a text file where I could easily see layout provided a visual display for level creation.generateControls() { let keyboard = 'QWERTYUIOPASDFGHJKLZXCVBNM'; let nums = '1234567890'; let number = 0; let letter = 0; let keyArray = [ [4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 12], [5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5], [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 0], [8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 5, 5, 5], [6, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 6], [0, 0, 0, 0, 7, 0, 0, 9, 10, 11] ]; for (let row = 0; row < keyArray.length; row++) { let list = document.getElementById(`row${row}`); keyArray[row].forEach(key => { let element = document.createElement('LI'); switch (key) { // number keys case 1: element.setAttribute("class", "keyboardKey"); element.setAttribute("id", `key${nums[number]}`); let textnode = document.createElement('P'); let textContent = document.createTextNode(`${nums[number]}`); textnode.setAttribute("class", "keyNumberContent"); textnode.appendChild(textContent); element.appendChild(textnode); list.appendChild(element); number += 1; break; // letter keys case 2: element.setAttribute("class", "keyboardKey"); element.setAttribute("id", `key${keyboard[letter]}`); let letternode = document.createElement('P'); let letterContent = document.createTextNode(`${keyboard[letter]}`); letternode.setAttribute("class", "keyLetterContent"); letternode.appendChild(letterContent); element.appendChild(letternode); list.appendChild(element); letter += 1; break; case 7: element.setAttribute("id", "space"); list.appendChild(element); break; // arrow keys // blank keys default: break; } }); } }

The platforms themselves were built of 3 separate pieces- the round left and right edges and a middle piece that extended a given number of blocks and defined with a number of 1-5 that represented it's shade value.

for (let i = 0; i < level.length; i++){
switch (level[i]){
case ' ':
width += WIDTHSPAN;
break;
case '\n':
height += HEIGHTSPAN;
width = 0;
break;
case '\t':
width += WIDTHSPAN*4;
break;
case 'c':
items[itemCount] = (new Coin(width, height - HEIGHTSPAN, itemCount));
itemCount += 1;
width += WIDTHSPAN;
break;
case 'T':
deco.push(new Tree(width, height + HEIGHTSPAN, 1.5));
width += WIDTHSPAN;
break;
case 't':
deco.push(new Tree(width, height + HEIGHTSPAN, 1));
width += WIDTHSPAN;
break;
case 'b':
deco.push(new Bush(width, height + HEIGHTSPAN, randomInt(0,5)));
width += WIDTHSPAN;
break;
case 'x':
blockCount += 1;
break;
case 'X':
blockCount += 1;
let depth = 5;
switch (height > 0) {
case (height >= 0 && height < 100):
depth = 5;
break;
case (height >= 100 && height < 200):
depth = 4;
break;
case (height >= 200 && height < 300):
depth = 3;
break;
case (height >= 300 && height < 400):
depth = 2;
break;
case height >= 400:
depth = 1;
break;
}
sceneObjects.push(new PlatformBuilder(blockCount, width, height, depth));
width += WIDTHSPAN*blockCount;
blockCount = 0;
break;
default:
}
}