three实现三维无底洞重力下落避障游戏代码

代码语言:html

所属分类:游戏

代码描述:three实现三维无底洞重力下落避障游戏代码,小球下落无底洞,键盘方向键控制躲避红色方块。

代码标签: three 三维 无底洞 重力 下落 避障 游戏 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  

  
  
  
<style>
body {
  background-color: black;
  margin: 0;
}
</style>



  
  
</head>

<body translate="no">

      <script  type="module">
import * as THREE from '//repo.bfw.wiki/bfwrepo/js/module/three/build/169/three.module.js';

class Game {
  constructor() {
    this.scene = new THREE.Scene();
    this.scene.fog = new THREE.Fog(0x0000ff, 1, 100);

    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    this.renderer = new THREE.WebGLRenderer({ antialias: false });

    // Set the renderer size and pixel ratio
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setPixelRatio(window.devicePixelRatio);
    document.body.appendChild(this.renderer.domElement);

    this.ball = null;
    this.obstacles = [];
    this.isInitialized = false;

    this.tunnelLength = 1000;
    this.tunnelSize = 10;
    this.ballVelocity = new THREE.Vector3(0, 0, 0);
    this.gravity = new THREE.Vector3(0, -0.015, 0);
    this.pullForce = new THREE.Vector3(0, 0, 0);
    this.maxPullForce = 0.005;
    this.damping = 0.98;
    this.verticalDamping = 0.995;
    this.bounceFactor = 0.7;
    this.tunnelBottom = -this.tunnelLength / 2 + 0.5;

    this.gameStartTime = 0;
    this.gameActive = false;
    this.level = 1;

    this.createUI();
    this.init();
    this.setupControls();

    this.bounceCount = 0; // Initialize bounce counter
  }

  createUI() {
    // Create a single UI container
    const uiElement = document.createElement('div');
    uiElement.id = 'gameUI';
    uiElement.style.position = 'absolute';
    uiElement.style.top = '10px';
    uiElement.style.left = '10px';
    uiElement.style.color = 'white';
    uiElement.style.fontSize = '20px';
    uiElement.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
    uiElement.style.padding = '10px';
    uiElement.style.borderRadius = '5px';
    document.body.appendChild(uiElement);

    // Create game over screen
    this.gameOverScreen = document.createElement('div');
    this.gameOverScreen.style.position = 'absolute';
    this.gameOverScreen.style.top = '50%';
    this.gameOverScreen.style.left = '50%';
    this.gameOverScreen.style.transform = 'translate(-50%, -50%)';
    this.gameOverScreen.style.color = 'white';
    this.gameOverScreen.style.fontSize = '30px';
    this.gameOverScreen.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
    this.gameOverScreen.style.padding = '20px';
    this.gameOverScreen.style.borderRadius = '10px';
    this.gameOverScreen.style.textAlign = 'center';
    this.gameOverScreen.style.display = 'none';
    document.body.appendChild(this.gameOverScreen);

    // Create new level button
    this.newLevelButton = document.createElement('button');
    this.newLevelButton.textContent = 'Start Next Level';
    this.newLevelButton.style.marginTop = '20px';
    this.newLevelButton.style.padding = '10px 20px';
    this.newLevelButton.style.fontSize = '20px';
    this.newLevelButton.addEventListener('click', () => this.startNewLevel());
    this.gameOverScreen.appendChild(this.newLevelButton);
  }

  init() {
    // Create square tunnel
    this.createTunnel();

    // Create ball only if it hasn't been created yet
    if (!this.ball) {
      this.createBall();
    }

    // Create light attached to the ball
    this.ballLight = new THREE.PointLight(0xffffff, 10, 100);
    this.ball.add(this.ballLight);

    // Position camera and make it a child of the ball
    this.camera.position.set(0, 7, 0);
    this.camera.rotation.x = -Math.PI / 2;

    // Create obstacles
    this.createObstacles();

    this.isInitialized = true;

    this.updateUI(); // Initialize UI display
  }

  createBall() {
    const ballGeometry = new THREE.SphereGeometry(0.5, 32, 32);
    const ballMaterial = new THREE.MeshPhysicalMaterial({
      color: 0xffffff,
      metalness: 0,
      roughness: 0,
      transmission: 1, // This makes the material transmissive
      thickness: 0.5, // Simulates the thickness of the glass
      ior: 1.5 });

    this.ball = new THREE.Mesh(ballGeometry, ballMaterial);
    this.ball.position.y = this.tunnelLength / 2 - 1;
    this.scene.add(this.ball);
  }

  createTunnel() {
    const tunnelGeometry = new THREE.BoxGeometry(this.tunnelSize, this.tunnelLength, this.tunnelSize);

    // Generate noise texture
    const textureSize = 8; // Reduced from 64 to 16 for more pixelation
    const noiseCanvas = this.generateNoiseTexture(textureSize, textureSize);
    const noiseTexture = new THREE.CanvasTexture(noiseCanvas);
    noiseTexture.minFilter = THREE.NearestFilter;
    noiseTexture.magFilter = THREE.NearestFilter;
    noiseTexture.wrapS = THREE.RepeatWrapping;
    noiseTexture.wrapT = THREE.RepeatWrapping;
    noiseTexture.repeat.set(0.5, this.tunnelLength / 10); // Reduced repeats

    const tunnelMaterial = new THREE.MeshStandardMaterial({
      color: 0x4422bb,
      map: noiseTexture,
      roughnessMap: noiseTexture,
      side: THREE.BackSide });


    this.tunnel = new THREE.Mesh(tunnelGeometry, tunnelMaterial);
    this.scene.add(this.tunnel);
  }

  createObstacles() {
    // Clear existing obstacles
    this.obstacles.forEach(obstacle => this.scene.remove(obstacle));
    this.obstacles = [];

    // Calculate number of obstacles based on level
    const baseObstacleCount = 50; // Start with 50 obstacles in level 1
    const obstacleIncreasePerLevel = 30; // Add 30 more obstacles each level
    const obstacleCount = baseObstacleCount + (this.level - 1) * obstacleIncreasePerLevel;

    const obstacleMaterial = new THREE.MeshPhongMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
      shininess: 50 });


    // Reuse the same geometry for all obstacles
    const baseGeometry = new THREE.PlaneGeometry(1, 1);

    for (let i = 0; i < obstacleCount; i++) {
      const obstacle = new THREE.Mesh(baseGeometry, obstacleMaterial);

      // Random size with some larger obstacles
      const size = Math.random() < 0.2 ? Math.random() * 3 + 2 : Math.random() * 1.5 + 0.5;
      obstacle.scale.set(size, size, 1);

      // Random position within the tunnel
      obstacle.position.x = (Math.random() - 0.5) * (this.tunnelSize - 2);
      obstacle.position.y = this.tunnelLength / 2 - Math.random() * this.tunnelLength;
      obstacle.position.z = (Math.random() - 0.5) * (.........完整代码请登录后点击上方下载按钮下载查看

网友评论0