diff --git a/11/index.html b/11/index.html
new file mode 100644
index 0000000..71c527b
--- /dev/null
+++ b/11/index.html
@@ -0,0 +1,10 @@
+
+
+
+ Tennjs
+
+
+
+
+
+
\ No newline at end of file
diff --git a/11/script.js b/11/script.js
new file mode 100644
index 0000000..cdc27bb
--- /dev/null
+++ b/11/script.js
@@ -0,0 +1,195 @@
+class GameView {
+ constructor() {
+ let canvas = document.querySelector("#canvas");
+ this.ctx = canvas.getContext("2d");
+ this.width = canvas.width;
+ this.height = canvas.height;
+ this.offsetTop = canvas.offsetTop;
+ }
+ draw(...entities) {
+ // Fill the canvas with black
+ this.ctx.fillStyle = "black";
+ this.ctx.fillRect(0, 0, this.width, this.height);
+ entities.forEach(entity => entity.draw(this.ctx));
+ }
+ drawScores(scores) {
+ this.ctx.fillStyle = "white";
+ this.ctx.font = "30px monospace";
+ this.ctx.textAlign = "left";
+ this.ctx.fillText(scores.leftScore.toString(), 50, 50);
+ this.ctx.textAlign = "right";
+ this.ctx.fillText(scores.rightScore.toString(), this.width - 50, 50);
+ }
+ drawGameOver() {
+ this.ctx.fillStyle = "white";
+ this.ctx.font = "30px monospace";
+ this.ctx.textAlign = "center";
+ this.ctx.fillText("GAME OVER", this.width / 2, this.height / 2);
+ }
+}
+class Entity {
+ constructor(x, y, width, height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+ boundingBox() {
+ return {
+ left: this.x,
+ right: this.x + this.width,
+ top: this.y,
+ bottom: this.y + this.height
+ };
+ }
+ draw(ctx) {
+ ctx.fillStyle = "white";
+ ctx.fillRect(this.x, this.y, this.width, this.height);
+ }
+}
+class Paddle extends Entity {
+ static WIDTH = 5;
+ static HEIGHT = 20
+ static OFFSET = 10;
+ constructor(x, y) {
+ super(x, y, Paddle.WIDTH, Paddle.HEIGHT);
+ }
+}
+
+class Ball extends Entity {
+ static SIZE = 5;
+ constructor() {
+ super(0, 0, Ball.SIZE, Ball.SIZE);
+ this.init();
+ }
+ init() {
+ this.x = 20;
+ this.y = 30;
+ this.xSpeed = 4;
+ this.ySpeed = 2;
+ }
+ update() {
+ this.x += this.xSpeed;
+ this.y += this.ySpeed;
+ }
+ adjustAngle(distanceFromTop, distanceFromBottom) {
+ if (distanceFromTop < 0) {
+ // If ball hit near top of paddle, reduce ySpeed
+ this.ySpeed -= 0.5;
+ } else if (distanceFromBottom < 0) {
+ // If ball hit near bottom of paddle, increase ySpeed
+ this.ySpeed += 0.5;
+ }
+ }
+ checkPaddleCollision(paddle, xSpeedAfterBounce) {
+ let ballBox = this.boundingBox();
+ let paddleBox = paddle.boundingBox();
+ // Check if the ball and paddle overlap vertically and horizontally
+ let collisionOccurred = (
+ ballBox.left < paddleBox.right &&
+ ballBox.right > paddleBox.left &&
+ ballBox.top < paddleBox.bottom &&
+ ballBox.bottom > paddleBox.top
+ );
+ if (collisionOccurred) {
+ let distanceFromTop = ballBox.top - paddleBox.top;
+ let distanceFromBottom = paddleBox.bottom - ballBox.bottom;
+ this.adjustAngle(distanceFromTop, distanceFromBottom);
+ this.xSpeed = xSpeedAfterBounce;
+ }
+ }
+ checkWallCollision(width, height, scores) {
+ let ballBox = this.boundingBox();
+ // Hit left wall
+ if (ballBox.left < 0) {
+ scores.rightScore++;
+ this.init();
+ }
+ // Hit right wall
+ if (ballBox.right > width) {
+ scores.leftScore++;
+ this.init();
+ }
+ // Hit top or bottom walls
+ if (ballBox.top < 0 || ballBox.bottom > height) {
+ this.ySpeed = -this.ySpeed;
+ }
+ }
+}
+
+class Scores {
+ constructor() {
+ this.leftScore = 0;
+ this.rightScore = 0;
+ }
+}
+class Computer {
+ static followBall(paddle, ball) {
+ const MAX_SPEED = 2;
+ let ballBox = ball.boundingBox();
+ let paddleBox = paddle.boundingBox();
+ if (ballBox.top < paddleBox.top) {
+ paddle.y -= MAX_SPEED;
+ } else if (ballBox.bottom > paddleBox.bottom) {
+ paddle.y += MAX_SPEED;
+ }
+ }
+}
+
+class Game {
+ constructor() {
+ this.gameView = new GameView();
+ this.ball = new Ball();
+ this.leftPaddle = new Paddle(Paddle.OFFSET, 10);
+ this.rightPaddle = new Paddle(
+ this.gameView.width - Paddle.OFFSET - Paddle.WIDTH,
+ 30
+ );
+ this.scores = new Scores();
+ this.gameOver = false;
+ document.addEventListener("mousemove", e => {
+ this.rightPaddle.y = e.y - this.gameView.offsetTop;
+ });
+ }
+ draw() {
+ this.gameView.draw(
+ this.ball,
+ this.leftPaddle,
+ this.rightPaddle
+ );
+ this.gameView.drawScores(this.scores);
+ }
+ checkCollision() {
+ this.ball.checkPaddleCollision(this.leftPaddle,
+ Math.abs(this.ball.xSpeed));
+ this.ball.checkPaddleCollision(this.rightPaddle,
+ -Math.abs(this.ball.xSpeed));
+ this.ball.checkWallCollision(
+ this.gameView.width,
+ this.gameView.height,
+ this.scores
+ );
+ if (this.scores.leftScore > 9 || this.scores.rightScore > 9) {
+ this.gameOver = true;
+ }
+ }
+ update() {
+ this.ball.update();
+ Computer.followBall(this.leftPaddle, this.ball);
+ }
+ loop() {
+ this.draw();
+ this.update();
+ this.checkCollision();
+ if (this.gameOver) {
+ this.draw();
+ this.gameView.drawGameOver();
+ } else {
+ // Call this method again after a timeout
+ setTimeout(() => this.loop(), 30);
+ }
+ }
+}
+
+let game = new Game();
+game.loop();
\ No newline at end of file
diff --git a/12/gist.html b/12/gist.html
new file mode 100644
index 0000000..6a9fb2f
--- /dev/null
+++ b/12/gist.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/12/index.html b/12/index.html
new file mode 100644
index 0000000..5fdb8c9
--- /dev/null
+++ b/12/index.html
@@ -0,0 +1,11 @@
+
+
+
+ Music
+
+
+
+ Playing
+
+
+
\ No newline at end of file
diff --git a/12/script.js b/12/script.js
new file mode 100644
index 0000000..987b34c
--- /dev/null
+++ b/12/script.js
@@ -0,0 +1,250 @@
+/////////////////
+// Instruments //
+/////////////////
+
+function mkDrums() {
+ let reverb = new Tone.Reverb({
+ decay: 1,
+ wet: 0.3
+ }).toDestination();
+
+ let hiHatFilter = new Tone.Filter(15000, "bandpass").connect(reverb);
+
+ let hiHat = new Tone.NoiseSynth({
+ envelope: {
+ attack: 0.001, decay: 0.1, sustain: 0, release: 0
+ },
+ volume: -6
+ }).connect(hiHatFilter);
+
+ class Snare {
+ constructor() {
+ this.noiseFilter = new Tone.Filter(5000, "bandpass").connect(reverb);
+ this.noiseSynth = new Tone.NoiseSynth({
+ envelope: {
+ attack: 0.001, decay: 0.1, sustain: 0, release: 0
+ },
+ volume: -12
+ }).connect(this.noiseFilter);
+
+ this.synth = new Tone.Synth({
+ envelope: {
+ attack: 0.0001, decay: 0.1, sustain: 0, release: 0
+ },
+ oscillator: { type: "sine" },
+ volume: -12
+ }).connect(reverb);
+ }
+
+ triggerAttackRelease(duration, when) {
+ this.noiseSynth.triggerAttackRelease(duration, when);
+ this.synth.triggerAttackRelease("G3", duration, when);
+ }
+ }
+
+ let snare = new Snare();
+
+ let kick = new Tone.MembraneSynth({
+ pitchDecay: 0.02,
+ octaves: 6,
+ volume: -9
+ }).connect(reverb);
+
+ return { hiHat, snare, kick };
+ }
+
+ let drums = mkDrums();
+
+ let lowBass = new Tone.FMSynth({
+ oscillator: {
+ type: "triangle"
+ },
+ envelope: {
+ attack: 0.0001, decay: 0.5, sustain: 0.3, release: 0.1
+ },
+ volume: -3
+ }).toDestination();
+
+ let highBass = new Tone.FMSynth({
+ oscillator: {
+ type: "square"
+ },
+ envelope: {
+ attack: 0.0001, decay: 0.1, sustain: 0.3, release: 0.1
+ },
+ volume: -9
+ }).toDestination();
+
+ let chordSynth = new Tone.PolySynth(Tone.Synth, {
+ oscillator: {
+ type: "triangle"
+ },
+ volume: -12
+ }).toDestination();
+
+ // Samples from freesound.org:
+ // https://freesound.org/people/MTG/sounds/357432/
+ // https://freesound.org/people/MTG/sounds/357336/
+ // https://freesound.org/people/MTG/sounds/357546/
+ let sampler = new Tone.Sampler({
+ urls: {
+ "C5": "trumpet-c5.mp3",
+ "D5": "trumpet-d5.mp3",
+ "F5": "trumpet-f5.mp3"
+ },
+ baseUrl: "https://skilldrick-jscc.s3.us-west-2.amazonaws.com/",
+ attack: 0,
+ release: 1,
+ volume: -24
+ }).toDestination();
+
+ ////////////////
+ // Sequencing //
+ ////////////////
+
+ // Converts a string to an array of notes or nulls.
+ // Dots in the string become nulls in the array and are silent.
+ function mkSequence(pattern) {
+ return pattern.split("").map(value => {
+ if (value == ".") {
+ return null;
+ } else {
+ return value;
+ }
+ });
+ }
+
+ // Converts a string to an array of notes or nulls.
+ // Spaces between pipes in the string become nulls in the array and are silent.
+ function mkPipeSequence(pattern) {
+ return pattern.split("|").map(value => {
+ if (value.trim() == "") {
+ return null;
+ } else {
+ return value;
+ }
+ });
+ }
+
+ let drumPattern = {
+ kick: "x..xx...x..xx...",
+ snare: "..x...x...x...xx",
+ hiHat: "xxxxxxxxxxxxxxxx",
+ };
+
+ let hiHatSequence = new Tone.Sequence(time => {
+ drums.hiHat.triggerAttackRelease("16n", time);
+ }, mkSequence(drumPattern.hiHat), "8n");
+
+ let snareSequence = new Tone.Sequence(time => {
+ drums.snare.triggerAttackRelease("16n", time);
+ }, mkSequence(drumPattern.snare), "8n");
+
+ let kickSequence = new Tone.Sequence(time => {
+ drums.kick.triggerAttackRelease(50, "16n", time);
+ }, mkSequence(drumPattern.kick), "8n");
+
+ let lowBassSequence = new Tone.Sequence((time, note) => {
+ lowBass.triggerAttackRelease(note, "16n", time, 0.6);
+ }, mkPipeSequence("G2| | |G2|G2| | | "), "8n");
+
+ let highBassSequence = new Tone.Sequence((time, note) => {
+ highBass.triggerAttackRelease(note, "16n", time, 0.3);
+ }, mkPipeSequence("G3|F3|E3|D3|G2|D3|G3|D3"), "8n");
+
+ let chords = {
+ 1: ["D4", "G4", "B4"],
+ 2: ["E4", "G4", "A4"],
+ 3: ["C4", "E4", "G4", "C5"],
+ 4: ["B3", "F4", "G4", "B4"],
+ };
+
+ function playChord(time, chordName) {
+ let notes = chords[chordName];
+ chordSynth.triggerAttackRelease(notes, "16n", time, 0.6);
+ }
+
+ let chordSequence1 = new Tone.Sequence((time, chordName) => {
+ playChord(time, chordName);
+ }, mkSequence("1..12..13..4124.1..42..13..413.3"), "8n");
+
+ let chordSequence2 = new Tone.Sequence((time, chordName) => {
+ playChord(time, chordName);
+ }, mkSequence("3..32..34..14213"), "8n");
+
+ let trumpetPart = new Tone.Part((time, note) => {
+ sampler.triggerAttackRelease(note, "1n", time);
+ }, [
+ ["0:0:0", "G5"],
+ ["0:2:0", "C5"],
+ ["1:0:0", "G5"],
+
+ ["2:0:0", "D5"],
+ ["2:2:0", "C5"],
+ ["3:0:0", "B4"],
+
+ ["4:0:0", "G5"],
+ ["4:2:0", "C5"],
+ ["5:0:0", "G5"],
+
+ ["6:0:0", "D5"],
+ ["6:2:0", "C5"],
+ ["7:0:0", "B4"],
+ ["7:2:0", "D5"],
+
+ ["8:0:0", "C5"],
+ ["8:2:0", "E5"],
+ ["9:0:0", "F5"],
+ ["9:2:0", "D5"],
+
+ ["10:0:0", "C5"],
+ ["10:2:0", "E5"],
+ ["11:0:0", "D5"],
+
+ ["12:0:0", "C5"],
+ ["12:2:0", "E5"],
+ ["13:0:0", "F5"],
+ ["13:2:0", "D5"],
+
+ ["14:0:0", "C5"],
+ ["14:2:0", "E5"],
+ ["15:0:0", ["B4", "G5"]]
+ ]);
+
+ //////////
+ // Song //
+ //////////
+
+ hiHatSequence.start("0:0:0").stop("44:0:0");
+ snareSequence.start("0:0:0").stop("44:0:0");
+ kickSequence.start("0:0:0").stop("44:0:0");
+
+ highBassSequence.start("0:0:0").stop("47:3:0");
+ lowBassSequence.start("4:0:0").stop("47:3:0");
+
+ chordSequence1.start("4:0:0").stop("20:0:0");
+ chordSequence2.start("20:0:0").stop("28:0:0");
+ chordSequence1.start("28:0:0").stop("40:0:0");
+
+ trumpetPart.start("12:0:0");
+
+ ////////////////////
+ // Event Handling //
+ ////////////////////
+
+ let play = document.querySelector("#play");
+ let playing = document.querySelector("#playing");
+
+ play.addEventListener('click', () => {
+ // hide this button
+ play.style = "display: none";
+ playing.style = "";
+
+ Tone.start();
+
+ // Modify this to start playback at a different part of the song.
+ Tone.Transport.position = "0:0:0";
+ Tone.Transport.bpm.value = 150;
+
+ Tone.Transport.start();
+ });
\ No newline at end of file
diff --git a/8/index.html b/8/index.html
index 63f7328..a82adb6 100644
--- a/8/index.html
+++ b/8/index.html
@@ -1,11 +1,11 @@
-
-
-
- Event Handlers
-
-
- Hello World!
- ow ow ow ow ow
-
-
+
+
+
+ Event Handlers
+
+
+ Hello World!
+ ow ow ow ow ow
+
+
\ No newline at end of file
diff --git a/8/index2.html b/8/index2.html
index 2c2c9eb..594e3ff 100644
--- a/8/index2.html
+++ b/8/index2.html
@@ -1,23 +1,23 @@
-
-
-
- Event Handlers
-
-
-
- Hello World!
-
- - The
- - Dog
- - Cat
- - Is
- - Was
- - And
- - Hungry
- - Green
-
-
-
-
-
+
+
+
+ Event Handlers
+
+
+
+ Hello World!
+
+ - The
+ - Dog
+ - Cat
+ - Is
+ - Was
+ - And
+ - Hungry
+ - Green
+
+
+
+
+
\ No newline at end of file
diff --git a/8/script.js b/8/script.js
index b3dae9f..dc54547 100644
--- a/8/script.js
+++ b/8/script.js
@@ -1,16 +1,16 @@
-let heading = document.querySelector("#main-heading");
-heading.addEventListener("click", () => {
- console.log("You clicked the heading!");
-});
-
-let para = document.querySelector("#para");
-para.addEventListener("click", () => {
- console.log("Charlie bit me!");
-});
-document.querySelector("em").addEventListener("click", () =>{
- console.log("You clicked the em element!");
- });
-document.querySelector("body").addEventListener("click", () => {
- console.log("You clicked the body element!");
- });
+let heading = document.querySelector("#main-heading");
+heading.addEventListener("click", () => {
+ console.log("You clicked the heading!");
+});
+
+let para = document.querySelector("#para");
+para.addEventListener("click", () => {
+ console.log("Charlie bit me!");
+});
+document.querySelector("em").addEventListener("click", () =>{
+ console.log("You clicked the em element!");
+ });
+document.querySelector("body").addEventListener("click", () => {
+ console.log("You clicked the body element!");
+ });
\ No newline at end of file
diff --git a/8/script2.js b/8/script2.js
index 473d151..18ec9be 100644
--- a/8/script2.js
+++ b/8/script2.js
@@ -1,26 +1,26 @@
-let wordList = document.querySelector("#word-list");
-let sentence = document.querySelector("#sentence");
-wordList.addEventListener("click", event => {
- let word = event.target.textContent;
- sentence.textContent += word;
- sentence.textContent += " ";
-});
-let box = document.querySelector("#box");
-let currentX = 0
-let currentY = 0
-document.querySelector("html").addEventListener("keydown", e => {
-
-if (e.repeat === true){
- return
- } else if (e.key == "w") {
- currentY -= 5;
- } else if (e.key == "a") {
- currentX -= 5;
- } else if (e.key == "s") {
- currentY += 5;
- } else if (e.key == "d") {
- currentX += 5;
-}
- box.style.left = currentX + "px";
- box.style.top = currentY + "px";
+let wordList = document.querySelector("#word-list");
+let sentence = document.querySelector("#sentence");
+wordList.addEventListener("click", event => {
+ let word = event.target.textContent;
+ sentence.textContent += word;
+ sentence.textContent += " ";
+});
+let box = document.querySelector("#box");
+let currentX = 0
+let currentY = 0
+document.querySelector("html").addEventListener("keydown", e => {
+
+if (e.repeat === true){
+ return
+ } else if (e.key == "w") {
+ currentY -= 5;
+ } else if (e.key == "a") {
+ currentX -= 5;
+ } else if (e.key == "s") {
+ currentY += 5;
+ } else if (e.key == "d") {
+ currentX += 5;
+}
+ box.style.left = currentX + "px";
+ box.style.top = currentY + "px";
});
\ No newline at end of file
diff --git a/8/style2.css b/8/style2.css
index 7b1501e..2178871 100644
--- a/8/style2.css
+++ b/8/style2.css
@@ -1,14 +1,14 @@
-li {
-cursor: crosshair;
-}
-li:hover {
- text-decoration: underline;
-}
-#box {
- position: fixed;
- left: 0px;
- top: 0px;
- width: 10px;
- height: 10px;
- background-color: hotpink;
+li {
+cursor: crosshair;
+}
+li:hover {
+ text-decoration: underline;
+}
+#box {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 10px;
+ height: 10px;
+ background-color: hotpink;
}
\ No newline at end of file
diff --git a/9/canvas.html b/9/canvas.html
index 107ec0a..6da5473 100644
--- a/9/canvas.html
+++ b/9/canvas.html
@@ -1,9 +1,9 @@
-
-
-
- Canvas
-
-
-
-
+
+
+
+ Canvas
+
+
+
+
= 300){
- forwards = false;
- }
- if (x <= 0){
- forwards = true
- }
-// y += 1;
-// x %= width;
-// y %= height;
-}
-
-function draw() {
- ctx.clearRect(0, 0, width, height);
- drawCircle(x, y);
-}
-setInterval(() => {
-update();
-draw();
+let canvas = document.querySelector("#canvas");
+let ctx = canvas.getContext("2d");
+let width = canvas.width;
+let height = canvas.height;
+let x = 0;
+let y = 0;
+let forwards = true;
+
+function drawCircle(x, y) {
+ ctx.fillStyle = "rgb(0, 128, 255)";
+ ctx.beginPath();
+ ctx.arc(x, y, 10, 0, Math.PI * 2, false);
+ ctx.fill();
+}
+function update() {
+ if (forwards === true) {
+ x += 1;
+ y = 10
+}
+ else{
+ x -= 1;
+ y = 10
+ }
+ if (x >= 300){
+ forwards = false;
+ }
+ if (x <= 0){
+ forwards = true
+ }
+// y += 1;
+// x %= width;
+// y %= height;
+}
+
+function draw() {
+ ctx.clearRect(0, 0, width, height);
+ drawCircle(x, y);
+}
+setInterval(() => {
+update();
+draw();
}, 1);
\ No newline at end of file
diff --git a/random/index.html b/random/index.html
new file mode 100644
index 0000000..9677197
--- /dev/null
+++ b/random/index.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file