消除箱子网页游戏

吕文林
2023-12-01
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>三维消除箱子游戏</title>
<style>
body {
    margin: 0;
    padding: 0;
    background-color: #eee;
    color: #333;
    font-family: helvetica;
}
canvas {
    position: absolute;
}
.hud {
    position: absolute;
    margin-left: 1em;
}
.hit {
    font-weight: bold;
    color: red;
}
#xiayiguan{
    position:absolute;
    left:1000px;
    top:500px;
    background-color: #4CAF50; 
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;

}
#jiansu{
    position:absolute;
    left:900px;
    top:500px;
    background-color: rgb(181, 197, 39); 
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;

}
</style>
</head>

<body>
<div class="hud">
    <h1 id="level"></h1>
    <p>点击箱子将其消除</p>
    <p id="score"></p>
</div>

<div id="webgl-container"></div>
<button id="xiayiguan" onclick="xiayiguan()">下一关</button>
<button id="jiansu"  onclick="jiansu()">减速</button>
<script src="three.min.js"></script>
<script src="game.js"></script>



</body>
</html>

//1,变量定义
var scene;
var cube;
var camera;
var renderer;
var clock;//计时器
var holder;//容器
var intersects;//交互变量
var particles=[];//例子数组
var level=1;
var totalLevels=4;
var score=0;
var totalTargets=1;//第一局的目标数
var speed=0.01;
var complete=false;//是否通关
var comments=["简单","中等","困难","疯狂"];
var clicktime=0;
var myLevel=document.getElementById("level");
var myScore=document.getElementById("score");
var mybutton=document.getElementById("xiayiguan");
var now = new Date();
var starttime = now.getMinutes();
//2,初始化
var raycaster=new THREE.Raycaster();//Raycaster类用于2D鼠标在3D场景中拾取对象
var mouse=new THREE.Vector2();
//创建场景
function myScene()
{
    scene=new THREE.Scene();
    var light=new THREE.AmbientLight(0xffffff);
    var width=window.innerWidth;
    var height=window.innerHeight;

    camera=new THREE.PerspectiveCamera(75,width/height,0.1,1000);//透视照相机
    camera.position.z=18;

    renderer=new THREE.WebGLRenderer({
        antialias:true,
        alpha:true
    });
    renderer.setSize(width,height);

    document.getElementById("webgl-container").appendChild(renderer.domElement);
    clock=new THREE.Clock();

    var sLight=new THREE.SpotLight(0xffffff);//聚光灯
    sLight.position.set(-100,100,100);
    scene.add(sLight);

    var aLight=new THREE.AmbientLight(0xffffff);//环境光
    scene.add(aLight);

}

//3,添加箱子
//箱子容器
function addHolder()
{
    holder=new THREE .Object3D();
    holder.name="holder"
    //装载若干箱子
    for(var i=0;i<totalTargets;i++)
    {
        var ranCol=new THREE.Color();
        ranCol.setRGB(Math.random(),Math.random(),Math.random());

        var geometry=new THREE.BoxGeometry(2,2,2);
        var material=new THREE.MeshPhongMaterial({
            color:ranCol,
            ambient:ranCol
        });

        var cube=new THREE.Mesh(geometry,material);
        cube.position.x=i*5;
        cube.name="cubeName"+i;

        var spinner=new THREE.Object3D();
        spinner.rotation.x=i*2.5*Math.PI;
        spinner.name="spinnerName"+i;

        spinner.add(cube);
        holder.add(spinner);
    };
    scene.add(holder);
}

//4,爆炸效果
function addExplosion(point)
{
    var timeNow=clock.getElapsedTime();//返回clock类内置时间长度,以秒为单位
    //产生四个爆炸物
    for(var i=0;i<4;i++)
    {
        var geometry=new THREE.BoxGeometry(1,1,1);
        var material=new THREE.MeshBasicMaterial({
            color:0x999999
        });
        var part=new THREE.Mesh(geometry,material);
        part.position.x=point.x;
        part.position.y=point.y;
        part.position.z=point.z;
        part.name="part"+i;
        part.birthDay=timeNow;
        scene.add(part);
        particles.push(part);//增加粒子
    };
}

