3D切块小游戏特效
代码语言:html
所属分类:游戏
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>HTML5切积木益智游戏源码 - A5源码</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { margin: 0; background-color: #000; background-image: radial-gradient(ellipse at top, #335476 0.0%, #31506e 11.1%, #304b67 22.2%, #2f4760 33.3%, #2d4359 44.4%, #2c3f51 55.6%, #2a3a4a 66.7%, #293643 77.8%, #28323d 88.9%, #262e36 100.0%); height: 100vh; overflow: hidden; font-family: monospace; font-weight: bold; letter-spacing: 0.06em; color: rgba(255, 255, 255, 0.75); } #c { display: block; touch-action: none; transform: translateZ(0); } /*///////////////////// // HUD // /////////////////////*/ .hud__score, .pause-btn { position: fixed; font-size: calc(14px + 2vw + 1vh); } .hud__score { top: 0.65em; left: 0.65em; pointer-events: none; user-select: none; } .cube-count-lbl { font-size: 0.46em; } .pause-btn { position: fixed; top: 0; right: 0; padding: 0.8em 0.65em; } .pause-btn > div { position: relative; width: 0.8em; height: 0.8em; opacity: 0.75; } .pause-btn > div::before, .pause-btn > div::after { content: ''; display: block; width: 34%; height: 100%; position: absolute; background-color: #fff; } .pause-btn > div::after { right: 0; } .slowmo { position: fixed; bottom: 0; width: 100%; pointer-events: none; opacity: 0; transition: opacity 0.4s; will-change: opacity; } .slowmo::before { content: 'SLOW-MO'; display: block; font-size: calc(8px + 1vw + 0.5vh); margin-left: 0.5em; margin-bottom: 8px; } .slowmo::after { content: ''; display: block; position: fixed; bottom: 0; width: 100%; height: 1.5vh; background-color: rgba(0, 0, 0, 0.25); z-index: -1; } .slowmo__bar { height: 1.5vh; background-color: rgba(255, 255, 255, 0.75); transform-origin: 0 0; } /*///////////////////// // MENUS // /////////////////////*/ .menus::before { content: ''; pointer-events: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: #000; opacity: 0; transition: opacity 0.2s; transition-timing-function: ease-in; } .menus.has-active::before { opacity: 0.08; transition-duration: 0.4s; transition-timing-function: ease-out; } .menus.interactive-mode::before { opacity: 0.02; } /* Menu containers */ .menu { pointer-events: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; user-select: none; text-align: center; color: rgba(255, 255, 255, 0.9); opacity: 0; visibility: hidden; transform: translateY(30px); transition-property: opacity, visibility, transform; transition-duration: 0.2s; transition-timing-function: ease-in; } .menu.active { opacity: 1; visibility: visible; transform: translateY(0); transition-duration: 0.4s; transition-timing-function: ease-out; } .menus.interactive-mode .menu.active { opacity: 0.6; } .menus:not(.interactive-mode) .menu.active > * { pointer-events: auto; } /* Common menu elements */ h1 { font-size: 4rem; line-height: 0.95; text-align: center; font-weight: bold; margin: 0 0.65em 1em; } h2 { font-size: 1.2rem; line-height: 1; text-align: center; font-weight: bold; margin: -1em 0.65em 1em; } .final-score-lbl { font-size: 5rem; margin: -0.2em 0 0; } .high-score-lbl { font-size: 1.2rem; margin: 0 0 2.5em; } button { display: block; position: relative; width: 200px; padding: 12px 20px; background: transparent; border: none; outline: none; user-select: none; font-family: monospace; font-weight: bold; font-size: 1.4rem; color: #fff; opacity: 0.75; transition: opacity 0.3s; } button::before { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(255, 255, 255, 0.15); transform: scale(0, 0); opacity: 0; transition: opacity 0.3s, transform 0.3s; } /* No `:focus` styles because this is a mouse/touch game! */ button:active { opacity: 1; } button:active::before { transform: scale(1, 1); opacity: 1; } .credits { position: fixed; width: 100%; left: 0; bottom: 20px; } a { color: white; } /* Only enable hover state on large screens */ @media (min-width: 1025px) { button:hover { opacity: 1; } button:hover::before { transform: scale(1, 1); opacity: 1; } } </style> </head> <body> <!-- Game canvas --> <canvas id="c"></canvas> <!-- Gameplay HUD --> <div class="hud"> <div class="hud__score"> <div class="score-lbl"></div> <div class="cube-count-lbl"></div> </div> <div class="pause-btn"><div></div></div> <div class="slowmo"> <div class="slowmo__bar"></div> </div> </div> <!-- Menu System --> <div class="menus"> <div class="menu menu--main"> <h1>切块</h1> <button type="button" class="play-normal-btn">开始游戏</button> <button type="button" class="play-casual-btn">休闲模式</button> </div> <div class="menu menu--pause"> <h1>暂停</h1> <button type="button" class="resume-btn">重新开始</button> <button type="button" class="menu-btn--pause">主菜单</button> </div> <div class="menu menu--score"> <h1>游戏结束</h1> <h2>分数:</h2> <div class="final-score-lbl"></div> <div class="high-score-lbl"></div> <button type="button" class="play-again-btn">再玩一次</button> <button type="button" class="menu-btn--score">主菜单</button> </div> </div> <script> // globalConfig.js // ============================================================================ // ============================================================================ // Provides global variables used by the entire program. // Most of this should be configuration. // Timing multiplier for entire game engine. let gameSpeed = 1; // Colors const BLUE = { r: 0x67, g: 0xd7, b: 0xf0 }; const GREEN = { r: 0xa6, g: 0xe0, b: 0x2c }; const PINK = { r: 0xfa, g: 0x24, b: 0x73 }; const ORANGE = { r: 0xfe, g: 0x95, b: 0x22 }; const allColors = [BLUE, GREEN, PINK, ORANGE]; // Gameplay const getSpawnDelay = () => { const spawnDelayMax = 1400; const spawnDelayMin = 550; const spawnDelay = spawnDelayMax - state.game.cubeCount * 3.1; return Math.max(spawnDelay, spawnDelayMin); } const doubleStrongEnableScore = 2000; // Number of cubes that must be smashed before activating a feature. const slowmoThreshold = 10; const strongThreshold = 25; const spinnerThreshold = 25; // Interaction state let pointerIsDown = false; // The last known position of the primary pointer in screen coordinates.` let pointerScreen = { x: 0, y: 0 }; // Same as `pointerScreen`, but converted to scene coordinates in rAF. let pointerScene = { x: 0, y: 0 }; // Minimum speed of pointer before "hits" are counted. const minPointerSpeed = 60; // The hit speed affects the direction the target post-hit. This number dampens that force. const hitDampening = 0.1; // Backboard receives shadows and is the farthest negative Z position of entities. const backboardZ = -400; const shadowColor = '#262e36'; // How much air drag is applied to standard objects const airDrag = 0.022; const gravity = 0.3; // Spark config const sparkColor = 'rgba(170,221,255,.9)'; const sparkThickness = 2.2; const airDragSpark = 0.1; // Track pointer positions to show trail const touchTrailColor = 'rgba(170,221,255,.62)'; const touchTrailThickness = 7; const touchPointLife = 120; const touchPoints = []; // Size of in-game targets. This affects rendered size and hit area. const targetRadius = 40; const targetHitRadius = 50; const makeTargetGlueColor = target => { // const alpha = (target.health - 1) / (target.maxHealth - 1); // return `rgba(170,221,255,${alpha.toFixed(3)})`; return 'rgb(170,221,255)'; }; // Size of target fragments const fragRadius = targetRadius / 3; // Game canvas element needed in setup.js and interaction.js const canvas = document.querySelector('#c'); // 3D camera config // Affects perspective const cameraDistance = 900; // Does not affect perspective const sceneScale = 1; // Objects that get too close to the camera will be faded out to transparent over this range. // const cameraFadeStartZ = 0.8*cameraDistance - 6*targetRadius; const cameraFadeStartZ = 0.45*cameraDistance; const cameraFadeEndZ = 0.65*cameraDistance; const cameraFadeRange = cameraFadeEndZ - cameraFadeStartZ; // Globals used to accumlate all vertices/polygons in each frame const allVertices = []; const allPolys = []; const allShadowVertices = []; const allShadowPolys = []; // state.js // ============================================================================ // ============================================================================ /////////// // Enums // /////////// // Game Modes const GAME_MODE_RANKED = Symbol('GAME_MODE_RANKED'); const GAME_MODE_CASUAL = Symbol('GAME_MODE_CASUAL'); // Available Menus const MENU_MAIN = Symbol('MENU_MAIN'); const MENU_PAUSE = Symbol('MENU_PAUSE'); const MENU_SCORE = Symbol('MENU_SCORE'); ////////////////// // Global State // ////////////////// const state = { game: { mode: GAME_MODE_RANKED, // Run time of current game. time: 0, // Player score. score: 0, // Total number of cubes smashed in game. cubeCount: 0 }, menus: { // Set to `null` to hide all menus active: MENU_MAIN } }; //////////////////////////// // Global State Selectors // //////////////////////////// const isInGame = () => !state.menus.active; const isMenuVisible = () => !!state.menus.active; const isCasualGame = () => state.game.mode ===.........完整代码请登录后点击上方下载按钮下载查看
网友评论0