VCHS Computer Science
Computer Science at Valley Catholic High School
Pages
Home
APCSA
APCSP
Ten Commandments
Jump
Tetris F2
Source Code
<!-- Shaw, Asmita Background idea by shaw Code by Asmita Music idea by Shaw and Asmita Code by Asmita Coding for compliment when the player clears a row still in progress by shaw (i don’t have the code with me now because it is with Shaw ~ Asmita) Testing by Asmita --> <!-- CSS --> <style> #grid { background-Image: url("https://media0.giphy.com/media/BHNfhgU63qrks/source.gif"); position: relative; border-right: solid 1px black; border-bottom: solid 1px black; } .block { position: absolute; border: solid 1px silver; } </style> <!-- HTML --> <div style="visibility:hidden"> <audio autoplay="" loop=""> <source src="https://t4.bcbits.com/stream/10b09531723acdccbc2e76951fee299e/mp3-128/1654 777605?p=0&ts=1555445165&t=af9de4c1517d8580e4a1305b7706c1e21e9c06f6&token=15554 45165_8a2322f34ab28dbf61dfb76f946cfd9c1f7dd016"> </audio> </div> <div id="grid" style="height: 400px; width: 250px;"></div> <!-- JavaScript --> <script> /** * JavaScript source code for an implementation of Tetris. * * Author: John P. Sprugeon * Version: 1 (3 April 2019) * * Dependencies: * * 1. Document contains an element with id "grid". * 2. CSS (Cascading Style Sheet): * a. Desired background color is specified for grid. * b. Elements of "block" class are positioned "absolute". * * Possible Enhancements * * 1. Score * 2. Restart * 3. High score * 4. Acceleration * 5. Pause * 6. Levels * 7. Piece preview * 8. Piece hold * 9. Configurable colors * 10. Configurable grid size * 11. Obstacles * 12. Float up (vs. drop down) * 13. Easter eggs (??) */ (function Tetris() { "use strict"; /***********/ /* GLOBALS */ /***********/ const UNITS = "px"; const StaticBlocks = []; let dynamicShape; let timerId; let gameIsOver = false; let gameIsStarted = false; /****************************/ /* OBJECTS AND CONSTRUCTORS */ /****************************/ /** * Constructs a block. * * e.g. new Block({bgColor: "red", left: 0, right: 0}) */ function Block(options) { // Initialize the new block. const element = createBlockElement(); let left = options.left; let top = options.top; updatePosition(); /* Private Functions */ function updateLeft() { element.style.left = (left * Block.unitsWide) + UNITS; } function updateTop() { element.style.top = (top * Block.unitsTall) + UNITS; } function updatePosition() { updateLeft(); updateTop(); } function createBlockElement() { const block = document.createElement("div"); block.classList.add("block"); block.style.height = Block.height; block.style.width = Block.width; block.style.backgroundColor = options.bgColor; return block; } function canMoveLeft() { return left > 0 && !isOffLimits({left: left - 1, top: top}); } function canMoveRight() { return left < Grid.blocksWide - 1 && !isOffLimits({left: left + 1, top: top}); } function canMoveDown() { return top < Grid.blocksTall - 1 && !isOffLimits({left: left, top: top + 1}); } function moveLeft() { --left; updateLeft(); } function moveRight() { ++left; updateLeft(); } function moveDown() { ++top; updateTop(); } /* Public Methods */ this.removeFrom = function(parentElement) { parentElement.removeChild(element); } this.addTo = function(parentElement) { parentElement.append(element); }; this.moveLeft = function() { if (canMoveLeft()) moveLeft(); }; this.moveRight = function() { if (canMoveRight()) moveRight(); }; this.moveDown = function() { if (canMoveDown()) moveDown(); }; this.shiftDown = function() { moveDown(); } this.canMoveRight = canMoveRight; this.canMoveLeft = canMoveLeft; this.canMoveDown = canMoveDown; this.getLeft = function() { return left; } this.getTop = function() { return top; } this.getPosition = function() { return {left: left, top: top}; } this.setLeft = function(value) { left = value; updateLeft(); } this.setTop = function(value) { top = value; updateTop(); } } Block.subdivisions = 25; Block.unitsWide = Block.subdivisions; Block.unitsTall = Block.subdivisions; Block.size = Block.subdivisions + UNITS; Block.width = Block.size; Block.height = Block.size; Object.freeze(Block); /** * The grid that holds the game pieces. */ const Grid = { blocksWide: 10, blocksTall: 16 }; Grid.width = (Grid.blocksWide * Block.unitsWide) + UNITS; Grid.height = (Grid.blocksTall * Block.unitsTall) + UNITS; Grid.element = (function() { const element = document.getElementById("grid"); element.style.height = Grid.height; element.style.width = Grid.width; return element; })(); Object.freeze(Grid); /** * Constructs a shape object composed of blocks. * The value of pIndex is the index of the block * around which the other blocks pivot when the * shape is rotated. If pIndex is undefined, the * shape does not rotate. */ function Shape(blocks, pIndex) { const numBlocks = blocks.length; const pivotBlock = (pIndex === undefined) ? null : blocks[pIndex]; blocks.forEach(function(block) { block.addTo(Grid.element); }); function canMoveRight() { if (gameIsOver) return false; for (let i = 0; i < numBlocks; ++i) { if (!blocks[i].canMoveRight()) return false; } return true; } function canMoveLeft() { if (gameIsOver) return false; for (let i = 0; i < numBlocks; ++i) { if (!blocks[i].canMoveLeft()) return false; } return true; } function canMoveDown() { if (gameIsOver) return false; for (let i = 0; i < numBlocks; ++i) { if (!blocks[i].canMoveDown()) return false; } return true; } function canPivot() { if (gameIsOver || pivotBlock === null) return false; const n = blocks.length; for (let i = 0; i < n; ++i) { const block = blocks[i]; const pos = getPivotedPosition(block); if (isOffLimits(pos)) return false; } return true; } function overlapsOtherShape() { const n = blocks.length; for (let i = 0; i < n; ++i) { const block = blocks[i]; const pos = block.getPosition(); if (isOffLimits(pos)) return true; } return false; } function moveDown() { for (let i = 0; i < numBlocks; ++i) blocks[i].moveDown(); } function moveLeft() { for (let i = 0; i < numBlocks; ++i) blocks[i].moveLeft(); } function moveRight() { for (let i = 0; i < numBlocks; ++i) blocks[i].moveRight(); } function freeze() { blocks.forEach(function(block) { StaticBlocks.push(block); }); StaticBlocks.sort(blockComparator); clearFullRows(); dynamicShape = getNextShape(); } function getPivotedPosition(block) { const B = [block.getTop(), block.getLeft()]; const P = [pivotBlock.getTop(), pivotBlock.getLeft()]; const Vr = [B[0] - P[0], B[1] - P[1]]; const Vt = [-1 * Vr[1], Vr[0]]; return {top: Vt[0] + P[0], left: Vt[1] + P[1]}; } </script>
Newer Post
Older Post
Home