//5,渲染
function render()
{
    holder.children.forEach(function(elem,index,array){
        elem.rotation.y+=(speed*(6-index));
        elem.children[0].rotation.x+=0.01;
        elem.children[0].rotation.y+=0.01;

    });
    if(particles.length>0)//粒子效果
    {
        particles.forEach(function(elem,index,array){
            switch(elem.name)
            {
                case "part0":
                    elem.position.x+=1;
                    break;
                case "part1":
                    elem.position.x-=1;
                    break;
                case "part2":
                    elem.position.y+=1;
                    break;
                case "part3":
                    elem.position.y-=1;
                    break;
                default:
                    break;
            }
            if(elem.birthDay-clock.getElapsedTime()<-1)
            {
                scene.remove(elem);
                particles.splice(index,1);//删除一个元素
            }

        })

    };
    renderer.render(scene,camera);
}
//6,鼠标响应
function onDocumentMouseDown(event)
{
    clicktime++;
    event.preventDefault();//取消事件默认动作
    //如果通关
    /*
    if(complete)
    {
        complete=false;
        score=0;
        restartScene();
        return;
    }
    */
    //计算鼠标坐标
    mouse.x=(event.clientX/window.innerWidth)*2-1;
    mouse.y=(event.clientY/window.innerHeight)*2-1;
    //映射鼠标坐标到照相机
    raycaster.setFromCamera(mouse,camera);

    //还没通关
    if(score<totalTargets)
    {
        holder.children.forEach(function(elem,index,array){
            intersects=raycaster.intersectObjects(elem.children);//射线是否与箱子相交,返回相交数量
            if(intersects.length>0 && intersects[0].object.visible)
            {
                intersects[0].object.visible=false;//箱子不可见
                addExplosion(intersects[0].point);//爆炸
                score+=1;

                if(score<totalTargets)//未通关
                {
                    myScore.innerHTML="<span class='hit'>命中!</span>得分:"+score+"/"+totalTargets;

                }
                else//通关
                {
                    //complete=true;
                    if(level<totalLevels)//未达到最后一关
                    {
                        
                        myScore.innerHTML="<strong>恭喜过关!</strong>点击按钮进行第"+(level+1)+"&nbsp;关!";


                    }
                    else//达到最后一关
                    {
                        now = new Date();
                        var endtime = now.getMinutes();
                        var gametime=endtime-starttime;
                        myScore.innerHTML="<strong>通关成功!</strong>点击按钮重新开始!";
                        mybutton.innerHTML="重新开始";
                  
                        alert("点击次数:"+clicktime+"  游戏时间:"+gametime+"分钟");



                    }

                };
            }
        });
    }
}

//7,通关设置
function restartScene()
{
    myScore.innerHTML="";
    if(level<totalLevels)
    {
        speed+=0.005;
        totalTargets+=1;
        level+=1;
    }
    else
    {
        speed=0.01;
        totalTargets=3;
        level=1;
    }
    myLevel.innerText=comments[level-1]+":第"+level+"关,共"+totalLevels+"关";
    scene.remove(holder);
    addHolder();

}
//8,其他函数
document.getElementById("webgl-container").addEventListener('mousedown', onDocumentMouseDown, false);

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

    render();
}
//重绘
function animate() {
    requestAnimationFrame(animate);
    render();
}

function xiayiguan()
{
    clicktime--;
    complete=false;
    score=0;
    restartScene();
    return;
}
function jiansu()
{
    speed=speed/5.0;
    return;
}
//载入设置
window.onload=function()
{
    this.myLevel.innerHTML=comments[this.level-1]+"第:"+level+"关,共"+this.totalLevels+"关";
    myScene();
    addHolder();
    animate();
    window.addEventListener('resize',this.onWindowResize,false);
}


 类似资料: