切块小游戏欢迎来到程序小院
玩法:
鼠标滑动控制放心,对准四周陨石点击鼠标左键进行发射子弹,打碎陨石获得分数,不要让陨石撞击星球哦<canvas id="c"></canvas>^^
开始游戏
<canvas id="c"></canvas>
css
#c {
display: block;
touch-action: none;
transform: translateZ(0);
}
.hud__score,
.pause-btn {
position: absolute;
font-size: calc(14px 2vw 1vh);
}
.hud__score {
top:200px;
margin-left: 10px;
pointer-events: none;
user-select: none;
}
.cube-count-lbl {
font-size: 0.46em;
}
.pause-btn {
position: absolute;
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: 900px;
position: absolute;
background-color: #fff;
}
js
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 === GAME_MODE_CASUAL;
const isPaused = () => state.menus.active === MENU_PAUSE;
///////////////////
// Local Storage //
///////////////////
const highScoreKey = '__menja__highScore';
const getHighScore = () => {
const raw = localStorage.getItem(highScoreKey);
return raw ? parseInt(raw, 10) : 0;
};
const setHighScore = score => localStorage.setItem(highScoreKey, String(score))
// utils.js
// ============================================================================
// ============================================================================
const invariant = (condition, message) => {
if (!condition) throw new Error(message);
};
/////////
// DOM //
/////////
const $ = selector => document.querySelector(selector);
const handleClick = (element, handler) => element.addEventListener('click', handler);
const handlePointerDown = (element, handler) => {
element.addEventListener('touchstart', handler);
element.addEventListener('mousedown', handler);
};
}
源码
需要源码请关注添加好友哦^ ^
转载:欢迎来到本站,转载请注明文章出处https://ormcc.com/