three+napejs实现疯狂小鸟弹弓射击建筑物重力交互效果代码
代码语言:html
所属分类:其他
代码描述:three+napejs实现疯狂小鸟弹弓射击建筑物重力交互效果代码
代码标签: three nape 疯狂 小鸟 弹弓 射击 建筑物 重力 交互
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
background: #87ceeb;
font-family: Arial, sans-serif;
}
#container {
width: 100vw;
height: 100vh;
position: relative;
}
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0, 0, 0, 0.7);
padding: 10px;
border-radius: 4px;
font-size: 14px;
z-index: 100;
}
#controls {
position: absolute;
bottom: 10px;
left: 10px;
color: white;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 4px;
font-size: 14px;
z-index: 100;
min-width: 200px;
}
#controls label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
#speedSlider {
width: 100%;
margin-bottom: 5px;
}
#speedValue {
font-size: 12px;
color: #aaa;
}
#threeCanvas {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body translate="no">
<div id="container">
<canvas id="threeCanvas"></canvas>
<div id="info">
<div><strong>Destroy the tower with the slingshot!</strong></div>
<div>Balls remaining: <span id="ballCount">5</span></div>
<div>Press SPACE to reset</div>
</div>
<div id="controls">
<label for="speedSlider">Physics Speed</label>
<input type="range" id="speedSlider" min="0.1" max="2.0" step="0.1" value="1.0">
<div id="speedValue">1.0x (Normal)</div>
</div>
</div>
<script >
async function initLibraries() {
console.log("Starting initialization...");
// 1. Wait for DOM to be ready
if (document.readyState === "loading") {
await new Promise(resolve => {
document.addEventListener("DOMContentLoaded", resolve, {
once: true });
});
}
console.log("DOM ready");
// 2. Import THREE.js
const THREE = await import("https://esm.sh/three");
window.THREE = THREE;
console.log("THREE loaded:", THREE);
// 3. Import and initialize Nape
console.log("Initializing Nape...");
const { default: initNape } =
await import("https://cdn.skypack.dev/@newkrok/nape-js@1.0.0");
initNape();
// 4. Wait a moment for Nape to fully initialize
await new Promise(resolve => setTimeout(resolve, 100));
console.log("Nape initialized, window.nape:", window.nape);
const nape = window.nape;
if (!nape) {
console.error("Nape failed to load!");
const infoEl = document.getElementById("info");
if (infoEl) {
infoEl.innerHTML =
'<div style="color: red;">Error: Nape physics engine failed to load</div>';
}
throw new Error("Nape not loaded");
}
console.log("All libraries loaded successfully!");
return { nape, THREE };
}
// ============================================
// CONSTANTS
// ============================================
const PHYSICS = {
PIXEL_RATIO: 17,
GRAVITY: 350,
WIND: 0,
TIMESTEP: 1 / 60,
VELOCITY_ITERATIONS: 10, // Több iteráció a pontosabb ütközésekhez
POSITION_ITERATIONS: 10 };
const GAME_CONFIG = {
maxBalls: 5,
slingshotPosition: { x: -15, y: 0 },
slingshotMaxStretch: 5,
slingshotPower: 15,
ballRadius: 0.5,
towerPosition: { x: 15, y: 0 } };
// ============================================
// NAPE PHYSICS WORLD
// ============================================
class NapeWorld {
constructor() {
this.pixelRatio = PHYSICS.PIXEL_RATIO;
this.space = new nape.space.Space(
new nape.geom.Vec2(PHYSICS.WIND, -PHYSICS.GRAVITY));
// Bullet-through megelőzése: jobb broadphase és CCD
if (this.space.get_broadphase) {
// Sweep and Prune használata (ha elérhető)
try {
this.space.set_sortingEnabled(true);
} catch (e) {
console.warn("Sorting not available in this Nape version");
}
}
this.paused = false;
this.breakableObjects = []; // Törhető objektumok listája
this.previousVelocities = new Map(); // Előző frame sebességek
this.speedMultiplier = 1.0; // Fizika sebesség szorzó
}
registerBreakable(obj) {
this.breakableObjects.push(obj);
}
unregisterBreakable(obj) {
const index = this.breakableObjects.indexOf(obj);
if (index > -1) {
this.breakableObjects.splice(index, 1);
}
}
checkCollisions() {
// Manuális ütközés ellenőrzés sebességváltozás alapján
for (const obj of this.breakableObjects) {
if (obj.isBroken) continue;
const body = obj.body;
const bodyId = body.get_id();
// Jelenlegi sebesség
const veloc.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0