Final output
What you can create
Habal max 3. Sakay 10 → illegal recruitment. Sakay 2 → Swakto.
Before you start
Not the Arena
New folder. No fighters. Garage must not use instanceof. Habal-habal max is 3 — ten sakay is illegal recruitment.
Full typed walkthrough: ACTIVITY-ride-start.md
Type the parent Ride
- 1
Create
js/ride.js. - 2
start()andmaxPassengers()throw until a subclass writes them. - 3
sakay(n)lives on the parent — checks max, then Swakto or illegal recruitment.
if (n > this.maxPassengers()) {
return 'Pffft… illegal recruitment. Max ' + this.maxPassengers() + ' lang dito.';
}
return this.boardOk(n);Habal max is 3. Ten passengers must fail with a funny line.
Jeepney, Tricycle, Habal
- 1
Each subclass implements
start()andmaxPassengers(). - 2
Habal-habal (Motorcycle) max = 3.
- 3
Optional witty
boardOk(count)per ride.
start() { return 'Vroom'; }
maxPassengers() { return 3; }Same method names. Different shouts and caps. That is the hook.
Garage — no instanceof
- 1
Garage HAS rides. It does not extend Ride.
- 2
startSelected()andsakaySelected(n)only call the methods. - 3
Add Tsinelas later — Garage stays untouched.
If you write instanceof, start that file over.
Load scripts in index.html
- 1
The empty starter has no
<script>tags — add them before</body>. - 2
Order matters: parent
ride.jsfirst, then subclasses, thengarage.js, thenmain.js. - 3
Only include a stretch ride after you create that file.
<script src="js/ride.js"></script>
<script src="js/jeepney.js"></script>
<script src="js/tricycle.js"></script>
<script src="js/motorcycle.js"></script>
<script src="js/lantsa.js"></script>
<script src="js/baobao.js"></script>
<script src="js/eroplano.js"></script>
<script src="js/bike.js"></script>
<script src="js/nwow.js"></script>
<script src="js/truck.js"></script>
<script src="js/bulldozer.js"></script>
<script src="js/tsinelas.js"></script>
<script src="js/garage.js"></script>
<script src="js/main.js"></script>Forgot a script? Console says the class is not defined.
Register rides in main.js
- 1
In
main.js: create a Garage, thengarage.add(new …())for each ride you loaded. - 2
Only add a stretch ride after its class file and script tag exist.
const garage = new Garage();
garage.add(new Jeepney());
garage.add(new Tricycle());
garage.add(new Motorcycle());
garage.add(new Lantsa());
garage.add(new BaoBao());
garage.add(new Eroplano());
garage.add(new Bike());
garage.add(new Nwow());
garage.add(new Truck());
garage.add(new Bulldozer());
garage.add(new Tsinelas());Forgot an add()? That ride never appears in the list.
Wire Start + Sakay
- 1
Still in
main.js: grab the board elements, render the ride list, hook Start and Sakay. - 2
Click a ride →
garage.select. Start / Sakay call Garage only — never the ride type. - 3
Prove: habal 10 → illegal · habal 2 → Swakto. Then write maxPassengers for habal on paper.
const list = document.getElementById('ride-list');
const startBtn = document.getElementById('start-btn');
const sakayBtn = document.getElementById('sakay-btn');
const paxInput = document.getElementById('pax');
const hint = document.getElementById('hint');
const shout = document.getElementById('shout');
const formula = document.getElementById('formula');
function showLine(line, codeLine) {
shout.textContent = line;
shout.classList.remove('is-live');
void shout.offsetWidth;
shout.classList.add('is-live');
formula.textContent = codeLine;
}
function setReady(ride) {
hint.textContent = 'Max ' + ride.maxPassengers() + ' passengers. Start or Sakay.';
startBtn.disabled = false;
sakayBtn.disabled = false;
paxInput.disabled = false;
paxInput.value = '1';
shout.textContent = '—';
shout.classList.remove('is-live');
formula.textContent = '';
}
function renderList() {
list.innerHTML = '';
garage.all().forEach((ride) => {
const item = document.createElement('li');
const button = document.createElement('button');
button.type = 'button';
button.innerHTML =
'<span>' + ride.label + '</span>' +
'<span class="ride-meta">' +
'<span class="ride-kind ' + ride.kind() + '">' + ride.kind() + '</span>' +
'<span class="ride-max">max ' + ride.maxPassengers() + '</span>' +
'</span>';
button.setAttribute('aria-pressed', garage.selected() === ride ? 'true' : 'false');
button.addEventListener('click', () => {
garage.select(ride);
setReady(ride);
renderList();
});
item.appendChild(button);
list.appendChild(item);
});
}
startBtn.addEventListener('click', () => {
const ride = garage.selected();
const line = garage.startSelected();
showLine(line, ride.kind() + '.start() → "' + line + '"');
});
sakayBtn.addEventListener('click', () => {
const ride = garage.selected();
const count = paxInput.value;
const line = garage.sakaySelected(count);
showLine(line, ride.kind() + '.sakay(' + count + ') · max ' + ride.maxPassengers());
});
renderList();Compare with the final output demo when you get stuck.
Done checklist
Submit
Ride Start repo only. Recite max passengers for habal with the file closed.
| Deliverable | What to turn in |
|---|---|
| Repo | GitHub URL for ride-start |
| Demo | Start + Sakay 10 on habal (illegal) + Sakay 2 (Swakto) |
| Defense | Why Garage does not need instanceof |
Start + Sakay already work? Continue Day 2 · Private, Fare, Boarded · Still on Warrior vs Witch? Finish the midterm roster then start a new folder.