<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <style> canvas { position: absolute; top: 45%; left: 50%; width: 640px; height: 640px; margin: -320px 0 0 -320px; } </style> </head> <body> <canvas></canvas> <script> 'use strict'; var canvas = document.querySelector('canvas'); canvas.width = 640; canvas.height = 640; var g = canvas.getContext('2d'); var right = { x: 1, y: 0 }; var down = { x: 0, y: 1 }; var left = { x: -1, y: 0 }; var EMPTY = -1; var BORDER = -2; var fallingShape; var nextShape; var dim = 640; var nRows = 18; var nCols = 12; var blockSize = 30; var topMargin = 50; var leftMargin = 20; var scoreX = 400; var scoreY = 330; var titleX = 130; var titleY = 160; var clickX = 120; var clickY = 400; var previewCenterX = 467; var previewCenterY = 97; var mainFont = 'bold 48px monospace'; var smallFont = 'bold 18px monospace'; var colors = ['green', 'red', 'blue', 'purple', 'orange', 'blueviolet', 'magenta']; var gridRect = { x: 46, y: 47, w: 308, h: 517 }; var previewRect = { x: 387, y: 47, w: 200, h: 200 }; var titleRect = { x: 100, y: 95, w: 252, h: 100 }; var clickRect = { x: 50, y: 375, w: 252, h: 40 }; var outerRect = { x: 5, y: 5, w: 630, h: 630 }; var squareBorder = 'white'; var titlebgColor = 'white'; var textColor = 'black'; var bgColor = '#DDEEFF'; var gridColor = '#BECFEA'; var gridBorderColor = '#7788AA'; var largeStroke = 5; var smallStroke = 2; // position of falling shape var fallingShapeRow; var fallingShapeCol; var keyDown = false; var fastDown = false; var grid = []; var scoreboard = new Scoreboard(); addEventListener('keydown', function (event) { if (!keyDown) { keyDown = true; if (scoreboard.isGameOver()) return; switch (event.key) { case 'w': case 'ArrowUp': if (canRotate(fallingShape)) rotate(fallingShape); break; case 'a': case 'ArrowLeft': if (canMove(fallingShape, left)) move(left); break; case 'd': case 'ArrowRight': if (canMove(fallingShape, right)) move(right); break; case 's': case 'ArrowDown': if (!fastDown) { fastDown = true; while (canMove(fallingShape, down)) { move(down); draw(); } shapeHasLanded(); } } draw(); } }); addEventListener('click', function () { startNewGame(); }); addEventListener('keyup', function () { keyDown = false; fastDown = false; }); function canRotate(s) { if (s === Shapes.Square) return false; var pos = new Array(4); for (var i = 0; i < pos.length; i++) { pos[i] = s.pos[i].slice(); } pos.forEach(function (row) { var tmp = row[0]; row[0] = row[1]; row[1] = -tmp; }); return pos.every(function (p) { var newCol = fallingShapeCol + p[0]; var newRow = fallingShapeRow + p[1]; return grid[newRow][newCol] === EMPTY; }); } function rotate(s) { if (s === Shapes.Square) return; s.pos.forEach(function (row) { var tmp = row[0]; row[0] = row[1]; row[1] = -tmp; }); } function move(dir) { fallingShapeRow += dir.y; fallingShapeCol += dir.x; } function canMove(s, dir) { return s.pos.every(function (p) { var newCol = fallingShapeCol + dir.x + p[0]; var newRow = fallingShapeRow + dir.y + p[1]; return grid[newRow][newCol] === EMPTY; }); } function shapeHasLanded() { addShape(fallingShape); if (fallingShapeRow < 2) { scoreboard.setGameOver(); scoreboard.setTopscore(); } else { scoreboard.addLines(removeLines()); } selectShape(); } function removeLines() { var count = 0; for (var r = 0; r < nRows - 1; r++) { for (var c = 1; c < nCols - 1; c++) { if (grid[r][c] === EMPTY) break; if (c === nCols - 2) { count++; removeLine(r); } } } return count; } function removeLine(line) { for (var c = 0; c < nCols; c++) grid[line][c] = EMPTY; for (var c = 0; c < nCols; c++) { for (var r = line; r > 0; r--) grid[r][c] = grid[r - 1][c]; } } function addShape(s) { s.pos.forEach(function (p) { grid[fallingShapeRow + p[1]][fallingShapeCol + p[0]] = s.ordinal; }); } function Shape(shape, o) { this.shape = shape; this.pos = this.reset(); this.ordinal = o; } var Shapes = { ZShape: [[0, -1], [0, 0], [-1, 0], [-1, 1]], SShape: [[0, -1], [0, 0], [1, 0], [1, 1]], IShape: [[0, -1], [0, 0], [0, 1], [0, 2]], TShape: [[-1, 0], [0, 0], [1, 0], [0, 1]], Square: [[0, 0], [1, 0], [0, 1], [1, 1]], LShape: [[-1, -1], [0, -1], [0, 0], [0, 1]], JShape: [[1, -1], [0, -1], [0, 0], [0, 1]] }; function getRandomShape() { var keys = Object.keys(Shapes); var ord = Math.floor(Math.random() * keys.length); var shape = Shapes[keys[ord]]; return new Shape(shape, ord); } Shape.prototype.reset = function () { this.pos = new Array(4); for (var i = 0; i < this.pos.length; i++) { this.pos[i] = this.shape[i].slice(); } return this.pos; } function selectShape() { fallingShapeRow = 1; fallingShapeCol = 5; fallingShape = nextShape; nextShape = getRandomShape(); if (fallingShape != null) { fallingShape.reset(); } } function Scoreboard() { this.MAXLEVEL = 9; var level = 0; var lines = 0; var score = 0; var topscore = 0; var gameOver = true; this.reset = function () { this.setTopscore(); level = lines = score = 0; gameOver = false; } this.setGameOver = function () { gameOver = true; } this.isGameOver = function () { return gameOver; } this.setTopscore = function () { if (score > topscore) { topscore = score; } } this.getTopscore = function () { return topscore; } this.getSpeed = function () { switch (level) { case 0: return 700; case 1: return 600; case 2: return 500; case 3: return 400; case 4: return 350; case 5: return 300; case 6: return 250; case 7: return 200; case 8: return 150; case 9: return 100; default: return 100; } } this.addScore = function (sc) { score += sc; } this.addLines = function (line) { switch (line) { case 1: this.addScore(10); break; case 2: this.addScore(20); break; case 3: this.addScore(30); break; case 4: this.addScore(40); break; default: return; } lines += line; if (lines > 10) { this.addLevel(); } } this.addLevel = function () { lines %= 10; if (level < this.MAXLEVEL) { level++; } } this.getLevel = function () { return level; } this.getLines = function () { return lines; } this.getScore = function () { return score; } } function draw() { g.clearRect(0, 0, canvas.width, canvas.height); drawUI(); if (scoreboard.isGameOver()) { drawStartScreen(); } else { drawFallingShape(); } } function drawStartScreen() { g.font = mainFont; fillRect(titleRect, titlebgColor); fillRect(clickRect, titlebgColor); g.fillStyle = textColor; g.fillText('Tetris', titleX, titleY); g.font = smallFont; g.fillText('click to start', clickX, clickY); } function fillRect(r, color) { g.fillStyle = color; g.fillRect(r.x, r.y, r.w, r.h); } function drawRect(r, color) { g.strokeStyle = color; g.strokeRect(r.x, r.y, r.w, r.h); } function drawSquare(colorIndex, r, c) { var bs = blockSize; g.fillStyle = colors[colorIndex]; g.fillRect(leftMargin + c * bs, topMargin + r * bs, bs, bs); g.lineWidth = smallStroke; g.strokeStyle = squareBorder; g.strokeRect(leftMargin + c * bs, topMargin + r * bs, bs, bs); } function drawUI() { // background fillRect(outerRect, bgColor); fillRect(gridRect, gridColor); // the blocks dropped in the grid for (var r = 0; r < nRows; r++) { for (var c = 0; c < nCols; c++) { var idx = grid[r][c]; if (idx > EMPTY) drawSquare(idx, r, c); } } // the borders of grid and preview panel g.lineWidth = largeStroke; drawRect(gridRect, gridBorderColor); drawRect(previewRect, gridBorderColor); drawRect(outerRect, gridBorderColor); // scoreboard g.fillStyle = textColor; g.font = smallFont; g.fillText('hiscore ' + scoreboard.getTopscore(), scoreX, scoreY); g.fillText('level ' + scoreboard.getLevel(), scoreX, scoreY + 30); g.fillText('lines ' + scoreboard.getLines(), scoreX, scoreY + 60); g.fillText('score ' + scoreboard.getScore(), scoreX, scoreY + 90); // preview var minX = 5, minY = 5, maxX = 0, maxY = 0; nextShape.pos.forEach(function (p) { minX = Math.min(minX, p[0]); minY = Math.min(minY, p[1]); maxX = Math.max(maxX, p[0]); maxY = Math.max(maxY, p[1]); }); var cx = previewCenterX - ((minX + maxX + 1) / 2.0 * blockSize); var cy = previewCenterY - ((minY + maxY + 1) / 2.0 * blockSize); g.translate(cx, cy); nextShape.shape.forEach(function (p) { drawSquare(nextShape.ordinal, p[1], p[0]); }); g.translate(-cx, -cy); } function drawFallingShape() { var idx = fallingShape.ordinal; fallingShape.pos.forEach(function (p) { drawSquare(idx, fallingShapeRow + p[1], fallingShapeCol + p[0]); }); } function animate(lastFrameTime) { var requestId = requestAnimationFrame(function () { animate(lastFrameTime); }); var time = new Date().getTime(); var delay = scoreboard.getSpeed(); if (lastFrameTime + delay < time) { if (!scoreboard.isGameOver()) { if (canMove(fallingShape, down)) { move(down); } else { shapeHasLanded(); } draw(); lastFrameTime = time; } else { cancelAnimationFrame(requestId); } } } function startNewGame() { initGrid(); selectShape(); scoreboard.reset(); animate(-1); } function initGrid() { function fill(arr, value) { for (var i = 0; i < arr.length; i++) { arr[i] = value; } } for (var r = 0; r < nRows; r++) { grid[r] = new Array(nCols); fill(grid[r], EMPTY); for (var c = 0; c < nCols; c++) { if (c === 0 || c === nCols - 1 || r === nRows - 1) grid[r][c] = BORDER; } } } function init() { initGrid(); selectShape(); draw(); } init(); </script> </body> </html>
Category Archives: Javascript
Blob Game with Collision Detection
<!DOCTYPE html> <html> <head> <style> body {background-color: Plum;} canvas{ border: 2px solid black;} </style> </head> <body> <img id="link1" src="link1 (2).png" alt="Link1" style="display:none"> <img id="link2" src="link2 (2).png" alt="Link2" style="display:none"> <img id="grass1" src="grass1.png" alt="Link2" style="display:none"> <img id="grass2" src="grass2.png" alt="Link2" style="display:none"> <img id="grass3" src="grass3.png" alt="Link2" style="display:none"> <img id="grass4" src="grass4.png" alt="Link2" style="display:none"> <img id="rock1" src="rock1.png" alt="Link2" style="display:none"> <canvas id = "game"></canvas> <script> var Key = { _pressed: {}, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, isDown: function(keyCode){ return this._pressed[keyCode]; }, onKeydown: function(event) { this._pressed[event.keyCode] = true; }, onKeyup: function(event) { delete this._pressed[event.keyCode]; } }; window.addEventListener('keyup', function(event) {Key.onKeyup(event); }, false); window.addEventListener('keydown', function(event) {Key.onKeydown(event); }, false); var OBSTACLES = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,1,1,0,0,0,0,0,0,0,0,0,0], [0,1,0,1,0,0,1,0,0,0,0,0,0,0], [0,1,1,1,0,1,0,1,0,0,0,0,0,0], [0,1,0,1,0,1,1,1,0,0,0,0,0,0], [0,1,1,1,0,1,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,1] ]; var canvas = document.getElementById('game'); canvas.width = 1400; //window.innerWidth; canvas.height =900; //window.innerHeight; var grid = 100; var player_width = document.getElementById("link1").width; var player_height = document.getElementById("link1").height; //var player_width = document.getElementById("rock1").width; //var player_height = document.getElementById("rock1").height; console.log(player_width, player_height); function isCollidedOb(x,y,width,height,obarray){ upperleft = [[Math.floor(y/grid)],[Math.floor(x/grid)]]; lowerleft = [[Math.floor((y+height)/grid)],[Math.floor((x)/grid)]]; upperright = [[Math.floor((y)/grid)],[Math.floor((x+width)/grid)]]; lowerright = [[Math.floor((y+height)/grid)],[Math.floor((x+width)/grid)]]; console.log(upperleft[0],lowerleft,upperright[0],lowerright); if(obarray[upperleft[0]][upperleft[1]] || obarray[lowerleft[0]][lowerleft[1]] || obarray[upperright[0]][upperright[1]] || obarray[lowerright[0]][lowerright[1]]){ return true; } return false; } function drawObs(obarray,grid){ for (let i = 0; i < obarray.length; i++) { for (let j = 0; j < obarray[i].length; j++) { if (obarray[i][j]){ ctx.drawImage(rock1,j*grid,i*grid); } } } } var x = 50; var y = 50; var toggle = 1; var grass1 = document.getElementById("grass1"); var rock1 = document.getElementById("rock1"); var ctx = canvas.getContext('2d'); var goalX = Math.random() * window.innerWidth; var goalY = Math.random() * window.innerHeight; var playerSize = 50; var goalSize = 15; var speed = 3; function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgb(24, 255, 0)"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawObs(OBSTACLES,grid); ctx.drawImage(grass1, 200, 200); //MOVE UP if(Key.isDown(Key.UP)){ toggle += 1; if(y < 0){ y= canvas.height-player_height; } if(!isCollidedOb(x,Math.abs(y-speed),player_width,player_height,OBSTACLES)){ y-=speed; } } //MOVE DOWN if(Key.isDown(Key.DOWN)){ toggle += 1; if(y > canvas.height){ y= y%canvas.height; } if(!isCollidedOb(x,y+speed,player_width,player_height,OBSTACLES)){ y+=speed; } } //MOVE LEFT if(Key.isDown(Key.LEFT)){ toggle += 1; if(x < 0){ x = canvas.width-player_width; } if(!isCollidedOb(x-speed,y,player_width,player_height,OBSTACLES)){ x-=speed; } } //MOVE RIGHT if(Key.isDown(Key.RIGHT)){ toggle += 1; if(x > canvas.width){ x= x%canvas.width; } if(!isCollidedOb(x+speed,y,player_width,player_height,OBSTACLES)){ x+=speed; } } if ((Math.abs(x-goalX))**2 + (Math.abs(y-goalY))**2 < (playerSize+goalSize)**2){ //playerSize += 5; goalX = Math.random() * canvas.width; goalY = Math.random() * canvas.height; } //var character = new Path2D(); //////////////////////////////////////////////////////////////////// //var character = new Image(); //toggle += 1; toggle %= 100; if(toggle > 50){ var character = document.getElementById("link1"); //character.src = document.getElementById("link1"); } else { //character.src = document.getElementById("link2");} var character = document.getElementById("link2");} //character.addEventListener('load', function() { // execute drawImage statements here ctx.drawImage(character, x, y); var goal = new Path2D(); goal.arc(goalX, goalY, goalSize, 0, 2 * Math.PI); ctx.fillStyle = "#FF0000" //ctx.fill(character); ctx.fill(goal) } setInterval(draw, 10); </script> </body> </html>