js实现俄罗斯方块游戏效果
代码语言:html
所属分类:游戏
代码描述:js实现俄罗斯方块游戏效果
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> body { margin: 0; position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; overflow: hidden; background-color: #eee; } .block { box-sizing: border-box; position: absolute; transform: scale(0.85); border-radius: 6px; } .block--test { background-color: rgba(152, 152, 152, 0.514); } .block--block { animation-name: drop; animation-timing-function: linear; animation-iteration-count: 1; background: linear-gradient(#E6DADA, #FFB88C, #FFAFBD, #606c88); background-size: 100vw 100vh; background-position: 0 0; background-attachment: fixed; } .block--invalid { background-color: #e538357e; } @keyframes drop { from { transform: translateY(-100vh) scale(0.85); } to { transform: translateY(0) scale(0.85); } } </style> </head> <body translate="no"> <script > /* Automatic and responsive Tetris can be made to clear the full lines but it's more fun to watch when it doesn't control it with the below 3 variables Created for my website https://kkmet.com */ const blockSize = 35 const stepSpeed = 70 const fallSpeed = 1500 const container = document.body const viewWidth = window.innerWidth const viewHeight = window.innerHeight const xBlockCount = Math.ceil(viewWidth / blockSize) const yBlockCount = Math.ceil(viewHeight / blockSize) let currentYIndex = 0 const STATES = { EMPTY: 'empty', TEST: 'test', INVALID: 'invalid', BLOCK: 'block', DONE: 'done', } const SHAPES = [ V_LINE, H_LINE, BOX, DOT, L_SHAPE_1, L_SHAPE_2, L_SHAPE_3, L_SHAPE_4, L_SHAPE_5, L_SHAPE_6, L_SHAPE_7, L_SHAPE_8, Z_SHAPE_1, Z_SHAPE_2, Z_SHAPE_3, Z_SHAPE_4, T_SHAPE_1, T_SHAPE_2, T_SHAPE_3, T_SHAPE_4, ] let grid = Array.from({ length: yBlockCount }, () => { return Array.from({ length: xBlockCount}, () => { return STATES.EMPTY }) }) addPiece() async function addPiece() { [x, y] = getCoordinates() await testShapes(x, y) let lastLineHasEmptyBlocks = currentYIndex < (yBlockCount - 1) || grid[yBlockCount - 1].some(x => x === STATES.EMPTY) if (lastLineHasEmptyBlocks) { addPiece() } } function getCoordinates() { const lineIsFull = !grid[currentYIndex].some(state => state === STATES.EMPTY) const lastLine = currentYIndex === (yBlockCount - 1) if (lineIsFull && !lastLine) { currentYIndex++ } let randomX = Math.floor(Math.random() * xBlockCount) while (grid[currentYIndex][randomX] !== STATES.EMPTY) { if (randomX === (xBlockCount - 1)) { randomX = 0 } else { randomX++ } } return [randomX, currentYIndex] } async function testShapes(x, y) { const shapeFunction = getRandomShapeFunction() const shapeCoords = shapeFunction(x, y) const previousShapeCoordsStates = [] let invalid = false shapeCoords.forEach(([x, y]) => { if (!grid[y] || !grid[y][x]) { invalid = true } previousShapeCoordsStates.push(grid[y][x]) grid[y][x] = STATES.TEST }) await draw(stepSpeed) if (invalid || invalidPoints(shapeCoords, previousShapeCoordsStates)) { setPoints(shapeCoords, STATES.INVALID) await draw(stepSpeed) shapeCoords.forEach(([x, y], index) => { if (grid[y] && grid[y][x]) { grid[y][x] = previousShapeCoordsStates[index] } }) await draw(stepSpeed) } else { setPoints(shapeCoords, STATES.BLOCK) await draw(fallSpeed) } } function createBlock(type, x, y) { const blockElement = document.createElement('div') blockElement.classList.add('block', `block--${type}`) blockElement.style.height = blockElement.style.width = `${blockSize}px` blockElement.style.bottom = `${y * blockSize}px` blockElement.style.left = `${x * blockSize}px` if (type === STATES.BLOCK) { blockElement.style.animationDuration = `${fallSpeed}ms` } container.appendChild(blockElement) return blockElement } function hasAccessibleX(y) { return grid[y].some((state, x) => { let accessible = true if (state !== STATES.EMPTY) { accessible = false } grid.forEach((row, index) => { if (index > y && row[x] !== STATES.EMPTY) { accessible = false } }) return accessible }) } function invalidPoints(shapeCoords, previousShapeCoordsStates).........完整代码请登录后点击上方下载按钮下载查看
网友评论0