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 + + + + + + + \ 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!

- -

-
- - + + + + Event Handlers + + + +

Hello World!

+ +

+
+ + \ 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