mirror of
https://github.com/wanghao221/moyu.git
synced 2026-05-06 21:40:28 +08:00
Add files via upload
This commit is contained in:
45
游戏-1.爱吹风的小狮子/css/style.css
Normal file
45
游戏-1.爱吹风的小狮子/css/style.css
Normal file
@@ -0,0 +1,45 @@
|
||||
@import url(https://fonts.googleapis.com/css?family=Open+Sans:800);
|
||||
#world {
|
||||
background: #ebe5e7;
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:100%;
|
||||
overflow:hidden;
|
||||
}
|
||||
#instructions{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
top:50%;
|
||||
margin: auto;
|
||||
margin-top:120px;
|
||||
font-family:'Open Sans', sans-serif;
|
||||
color:#653f4c;
|
||||
font-size:.9em;
|
||||
text-transform: uppercase;
|
||||
text-align : center;
|
||||
user-select: none;
|
||||
}
|
||||
.lightInstructions {
|
||||
color:#993f4c;
|
||||
font-size:.8em;
|
||||
}
|
||||
|
||||
#credits{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
margin: auto;
|
||||
bottom:0;
|
||||
margin-bottom:20px;
|
||||
font-family:'Open Sans', sans-serif;
|
||||
color:#b297a2;
|
||||
font-size:0.7em;
|
||||
text-transform: uppercase;
|
||||
text-align : center;
|
||||
}
|
||||
#credits a {
|
||||
color:#b297a2;
|
||||
}
|
||||
|
||||
#credits .society6 {
|
||||
color:#993f4c;
|
||||
}
|
||||
32
游戏-1.爱吹风的小狮子/index.html
Normal file
32
游戏-1.爱吹风的小狮子/index.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>海拥 | 爱吹风的小狮子</title>
|
||||
<link rel="icon" type="image/x-icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<div id="world"></div>
|
||||
<div id="instructions">按住并拖动以产生风<br/><span class="lightInstructions">小狮子一定会很舒服</span></div>
|
||||
|
||||
<div id="credits">
|
||||
<div class="made-with-love">
|
||||
Made with
|
||||
<i>♥</i> by
|
||||
<a target="_blank" href="http://haiyong.site/index">海拥</a>
|
||||
</div>
|
||||
<p>Copyright © <a href="http://haiyong.site/moyu">摸鱼小游戏</a></p>
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="css/style.css"/>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>
|
||||
|
||||
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js"></script>
|
||||
|
||||
<script src="js/script.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
717
游戏-1.爱吹风的小狮子/js/script.js
Normal file
717
游戏-1.爱吹风的小狮子/js/script.js
Normal file
@@ -0,0 +1,717 @@
|
||||
//THREEJS RELATED VARIABLES
|
||||
|
||||
var scene,
|
||||
camera,
|
||||
controls,
|
||||
fieldOfView,
|
||||
aspectRatio,
|
||||
nearPlane,
|
||||
farPlane,
|
||||
shadowLight,
|
||||
backLight,
|
||||
light,
|
||||
renderer,
|
||||
container;
|
||||
|
||||
//SCENE
|
||||
var floor, lion, fan,
|
||||
isBlowing = false;
|
||||
|
||||
//SCREEN VARIABLES
|
||||
|
||||
var HEIGHT,
|
||||
WIDTH,
|
||||
windowHalfX,
|
||||
windowHalfY,
|
||||
mousePos = {x:0,y:0};
|
||||
dist = 0;
|
||||
|
||||
//INIT THREE JS, SCREEN AND MOUSE EVENTS
|
||||
|
||||
function init(){
|
||||
scene = new THREE.Scene();
|
||||
HEIGHT = window.innerHeight;
|
||||
WIDTH = window.innerWidth;
|
||||
aspectRatio = WIDTH / HEIGHT;
|
||||
fieldOfView = 60;
|
||||
nearPlane = 1;
|
||||
farPlane = 2000;
|
||||
camera = new THREE.PerspectiveCamera(
|
||||
fieldOfView,
|
||||
aspectRatio,
|
||||
nearPlane,
|
||||
farPlane);
|
||||
camera.position.z = 800;
|
||||
camera.position.y = 0;
|
||||
camera.lookAt(new THREE.Vector3(0,0,0));
|
||||
renderer = new THREE.WebGLRenderer({alpha: true, antialias: true });
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
renderer.setSize(WIDTH, HEIGHT);
|
||||
renderer.shadowMapEnabled = true;
|
||||
container = document.getElementById('world');
|
||||
container.appendChild(renderer.domElement);
|
||||
windowHalfX = WIDTH / 2;
|
||||
windowHalfY = HEIGHT / 2;
|
||||
window.addEventListener('resize', onWindowResize, false);
|
||||
document.addEventListener('mousemove', handleMouseMove, false);
|
||||
document.addEventListener('mousedown', handleMouseDown, false);
|
||||
document.addEventListener('mouseup', handleMouseUp, false);
|
||||
document.addEventListener('touchstart', handleTouchStart, false);
|
||||
document.addEventListener('touchend', handleTouchEnd, false);
|
||||
document.addEventListener('touchmove',handleTouchMove, false);
|
||||
/*
|
||||
controls = new THREE.OrbitControls( camera, renderer.domElement);
|
||||
//*/
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
HEIGHT = window.innerHeight;
|
||||
WIDTH = window.innerWidth;
|
||||
windowHalfX = WIDTH / 2;
|
||||
windowHalfY = HEIGHT / 2;
|
||||
renderer.setSize(WIDTH, HEIGHT);
|
||||
camera.aspect = WIDTH / HEIGHT;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
function handleMouseMove(event) {
|
||||
mousePos = {x:event.clientX, y:event.clientY};
|
||||
}
|
||||
|
||||
function handleMouseDown(event) {
|
||||
isBlowing = true;
|
||||
}
|
||||
function handleMouseUp(event) {
|
||||
isBlowing = false;
|
||||
}
|
||||
|
||||
function handleTouchStart(event) {
|
||||
if (event.touches.length > 1) {
|
||||
event.preventDefault();
|
||||
mousePos = {x:event.touches[0].pageX, y:event.touches[0].pageY};
|
||||
isBlowing = true;
|
||||
}
|
||||
}
|
||||
|
||||
function handleTouchEnd(event) {
|
||||
//mousePos = {x:windowHalfX, y:windowHalfY};
|
||||
isBlowing = false;
|
||||
}
|
||||
|
||||
function handleTouchMove(event) {
|
||||
if (event.touches.length == 1) {
|
||||
event.preventDefault();
|
||||
mousePos = {x:event.touches[0].pageX, y:event.touches[0].pageY};
|
||||
isBlowing = true;
|
||||
}
|
||||
}
|
||||
|
||||
function createLights() {
|
||||
light = new THREE.HemisphereLight(0xffffff, 0xffffff, .5)
|
||||
|
||||
shadowLight = new THREE.DirectionalLight(0xffffff, .8);
|
||||
shadowLight.position.set(200, 200, 200);
|
||||
shadowLight.castShadow = true;
|
||||
shadowLight.shadowDarkness = .2;
|
||||
|
||||
backLight = new THREE.DirectionalLight(0xffffff, .4);
|
||||
backLight.position.set(-100, 200, 50);
|
||||
backLight.shadowDarkness = .1;
|
||||
backLight.castShadow = true;
|
||||
|
||||
scene.add(backLight);
|
||||
scene.add(light);
|
||||
scene.add(shadowLight);
|
||||
}
|
||||
|
||||
function createFloor(){
|
||||
floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(1000,500), new THREE.MeshBasicMaterial({color: 0xebe5e7}));
|
||||
floor.rotation.x = -Math.PI/2;
|
||||
floor.position.y = -100;
|
||||
floor.receiveShadow = true;
|
||||
scene.add(floor);
|
||||
}
|
||||
|
||||
function createLion(){
|
||||
lion = new Lion();
|
||||
scene.add(lion.threegroup);
|
||||
}
|
||||
|
||||
function createFan(){
|
||||
fan = new Fan();
|
||||
fan.threegroup.position.z = 350;
|
||||
scene.add(fan.threegroup);
|
||||
}
|
||||
|
||||
Fan = function(){
|
||||
this.isBlowing = false;
|
||||
this.speed = 0;
|
||||
this.acc =0;
|
||||
this.redMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xad3525,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
this.greyMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0x653f4c,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.yellowMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xfdd276,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
var coreGeom = new THREE.BoxGeometry(10,10,20);
|
||||
var sphereGeom = new THREE.BoxGeometry(10, 10, 3);
|
||||
var propGeom = new THREE.BoxGeometry(10,30,2);
|
||||
propGeom.applyMatrix( new THREE.Matrix4().makeTranslation( 0,25,0) );
|
||||
|
||||
this.core = new THREE.Mesh(coreGeom,this.greyMat);
|
||||
|
||||
// propellers
|
||||
var prop1 = new THREE.Mesh(propGeom, this.redMat);
|
||||
prop1.position.z = 15;
|
||||
var prop2 = prop1.clone();
|
||||
prop2.rotation.z = Math.PI/2;
|
||||
var prop3 = prop1.clone();
|
||||
prop3.rotation.z = Math.PI;
|
||||
var prop4 = prop1.clone();
|
||||
prop4.rotation.z = -Math.PI/2;
|
||||
|
||||
this.sphere = new THREE.Mesh(sphereGeom, this.yellowMat);
|
||||
this.sphere.position.z = 15;
|
||||
|
||||
this.propeller = new THREE.Group();
|
||||
this.propeller.add(prop1);
|
||||
this.propeller.add(prop2);
|
||||
this.propeller.add(prop3);
|
||||
this.propeller.add(prop4);
|
||||
|
||||
this.threegroup = new THREE.Group();
|
||||
this.threegroup.add(this.core);
|
||||
this.threegroup.add(this.propeller);
|
||||
this.threegroup.add(this.sphere);
|
||||
}
|
||||
|
||||
Fan.prototype.update = function(xTarget, yTarget){
|
||||
this.threegroup.lookAt(new THREE.Vector3(0,80,60));
|
||||
this.tPosX = rule3(xTarget, -200, 200, -250, 250);
|
||||
this.tPosY = rule3(yTarget, -200, 200, 250, -250);
|
||||
|
||||
this.threegroup.position.x += (this.tPosX - this.threegroup.position.x) /10;
|
||||
this.threegroup.position.y += (this.tPosY - this.threegroup.position.y) /10;
|
||||
|
||||
this.targetSpeed = (this.isBlowing) ? .3 : .01;
|
||||
if (this.isBlowing && this.speed < .5){
|
||||
this.acc +=.001;
|
||||
this.speed += this.acc;
|
||||
}else if (!this.isBlowing){
|
||||
this.acc = 0;
|
||||
this.speed *= .98;
|
||||
}
|
||||
this.propeller.rotation.z += this.speed;
|
||||
}
|
||||
|
||||
Lion = function(){
|
||||
this.windTime = 0;
|
||||
this.bodyInitPositions = [];
|
||||
this.maneParts = [];
|
||||
this.threegroup = new THREE.Group();
|
||||
this.yellowMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xfdd276,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
this.redMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xad3525,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.pinkMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xe55d2b,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.whiteMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0xffffff,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.purpleMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0x451954,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.greyMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0x653f4c,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
this.blackMat = new THREE.MeshLambertMaterial ({
|
||||
color: 0x302925,
|
||||
shading:THREE.FlatShading
|
||||
});
|
||||
|
||||
|
||||
var bodyGeom = new THREE.CylinderGeometry(30,80, 140, 4);
|
||||
var maneGeom = new THREE.BoxGeometry(40,40,15);
|
||||
var faceGeom = new THREE.BoxGeometry(80,80,80);
|
||||
var spotGeom = new THREE.BoxGeometry(4,4,4);
|
||||
var mustacheGeom = new THREE.BoxGeometry(30,2,1);
|
||||
mustacheGeom.applyMatrix( new THREE.Matrix4().makeTranslation( 15, 0, 0 ) );
|
||||
|
||||
var earGeom = new THREE.BoxGeometry(20,20,20);
|
||||
var noseGeom = new THREE.BoxGeometry(40,40,20);
|
||||
var eyeGeom = new THREE.BoxGeometry(5,30,30);
|
||||
var irisGeom = new THREE.BoxGeometry(4,10,10);
|
||||
var mouthGeom = new THREE.BoxGeometry(20,20,10);
|
||||
var smileGeom = new THREE.TorusGeometry( 12, 4, 2, 10, Math.PI );
|
||||
var lipsGeom = new THREE.BoxGeometry(40,15,20);
|
||||
var kneeGeom = new THREE.BoxGeometry(25, 80, 80);
|
||||
kneeGeom.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 50, 0 ) );
|
||||
var footGeom = new THREE.BoxGeometry(40, 20, 20);
|
||||
|
||||
// body
|
||||
this.body = new THREE.Mesh(bodyGeom, this.yellowMat);
|
||||
this.body.position.z = -60;
|
||||
this.body.position.y = -30;
|
||||
this.bodyVertices = [0,1,2,3,4,10];
|
||||
|
||||
for (var i=0;i<this.bodyVertices.length; i++){
|
||||
var tv = this.body.geometry.vertices[this.bodyVertices[i]];
|
||||
tv.z =70;
|
||||
//tv.x = 0;
|
||||
this.bodyInitPositions.push({x:tv.x, y:tv.y, z:tv.z});
|
||||
}
|
||||
|
||||
// knee
|
||||
this.leftKnee = new THREE.Mesh(kneeGeom, this.yellowMat);
|
||||
this.leftKnee.position.x = 65;
|
||||
this.leftKnee.position.z = -20;
|
||||
this.leftKnee.position.y = -110;
|
||||
this.leftKnee.rotation.z = -.3;
|
||||
|
||||
this.rightKnee = new THREE.Mesh(kneeGeom, this.yellowMat);
|
||||
this.rightKnee.position.x = -65;
|
||||
this.rightKnee.position.z = -20;
|
||||
this.rightKnee.position.y = -110;
|
||||
this.rightKnee.rotation.z = .3;
|
||||
|
||||
// feet
|
||||
this.backLeftFoot = new THREE.Mesh(footGeom, this.yellowMat);
|
||||
this.backLeftFoot.position.z = 30;
|
||||
this.backLeftFoot.position.x = 75;
|
||||
this.backLeftFoot.position.y = -90;
|
||||
|
||||
this.backRightFoot = new THREE.Mesh(footGeom, this.yellowMat);
|
||||
this.backRightFoot.position.z = 30;
|
||||
this.backRightFoot.position.x = -75;
|
||||
this.backRightFoot.position.y = -90;
|
||||
|
||||
this.frontRightFoot = new THREE.Mesh(footGeom, this.yellowMat);
|
||||
this.frontRightFoot.position.z = 40;
|
||||
this.frontRightFoot.position.x = -22;
|
||||
this.frontRightFoot.position.y = -90;
|
||||
|
||||
this.frontLeftFoot = new THREE.Mesh(footGeom, this.yellowMat);
|
||||
this.frontLeftFoot.position.z = 40;
|
||||
this.frontLeftFoot.position.x = 22;
|
||||
this.frontLeftFoot.position.y = -90;
|
||||
|
||||
// mane
|
||||
|
||||
this.mane = new THREE.Group();
|
||||
|
||||
for (var j=0; j<4; j++){
|
||||
for (var k=0; k<4; k++){
|
||||
var manePart = new THREE.Mesh(maneGeom, this.redMat);
|
||||
manePart.position.x = (j*40)-60;
|
||||
manePart.position.y = (k*40)-60;
|
||||
|
||||
var amp;
|
||||
var zOffset;
|
||||
var periodOffset = Math.random()*Math.PI*2;
|
||||
var angleOffsetY, angleOffsetX;
|
||||
var angleAmpY, angleAmpX;
|
||||
var xInit, yInit;
|
||||
|
||||
|
||||
if ((j==0 && k==0) || (j==0 && k==3) || (j==3 && k==0) || (j==3 && k==3)){
|
||||
amp = -10-Math.floor(Math.random()*5);
|
||||
zOffset = -5;
|
||||
}else if (j==0 || k ==0 || j==3 || k==3){
|
||||
amp = -5-Math.floor(Math.random()*5);
|
||||
zOffset = 0;
|
||||
}else{
|
||||
amp = 0;
|
||||
zOffset = 0;
|
||||
}
|
||||
|
||||
this.maneParts.push({mesh:manePart, amp:amp, zOffset:zOffset, periodOffset:periodOffset, xInit:manePart.position.x, yInit:manePart.position.y});
|
||||
this.mane.add(manePart);
|
||||
}
|
||||
}
|
||||
|
||||
this.mane.position.y = -10;
|
||||
this.mane.position.z = 80;
|
||||
//this.mane.rotation.z = Math.PI/4;
|
||||
|
||||
// face
|
||||
this.face = new THREE.Mesh(faceGeom, this.yellowMat);
|
||||
this.face.position.z = 135;
|
||||
|
||||
// Mustaches
|
||||
|
||||
this.mustaches = [];
|
||||
|
||||
this.mustache1 = new THREE.Mesh(mustacheGeom, this.greyMat);
|
||||
this.mustache1.position.x = 30;
|
||||
this.mustache1.position.y = -5;
|
||||
this.mustache1.position.z = 175;
|
||||
this.mustache2 = this.mustache1.clone();
|
||||
this.mustache2.position.x = 35;
|
||||
this.mustache2.position.y = -12;
|
||||
this.mustache3 = this.mustache1.clone();
|
||||
this.mustache3.position.y = -19;
|
||||
this.mustache3.position.x = 30;
|
||||
this.mustache4 = this.mustache1.clone();
|
||||
this.mustache4.rotation.z = Math.PI;
|
||||
this.mustache4.position.x = -30;
|
||||
this.mustache5 = new THREE.Mesh(mustacheGeom, this.blackMat);
|
||||
this.mustache5 = this.mustache2.clone();
|
||||
this.mustache5.rotation.z = Math.PI;
|
||||
this.mustache5.position.x = -35;
|
||||
this.mustache6 = new THREE.Mesh(mustacheGeom, this.blackMat);
|
||||
this.mustache6 = this.mustache3.clone();
|
||||
this.mustache6.rotation.z = Math.PI;
|
||||
this.mustache6.position.x = -30;
|
||||
|
||||
this.mustaches.push(this.mustache1);
|
||||
this.mustaches.push(this.mustache2);
|
||||
this.mustaches.push(this.mustache3);
|
||||
this.mustaches.push(this.mustache4);
|
||||
this.mustaches.push(this.mustache5);
|
||||
this.mustaches.push(this.mustache6);
|
||||
|
||||
// spots
|
||||
this.spot1 = new THREE.Mesh(spotGeom, this.redMat);
|
||||
this.spot1.position.x = 39;
|
||||
this.spot1.position.z = 150;
|
||||
|
||||
this.spot2 = this.spot1.clone();
|
||||
this.spot2.position.z = 160;
|
||||
this.spot2.position.y = -10;
|
||||
|
||||
this.spot3 = this.spot1.clone();
|
||||
this.spot3.position.z = 140;
|
||||
this.spot3.position.y = -15;
|
||||
|
||||
this.spot4 = this.spot1.clone();
|
||||
this.spot4.position.z = 150;
|
||||
this.spot4.position.y = -20;
|
||||
|
||||
this.spot5 = this.spot1.clone();
|
||||
this.spot5.position.x = -39;
|
||||
this.spot6 = this.spot2.clone();
|
||||
this.spot6.position.x = -39;
|
||||
this.spot7 = this.spot3.clone();
|
||||
this.spot7.position.x = -39;
|
||||
this.spot8 = this.spot4.clone();
|
||||
this.spot8.position.x = -39;
|
||||
|
||||
// eyes
|
||||
this.leftEye = new THREE.Mesh(eyeGeom, this.whiteMat);
|
||||
this.leftEye.position.x = 40;
|
||||
this.leftEye.position.z = 120;
|
||||
this.leftEye.position.y = 25;
|
||||
|
||||
this.rightEye = new THREE.Mesh(eyeGeom, this.whiteMat);
|
||||
this.rightEye.position.x = -40;
|
||||
this.rightEye.position.z = 120;
|
||||
this.rightEye.position.y = 25;
|
||||
|
||||
// iris
|
||||
this.leftIris = new THREE.Mesh(irisGeom, this.purpleMat);
|
||||
this.leftIris.position.x = 42;
|
||||
this.leftIris.position.z = 120;
|
||||
this.leftIris.position.y = 25;
|
||||
|
||||
this.rightIris = new THREE.Mesh(irisGeom, this.purpleMat);
|
||||
this.rightIris.position.x = -42;
|
||||
this.rightIris.position.z = 120;
|
||||
this.rightIris.position.y = 25;
|
||||
|
||||
// mouth
|
||||
this.mouth = new THREE.Mesh(mouthGeom, this.blackMat);
|
||||
this.mouth.position.z = 171;
|
||||
this.mouth.position.y = -30;
|
||||
this.mouth.scale.set(.5,.5,1);
|
||||
|
||||
// smile
|
||||
this.smile = new THREE.Mesh(smileGeom, this.greyMat);
|
||||
this.smile.position.z = 173;
|
||||
this.smile.position.y = -15;
|
||||
this.smile.rotation.z = -Math.PI;
|
||||
|
||||
// lips
|
||||
this.lips = new THREE.Mesh(lipsGeom, this.yellowMat);
|
||||
this.lips.position.z = 165;
|
||||
this.lips.position.y = -45;
|
||||
|
||||
|
||||
// ear
|
||||
this.rightEar = new THREE.Mesh(earGeom, this.yellowMat);
|
||||
this.rightEar.position.x = -50;
|
||||
this.rightEar.position.y = 50;
|
||||
this.rightEar.position.z = 105;
|
||||
|
||||
this.leftEar = new THREE.Mesh(earGeom, this.yellowMat);
|
||||
this.leftEar.position.x = 50;
|
||||
this.leftEar.position.y = 50;
|
||||
this.leftEar.position.z = 105;
|
||||
|
||||
// nose
|
||||
this.nose = new THREE.Mesh(noseGeom, this.greyMat);
|
||||
this.nose.position.z = 170;
|
||||
this.nose.position.y = 25;
|
||||
|
||||
// head
|
||||
this.head = new THREE.Group();
|
||||
this.head.add(this.face);
|
||||
this.head.add(this.mane);
|
||||
this.head.add(this.rightEar);
|
||||
this.head.add(this.leftEar);
|
||||
this.head.add(this.nose);
|
||||
this.head.add(this.leftEye);
|
||||
this.head.add(this.rightEye);
|
||||
this.head.add(this.leftIris);
|
||||
this.head.add(this.rightIris);
|
||||
this.head.add(this.mouth);
|
||||
this.head.add(this.smile);
|
||||
this.head.add(this.lips);
|
||||
this.head.add(this.spot1);
|
||||
this.head.add(this.spot2);
|
||||
this.head.add(this.spot3);
|
||||
this.head.add(this.spot4);
|
||||
this.head.add(this.spot5);
|
||||
this.head.add(this.spot6);
|
||||
this.head.add(this.spot7);
|
||||
this.head.add(this.spot8);
|
||||
this.head.add(this.mustache1);
|
||||
this.head.add(this.mustache2);
|
||||
this.head.add(this.mustache3);
|
||||
this.head.add(this.mustache4);
|
||||
this.head.add(this.mustache5);
|
||||
this.head.add(this.mustache6);
|
||||
|
||||
|
||||
this.head.position.y = 60;
|
||||
|
||||
this.threegroup.add(this.body);
|
||||
this.threegroup.add(this.head);
|
||||
this.threegroup.add(this.leftKnee);
|
||||
this.threegroup.add(this.rightKnee);
|
||||
this.threegroup.add(this.backLeftFoot);
|
||||
this.threegroup.add(this.backRightFoot);
|
||||
this.threegroup.add(this.frontRightFoot);
|
||||
this.threegroup.add(this.frontLeftFoot);
|
||||
|
||||
this.threegroup.traverse( function ( object ) {
|
||||
if ( object instanceof THREE.Mesh ) {
|
||||
object.castShadow = true;
|
||||
object.receiveShadow = true;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
Lion.prototype.updateBody = function(speed){
|
||||
|
||||
this.head.rotation.y += (this.tHeagRotY - this.head.rotation.y) / speed;
|
||||
this.head.rotation.x += (this.tHeadRotX - this.head.rotation.x) / speed;
|
||||
this.head.position.x += (this.tHeadPosX-this.head.position.x) / speed;
|
||||
this.head.position.y += (this.tHeadPosY-this.head.position.y) / speed;
|
||||
this.head.position.z += (this.tHeadPosZ-this.head.position.z) / speed;
|
||||
|
||||
this.leftEye.scale.y += (this.tEyeScale - this.leftEye.scale.y) / (speed*2);
|
||||
this.rightEye.scale.y = this.leftEye.scale.y;
|
||||
|
||||
this.leftIris.scale.y += (this.tIrisYScale - this.leftIris.scale.y) / (speed*2);
|
||||
this.rightIris.scale.y = this.leftIris.scale.y;
|
||||
|
||||
this.leftIris.scale.z += (this.tIrisZScale - this.leftIris.scale.z) / (speed*2);
|
||||
this.rightIris.scale.z = this.leftIris.scale.z;
|
||||
|
||||
this.leftIris.position.y += (this.tIrisPosY - this.leftIris.position.y) / speed;
|
||||
this.rightIris.position.y = this.leftIris.position.y;
|
||||
this.leftIris.position.z += (this.tLeftIrisPosZ - this.leftIris.position.z) / speed;
|
||||
this.rightIris.position.z += (this.tRightIrisPosZ - this.rightIris.position.z) / speed;
|
||||
|
||||
this.rightKnee.rotation.z += (this.tRightKneeRotZ - this.rightKnee.rotation.z) / speed;
|
||||
this.leftKnee.rotation.z += (this.tLeftKneeRotZ - this.leftKnee.rotation.z) / speed;
|
||||
|
||||
this.lips.position.x += (this.tLipsPosX - this.lips.position.x) / speed;
|
||||
this.lips.position.y += (this.tLipsPosY - this.lips.position.y) / speed;
|
||||
this.smile.position.x += (this.tSmilePosX - this.smile.position.x) / speed;
|
||||
this.mouth.position.z += (this.tMouthPosZ - this.mouth.position.z) / speed;
|
||||
this.smile.position.z += (this.tSmilePosZ - this.smile.position.z) / speed;
|
||||
this.smile.position.y += (this.tSmilePosY - this.smile.position.y) / speed;
|
||||
this.smile.rotation.z += (this.tSmileRotZ - this.smile.rotation.z) / speed;
|
||||
}
|
||||
|
||||
Lion.prototype.look = function(xTarget, yTarget){
|
||||
this.tHeagRotY = rule3(xTarget, -200, 200, -Math.PI/4, Math.PI/4);
|
||||
this.tHeadRotX = rule3(yTarget, -200,200, -Math.PI/4, Math.PI/4);
|
||||
this.tHeadPosX = rule3(xTarget, -200, 200, 70,-70);
|
||||
this.tHeadPosY = rule3(yTarget, -140, 260, 20, 100);
|
||||
this.tHeadPosZ = 0;
|
||||
|
||||
|
||||
this.tEyeScale = 1;
|
||||
this.tIrisYScale = 1;
|
||||
this.tIrisZScale = 1;
|
||||
this.tIrisPosY = rule3(yTarget, -200,200, 35,15);
|
||||
this.tLeftIrisPosZ = rule3(xTarget, -200, 200, 130, 110);
|
||||
this.tRightIrisPosZ = rule3(xTarget, -200, 200, 110, 130);
|
||||
|
||||
this.tLipsPosX = 0;
|
||||
this.tLipsPosY = -45;
|
||||
|
||||
this.tSmilePosX = 0;
|
||||
this.tMouthPosZ = 174;
|
||||
this.tSmilePosZ = 173;
|
||||
this.tSmilePosY = -15;
|
||||
this.tSmileRotZ = -Math.PI;
|
||||
|
||||
this.tRightKneeRotZ = rule3(xTarget, -200, 200, .3-Math.PI/8, .3+Math.PI/8);
|
||||
this.tLeftKneeRotZ = rule3(xTarget, -200, 200, -.3-Math.PI/8, -.3+Math.PI/8)
|
||||
|
||||
|
||||
this.updateBody(10);
|
||||
|
||||
this.mane.rotation.y = 0;
|
||||
this.mane.rotation.x = 0;
|
||||
|
||||
for (var i=0; i<this.maneParts.length; i++){
|
||||
var m = this.maneParts[i].mesh;
|
||||
m.position.z = 0;
|
||||
m.rotation.y = 0;
|
||||
}
|
||||
|
||||
for (var i=0; i<this.mustaches.length; i++){
|
||||
var m = this.mustaches[i];
|
||||
m.rotation.y = 0;
|
||||
}
|
||||
|
||||
|
||||
for (var i=0; i<this.bodyVertices.length; i++){
|
||||
var tvInit = this.bodyInitPositions[i];
|
||||
var tv = this.body.geometry.vertices[this.bodyVertices[i]];
|
||||
tv.x = tvInit.x + this.head.position.x;
|
||||
}
|
||||
this.body.geometry.verticesNeedUpdate = true;
|
||||
}
|
||||
|
||||
Lion.prototype.cool = function(xTarget, yTarget){
|
||||
this.tHeagRotY = rule3(xTarget, -200, 200, Math.PI/4, -Math.PI/4);
|
||||
this.tHeadRotX = rule3(yTarget, -200,200, Math.PI/4, -Math.PI/4);
|
||||
this.tHeadPosX = rule3(xTarget, -200, 200, -70,70);
|
||||
this.tHeadPosY = rule3(yTarget, -140, 260, 100, 20);
|
||||
this.tHeadPosZ = 100;
|
||||
|
||||
this.tEyeScale = 0.1;
|
||||
this.tIrisYScale = 0.1;
|
||||
this.tIrisZScale = 3;
|
||||
|
||||
this.tIrisPosY = 20;
|
||||
this.tLeftIrisPosZ = 120;
|
||||
this.tRightIrisPosZ = 120;
|
||||
|
||||
this.tLipsPosX = rule3(xTarget, -200, 200, -15,15);
|
||||
this.tLipsPosY = rule3(yTarget, -200, 200, -45,-40);
|
||||
|
||||
this.tMouthPosZ = 168;
|
||||
this.tSmilePosX = rule3(xTarget, -200, 200, -15,15);
|
||||
this.tSmilePosY = rule3(yTarget, -200, 200, -20,-8);
|
||||
this.tSmilePosZ = 176;
|
||||
this.tSmileRotZ = rule3(xTarget, -200, 200, -Math.PI-.3, -Math.PI+.3);
|
||||
|
||||
this.tRightKneeRotZ = rule3(xTarget, -200, 200, .3+Math.PI/8, .3-Math.PI/8);
|
||||
this.tLeftKneeRotZ = rule3(xTarget, -200, 200, -.3+Math.PI/8, -.3-Math.PI/8);
|
||||
|
||||
this.updateBody(10);
|
||||
|
||||
this.mane.rotation.y = -.8*this.head.rotation.y;
|
||||
this.mane.rotation.x = -.8*this.head.rotation.x;
|
||||
|
||||
var dt = 20000 / (xTarget*xTarget+yTarget*yTarget);
|
||||
dt = Math.max(Math.min(dt,1), .5);
|
||||
this.windTime += dt;
|
||||
|
||||
for (var i=0; i<this.maneParts.length; i++){
|
||||
var m = this.maneParts[i].mesh;
|
||||
var amp = this.maneParts[i].amp;
|
||||
var zOffset = this.maneParts[i].zOffset;
|
||||
var periodOffset = this.maneParts[i].periodOffset;
|
||||
|
||||
m.position.z = zOffset + Math.cos(this.windTime+periodOffset)*amp*dt*2;
|
||||
}
|
||||
|
||||
this.leftEar.rotation.x = Math.cos(this.windTime)*Math.PI/16*dt;
|
||||
this.rightEar.rotation.x = -Math.cos(this.windTime)*Math.PI/16*dt;
|
||||
|
||||
|
||||
for (var i=0; i<this.mustaches.length; i++){
|
||||
var m = this.mustaches[i];
|
||||
var amp = (i<3) ? -Math.PI/8 : Math.PI/8;
|
||||
m.rotation.y = amp + Math.cos(this.windTime + i)*dt*amp;
|
||||
};
|
||||
|
||||
for (var i=0; i<this.bodyVertices.length; i++){
|
||||
var tvInit = this.bodyInitPositions[i];
|
||||
var tv = this.body.geometry.vertices[this.bodyVertices[i]];
|
||||
tv.x = tvInit.x + this.head.position.x;
|
||||
}
|
||||
this.body.geometry.verticesNeedUpdate = true;
|
||||
}
|
||||
|
||||
function loop(){
|
||||
render();
|
||||
var xTarget = (mousePos.x-windowHalfX);
|
||||
var yTarget= (mousePos.y-windowHalfY);
|
||||
|
||||
fan.isBlowing = isBlowing;
|
||||
fan.update(xTarget, yTarget);
|
||||
if(isBlowing) {
|
||||
lion.cool(xTarget, yTarget);
|
||||
}else{
|
||||
lion.look(xTarget, yTarget);
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
function render(){
|
||||
if (controls) controls.update();
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
createLights();
|
||||
createFloor();
|
||||
createLion();
|
||||
createFan();
|
||||
loop();
|
||||
|
||||
|
||||
function clamp(v,min, max){
|
||||
return Math.min(Math.max(v, min), max);
|
||||
}
|
||||
|
||||
function rule3(v,vmin,vmax,tmin, tmax){
|
||||
var nv = Math.max(Math.min(v,vmax), vmin);
|
||||
var dv = vmax-vmin;
|
||||
var pc = (nv-vmin)/dv;
|
||||
var dt = tmax-tmin;
|
||||
var tv = tmin + (pc*dt);
|
||||
return tv;
|
||||
|
||||
}
|
||||
652
游戏-2.响应式2048小游戏/css/style.css
Normal file
652
游戏-2.响应式2048小游戏/css/style.css
Normal file
@@ -0,0 +1,652 @@
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline
|
||||
}
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style: none
|
||||
}
|
||||
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none
|
||||
}
|
||||
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0
|
||||
}
|
||||
|
||||
@charset "UTF-8";
|
||||
@import url("https://fonts.googleapis.com/css?family=Arvo");
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1B9AAA;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid currentColor;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #14727e;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
a:active {
|
||||
color: #0d4a52;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
font-family: "Arvo", Helvetica, sans-serif;
|
||||
font-family: 12px;
|
||||
color: #555;
|
||||
background: #F8FFE5;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.6;
|
||||
font-size: 16px;
|
||||
}
|
||||
@media screen and (max-width:400px) {
|
||||
.haiyong{
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.inspired {
|
||||
margin-top: 1em;
|
||||
font-size: 0.9rem;
|
||||
color: #9a9a95;
|
||||
}
|
||||
|
||||
header {
|
||||
color: #F8FFE5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header span {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
margin: 0 0.4rem;
|
||||
background: #FFC43D;
|
||||
}
|
||||
@media screen and (max-width:440px) {
|
||||
header span {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
line-height: 3rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width:375px) {
|
||||
header span {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
header span:nth-of-type(2) {
|
||||
background: #EF476F;
|
||||
}
|
||||
|
||||
header span:nth-of-type(3) {
|
||||
background: #1B9AAA;
|
||||
}
|
||||
|
||||
header span:nth-of-type(4) {
|
||||
background: #06D6A0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.directions {
|
||||
padding: 2rem;
|
||||
border-top: 1px solid #9a9a95;
|
||||
border-bottom: 1px solid #9a9a95;
|
||||
}
|
||||
@media screen and (max-width:440px) {
|
||||
.directions{
|
||||
padding: 1rem;
|
||||
|
||||
}
|
||||
}
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
padding-bottom: 3.5rem;
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
max-width: 550px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header .container {
|
||||
padding: 0;
|
||||
padding: 2rem 4rem;
|
||||
max-width: 900px;
|
||||
}
|
||||
@media screen and (max-width:440px) {
|
||||
header .container {
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
}
|
||||
.scores {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.score-container {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin: 0.8rem;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.score-container.best-score {
|
||||
color: #9a9a95;
|
||||
}
|
||||
|
||||
.score {
|
||||
margin-left: 1rem;
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
font-size: 1.5rem;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.game {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
background: #9a9a95;
|
||||
padding: 7px;
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tile-container {
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
width: 270px;
|
||||
height: 270px;
|
||||
}
|
||||
|
||||
.tile,
|
||||
.background {
|
||||
display: block;
|
||||
color: #F8FFE5;
|
||||
position: absolute;
|
||||
width: 67.5px;
|
||||
height: 67.5px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.background {
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
border: 5px solid #9a9a95;
|
||||
background-color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile {
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
background: #FFC43D;
|
||||
color: #F8FFE5;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
font-size: 1.8rem;
|
||||
align-items: center;
|
||||
-webkit-transition: 110ms ease-in-out;
|
||||
transition: 110ms ease-in-out;
|
||||
border-radius: 3px;
|
||||
border: 7px solid #9a9a95;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tile--4 {
|
||||
background: #EF476F;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--8 {
|
||||
background: #1B9AAA;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--16 {
|
||||
background: #06D6A0;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--32 {
|
||||
background: #f37694;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--64 {
|
||||
background: #22c2d6;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--128 {
|
||||
background: #17f8be;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--256 {
|
||||
background: #ffd470;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--512 {
|
||||
background: #eb184a;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--1024 {
|
||||
background: #14727e;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--2048 {
|
||||
background: #05a47b;
|
||||
color: #F8FFE5;
|
||||
}
|
||||
|
||||
.tile--pop {
|
||||
-webkit-animation: pop 0.3s ease-in-out;
|
||||
animation: pop 0.3s ease-in-out;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.tile--shrink {
|
||||
-webkit-animation: shrink 0.5s ease-in-out;
|
||||
animation: shrink 0.5s ease-in-out;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.add {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: 120%;
|
||||
top: 0;
|
||||
font-size: 1rem;
|
||||
color: #1B9AAA;
|
||||
}
|
||||
|
||||
.add.active {
|
||||
-webkit-animation: add 0.8s ease-in-out;
|
||||
animation: add 0.8s ease-in-out;
|
||||
}
|
||||
|
||||
@-webkit-keyframes add {
|
||||
0% {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
top: -100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes add {
|
||||
0% {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
top: -100%;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes pop {
|
||||
0% {
|
||||
-webkit-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: scale(1.1);
|
||||
transform: scale(1.1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pop {
|
||||
0% {
|
||||
-webkit-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: scale(1.1);
|
||||
transform: scale(1.1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes shrink {
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(0.9);
|
||||
transform: scale(0.9);
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shrink {
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(0.9);
|
||||
transform: scale(0.9);
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.end {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
background: rgba(85, 85, 85, 0.9);
|
||||
color: white;
|
||||
font-size: 2rem;
|
||||
-webkit-transition: opacity 0.3s ease-in-out;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.end btn {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.end.active {
|
||||
opacity: 1;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.monkey {
|
||||
font-size: 3rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
background: #1B9AAA;
|
||||
letter-spacing: 1px;
|
||||
color: white;
|
||||
font-weight: 300;
|
||||
padding: 0.9em 1.5em;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #14727e;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background-color: #0d4a52;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
box-shadow: 0 0 10px #0d4a52 inset;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.not-recommended {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin-top: 0.8rem;
|
||||
}
|
||||
.not-recommended *+* {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.not-recommended__item+.not-recommended__annotation:before {
|
||||
font-size: 30px;
|
||||
content: "😐";
|
||||
}
|
||||
|
||||
.not-recommended__item:hover+.not-recommended__annotation:before {
|
||||
content: "😟";
|
||||
}
|
||||
|
||||
.not-recommended__item:focus+.not-recommended__annotation:before {
|
||||
content: "😄";
|
||||
}
|
||||
|
||||
.not-recommended__item:active+.not-recommended__annotation:before {
|
||||
content: "😨";
|
||||
}
|
||||
footer {
|
||||
background-color: #158ca5;
|
||||
bottom: 0;
|
||||
box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
left: 0;
|
||||
padding: 15px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
}
|
||||
footer a {
|
||||
color: white;
|
||||
}
|
||||
footer .center {
|
||||
justify-content: center;
|
||||
}
|
||||
65
游戏-2.响应式2048小游戏/index.html
Normal file
65
游戏-2.响应式2048小游戏/index.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=0">
|
||||
<title>海拥 | 2048</title>
|
||||
<meta name="keywords" content="游戏" />
|
||||
<meta name="description" content="游戏 | 2048小游戏;立志打造一个拥有100个小游戏的摸鱼网站。Made By Haiyong,技术支持——海拥" />
|
||||
<meta name="author" content="海拥(http://haiyong.site/game)" />
|
||||
<meta name="copyright" content="海拥(http://haiyong.site/game)" />
|
||||
<link rel="icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg" sizes="192x192" />
|
||||
<link rel="stylesheet" href="css/style.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div class="container">
|
||||
<h1><span>2</span><span>0</span><span>4</span><span>8</span></h1>
|
||||
<p class="inspired">by the 原2048的灵感</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<div class="directions">
|
||||
<p id="haiyong" class="haiyong"><strong>如何玩:</strong> 使用鼠标方向键键移动数字方块。相邻的两个方块数字相同,它们可合并成一个!</p>
|
||||
</div>
|
||||
<div class="scores">
|
||||
<div class="score-container best-score">
|
||||
历史最高
|
||||
<div class="score">
|
||||
<div id="bestScore">0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-container">
|
||||
分数:
|
||||
<div class="score">
|
||||
<div id="score">0</div>
|
||||
<div class="add" id="add"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="game">
|
||||
<div id="tile-container" class="tile-container"></div>
|
||||
<div class="end" id="end">游戏结束<div class="monkey">🙈</div><button class="btn not-recommended__item js-restart-btn"
|
||||
id="try-again">再试一次</button></div>
|
||||
</div>
|
||||
|
||||
<div class="not-recommended">
|
||||
<button class="btn not-recommended__item js-restart-btn" id="restart">重新启动游戏</button>
|
||||
<span class="not-recommended__annotation"></span>
|
||||
</div>
|
||||
<footer>
|
||||
<span class="author">Created by <a href="http://haiyong.site/index">Haiyong</a></span>
|
||||
|
||||
<span class="center">2048</span>
|
||||
|
||||
<span class="opposite">友链:<a href="https://www.captainai.net/haiyong">人工智能学习</a></span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
453
游戏-2.响应式2048小游戏/js/script.js
Normal file
453
游戏-2.响应式2048小游戏/js/script.js
Normal file
@@ -0,0 +1,453 @@
|
||||
'use strict';
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
var game = null;
|
||||
var bestScore = 0;
|
||||
var scoreDiv = document.getElementById('score');
|
||||
var bestScoreDiv = document.getElementById('bestScore');
|
||||
var addDiv = document.getElementById('add');
|
||||
var endDiv = document.getElementById('end');
|
||||
var size = 4;
|
||||
var nextId = 1;
|
||||
var score = 0;
|
||||
|
||||
function initGame() {
|
||||
game = Array(size * size).fill(null); // 4 x 4 grid, represented as an array
|
||||
initBestScore();
|
||||
}
|
||||
|
||||
function initBestScore() {
|
||||
bestScore = localStorage.getItem('bestScore') || 0;
|
||||
bestScoreDiv.innerHTML = bestScore;
|
||||
}
|
||||
|
||||
function updateDOM(before, after) {
|
||||
var newElements = getNewElementsDOM(before, after);
|
||||
var existingElements = getExistingElementsDOM(before, after);
|
||||
var mergedTiles = getMergedTiles(after);
|
||||
removeElements(mergedTiles);
|
||||
drawGame(newElements, true);
|
||||
drawGame(existingElements);
|
||||
}
|
||||
|
||||
function removeElements(mergedTiles) {
|
||||
for (var _iterator = mergedTiles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
var tile = _ref;
|
||||
|
||||
var _loop = function _loop() {
|
||||
if (_isArray2) {
|
||||
if (_i2 >= _iterator2.length) return 'break';
|
||||
_ref2 = _iterator2[_i2++];
|
||||
} else {
|
||||
_i2 = _iterator2.next();
|
||||
if (_i2.done) return 'break';
|
||||
_ref2 = _i2.value;
|
||||
}
|
||||
|
||||
var id = _ref2;
|
||||
|
||||
var currentElm = document.getElementById(id);
|
||||
positionTile(tile, currentElm);
|
||||
currentElm.classList.add('tile--shrink');
|
||||
setTimeout(function () {
|
||||
currentElm.remove();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
for (var _iterator2 = tile.mergedIds, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
||||
var _ref2;
|
||||
|
||||
var _ret = _loop();
|
||||
|
||||
if (_ret === 'break') break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMergedTiles(after) {
|
||||
return after.filter(function (tile) {
|
||||
return tile && tile.mergedIds;
|
||||
});
|
||||
}
|
||||
|
||||
function getNewElementsDOM(before, after) {
|
||||
var beforeIds = before.filter(function (tile) {
|
||||
return tile;
|
||||
}).map(function (tile) {
|
||||
return tile.id;
|
||||
});
|
||||
var newElements = after.filter(function (tile) {
|
||||
return tile && beforeIds.indexOf(tile.id) === -1;
|
||||
});
|
||||
return newElements;
|
||||
}
|
||||
|
||||
function getExistingElementsDOM(before, after) {
|
||||
var beforeIds = before.filter(function (tile) {
|
||||
return tile;
|
||||
}).map(function (tile) {
|
||||
return tile.id;
|
||||
});
|
||||
var existingElements = after.filter(function (tile) {
|
||||
return tile && beforeIds.indexOf(tile.id) !== -1;
|
||||
});
|
||||
return existingElements;
|
||||
}
|
||||
|
||||
function drawBackground() {
|
||||
var tileContainer = document.getElementById('tile-container');
|
||||
tileContainer.innerHTML = '';
|
||||
for (var i = 0; i < game.length; i++) {
|
||||
var tile = game[i];
|
||||
var tileDiv = document.createElement('div');
|
||||
var x = i % size;
|
||||
var y = Math.floor(i / size);
|
||||
tileDiv.style.top = y * 67.5 + 'px';
|
||||
tileDiv.style.left = x * 67.5 + 'px';
|
||||
|
||||
tileDiv.classList.add("background");
|
||||
tileContainer.appendChild(tileDiv);
|
||||
}
|
||||
}
|
||||
|
||||
function positionTile(tile, elm) {
|
||||
var x = tile.index % size;
|
||||
var y = Math.floor(tile.index / size);
|
||||
elm.style.top = y * 67.5 + 'px';
|
||||
elm.style.left = x * 67.5 + 'px';
|
||||
}
|
||||
|
||||
function drawGame(tiles, isNew) {
|
||||
var tileContainer = document.getElementById('tile-container');
|
||||
for (var i = 0; i < tiles.length; i++) {
|
||||
var tile = tiles[i];
|
||||
if (tile) {
|
||||
if (isNew) {
|
||||
(function () {
|
||||
var tileDiv = document.createElement('div');
|
||||
positionTile(tile, tileDiv);
|
||||
tileDiv.classList.add('tile', 'tile--' + tile.value);
|
||||
tileDiv.id = tile.id;
|
||||
setTimeout(function () {
|
||||
tileDiv.classList.add("tile--pop");
|
||||
}, tile.mergedIds ? 1 : 150);
|
||||
tileDiv.innerHTML = '<p>' + tile.value + '</p>';
|
||||
tileContainer.appendChild(tileDiv);
|
||||
})();
|
||||
} else {
|
||||
var currentElement = document.getElementById(tile.id);
|
||||
positionTile(tile, currentElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function gameOver() {
|
||||
if (game.filter(function (number) {
|
||||
return number === null;
|
||||
}).length === 0) {
|
||||
var sameNeighbors = game.find(function (tile, i) {
|
||||
var isRightSame = game[i + 1] && (i + 1) % 4 !== 0 ? tile.value === game[i + 1].value : false;
|
||||
var isDownSame = game[i + 4] ? tile.value === game[i + 4].value : false;
|
||||
if (isRightSame || isDownSame) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return !sameNeighbors;
|
||||
}
|
||||
}
|
||||
|
||||
function generateNewNumber() {
|
||||
// 0.9 probability of 2, 0.1 probability of 4
|
||||
var p = Math.random() * 100;
|
||||
return p <= 90 ? 2 : 4;
|
||||
}
|
||||
|
||||
function addRandomNumber() {
|
||||
// Adds either a 2 or a 4 to an empty position in the game array
|
||||
var emptyCells = game.map(function (_, index) {
|
||||
return index;
|
||||
}).filter(function (index) {
|
||||
return game[index] === null;
|
||||
});
|
||||
if (emptyCells.length === 0) {
|
||||
return;
|
||||
}
|
||||
var newPos = emptyCells[Math.floor(Math.random() * emptyCells.length)];
|
||||
var newObj = {
|
||||
id: nextId++,
|
||||
index: newPos,
|
||||
value: generateNewNumber()
|
||||
};
|
||||
game.splice(newPos, 1, newObj);
|
||||
}
|
||||
|
||||
function getIndexForPoint(x, y) {
|
||||
return y * size + x;
|
||||
}
|
||||
|
||||
function reflectGrid(grid) {
|
||||
var reflectedGame = Array(size * size).fill(0);
|
||||
for (var row = 0; row < size; row++) {
|
||||
for (var col = 0; col < size; col++) {
|
||||
var index1 = getIndexForPoint(col, row);
|
||||
var index2 = getIndexForPoint(size - col - 1, row);
|
||||
reflectedGame[index1] = grid[index2];
|
||||
}
|
||||
}
|
||||
return reflectedGame;
|
||||
}
|
||||
|
||||
function rotateLeft90Deg(grid) {
|
||||
var rotatedGame = Array(size * size).fill(0);
|
||||
for (var row = 0; row < size; row++) {
|
||||
for (var col = 0; col < size; col++) {
|
||||
var index1 = getIndexForPoint(col, row);
|
||||
var index2 = getIndexForPoint(size - 1 - row, col);
|
||||
rotatedGame[index1] = grid[index2];
|
||||
}
|
||||
}
|
||||
return rotatedGame;
|
||||
}
|
||||
|
||||
function rotateRight90Deg(grid) {
|
||||
var rotatedGame = Array(size * size).fill(0);
|
||||
for (var row = 0; row < size; row++) {
|
||||
for (var col = 0; col < size; col++) {
|
||||
var index1 = getIndexForPoint(col, row);
|
||||
var index2 = getIndexForPoint(row, size - 1 - col);
|
||||
rotatedGame[index1] = grid[index2];
|
||||
}
|
||||
}
|
||||
return rotatedGame;
|
||||
}
|
||||
|
||||
/*
|
||||
For any cell whose neighbor to the right is empty, move that cell
|
||||
to the right. For any cell whose neighbor to the right is equal
|
||||
to the same value, combine the values together (e.g. 2+2 = 4)
|
||||
*/
|
||||
function shiftGameRight(gameGrid) {
|
||||
// reflect game grid
|
||||
var reflectedGame = reflectGrid(gameGrid);
|
||||
// shift left
|
||||
reflectedGame = shiftGameLeft(reflectedGame);
|
||||
// reflect back
|
||||
return reflectGrid(reflectedGame);
|
||||
}
|
||||
|
||||
function shiftGameLeft(gameGrid) {
|
||||
var newGameState = [];
|
||||
var totalAdd = 0;
|
||||
// for rows
|
||||
for (var i = 0; i < size; i++) {
|
||||
// for columns
|
||||
var firstPos = 4 * i;
|
||||
var lastPos = size + 4 * i;
|
||||
var currentRow = gameGrid.slice(firstPos, lastPos);
|
||||
var filteredRow = currentRow.filter(function (row) {
|
||||
return row;
|
||||
});
|
||||
for (var _iterator3 = filteredRow, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
|
||||
var _ref3;
|
||||
|
||||
if (_isArray3) {
|
||||
if (_i3 >= _iterator3.length) break;
|
||||
_ref3 = _iterator3[_i3++];
|
||||
} else {
|
||||
_i3 = _iterator3.next();
|
||||
if (_i3.done) break;
|
||||
_ref3 = _i3.value;
|
||||
}
|
||||
|
||||
var row = _ref3;
|
||||
|
||||
delete row.mergedIds;
|
||||
}
|
||||
|
||||
for (var j = 0; j < filteredRow.length - 1; j++) {
|
||||
if (filteredRow[j].value === filteredRow[j + 1].value) {
|
||||
var sum = filteredRow[j].value * 2;
|
||||
filteredRow[j] = {
|
||||
id: nextId++,
|
||||
mergedIds: [filteredRow[j].id, filteredRow[j + 1].id],
|
||||
value: sum
|
||||
};
|
||||
filteredRow.splice(j + 1, 1);
|
||||
score += sum;
|
||||
totalAdd += sum;
|
||||
}
|
||||
}
|
||||
while (filteredRow.length < size) {
|
||||
filteredRow.push(null);
|
||||
};
|
||||
newGameState = [].concat(newGameState, filteredRow);
|
||||
}
|
||||
|
||||
if (totalAdd > 0) {
|
||||
scoreDiv.innerHTML = score;
|
||||
addDiv.innerHTML = '+' + totalAdd;
|
||||
addDiv.classList.add('active');
|
||||
setTimeout(function () {
|
||||
addDiv.classList.remove("active");
|
||||
}, 800);
|
||||
if (score > bestScore) {
|
||||
localStorage.setItem('bestScore', score);
|
||||
initBestScore();
|
||||
}
|
||||
}
|
||||
return newGameState;
|
||||
}
|
||||
|
||||
function shiftGameUp(gameGrid) {
|
||||
var rotatedGame = rotateLeft90Deg(gameGrid);
|
||||
rotatedGame = shiftGameLeft(rotatedGame);
|
||||
return rotateRight90Deg(rotatedGame);
|
||||
}
|
||||
|
||||
function shiftGameDown(gameGrid) {
|
||||
var rotatedGame = rotateRight90Deg(gameGrid);
|
||||
rotatedGame = shiftGameLeft(rotatedGame);
|
||||
return rotateLeft90Deg(rotatedGame);
|
||||
}
|
||||
|
||||
var buttons = document.querySelectorAll(".js-restart-btn");
|
||||
var length = buttons.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (document.addEventListener) {
|
||||
buttons[i].addEventListener("click", function () {
|
||||
newGameStart();
|
||||
});
|
||||
} else {
|
||||
buttons[i].attachEvent("onclick", function () {
|
||||
newGameStart();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleKeypress);
|
||||
document.addEventListener('touchstart', handleTouchStart, false);
|
||||
document.addEventListener('touchmove', handleTouchMove, false);
|
||||
|
||||
var xDown = null;
|
||||
var yDown = null;
|
||||
|
||||
function handleTouchStart(evt) {
|
||||
xDown = evt.touches[0].clientX;
|
||||
yDown = evt.touches[0].clientY;
|
||||
};
|
||||
|
||||
function handleTouchMove(evt) {
|
||||
var prevGame = [].concat(game);
|
||||
if (!xDown || !yDown) {
|
||||
return;
|
||||
}
|
||||
var xUp = evt.touches[0].clientX;
|
||||
var yUp = evt.touches[0].clientY;
|
||||
|
||||
var xDiff = xDown - xUp;
|
||||
var yDiff = yDown - yUp;
|
||||
|
||||
if (Math.abs(xDiff) > Math.abs(yDiff)) {
|
||||
if (xDiff > 0) {
|
||||
game = shiftGameLeft(game);
|
||||
} else {
|
||||
game = shiftGameRight(game);
|
||||
}
|
||||
} else {
|
||||
if (yDiff > 0) {
|
||||
game = shiftGameUp(game);
|
||||
} else {
|
||||
game = shiftGameDown(game);
|
||||
}
|
||||
}
|
||||
game = game.map(function (tile, index) {
|
||||
if (tile) {
|
||||
return _extends({}, tile, {
|
||||
index: index
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
addRandomNumber();
|
||||
updateDOM(prevGame, game);
|
||||
if (gameOver()) {
|
||||
setTimeout(function () {
|
||||
endDiv.classList.add('active');
|
||||
}, 800);
|
||||
return;
|
||||
}
|
||||
xDown = null;
|
||||
yDown = null;
|
||||
};
|
||||
|
||||
function handleKeypress(evt) {
|
||||
var modifiers = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
|
||||
var whichKey = event.which;
|
||||
|
||||
var prevGame = [].concat(game);
|
||||
|
||||
if (!modifiers) {
|
||||
event.preventDefault();
|
||||
switch (whichKey) {
|
||||
case 37:
|
||||
game = shiftGameLeft(game);
|
||||
break;
|
||||
case 38:
|
||||
game = shiftGameUp(game);
|
||||
break;
|
||||
case 39:
|
||||
game = shiftGameRight(game);
|
||||
break;
|
||||
case 40:
|
||||
game = shiftGameDown(game);
|
||||
break;
|
||||
}
|
||||
game = game.map(function (tile, index) {
|
||||
if (tile) {
|
||||
return _extends({}, tile, {
|
||||
index: index
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
addRandomNumber();
|
||||
updateDOM(prevGame, game);
|
||||
if (gameOver()) {
|
||||
setTimeout(function () {
|
||||
endDiv.classList.add('active');
|
||||
}, 800);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function newGameStart() {
|
||||
document.getElementById('tile-container').innerHTML = '';
|
||||
endDiv.classList.remove('active');
|
||||
score = 0;
|
||||
scoreDiv.innerHTML = score;
|
||||
initGame();
|
||||
drawBackground();
|
||||
var previousGame = [].concat(game);
|
||||
addRandomNumber();
|
||||
addRandomNumber();
|
||||
updateDOM(previousGame, game);
|
||||
}
|
||||
|
||||
newGameStart();
|
||||
5
游戏-3.飞机躲避障碍/css/style.css
Normal file
5
游戏-3.飞机躲避障碍/css/style.css
Normal file
@@ -0,0 +1,5 @@
|
||||
*{margin:0px;padding:0px; font-family: "微软雅黑";}
|
||||
html,iframe,body{height:100%}
|
||||
.none{display:none !important}
|
||||
@media screen and (max-width: 640px){#mobileFrame{display:none !important;}}
|
||||
#hidemobile{font-size: 14px;font-weight: bold;border: 1px solid silver;position: absolute;right: 20px;top: 8px;width: 15px;height: 15px;text-align: center;padding: 0;line-height: 15px;border-radius: 15px;cursor:pointer;}
|
||||
24
游戏-3.飞机躲避障碍/index.html
Normal file
24
游戏-3.飞机躲避障碍/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
|
||||
<title>海拥 | 飞机躲避障碍</title>
|
||||
<link rel="icon" type="image/x-icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg"/>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="js/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="https://www.jsdaima.com/Uploads/js/201804/1523085687/index.html" frameborder="0" width="100%" height="100%"></iframe>
|
||||
</body>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
7
游戏-3.飞机躲避障碍/js/script.js
Normal file
7
游戏-3.飞机躲避障碍/js/script.js
Normal file
@@ -0,0 +1,7 @@
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
54
游戏-4.圣诞老人过桥/css/style.css
Normal file
54
游戏-4.圣诞老人过桥/css/style.css
Normal file
@@ -0,0 +1,54 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
cursor: grab;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
background-color: #1e1a33;
|
||||
}
|
||||
|
||||
div,
|
||||
i {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
i {
|
||||
position: fixed;
|
||||
color: white;
|
||||
top: -10%;
|
||||
z-index: 9999;
|
||||
animation-name: snowflakes-fall, snowflakes-shake;
|
||||
animation-duration: 10s, 3s;
|
||||
animation-timing-function: linear, ease-in-out;
|
||||
animation-iteration-count: infinite, infinite;
|
||||
animation-play-state: running, running;
|
||||
}
|
||||
|
||||
@keyframes snowflakes-fall {
|
||||
0% {
|
||||
top: -10%;
|
||||
}
|
||||
100% {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes snowflakes-shake {
|
||||
0% {
|
||||
transform: translateX(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(80px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0px);
|
||||
}
|
||||
}
|
||||
23
游戏-4.圣诞老人过桥/index.html
Normal file
23
游戏-4.圣诞老人过桥/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" >
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>海拥 | 圣诞老人过桥</title>
|
||||
<link rel="icon" type="image/x-icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg"/>
|
||||
<link rel="stylesheet" href="https://demo.mycodes.net/html5/guoxuanya/css/style.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script src="js/script.js"></script>
|
||||
<script type="module">
|
||||
import { quotes } from "http://haiyong.site/wp-includes/js/quotes.js";
|
||||
let randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
|
||||
console.log(
|
||||
`%c✨ ${randomQuote}`,
|
||||
"font-size:20px; background:#FFF; color:#581845;padding:10px; border: 3px solid #581845;border-radius:10px;"
|
||||
);</script>
|
||||
<div style="text-align:center;">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
655
游戏-4.圣诞老人过桥/js/script.js
Normal file
655
游戏-4.圣诞老人过桥/js/script.js
Normal file
@@ -0,0 +1,655 @@
|
||||
let status = "waiting";
|
||||
let lastTimestamp;
|
||||
let santaX;
|
||||
let santaY;
|
||||
let sceneOffset;
|
||||
let score = 0;
|
||||
let platforms = [];
|
||||
let sticks = [];
|
||||
let trees = [];
|
||||
let clouds = [];
|
||||
|
||||
const config = {
|
||||
canvasWidth: 375,
|
||||
canvasHeight: 375,
|
||||
platformHeight: 100,
|
||||
santaDistanceFromEdge: 10,
|
||||
paddingX: 100,
|
||||
perfectAreaSize: 10,
|
||||
backgroundSpeedMultiplier: 0.2,
|
||||
speed: 4,
|
||||
santaWidth: 17,
|
||||
santaHeight: 30
|
||||
};
|
||||
|
||||
const colours = {
|
||||
lightBg: "#62AFB9",
|
||||
medBg: "#182757",
|
||||
darkBg: "#0D5B66",
|
||||
lightHill: "#E9E9E9",
|
||||
medHill: "#34A65F",
|
||||
darkHill: "#07133A",
|
||||
platform: "#9B4546",
|
||||
platformTop: "#620E0E",
|
||||
em: "#CC231E",
|
||||
skin: "#CF6D60"
|
||||
};
|
||||
|
||||
const hills = [
|
||||
{
|
||||
baseHeight: 120,
|
||||
amplitude: 20,
|
||||
stretch: 0.5,
|
||||
colour: colours.lightHill
|
||||
},
|
||||
{
|
||||
baseHeight: 100,
|
||||
amplitude: 10,
|
||||
stretch: 1,
|
||||
colour: colours.medHill
|
||||
},
|
||||
{
|
||||
baseHeight: 70,
|
||||
amplitude: 20,
|
||||
stretch: 0.5,
|
||||
colour: colours.darkHill
|
||||
}
|
||||
];
|
||||
|
||||
const scoreElement = createElementStyle(
|
||||
"div",
|
||||
`position:absolute;top:1.5em;font-size:5em;font-weight:900;text-shadow:${addShadow(
|
||||
colours.darkHill,
|
||||
7
|
||||
)}`
|
||||
);
|
||||
const canvas = createElementStyle("canvas");
|
||||
const introductionElement = createElementStyle(
|
||||
"div",
|
||||
`font-size:1.2em;position:absolute;text-align:center;transition:opacity 2s;width:250px`,
|
||||
"按住任意位置以伸出杆子,确定好他的长度,否则圣诞老人会掉下来"
|
||||
);
|
||||
const perfectElement = createElementStyle(
|
||||
"div",
|
||||
"position:absolute;opacity:0;transition:opacity 2s",
|
||||
"双倍分数"
|
||||
);
|
||||
const restartButton = createElementStyle(
|
||||
"button",
|
||||
`width:120px;height:120px;position:absolute;border-radius:50%;color:white;background-color:${colours.em};border:none;font-weight:700;font-size:1.2em;display:none;cursor:pointer`,
|
||||
"重新开始"
|
||||
);
|
||||
|
||||
for (let i = 0; i <= 30; i++) {
|
||||
createElementStyle(
|
||||
"i",
|
||||
`font-size: ${3 * Math.random()}em;left: ${
|
||||
100 * Math.random()
|
||||
}%; animation-delay: ${10 * Math.random()}s, ${2 * Math.random()}s`,
|
||||
"."
|
||||
);
|
||||
}
|
||||
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
Array.prototype.last = function () {
|
||||
return this[this.length - 1];
|
||||
};
|
||||
|
||||
Math.sinus = function (degree) {
|
||||
return Math.sin((degree / 180) * Math.PI);
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", function (event) {
|
||||
if (event.key == " ") {
|
||||
event.preventDefault();
|
||||
resetGame();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
["mousedown", "touchstart"].forEach(function (evt) {
|
||||
window.addEventListener(evt, function (event) {
|
||||
if (status == "waiting") {
|
||||
lastTimestamp = undefined;
|
||||
introductionElement.style.opacity = 0;
|
||||
status = "stretching";
|
||||
window.requestAnimationFrame(animate);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
["mouseup", "touchend"].forEach(function (evt) {
|
||||
window.addEventListener(evt, function (event) {
|
||||
if (status == "stretching") {
|
||||
status = "turning";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function (event) {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
draw();
|
||||
});
|
||||
|
||||
restartButton.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
resetGame();
|
||||
restartButton.style.display = "none";
|
||||
});
|
||||
|
||||
window.requestAnimationFrame(animate);
|
||||
|
||||
resetGame();
|
||||
|
||||
function resetGame() {
|
||||
status = "waiting";
|
||||
lastTimestamp = undefined;
|
||||
sceneOffset = 0;
|
||||
score = 0;
|
||||
introductionElement.style.opacity = 1;
|
||||
perfectElement.style.opacity = 0;
|
||||
restartButton.style.display = "none";
|
||||
scoreElement.innerText = score;
|
||||
platforms = [{ x: 50, w: 50 }];
|
||||
santaX = platforms[0].x + platforms[0].w - config.santaDistanceFromEdge;
|
||||
santaY = 0;
|
||||
sticks = [{ x: platforms[0].x + platforms[0].w, length: 0, rotation: 0 }];
|
||||
trees = [];
|
||||
clouds = [];
|
||||
|
||||
for (let i = 0; i <= 20; i++) {
|
||||
if (i <= 3) generatePlatform();
|
||||
generateTree();
|
||||
generateCloud();
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
|
||||
function generateCloud() {
|
||||
const minimumGap = 60;
|
||||
const maximumGap = 300;
|
||||
|
||||
const lastCloud = clouds[clouds.length - 1];
|
||||
let furthestX = lastCloud ? lastCloud.x : 0;
|
||||
|
||||
const x =
|
||||
furthestX +
|
||||
minimumGap +
|
||||
Math.floor(Math.random() * (maximumGap - minimumGap));
|
||||
|
||||
const y =
|
||||
minimumGap +
|
||||
Math.floor(Math.random() * (maximumGap - minimumGap)) -
|
||||
window.innerHeight / 1.2;
|
||||
|
||||
const w = Math.floor(Math.random() * 15 + 15);
|
||||
clouds.push({ x, y, w });
|
||||
}
|
||||
|
||||
function generateTree() {
|
||||
const minimumGap = 30;
|
||||
const maximumGap = 150;
|
||||
|
||||
const lastTree = trees[trees.length - 1];
|
||||
let furthestX = lastTree ? lastTree.x : 0;
|
||||
|
||||
const x =
|
||||
furthestX +
|
||||
minimumGap +
|
||||
Math.floor(Math.random() * (maximumGap - minimumGap));
|
||||
|
||||
const treeColors = [colours.lightHill, colours.medBg, colours.medHill];
|
||||
const color = treeColors[Math.floor(Math.random() * 3)];
|
||||
|
||||
trees.push({ x, color });
|
||||
}
|
||||
|
||||
function generatePlatform() {
|
||||
const minimumGap = 40;
|
||||
const maximumGap = 200;
|
||||
const minimumWidth = 20;
|
||||
const maximumWidth = 100;
|
||||
|
||||
const lastPlatform = platforms[platforms.length - 1];
|
||||
let furthestX = lastPlatform.x + lastPlatform.w;
|
||||
|
||||
const x =
|
||||
furthestX +
|
||||
minimumGap +
|
||||
Math.floor(Math.random() * (maximumGap - minimumGap));
|
||||
const w =
|
||||
minimumWidth + Math.floor(Math.random() * (maximumWidth - minimumWidth));
|
||||
|
||||
platforms.push({ x, w });
|
||||
}
|
||||
|
||||
function animate(timestamp) {
|
||||
if (!lastTimestamp) {
|
||||
lastTimestamp = timestamp;
|
||||
window.requestAnimationFrame(animate);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case "waiting":
|
||||
return;
|
||||
case "stretching": {
|
||||
sticks.last().length += (timestamp - lastTimestamp) / config.speed;
|
||||
break;
|
||||
}
|
||||
case "turning": {
|
||||
sticks.last().rotation += (timestamp - lastTimestamp) / config.speed;
|
||||
|
||||
if (sticks.last().rotation > 90) {
|
||||
sticks.last().rotation = 90;
|
||||
|
||||
const [nextPlatform, perfectHit] = thePlatformTheStickHits();
|
||||
if (nextPlatform) {
|
||||
score += perfectHit ? 2 : 1;
|
||||
scoreElement.innerText = score;
|
||||
|
||||
if (perfectHit) {
|
||||
perfectElement.style.opacity = 1;
|
||||
setTimeout(() => (perfectElement.style.opacity = 0), 1000);
|
||||
}
|
||||
|
||||
generatePlatform();
|
||||
generateTree();
|
||||
generateTree();
|
||||
|
||||
generateCloud();
|
||||
generateCloud();
|
||||
}
|
||||
|
||||
status = "walking";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "walking": {
|
||||
santaX += (timestamp - lastTimestamp) / config.speed;
|
||||
|
||||
const [nextPlatform] = thePlatformTheStickHits();
|
||||
if (nextPlatform) {
|
||||
const maxSantaX =
|
||||
nextPlatform.x + nextPlatform.w - config.santaDistanceFromEdge;
|
||||
if (santaX > maxSantaX) {
|
||||
santaX = maxSantaX;
|
||||
status = "transitioning";
|
||||
}
|
||||
} else {
|
||||
const maxSantaX =
|
||||
sticks.last().x + sticks.last().length + config.santaWidth;
|
||||
if (santaX > maxSantaX) {
|
||||
santaX = maxSantaX;
|
||||
status = "falling";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "transitioning": {
|
||||
sceneOffset += (timestamp - lastTimestamp) / (config.speed / 2);
|
||||
|
||||
const [nextPlatform] = thePlatformTheStickHits();
|
||||
if (sceneOffset > nextPlatform.x + nextPlatform.w - config.paddingX) {
|
||||
sticks.push({
|
||||
x: nextPlatform.x + nextPlatform.w,
|
||||
length: 0,
|
||||
rotation: 0
|
||||
});
|
||||
status = "waiting";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "falling": {
|
||||
if (sticks.last().rotation < 180)
|
||||
sticks.last().rotation += (timestamp - lastTimestamp) / config.speed;
|
||||
|
||||
santaY += (timestamp - lastTimestamp) / (config.speed / 2);
|
||||
const maxSantaY =
|
||||
config.platformHeight +
|
||||
100 +
|
||||
(window.innerHeight - config.canvasHeight) / 2;
|
||||
if (santaY > maxSantaY) {
|
||||
restartButton.style.display = "block";
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Error("Wrong status");
|
||||
}
|
||||
|
||||
draw();
|
||||
window.requestAnimationFrame(animate);
|
||||
|
||||
lastTimestamp = timestamp;
|
||||
}
|
||||
|
||||
function thePlatformTheStickHits() {
|
||||
if (sticks.last().rotation != 90)
|
||||
throw Error(`Stick is ${sticks.last().rotation}°`);
|
||||
const stickFarX = sticks.last().x + sticks.last().length;
|
||||
|
||||
const platformTheStickHits = platforms.find(
|
||||
(platform) => platform.x < stickFarX && stickFarX < platform.x + platform.w
|
||||
);
|
||||
|
||||
if (
|
||||
platformTheStickHits &&
|
||||
platformTheStickHits.x +
|
||||
platformTheStickHits.w / 2 -
|
||||
config.perfectAreaSize / 2 <
|
||||
stickFarX &&
|
||||
stickFarX <
|
||||
platformTheStickHits.x +
|
||||
platformTheStickHits.w / 2 +
|
||||
config.perfectAreaSize / 2
|
||||
)
|
||||
return [platformTheStickHits, true];
|
||||
|
||||
return [platformTheStickHits, false];
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ctx.save();
|
||||
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
drawBackground();
|
||||
ctx.translate(
|
||||
(window.innerWidth - config.canvasWidth) / 2 - sceneOffset,
|
||||
(window.innerHeight - config.canvasHeight) / 2
|
||||
);
|
||||
|
||||
drawPlatforms();
|
||||
drawSanta();
|
||||
drawSticks();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawPlatforms() {
|
||||
platforms.forEach(({ x, w }) => {
|
||||
let newX = x + 3;
|
||||
let newW = w - 6;
|
||||
let platformHeight =
|
||||
config.platformHeight + (window.innerHeight - config.canvasHeight) / 2;
|
||||
ctx.fillStyle = colours.platform;
|
||||
ctx.fillRect(
|
||||
newX,
|
||||
config.canvasHeight - config.platformHeight,
|
||||
newW,
|
||||
platformHeight
|
||||
);
|
||||
|
||||
for (let i = 1; i <= platformHeight / 10; ++i) {
|
||||
let yGap = config.canvasHeight - config.platformHeight + i * 10;
|
||||
ctx.moveTo(newX, yGap);
|
||||
ctx.lineTo(newX + newW, yGap);
|
||||
let xGap = i % 2 ? 0 : 10;
|
||||
for (let j = 1; j < newW / 30; ++j) {
|
||||
let x = j * 20 + xGap;
|
||||
ctx.moveTo(newX + x, yGap);
|
||||
ctx.lineTo(newX + x, yGap + 10);
|
||||
}
|
||||
ctx.strokeStyle = colours.platformTop;
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
ctx.fillStyle = colours.platformTop;
|
||||
ctx.fillRect(x, config.canvasHeight - config.platformHeight, w, 10);
|
||||
|
||||
if (sticks.last().x < x) {
|
||||
ctx.fillStyle = "white";
|
||||
ctx.fillRect(
|
||||
x + w / 2 - config.perfectAreaSize / 2,
|
||||
config.canvasHeight - config.platformHeight,
|
||||
config.perfectAreaSize,
|
||||
config.perfectAreaSize
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function drawSanta() {
|
||||
ctx.save();
|
||||
ctx.fillStyle = "red";
|
||||
ctx.translate(
|
||||
santaX - config.santaWidth / 2,
|
||||
santaY +
|
||||
config.canvasHeight -
|
||||
config.platformHeight -
|
||||
config.santaHeight / 2
|
||||
);
|
||||
|
||||
ctx.fillRect(
|
||||
-config.santaWidth / 2,
|
||||
-config.santaHeight / 2,
|
||||
config.santaWidth,
|
||||
config.santaHeight - 4
|
||||
);
|
||||
|
||||
const legDistance = 5;
|
||||
ctx.beginPath();
|
||||
ctx.arc(legDistance, 11.5, 3, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.arc(-legDistance, 11.5, 3, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = colours.skin;
|
||||
ctx.arc(5, -7, 3, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = "white";
|
||||
ctx.arc(7, -2, 3, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = "red";
|
||||
ctx.moveTo(-8, -13.5);
|
||||
ctx.lineTo(-15, -3.5);
|
||||
ctx.lineTo(-5, -7);
|
||||
ctx.fill();
|
||||
|
||||
ctx.fillStyle = "white";
|
||||
ctx.fillRect(-config.santaWidth / 2, -12, config.santaWidth, 3);
|
||||
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(-config.santaWidth / 2, 2, config.santaWidth, 2);
|
||||
ctx.fillStyle = "white";
|
||||
ctx.fillRect(-config.santaWidth / 2, 4, config.santaWidth, 4.5);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = "white";
|
||||
ctx.arc(-17, -2, 3, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawSticks() {
|
||||
sticks.forEach((stick) => {
|
||||
ctx.save();
|
||||
|
||||
ctx.translate(stick.x, config.canvasHeight - config.platformHeight);
|
||||
ctx.rotate((Math.PI / 180) * stick.rotation);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = 4;
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.lineTo(0, -stick.length);
|
||||
|
||||
ctx.strokeStyle = ctx.createPattern(createCandyPattern(), "repeat");
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
});
|
||||
}
|
||||
|
||||
function drawBackground() {
|
||||
var gradient = ctx.createRadialGradient(
|
||||
window.innerWidth / 2,
|
||||
window.innerHeight / 2,
|
||||
0,
|
||||
window.innerHeight / 2,
|
||||
window.innerWidth / 2,
|
||||
window.innerWidth
|
||||
);
|
||||
gradient.addColorStop(0, colours.lightBg);
|
||||
gradient.addColorStop(1, colours.darkBg);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
|
||||
hills.forEach((hill) =>
|
||||
drawHill(hill.baseHeight, hill.amplitude, hill.stretch, hill.colour)
|
||||
);
|
||||
trees.forEach((tree) => drawTree(tree.x, tree.color));
|
||||
clouds.forEach((cloud) => drawCloud(cloud.x, cloud.y, cloud.w));
|
||||
}
|
||||
|
||||
function drawHill(baseHeight, amplitude, stretch, color) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, window.innerHeight);
|
||||
ctx.lineTo(0, getHillY(0, baseHeight, amplitude, stretch));
|
||||
for (let i = 0; i < window.innerWidth; i++) {
|
||||
ctx.lineTo(i, getHillY(i, baseHeight, amplitude, stretch));
|
||||
}
|
||||
ctx.lineTo(window.innerWidth, window.innerHeight);
|
||||
ctx.fillStyle = color;
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function drawTree(x, color) {
|
||||
ctx.save();
|
||||
ctx.translate(
|
||||
(-sceneOffset * config.backgroundSpeedMultiplier + x) * hills[1].stretch,
|
||||
getTreeY(x, hills[1].baseHeight, hills[1].amplitude)
|
||||
);
|
||||
|
||||
const treeTrunkHeight = 15;
|
||||
const treeTrunkWidth = 10;
|
||||
const treeCrownHeight = 60;
|
||||
const treeCrownWidth = 30;
|
||||
|
||||
// Draw trunk
|
||||
ctx.fillStyle = colours.darkHill;
|
||||
ctx.fillRect(
|
||||
-treeTrunkWidth / 2,
|
||||
-treeTrunkHeight,
|
||||
treeTrunkWidth,
|
||||
treeTrunkHeight
|
||||
);
|
||||
|
||||
// Draw crown
|
||||
ctx.beginPath();
|
||||
|
||||
ctx.moveTo(-treeCrownWidth / 2, -treeTrunkHeight * 3);
|
||||
ctx.lineTo(0, -(treeTrunkHeight + treeCrownHeight));
|
||||
ctx.lineTo(treeCrownWidth / 2, -treeTrunkHeight * 3);
|
||||
|
||||
ctx.moveTo(-treeCrownWidth / 2, -treeTrunkHeight * 2);
|
||||
ctx.lineTo(0, -(treeTrunkHeight / 2 + treeCrownHeight));
|
||||
ctx.lineTo(treeCrownWidth / 2, -treeTrunkHeight * 2);
|
||||
|
||||
ctx.moveTo(-treeCrownWidth / 2, -treeTrunkHeight);
|
||||
ctx.lineTo(0, -(treeTrunkHeight + treeCrownHeight / 2));
|
||||
ctx.lineTo(treeCrownWidth / 2, -treeTrunkHeight);
|
||||
|
||||
ctx.fillStyle = color;
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawCloud(x, y, width) {
|
||||
ctx.save();
|
||||
ctx.translate(
|
||||
(-sceneOffset * config.backgroundSpeedMultiplier + x) * hills[1].stretch,
|
||||
getTreeY(x, hills[1].baseHeight, hills[1].amplitude)
|
||||
);
|
||||
|
||||
height = width * 1.5;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, width, Math.PI * 0.5, Math.PI * 1.5);
|
||||
ctx.arc(x + height, y - width, height, Math.PI * 1, Math.PI * 2);
|
||||
ctx.arc(x + height * 2, y - width, height, Math.PI * 1.2, Math.PI);
|
||||
ctx.arc(x + width * 3, y, width, Math.PI * 1.5, Math.PI * 0.5);
|
||||
ctx.moveTo(x + width * 3, y + width);
|
||||
ctx.lineTo(x, y + width);
|
||||
ctx.fillStyle = "rgba(255, 255, 255, .3)";
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function createCandyPattern() {
|
||||
const patternCanvas = document.createElement("canvas");
|
||||
const pctx = patternCanvas.getContext("2d");
|
||||
|
||||
const max = 15;
|
||||
let i = 0;
|
||||
let x = 0;
|
||||
let z = 90;
|
||||
|
||||
while (i < max) {
|
||||
pctx.beginPath();
|
||||
pctx.moveTo(0, x);
|
||||
pctx.lineTo(0, z);
|
||||
pctx.lineWidth = 24;
|
||||
pctx.strokeStyle = "red";
|
||||
pctx.stroke();
|
||||
|
||||
pctx.beginPath();
|
||||
pctx.moveTo(0, x + 24);
|
||||
pctx.lineTo(0, z + 24);
|
||||
pctx.lineWidth = 24;
|
||||
pctx.strokeStyle = "white";
|
||||
pctx.stroke();
|
||||
|
||||
x += 48;
|
||||
z += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
return patternCanvas;
|
||||
}
|
||||
|
||||
function getHillY(windowX, baseHeight, amplitude, stretch) {
|
||||
const sineBaseY = window.innerHeight - baseHeight;
|
||||
return (
|
||||
Math.sinus(
|
||||
(sceneOffset * config.backgroundSpeedMultiplier + windowX) * stretch
|
||||
) *
|
||||
amplitude +
|
||||
sineBaseY
|
||||
);
|
||||
}
|
||||
|
||||
function getTreeY(x, baseHeight, amplitude) {
|
||||
const sineBaseY = window.innerHeight - baseHeight;
|
||||
return Math.sinus(x) * amplitude + sineBaseY;
|
||||
}
|
||||
|
||||
function createElementStyle(element, cssStyles = null, inner = null) {
|
||||
const g = document.createElement(element);
|
||||
if (cssStyles) g.style.cssText = cssStyles;
|
||||
if (inner) g.innerHTML = inner;
|
||||
document.body.appendChild(g);
|
||||
return g;
|
||||
}
|
||||
|
||||
function addShadow(colour, depth) {
|
||||
let shadow = "";
|
||||
for (let i = 0; i <= depth; i++) {
|
||||
shadow += `${i}px ${i}px 0 ${colour}`;
|
||||
shadow += i < depth ? ", " : "";
|
||||
}
|
||||
return shadow;
|
||||
}
|
||||
267
游戏-5.切方块/css/style.css
Normal file
267
游戏-5.切方块/css/style.css
Normal file
@@ -0,0 +1,267 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
64
游戏-5.切方块/index.html
Normal file
64
游戏-5.切方块/index.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>海拥 | 切方块</title>
|
||||
<meta name="keywords" content="游戏" />
|
||||
<meta name="description" content="海拥的游戏库,切方块,立志打造一个拥有100个小游戏和小工具的摸鱼网站。Made By Haiyong,技术支持——海拥" />
|
||||
<meta name="author" content="海拥(http://haiyong.site)" />
|
||||
<meta name="copyright" content="海拥(http://haiyong.site)" />
|
||||
<link rel="icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg" sizes="192x192" />
|
||||
<link rel="stylesheet" href="css/style.css"/>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</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 class="credits">一个 8 KB 的游戏 by<a href="http://haiyong.site/index"> 海拥</a><br><br>
|
||||
<a href="http://haiyong.site/moyu">摸鱼</a>
|
||||
</div>
|
||||
</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>
|
||||
</body>
|
||||
<script src="js/script.js"></script>
|
||||
</html>
|
||||
2184
游戏-5.切方块/js/script.js
Normal file
2184
游戏-5.切方块/js/script.js
Normal file
File diff suppressed because it is too large
Load Diff
311
游戏-6.打地鼠/css/style.css
Normal file
311
游戏-6.打地鼠/css/style.css
Normal file
@@ -0,0 +1,311 @@
|
||||
*,
|
||||
*::after,
|
||||
*::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
background-color: black;
|
||||
background-image: url('img/background1.png');
|
||||
}
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
.game {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 320px;
|
||||
height: 540px;
|
||||
padding: 20px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.holes {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.hole {
|
||||
position: relative;
|
||||
width: 150px;
|
||||
height: 120px;
|
||||
padding-top: 40px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hole__up {
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
background-image: url('img/hole-up.png');
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.hole__down {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
margin-top: -20px;
|
||||
background-image: url('img/hole-down.png');
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.mole {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-left: 23px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
animation-name: mole-def;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: backwards;
|
||||
}
|
||||
.mole:nth-of-type(1) {
|
||||
background-image: url('img/mole.png');
|
||||
}
|
||||
.mole:nth-of-type(2) {
|
||||
background-image: url('img/mole2.png');
|
||||
}
|
||||
.mole--1 {
|
||||
animation-duration: 3s;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
.mole--2 {
|
||||
animation-duration: 3s;
|
||||
animation-delay: 2.5s;
|
||||
}
|
||||
.mole--3 {
|
||||
animation-duration: 4s;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
.mole--4 {
|
||||
animation-duration: 4s;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
.mole--5 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
.mole--6 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 3.75s;
|
||||
}
|
||||
.mole--7 {
|
||||
animation-duration: 2.5s;
|
||||
animation-delay: 1.5s;
|
||||
}
|
||||
.mole--8 {
|
||||
animation-duration: 2.5s;
|
||||
animation-delay: 2.75s;
|
||||
}
|
||||
.mole--9 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
.mole--10 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 2.75s;
|
||||
}
|
||||
.mole--11 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 3s;
|
||||
}
|
||||
.mole--12 {
|
||||
animation-duration: 3.5s;
|
||||
animation-delay: 4.75s;
|
||||
}
|
||||
.mole-input:checked + .mole {
|
||||
display: none;
|
||||
}
|
||||
@keyframes mole-def {
|
||||
0% {
|
||||
transform: translateY(100px);
|
||||
}
|
||||
10% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
20% {
|
||||
transform: translateY(10px);
|
||||
}
|
||||
30% {
|
||||
transform: translateY(100px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(100px);
|
||||
}
|
||||
}
|
||||
.score {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
color: white;
|
||||
}
|
||||
.score__text {
|
||||
margin: 0;
|
||||
font-size: 50px;
|
||||
}
|
||||
.score__wrapper {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 67px;
|
||||
height: 67px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.score__wrapper-points {
|
||||
position: absolute;
|
||||
top: -857px;
|
||||
}
|
||||
.score__radio {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
opacity: 0;
|
||||
/* for iphone */
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
.score__radio:checked {
|
||||
height: 0;
|
||||
}
|
||||
.score__points {
|
||||
width: 67px;
|
||||
height: 908px;
|
||||
background-image: url('img/time.png');
|
||||
}
|
||||
.timer {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.timer__progress {
|
||||
height: 100%;
|
||||
transform: translate(0);
|
||||
background-color: darkred;
|
||||
box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4);
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: 1;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
.timer__progress::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent);
|
||||
z-index: 1;
|
||||
background-size: 50px 50px;
|
||||
animation: move 2s linear infinite;
|
||||
overflow: hidden;
|
||||
}
|
||||
@keyframes move {
|
||||
0% {
|
||||
background-position: 50px 50px;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
}
|
||||
@keyframes translate {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
#start-easy:checked ~ .game .timer .timer__progress {
|
||||
animation-duration: 15s;
|
||||
}
|
||||
#start-easy:checked ~ .screen--finish {
|
||||
animation-duration: 15s;
|
||||
}
|
||||
#start-medium:checked ~ .game .timer .timer__progress {
|
||||
animation-duration: 10s;
|
||||
}
|
||||
#start-medium:checked ~ .screen--finish {
|
||||
animation-duration: 10s;
|
||||
}
|
||||
#start-hard:checked ~ .game .timer .timer__progress {
|
||||
animation-duration: 7s;
|
||||
}
|
||||
#start-hard:checked ~ .screen--finish {
|
||||
animation-duration: 7s;
|
||||
}
|
||||
#start-ultra:checked ~ .game .timer .timer__progress {
|
||||
animation-duration: 5s;
|
||||
}
|
||||
#start-ultra:checked ~ .screen--finish {
|
||||
animation-duration: 5s;
|
||||
}
|
||||
.start:checked ~ .game .timer .timer__progress {
|
||||
animation-name: translate;
|
||||
}
|
||||
.start:checked ~ .screen--start {
|
||||
display: none;
|
||||
}
|
||||
.start:checked ~ .screen--finish {
|
||||
animation-name: bounce;
|
||||
}
|
||||
.screen {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
z-index: 1;
|
||||
padding: 20px;
|
||||
font-size: 30px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
.screen--finish {
|
||||
animation-iteration-count: 1;
|
||||
transform: translate3d(0, -3000px, 0);
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
.screen h1 {
|
||||
font-size: 40px;
|
||||
}
|
||||
.screen label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.screen a {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.screen__text {
|
||||
color: white;
|
||||
text-align: center;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.screen__wrapper {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
@keyframes bounce {
|
||||
95% {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, -3000px, 0);
|
||||
}
|
||||
100% {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
125
游戏-6.打地鼠/index.html
Normal file
125
游戏-6.打地鼠/index.html
Normal file
@@ -0,0 +1,125 @@
|
||||
<!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 charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="google-site-verification" content="i3bVXD3ywVilJt3b0Denbr2n41les3p8ciIldduw4X0" />
|
||||
<title>海拥 | 打地鼠</title>
|
||||
<link rel="icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg" sizes="192x192" />
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<input type="checkbox" class="start" id="start-easy">
|
||||
<input type="checkbox" class="start" id="start-medium">
|
||||
<input type="checkbox" class="start" id="start-hard">
|
||||
<input type="checkbox" class="start" id="start-ultra">
|
||||
<div class="screen screen--start">
|
||||
<h1>打地鼠</h1>
|
||||
<p>选择难度</p>
|
||||
<label for="start-easy" class="screen__text">简单</label>
|
||||
<label for="start-medium" class="screen__text">一般</label>
|
||||
<label for="start-hard" class="screen__text">困难</label>
|
||||
<label for="start-ultra" class="screen__text">炼狱</label>
|
||||
</div>
|
||||
<div class="screen screen--finish">
|
||||
<a href="" class="screen__text">
|
||||
<div class="screen__wrapper">
|
||||
点击重开
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="game">
|
||||
<div class="holes">
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole1" id="mole1">
|
||||
<label class="mole mole--1" for="mole1"></label>
|
||||
<input class="mole-input" type="radio" name="mole2" id="mole2">
|
||||
<label class="mole mole--2" for="mole2"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole3" id="mole3">
|
||||
<label class="mole mole--3" for="mole3"></label>
|
||||
<input class="mole-input" type="radio" name="mole4" id="mole4">
|
||||
<label class="mole mole--4" for="mole4"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="holes">
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole5" id="mole5">
|
||||
<label class="mole mole--5" for="mole5"></label>
|
||||
<input class="mole-input" type="radio" name="mole6" id="mole6">
|
||||
<label class="mole mole--6" for="mole6"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole7" id="mole7">
|
||||
<label class="mole mole--7" for="mole7"></label>
|
||||
<input class="mole-input" type="radio" name="mole8" id="mole8">
|
||||
<label class="mole mole--8" for="mole8"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="holes">
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole9" id="mole9">
|
||||
<label class="mole mole--9" for="mole9"></label>
|
||||
<input class="mole-input" type="radio" name="mole10" id="mole10">
|
||||
<label class="mole mole--10" for="mole10"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
<div class="hole">
|
||||
<div class="hole__up"></div>
|
||||
<input class="mole-input" type="radio" name="mole11" id="mole11">
|
||||
<label class="mole mole--11" for="mole11"></label>
|
||||
<input class="mole-input" type="radio" name="mole12" id="mole12">
|
||||
<label class="mole mole--12" for="mole12"></label>
|
||||
<div class="hole__down"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="score">
|
||||
<!--<p class="score__text">SCORE:</p>-->
|
||||
<div class="score__wrapper">
|
||||
<div class="score__wrapper-points">
|
||||
<input type="radio" name="mole1" class="score__radio" checked>
|
||||
<input type="radio" name="mole2" class="score__radio" checked>
|
||||
<input type="radio" name="mole3" class="score__radio" checked>
|
||||
<input type="radio" name="mole4" class="score__radio" checked>
|
||||
<input type="radio" name="mole5" class="score__radio" checked>
|
||||
<input type="radio" name="mole6" class="score__radio" checked>
|
||||
<input type="radio" name="mole7" class="score__radio" checked>
|
||||
<input type="radio" name="mole8" class="score__radio" checked>
|
||||
<input type="radio" name="mole9" class="score__radio" checked>
|
||||
<input type="radio" name="mole10" class="score__radio" checked>
|
||||
<input type="radio" name="mole11" class="score__radio" checked>
|
||||
<input type="radio" name="mole12" class="score__radio" checked>
|
||||
<div class="score__points"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timer">
|
||||
<div class="timer__progress"></div>
|
||||
</div>
|
||||
<div style="text-align:center;">
|
||||
<p><a href="http://haiyong.site/game" target="_blank">回到游戏首页</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1
游戏-6.打地鼠/js/script.js
Normal file
1
游戏-6.打地鼠/js/script.js
Normal file
@@ -0,0 +1 @@
|
||||
//无JS
|
||||
72
游戏-7.JS闯关小游戏/css/style.css
Normal file
72
游戏-7.JS闯关小游戏/css/style.css
Normal file
@@ -0,0 +1,72 @@
|
||||
body {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #ffff7f;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.background {
|
||||
table-layout: fixed;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.background td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.lava, .actor {
|
||||
background: #e55;
|
||||
}
|
||||
|
||||
.wall {
|
||||
background: #444;
|
||||
border: solid 3px #333;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.actor {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.coin {
|
||||
background: #e2e838;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.player {
|
||||
background: #335699;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.lost .player {
|
||||
background: #a04040;
|
||||
}
|
||||
|
||||
.won .player {
|
||||
background: green;
|
||||
}
|
||||
|
||||
.game {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
#footer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 60%;
|
||||
margin: auto;
|
||||
margin-top: 120px;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: #fdde8c;
|
||||
font-size: 0.8em;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
user-select: none;
|
||||
}
|
||||
a{
|
||||
color: #00f3ff;
|
||||
}
|
||||
60
游戏-7.JS闯关小游戏/index.html
Normal file
60
游戏-7.JS闯关小游戏/index.html
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>海拥 | JS闯关小游戏</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="keywords" content="海拥,游戏,JS闯关小游戏" />
|
||||
<meta name="description" content="一个有趣好玩的JS闯关小游戏 。Made By Haiyong,技术支持——海拥" />
|
||||
<meta name="author" content="海拥(http://haiyong.site)" />
|
||||
<meta name="copyright" content="海拥(http://haiyong.site)" />
|
||||
<link rel="icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg"/>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h2>简单的 JavaScript 游戏
|
||||
请用电脑打开,上下左右控制方向
|
||||
吃完所有金币进入下一关</h2>
|
||||
<script src="js/script.js"></script>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<div id="footer">
|
||||
<!-- menu Start -->
|
||||
<div class="copy-text">
|
||||
<p align="center">© <a href="http://haiyong.site/">Haiyong. All Rights Reserved </a></p>
|
||||
<p align="center">
|
||||
<a href="http://haiyong.site/moyu">摸鱼</a> |
|
||||
<a href="http://haiyong.site/index">作者简介</a> |
|
||||
<a href="http://haiyong.site/game">游戏</a> |
|
||||
<a href="http://haiyong.site/tools">工具</a> |
|
||||
<a href="http://haiyong.site">博客</a> |
|
||||
<a href="http://haiyong.site/contact">联系</a>
|
||||
</p>
|
||||
</div>
|
||||
<!-- menu End -->
|
||||
|
||||
<p align="center">
|
||||
<a href="https://haiyong.blog.csdn.net/">CSDN</a> |
|
||||
<a href="https://juejin.cn/user/2040341402229751">掘金</a> |
|
||||
<a href="https://bbs.huaweicloud.com/community/usersnew/id_1628036118897599">华为云</a> | <a href="https://cloud.tencent.com/developer/user/8932508">腾讯云</a> | <a href="http://zsysjq.com.cn/store/127">致知店铺</a> |
|
||||
<a href="https://space.bilibili.com/63551025">哔哩哔哩</a> | <a href="https://www.zhihu.com/people/haiyongblog">知乎</a> | <a href="https://my.oschina.net/haiyongblog">开源中国</a> |
|
||||
<a href="https://segmentfault.com/u/haiyong">思否</a> |
|
||||
<a href="https://www.modb.pro/u/441674">墨天轮</a> |
|
||||
<a href="https://www.jianshu.com/u/ccc5356d0293">简书</a> |
|
||||
<a href="https://github.com/wanghao221/">GitHub</a> |
|
||||
<a href="https://gitee.com/haiyongcsdn/haiyong">Gitee</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
489
游戏-7.JS闯关小游戏/js/script.js
Normal file
489
游戏-7.JS闯关小游戏/js/script.js
Normal file
@@ -0,0 +1,489 @@
|
||||
var LEVELS = [
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" xxx ",
|
||||
" xx xx xx!xx ",
|
||||
" o o xx x!!!x ",
|
||||
" xx!xx ",
|
||||
" xxxxx xvx ",
|
||||
" xx ",
|
||||
" xx o o x ",
|
||||
" x o x ",
|
||||
" x xxxxx o x ",
|
||||
" x xxxx o x ",
|
||||
" x @ x x xxxxx x ",
|
||||
" xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxx ",
|
||||
" x x x x ",
|
||||
" x!!!x x!!!!!x ",
|
||||
" x!!!x x!!!!!x ",
|
||||
" xxxxx xxxxxxx ",
|
||||
" ",
|
||||
" "
|
||||
],
|
||||
[
|
||||
" x!!x xxxxxxx x!x ",
|
||||
" x!!x xxxx xxxx x!x ",
|
||||
" x!!xxxxxxxxxx xx xx x!x ",
|
||||
" xx!!!!!!!!!!xx xx xx x!x ",
|
||||
" xxxxxxxxxx!!x x o o o x!x ",
|
||||
" xx!x x o o xx!x ",
|
||||
" x!x x xxxxxxxxxxxxxxx!!x ",
|
||||
" xvx x x x !!!!!!!!!!!!!!xx ",
|
||||
" xx | | | xx xxxxxxxxxxxxxxxxxxxxx ",
|
||||
" xx!!!!!!!!!!!xx v ",
|
||||
" xxxx!!!!!xxxx ",
|
||||
" x x xxxxxxx xxx xxx ",
|
||||
" x x x x x x ",
|
||||
" x x x x ",
|
||||
" x x xx x ",
|
||||
" xx x x x ",
|
||||
" x x o o x x x x ",
|
||||
" xxxxxxx xxx xxx x x x x x x ",
|
||||
" xx xx x x x x xxxxxx x x xxxxxxxxx x ",
|
||||
" xx xx x o x x xx x x x x ",
|
||||
" @ x x x x x x x x x x ",
|
||||
" xxx x x x x x x x xxxxx xxxxxx x ",
|
||||
" x x x x xx o xx x x x o x x x ",
|
||||
"!!!!x x!!!!!!x x!!!!!!xx xx!!!!!!!!xx x!!!!!!!!!! x = x x x ",
|
||||
"!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxx x!!!!!!!xx! xxxxxxxxxxxxx xx o o xx ",
|
||||
"!!!!x x!!!!!!x x!!!!!x o xx!!!!!!xx ! xx xx ",
|
||||
"!!!!x x!!!!!!x x!!!!!x xx!!!!!!xx ! xxxxxxx ",
|
||||
"!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxxxxxx!!!!!!xx ! ",
|
||||
"!!!!x x!!!!!!x x!!!!!!xxxxxxxxx!!!!!!!!!!!!!!!!!!xx ! ",
|
||||
"!!!!x x!!!!!!x x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!xx ! "
|
||||
],
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" o ",
|
||||
" ",
|
||||
" x ",
|
||||
" x ",
|
||||
" x ",
|
||||
" x ",
|
||||
" xxx ",
|
||||
" x x !!! !!! xxx ",
|
||||
" x x !x! !x! ",
|
||||
" xxx xxx x x ",
|
||||
" x x x oooo x xxx ",
|
||||
" x x x x x!!!x ",
|
||||
" x x xxxxxxxxxxxx xxx ",
|
||||
" xx xx x x x ",
|
||||
" x xxxxxxxxx xxxxxxxx x x ",
|
||||
" x x x x!!!x ",
|
||||
" x x x xxx ",
|
||||
" xx xx x ",
|
||||
" x x= = = = x xxx ",
|
||||
" x x x x!!!x ",
|
||||
" x x = = = =x o xxx xxx ",
|
||||
" xx xx x x!!!x ",
|
||||
" o o x x x x xxv xxx ",
|
||||
" x x x x x!!!x ",
|
||||
" xxx xxx xxx xxx o o x!!!!!!!!!!!!!!x vx ",
|
||||
" x xxx x x xxx x x!!!!!!!!!!!!!!x ",
|
||||
" x x xxxxxxxxxxxxxxxxxxxxxxx ",
|
||||
" xx xx xxx ",
|
||||
" xxx x x x x!!!x xxx ",
|
||||
" x x x xxx x xxx x x ",
|
||||
" x x xxx xxxxxxx xxxxx x ",
|
||||
" x x x x x x ",
|
||||
" x xx x x x x x ",
|
||||
" x x |xxxx| |xxxx| xxx xxx x ",
|
||||
" x xxx o o x x xxx x ",
|
||||
" x xxxxx xx x xxx x!!!x x x ",
|
||||
" x oxxxo x xxx x x x xxx xxx x ",
|
||||
" x xxx xxxxxxxxxxxxx x oo x x oo x x oo xx xx xxx x ",
|
||||
" x @ x x x!!x x!!!!x x!!!!x xx xx x x ",
|
||||
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ",
|
||||
" ",
|
||||
" "
|
||||
],
|
||||
[
|
||||
" xxx x ",
|
||||
" x ",
|
||||
" xxxxx ",
|
||||
" x ",
|
||||
" x xxx ",
|
||||
" o x x x ",
|
||||
" o o oxxx x ",
|
||||
" xxx x ",
|
||||
" ! o ! xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx ",
|
||||
" x x x x x x x x x x x x x x x ",
|
||||
" x= o x x xxx x xxx x xxx x xxx x xxx x xxx x xxxxx ",
|
||||
" x x x x x x x x x x x x x x x ",
|
||||
" ! o ! o xxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxxxx ",
|
||||
" ",
|
||||
" o xxx xx ",
|
||||
" ",
|
||||
" ",
|
||||
" xx ",
|
||||
" xxx xxx ",
|
||||
" ",
|
||||
" o x x ",
|
||||
" xx xx ",
|
||||
" xxx xxx xxx x x ",
|
||||
" ",
|
||||
" || ",
|
||||
" xxxxxxxxxxx ",
|
||||
" x x o xxxxxxxxx o xxxxxxxxx o xx x ",
|
||||
" x x x x x x x || x x ",
|
||||
" x @ xxxxx o xxxxx o xxxxx ",
|
||||
" xxxxxxx xxxxx xx xx xxx ",
|
||||
" x= = =x x xxx ",
|
||||
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x!!!!!!!!!!!!!!!!!!!!!xxx!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
|
||||
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
" "
|
||||
]
|
||||
];
|
||||
|
||||
function Vector(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Vector.prototype.plus = function (other) {
|
||||
return new Vector(this.x + other.x, this.y + other.y);
|
||||
};
|
||||
|
||||
Vector.prototype.times = function (scale) {
|
||||
return new Vector(this.x * scale, this.y * scale);
|
||||
};
|
||||
|
||||
// 注意:使用大写单词表示构造函数是值
|
||||
var actorchars = {
|
||||
"@": Player,
|
||||
o: Coin,
|
||||
"=": Lava,
|
||||
"|": Lava,
|
||||
v: Lava
|
||||
};
|
||||
|
||||
function Player(pos) {
|
||||
this.pos = pos.plus(new Vector(0, -0.5));
|
||||
this.size = new Vector(0.5, 1);
|
||||
this.speed = new Vector(0, 0);
|
||||
}
|
||||
Player.prototype.type = "player";
|
||||
|
||||
function Lava(pos, ch) {
|
||||
this.pos = pos;
|
||||
this.size = new Vector(1, 1);
|
||||
if (ch === "=") this.speed = new Vector(2, 0);
|
||||
else if (ch === "|") this.speed = new Vector(0, 2);
|
||||
else if (ch === "v") {
|
||||
this.speed = new Vector(0, 3);
|
||||
this.repeatPos = pos;
|
||||
}
|
||||
}
|
||||
Lava.prototype.type = "Lava";
|
||||
|
||||
function Coin(pos) {
|
||||
this.basePos = this.pos = pos;
|
||||
this.size = new Vector(0.6, 0.6);
|
||||
// 回头看看
|
||||
this.wobble = Math.random() * Math.PI * 2;
|
||||
}
|
||||
Coin.prototype.type = "coin";
|
||||
|
||||
Level.prototype.isFinished = function () {
|
||||
return this.status != null && this.finishDelay < 0;
|
||||
};
|
||||
|
||||
function Level(plan) {
|
||||
this.width = plan[0].length;
|
||||
this.height = plan.length;
|
||||
this.grid = [];
|
||||
this.actors = [];
|
||||
|
||||
for (var y = 0; y < this.height; y++) {
|
||||
var line = plan[y],
|
||||
gridLine = [];
|
||||
for (var x = 0; x < this.width; x++) {
|
||||
var ch = line[x],
|
||||
fieldType = null;
|
||||
var Actor = actorchars[ch];
|
||||
if (Actor) this.actors.push(new Actor(new Vector(x, y), ch));
|
||||
else if (ch === "x") fieldType = "wall";
|
||||
else if (ch === "!") fieldType = "lava";
|
||||
else if (ch === "|") fieldType = "lava";
|
||||
else if (ch === "=") fieldType = "lava";
|
||||
else if (ch === "v") {
|
||||
fieldType = "lava";
|
||||
console.log(fieldType);
|
||||
}
|
||||
gridLine.push(fieldType);
|
||||
}
|
||||
this.grid.push(gridLine);
|
||||
}
|
||||
this.player = this.actors.filter(function (actor) {
|
||||
return actor.type === "player";
|
||||
})[0];
|
||||
this.status = this.finishDelay = null;
|
||||
}
|
||||
|
||||
function element(name, className) {
|
||||
var elem = document.createElement(name);
|
||||
if (className) elem.className = className;
|
||||
return elem;
|
||||
}
|
||||
|
||||
function DOMDisplay(parent, level) {
|
||||
this.wrap = parent.appendChild(element("div", "game"));
|
||||
this.level = level;
|
||||
|
||||
this.wrap.appendChild(this.drawBackground());
|
||||
this.actorLayer = null;
|
||||
this.drawFrame();
|
||||
}
|
||||
|
||||
var scale = 15;
|
||||
|
||||
DOMDisplay.prototype.drawBackground = function () {
|
||||
var table = element("table", "background");
|
||||
table.style.width = this.level.width * scale + "px";
|
||||
table.style.height = this.level.height * scale + "px";
|
||||
this.level.grid.forEach(function (row) {
|
||||
var rowElement = table.appendChild(element("tr"));
|
||||
rowElement.style.height = scale + "px";
|
||||
row.forEach(function (type) {
|
||||
rowElement.appendChild(element("td", type));
|
||||
});
|
||||
});
|
||||
return table;
|
||||
};
|
||||
|
||||
DOMDisplay.prototype.drawActors = function () {
|
||||
var wrap = element("div");
|
||||
this.level.actors.forEach(function (actor) {
|
||||
var rect = wrap.appendChild(element("div", "actor " + actor.type));
|
||||
rect.style.width = actor.size.x * scale + "px";
|
||||
rect.style.height = actor.size.y * scale + "px";
|
||||
rect.style.left = actor.pos.x * scale + "px";
|
||||
rect.style.top = actor.pos.y * scale + "px";
|
||||
});
|
||||
return wrap;
|
||||
};
|
||||
|
||||
DOMDisplay.prototype.drawFrame = function () {
|
||||
if (this.actorLayer) this.wrap.removeChild(this.actorLayer);
|
||||
this.actorLayer = this.wrap.appendChild(this.drawActors());
|
||||
this.wrap.className = "game " + (this.level.status || "");
|
||||
this.scrollPlayerIntoView();
|
||||
};
|
||||
|
||||
// 稍后清除
|
||||
DOMDisplay.prototype.scrollPlayerIntoView = function () {
|
||||
var width = this.wrap.clientWidth;
|
||||
var height = this.wrap.clientHeight;
|
||||
var margin = width / 3;
|
||||
|
||||
// The viewport
|
||||
var left = this.wrap.scrollLeft,
|
||||
right = left + width;
|
||||
var top = this.wrap.scrollTop,
|
||||
bottom = top + height;
|
||||
|
||||
var player = this.level.player;
|
||||
var center = player.pos.plus(player.size.times(0.5)).times(scale);
|
||||
|
||||
if (center.x < left + margin) this.wrap.scrollLeft = center.x - margin;
|
||||
else if (center.x > right - margin)
|
||||
this.wrap.scrollLeft = center.x + margin - width;
|
||||
if (center.y < top + margin) this.wrap.scrollTop = center.y - margin;
|
||||
else if (center.y > bottom - margin)
|
||||
this.wrap.scrollTop = center.y + margin - height;
|
||||
};
|
||||
|
||||
DOMDisplay.prototype.clear = function () {
|
||||
this.wrap.parentNode.removeChild(this.wrap);
|
||||
};
|
||||
|
||||
Level.prototype.obstacleAt = function (pos, size) {
|
||||
var xStart = Math.floor(pos.x);
|
||||
var xEnd = Math.ceil(pos.x + size.x);
|
||||
var yStart = Math.floor(pos.y);
|
||||
var yEnd = Math.ceil(pos.y + size.y);
|
||||
|
||||
if (xStart < 0 || xEnd > this.width || yStart < 0) return "wall";
|
||||
if (yEnd > this.height) return "lava";
|
||||
for (var y = yStart; y < yEnd; y++) {
|
||||
for (var x = xStart; x < xEnd; x++) {
|
||||
var fieldType = this.grid[y][x];
|
||||
if (fieldType) return fieldType;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Level.prototype.actorAt = function (actor) {
|
||||
for (var i = 0; i < this.actors.length; i++) {
|
||||
var other = this.actors[i];
|
||||
if (
|
||||
other != actor &&
|
||||
actor.pos.x + actor.size.x > other.pos.x &&
|
||||
actor.pos.x < other.pos.x + other.size.x &&
|
||||
actor.pos.y + actor.size.y > other.pos.y &&
|
||||
actor.pos.y < other.pos.y + other.size.y
|
||||
)
|
||||
return other;
|
||||
}
|
||||
};
|
||||
|
||||
var maxStep = 0.05;
|
||||
|
||||
Level.prototype.animate = function (step, keys) {
|
||||
if (this.status != null) this.finishDelay -= step;
|
||||
|
||||
while (step > 0) {
|
||||
var thisStep = Math.min(step, maxStep);
|
||||
this.actors.forEach(function (actor) {
|
||||
actor.act(thisStep, this, keys);
|
||||
}, this);
|
||||
step -= thisStep;
|
||||
}
|
||||
};
|
||||
|
||||
Lava.prototype.act = function (step, level) {
|
||||
var newPos = this.pos.plus(this.speed.times(step));
|
||||
if (!level.obstacleAt(newPos, this.size)) this.pos = newPos;
|
||||
else if (this.repeatPos) this.pos = this.repeatPos;
|
||||
else this.speed = this.speed.times(-1);
|
||||
};
|
||||
|
||||
var wobbleSpeed = 8,
|
||||
wobbleDist = 0.07;
|
||||
|
||||
Coin.prototype.act = function (step) {
|
||||
this.wobble += step * wobbleSpeed;
|
||||
var wobblePos = Math.sin(this.wobble) * wobbleDist;
|
||||
this.pos = this.basePos.plus(new Vector(0, wobblePos));
|
||||
};
|
||||
|
||||
var playerXSpeed = 10;
|
||||
|
||||
Player.prototype.moveX = function (step, level, keys) {
|
||||
this.speed.x = 0;
|
||||
if (keys.left) this.speed.x -= playerXSpeed;
|
||||
if (keys.right) this.speed.x += playerXSpeed;
|
||||
|
||||
var motion = new Vector(this.speed.x * step, 0);
|
||||
var newPos = this.pos.plus(motion);
|
||||
var obstacle = level.obstacleAt(newPos, this.size);
|
||||
if (obstacle) level.playerTouched(obstacle);
|
||||
else this.pos = newPos;
|
||||
};
|
||||
|
||||
var gravity = 30;
|
||||
var jumpSpeed = 17;
|
||||
|
||||
Player.prototype.moveY = function (step, level, keys) {
|
||||
this.speed.y += step * gravity;
|
||||
var motion = new Vector(0, this.speed.y * step);
|
||||
var newPos = this.pos.plus(motion);
|
||||
var obstacle = level.obstacleAt(newPos, this.size);
|
||||
if (obstacle) {
|
||||
level.playerTouched(obstacle);
|
||||
if (keys.up && this.speed.y > 0) this.speed.y = -jumpSpeed;
|
||||
else this.speed.y = 0;
|
||||
} else {
|
||||
this.pos = newPos;
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.act = function (step, level, keys) {
|
||||
this.moveX(step, level, keys);
|
||||
this.moveY(step, level, keys);
|
||||
|
||||
var otherActor = level.actorAt(this);
|
||||
if (otherActor) level.playerTouched(otherActor.type, otherActor);
|
||||
|
||||
// 丢失动画
|
||||
if (level.status == "lost") {
|
||||
this.pos.y += step;
|
||||
this.size.y -= step;
|
||||
}
|
||||
};
|
||||
|
||||
Level.prototype.playerTouched = function (type, actor) {
|
||||
if (type == "lava" && this.status == null) {
|
||||
this.status = "lost";
|
||||
this.finishDelay = 1;
|
||||
} else if (type == "coin") {
|
||||
this.actors = this.actors.filter(function (other) {
|
||||
return other != actor;
|
||||
});
|
||||
if (
|
||||
!this.actors.some(function (actor) {
|
||||
return actor.type == "coin";
|
||||
})
|
||||
) {
|
||||
this.status = "won";
|
||||
this.finishDelay = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var arrowCodes = { 37: "left", 38: "up", 39: "right" };
|
||||
|
||||
function trackKeys(codes) {
|
||||
var pressed = Object.create(null);
|
||||
function handler(event) {
|
||||
if (codes.hasOwnProperty(event.keyCode)) {
|
||||
var down = event.type == "keydown";
|
||||
pressed[codes[event.keyCode]] = down;
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
addEventListener("keydown", handler);
|
||||
addEventListener("keyup", handler);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
function runAnimation(frameFunc) {
|
||||
var lastTime = null;
|
||||
function frame(time) {
|
||||
var stop = false;
|
||||
if (lastTime != null) {
|
||||
var timeStep = Math.min(time - lastTime, 100) / 1000;
|
||||
stop = frameFunc(timeStep) === false;
|
||||
}
|
||||
lastTime = time;
|
||||
if (!stop) requestAnimationFrame(frame);
|
||||
}
|
||||
requestAnimationFrame(frame);
|
||||
}
|
||||
|
||||
var arrows = trackKeys(arrowCodes);
|
||||
|
||||
function runLevel(level, Display, andThen) {
|
||||
var display = new Display(document.body, level);
|
||||
runAnimation(function (step) {
|
||||
level.animate(step, arrows);
|
||||
display.drawFrame(step);
|
||||
if (level.isFinished()) {
|
||||
display.clear();
|
||||
if (andThen) andThen(level.status);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function runGame(plans, Display) {
|
||||
function startLevel(n) {
|
||||
runLevel(new Level(plans[n]), Display, function (status) {
|
||||
if (status == "lost") startLevel(n);
|
||||
else if (n < plans.length - 1) startLevel(n + 1);
|
||||
else alert("You win!");
|
||||
});
|
||||
}
|
||||
startLevel(0);
|
||||
}
|
||||
|
||||
runGame(LEVELS, DOMDisplay);
|
||||
106
游戏-8.盖塔楼/css/style.css
Normal file
106
游戏-8.盖塔楼/css/style.css
Normal file
@@ -0,0 +1,106 @@
|
||||
@import url("https://fonts.googleapis.com/css?family=Comfortaa");
|
||||
html, body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
font-family: "Comfortaa", cursive;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#container #score {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 10vh;
|
||||
transition: transform 0.5s ease;
|
||||
color: #333344;
|
||||
transform: translatey(-200px) scale(1);
|
||||
}
|
||||
#container #game {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
#container .game-over {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 85%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
#container .game-over * {
|
||||
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||
opacity: 0;
|
||||
transform: translatey(-50px);
|
||||
color: #333344;
|
||||
}
|
||||
#container .game-over h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 40px;
|
||||
}
|
||||
#container .game-ready {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
}
|
||||
#container .game-ready #start-button {
|
||||
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||
opacity: 0;
|
||||
transform: translatey(-50px);
|
||||
border: 3px solid #333344;
|
||||
padding: 10px 20px;
|
||||
background-color: transparent;
|
||||
color: #333344;
|
||||
font-size: 30px;
|
||||
}
|
||||
#container #instructions {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 16vh;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||
opacity: 0;
|
||||
}
|
||||
#container #instructions.hide {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
#container.playing #score, #container.resetting #score {
|
||||
transform: translatey(0px) scale(1);
|
||||
}
|
||||
#container.playing #instructions {
|
||||
opacity: 1;
|
||||
}
|
||||
#container.ready .game-ready #start-button {
|
||||
opacity: 1;
|
||||
transform: translatey(0);
|
||||
}
|
||||
#container.ended #score {
|
||||
transform: translatey(6vh) scale(1.5);
|
||||
}
|
||||
#container.ended .game-over * {
|
||||
opacity: 1;
|
||||
transform: translatey(0);
|
||||
}
|
||||
#container.ended .game-over p {
|
||||
transition-delay: 0.3s;
|
||||
}
|
||||
49
游戏-8.盖塔楼/index.html
Normal file
49
游戏-8.盖塔楼/index.html
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>海拥 | 盖塔楼</title>
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no">
|
||||
<meta name="keywords" content="盖塔楼" />
|
||||
<meta name="description" content="盖塔楼" />
|
||||
<meta name="author" content="海拥(http://haiyong.site)" />
|
||||
<meta name="copyright" content="海拥(http://haiyong.site)" />
|
||||
<link rel="icon" type="image/x-icon" href="http://haiyong.site/wp-content/uploads/2021/07/cropped-59255587-1-192x192.jpg" />
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div id="container">
|
||||
<div id="game"></div>
|
||||
<div id="score">0</div>
|
||||
<div id="instructions">单击(或按空格)放置砖块</div>
|
||||
<div class="game-over">
|
||||
<h2>Game Over</h2>
|
||||
<p>你做的很好啦,你是最棒的</p>
|
||||
<p>单击或按空格重新开始</p>
|
||||
</div>
|
||||
<div class="game-ready">
|
||||
<div id="start-button">开始</div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<!-- <script src="https://codepen.io/steveg3003/pen/zBVakw"></script> -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?a9430a37066911650e26adadcc42798a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
<script src="js/script.js"></script>
|
||||
</html>
|
||||
312
游戏-8.盖塔楼/js/script.js
Normal file
312
游戏-8.盖塔楼/js/script.js
Normal file
@@ -0,0 +1,312 @@
|
||||
"use strict";
|
||||
console.clear();
|
||||
class Stage {
|
||||
constructor() {
|
||||
// container
|
||||
this.render = function () {
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
};
|
||||
this.add = function (elem) {
|
||||
this.scene.add(elem);
|
||||
};
|
||||
this.remove = function (elem) {
|
||||
this.scene.remove(elem);
|
||||
};
|
||||
this.container = document.getElementById('game');
|
||||
// renderer
|
||||
this.renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
alpha: false
|
||||
});
|
||||
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
this.renderer.setClearColor('#D0CBC7', 1);
|
||||
this.container.appendChild(this.renderer.domElement);
|
||||
// scene
|
||||
this.scene = new THREE.Scene();
|
||||
// camera
|
||||
let aspect = window.innerWidth / window.innerHeight;
|
||||
let d = 20;
|
||||
this.camera = new THREE.OrthographicCamera(-d * aspect, d * aspect, d, -d, -100, 1000);
|
||||
this.camera.position.x = 2;
|
||||
this.camera.position.y = 2;
|
||||
this.camera.position.z = 2;
|
||||
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
|
||||
//light
|
||||
this.light = new THREE.DirectionalLight(0xffffff, 0.5);
|
||||
this.light.position.set(0, 499, 0);
|
||||
this.scene.add(this.light);
|
||||
this.softLight = new THREE.AmbientLight(0xffffff, 0.4);
|
||||
this.scene.add(this.softLight);
|
||||
window.addEventListener('resize', () => this.onResize());
|
||||
this.onResize();
|
||||
}
|
||||
setCamera(y, speed = 0.3) {
|
||||
TweenLite.to(this.camera.position, speed, { y: y + 4, ease: Power1.easeInOut });
|
||||
TweenLite.to(this.camera.lookAt, speed, { y: y, ease: Power1.easeInOut });
|
||||
}
|
||||
onResize() {
|
||||
let viewSize = 30;
|
||||
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
this.camera.left = window.innerWidth / -viewSize;
|
||||
this.camera.right = window.innerWidth / viewSize;
|
||||
this.camera.top = window.innerHeight / viewSize;
|
||||
this.camera.bottom = window.innerHeight / -viewSize;
|
||||
this.camera.updateProjectionMatrix();
|
||||
}
|
||||
}
|
||||
class Block {
|
||||
constructor(block) {
|
||||
// set size and position
|
||||
this.STATES = { ACTIVE: 'active', STOPPED: 'stopped', MISSED: 'missed' };
|
||||
this.MOVE_AMOUNT = 12;
|
||||
this.dimension = { width: 0, height: 0, depth: 0 };
|
||||
this.position = { x: 0, y: 0, z: 0 };
|
||||
this.targetBlock = block;
|
||||
this.index = (this.targetBlock ? this.targetBlock.index : 0) + 1;
|
||||
this.workingPlane = this.index % 2 ? 'x' : 'z';
|
||||
this.workingDimension = this.index % 2 ? 'width' : 'depth';
|
||||
// set the dimensions from the target block, or defaults.
|
||||
this.dimension.width = this.targetBlock ? this.targetBlock.dimension.width : 10;
|
||||
this.dimension.height = this.targetBlock ? this.targetBlock.dimension.height : 2;
|
||||
this.dimension.depth = this.targetBlock ? this.targetBlock.dimension.depth : 10;
|
||||
this.position.x = this.targetBlock ? this.targetBlock.position.x : 0;
|
||||
this.position.y = this.dimension.height * this.index;
|
||||
this.position.z = this.targetBlock ? this.targetBlock.position.z : 0;
|
||||
this.colorOffset = this.targetBlock ? this.targetBlock.colorOffset : Math.round(Math.random() * 100);
|
||||
// set color
|
||||
if (!this.targetBlock) {
|
||||
this.color = 0x333344;
|
||||
}
|
||||
else {
|
||||
let offset = this.index + this.colorOffset;
|
||||
var r = Math.sin(0.3 * offset) * 55 + 200;
|
||||
var g = Math.sin(0.3 * offset + 2) * 55 + 200;
|
||||
var b = Math.sin(0.3 * offset + 4) * 55 + 200;
|
||||
this.color = new THREE.Color(r / 255, g / 255, b / 255);
|
||||
}
|
||||
// state
|
||||
this.state = this.index > 1 ? this.STATES.ACTIVE : this.STATES.STOPPED;
|
||||
// set direction
|
||||
this.speed = -0.1 - (this.index * 0.005);
|
||||
if (this.speed < -4)
|
||||
this.speed = -4;
|
||||
this.direction = this.speed;
|
||||
// create block
|
||||
let geometry = new THREE.BoxGeometry(this.dimension.width, this.dimension.height, this.dimension.depth);
|
||||
geometry.applyMatrix(new THREE.Matrix4().makeTranslation(this.dimension.width / 2, this.dimension.height / 2, this.dimension.depth / 2));
|
||||
this.material = new THREE.MeshToonMaterial({ color: this.color, shading: THREE.FlatShading });
|
||||
this.mesh = new THREE.Mesh(geometry, this.material);
|
||||
this.mesh.position.set(this.position.x, this.position.y + (this.state == this.STATES.ACTIVE ? 0 : 0), this.position.z);
|
||||
if (this.state == this.STATES.ACTIVE) {
|
||||
this.position[this.workingPlane] = Math.random() > 0.5 ? -this.MOVE_AMOUNT : this.MOVE_AMOUNT;
|
||||
}
|
||||
}
|
||||
reverseDirection() {
|
||||
this.direction = this.direction > 0 ? this.speed : Math.abs(this.speed);
|
||||
}
|
||||
place() {
|
||||
this.state = this.STATES.STOPPED;
|
||||
let overlap = this.targetBlock.dimension[this.workingDimension] - Math.abs(this.position[this.workingPlane] - this.targetBlock.position[this.workingPlane]);
|
||||
let blocksToReturn = {
|
||||
plane: this.workingPlane,
|
||||
direction: this.direction
|
||||
};
|
||||
if (this.dimension[this.workingDimension] - overlap < 0.3) {
|
||||
overlap = this.dimension[this.workingDimension];
|
||||
blocksToReturn.bonus = true;
|
||||
this.position.x = this.targetBlock.position.x;
|
||||
this.position.z = this.targetBlock.position.z;
|
||||
this.dimension.width = this.targetBlock.dimension.width;
|
||||
this.dimension.depth = this.targetBlock.dimension.depth;
|
||||
}
|
||||
if (overlap > 0) {
|
||||
let choppedDimensions = { width: this.dimension.width, height: this.dimension.height, depth: this.dimension.depth };
|
||||
choppedDimensions[this.workingDimension] -= overlap;
|
||||
this.dimension[this.workingDimension] = overlap;
|
||||
let placedGeometry = new THREE.BoxGeometry(this.dimension.width, this.dimension.height, this.dimension.depth);
|
||||
placedGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(this.dimension.width / 2, this.dimension.height / 2, this.dimension.depth / 2));
|
||||
let placedMesh = new THREE.Mesh(placedGeometry, this.material);
|
||||
let choppedGeometry = new THREE.BoxGeometry(choppedDimensions.width, choppedDimensions.height, choppedDimensions.depth);
|
||||
choppedGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(choppedDimensions.width / 2, choppedDimensions.height / 2, choppedDimensions.depth / 2));
|
||||
let choppedMesh = new THREE.Mesh(choppedGeometry, this.material);
|
||||
let choppedPosition = {
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
z: this.position.z
|
||||
};
|
||||
if (this.position[this.workingPlane] < this.targetBlock.position[this.workingPlane]) {
|
||||
this.position[this.workingPlane] = this.targetBlock.position[this.workingPlane];
|
||||
}
|
||||
else {
|
||||
choppedPosition[this.workingPlane] += overlap;
|
||||
}
|
||||
placedMesh.position.set(this.position.x, this.position.y, this.position.z);
|
||||
choppedMesh.position.set(choppedPosition.x, choppedPosition.y, choppedPosition.z);
|
||||
blocksToReturn.placed = placedMesh;
|
||||
if (!blocksToReturn.bonus)
|
||||
blocksToReturn.chopped = choppedMesh;
|
||||
}
|
||||
else {
|
||||
this.state = this.STATES.MISSED;
|
||||
}
|
||||
this.dimension[this.workingDimension] = overlap;
|
||||
return blocksToReturn;
|
||||
}
|
||||
tick() {
|
||||
if (this.state == this.STATES.ACTIVE) {
|
||||
let value = this.position[this.workingPlane];
|
||||
if (value > this.MOVE_AMOUNT || value < -this.MOVE_AMOUNT)
|
||||
this.reverseDirection();
|
||||
this.position[this.workingPlane] += this.direction;
|
||||
this.mesh.position[this.workingPlane] = this.position[this.workingPlane];
|
||||
}
|
||||
}
|
||||
}
|
||||
class Game {
|
||||
constructor() {
|
||||
this.STATES = {
|
||||
'LOADING': 'loading',
|
||||
'PLAYING': 'playing',
|
||||
'READY': 'ready',
|
||||
'ENDED': 'ended',
|
||||
'RESETTING': 'resetting'
|
||||
};
|
||||
this.blocks = [];
|
||||
this.state = this.STATES.LOADING;
|
||||
this.stage = new Stage();
|
||||
this.mainContainer = document.getElementById('container');
|
||||
this.scoreContainer = document.getElementById('score');
|
||||
this.startButton = document.getElementById('start-button');
|
||||
this.instructions = document.getElementById('instructions');
|
||||
this.scoreContainer.innerHTML = '0';
|
||||
this.newBlocks = new THREE.Group();
|
||||
this.placedBlocks = new THREE.Group();
|
||||
this.choppedBlocks = new THREE.Group();
|
||||
this.stage.add(this.newBlocks);
|
||||
this.stage.add(this.placedBlocks);
|
||||
this.stage.add(this.choppedBlocks);
|
||||
this.addBlock();
|
||||
this.tick();
|
||||
this.updateState(this.STATES.READY);
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.keyCode == 32)
|
||||
this.onAction();
|
||||
});
|
||||
document.addEventListener('click', e => {
|
||||
this.onAction();
|
||||
});
|
||||
document.addEventListener('touchstart', e => {
|
||||
e.preventDefault();
|
||||
// this.onAction();
|
||||
// ☝️ this triggers after click on android so you
|
||||
// insta-lose, will figure it out later.
|
||||
});
|
||||
}
|
||||
updateState(newState) {
|
||||
for (let key in this.STATES)
|
||||
this.mainContainer.classList.remove(this.STATES[key]);
|
||||
this.mainContainer.classList.add(newState);
|
||||
this.state = newState;
|
||||
}
|
||||
onAction() {
|
||||
switch (this.state) {
|
||||
case this.STATES.READY:
|
||||
this.startGame();
|
||||
break;
|
||||
case this.STATES.PLAYING:
|
||||
this.placeBlock();
|
||||
break;
|
||||
case this.STATES.ENDED:
|
||||
this.restartGame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
startGame() {
|
||||
if (this.state != this.STATES.PLAYING) {
|
||||
this.scoreContainer.innerHTML = '0';
|
||||
this.updateState(this.STATES.PLAYING);
|
||||
this.addBlock();
|
||||
}
|
||||
}
|
||||
restartGame() {
|
||||
this.updateState(this.STATES.RESETTING);
|
||||
let oldBlocks = this.placedBlocks.children;
|
||||
let removeSpeed = 0.2;
|
||||
let delayAmount = 0.02;
|
||||
for (let i = 0; i < oldBlocks.length; i++) {
|
||||
TweenLite.to(oldBlocks[i].scale, removeSpeed, { x: 0, y: 0, z: 0, delay: (oldBlocks.length - i) * delayAmount, ease: Power1.easeIn, onComplete: () => this.placedBlocks.remove(oldBlocks[i]) });
|
||||
TweenLite.to(oldBlocks[i].rotation, removeSpeed, { y: 0.5, delay: (oldBlocks.length - i) * delayAmount, ease: Power1.easeIn });
|
||||
}
|
||||
let cameraMoveSpeed = removeSpeed * 2 + (oldBlocks.length * delayAmount);
|
||||
this.stage.setCamera(2, cameraMoveSpeed);
|
||||
let countdown = { value: this.blocks.length - 1 };
|
||||
TweenLite.to(countdown, cameraMoveSpeed, { value: 0, onUpdate: () => { this.scoreContainer.innerHTML = String(Math.round(countdown.value)); } });
|
||||
this.blocks = this.blocks.slice(0, 1);
|
||||
setTimeout(() => {
|
||||
this.startGame();
|
||||
}, cameraMoveSpeed * 1000);
|
||||
}
|
||||
placeBlock() {
|
||||
let currentBlock = this.blocks[this.blocks.length - 1];
|
||||
let newBlocks = currentBlock.place();
|
||||
this.newBlocks.remove(currentBlock.mesh);
|
||||
if (newBlocks.placed)
|
||||
this.placedBlocks.add(newBlocks.placed);
|
||||
if (newBlocks.chopped) {
|
||||
this.choppedBlocks.add(newBlocks.chopped);
|
||||
let positionParams = { y: '-=30', ease: Power1.easeIn, onComplete: () => this.choppedBlocks.remove(newBlocks.chopped) };
|
||||
let rotateRandomness = 10;
|
||||
let rotationParams = {
|
||||
delay: 0.05,
|
||||
x: newBlocks.plane == 'z' ? ((Math.random() * rotateRandomness) - (rotateRandomness / 2)) : 0.1,
|
||||
z: newBlocks.plane == 'x' ? ((Math.random() * rotateRandomness) - (rotateRandomness / 2)) : 0.1,
|
||||
y: Math.random() * 0.1,
|
||||
};
|
||||
if (newBlocks.chopped.position[newBlocks.plane] > newBlocks.placed.position[newBlocks.plane]) {
|
||||
positionParams[newBlocks.plane] = '+=' + (40 * Math.abs(newBlocks.direction));
|
||||
}
|
||||
else {
|
||||
positionParams[newBlocks.plane] = '-=' + (40 * Math.abs(newBlocks.direction));
|
||||
}
|
||||
TweenLite.to(newBlocks.chopped.position, 1, positionParams);
|
||||
TweenLite.to(newBlocks.chopped.rotation, 1, rotationParams);
|
||||
}
|
||||
this.addBlock();
|
||||
}
|
||||
addBlock() {
|
||||
let lastBlock = this.blocks[this.blocks.length - 1];
|
||||
if (lastBlock && lastBlock.state == lastBlock.STATES.MISSED) {
|
||||
return this.endGame();
|
||||
}
|
||||
this.scoreContainer.innerHTML = String(this.blocks.length - 1);
|
||||
let newKidOnTheBlock = new Block(lastBlock);
|
||||
this.newBlocks.add(newKidOnTheBlock.mesh);
|
||||
this.blocks.push(newKidOnTheBlock);
|
||||
this.stage.setCamera(this.blocks.length * 2);
|
||||
if (this.blocks.length >= 5)
|
||||
this.instructions.classList.add('hide');
|
||||
}
|
||||
endGame() {
|
||||
this.updateState(this.STATES.ENDED);
|
||||
}
|
||||
tick() {
|
||||
this.blocks[this.blocks.length - 1].tick();
|
||||
this.stage.render();
|
||||
requestAnimationFrame(() => { this.tick(); });
|
||||
}
|
||||
}
|
||||
let game = new Game();
|
||||
|
||||
;(function(){
|
||||
|
||||
var icon = '<svg class="sg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 185.31 251.89"><path d="M66.8,144.17c0-66.24,22.46-113.09,80.72-112.32,81.48,1.07,80.72,46.08,80.72,112.32,0,5.15,8.38,3.81,7.62,19-2.28,19.42-9.44,14.63-10.39,19.85-9.26,51.08-40.65,88.67-77.95,88.67-37.76,0-69.47-38.53-78.28-90.58-.82-4.85-5.86-.8-6.42-18.68C61.47,146.07,66.8,149.07,66.8,144.17Z" transform="translate(-56.6 -25.84)" style="fill:#ffdfbf;fill-rule:evenodd"/><path d="M147.52,31.85C99.49,31.22,75.79,63,69,111.24c8.78-23.84,27.86-26,64.33-26.54,70.62-1.13,88.39,8.27,79.64,96.55-1.84,18.6-6.1,24.62-28.36,39.74-12.07,8.2,18.54-26.37-49.78-27-49.5-.43-30.06,36.41-40.06,29.44a81.88,81.88,0,0,1-20.28-20.73c12.89,40.76,40.76,69,73.08,69,37.3,0,68.69-37.59,77.95-88.67l2.77-38.89C228.24,77.93,229,32.91,147.52,31.85Z" transform="translate(-56.6 -25.84)" style="fill:#d0b57b;fill-rule:evenodd"/><path d="M146.13,31.84h1.39c81.48,1.07,80.72,46.08,80.72,112.33,0,5.15,8.38,3.81,7.62,19-2.28,19.42-9.44,14.63-10.39,19.85-9.26,51.08-40.65,88.67-77.95,88.67-37.76,0-69.47-38.53-78.28-90.58-.82-4.85-5.86-.8-6.42-18.68-1.34-16.39,4-13.39,4-18.29,0-65.71,22.11-112.33,79.33-112.33m0-6h0c-29.39,0-51.65,11.54-66.18,34.3C67.3,80,60.86,108.06,60.8,143.68h0c-2.54,3.05-4.94,7-4,19.12.4,12.11,2.72,16.46,6.59,19.86,9.65,56,44.19,95.07,84.11,95.07,19.91,0,38.59-9.42,54-27.25,14.35-16.57,24.87-39.79,29.66-65.45l0,0c4.22-2.57,8.87-6.53,10.58-21.1l0-.2v-.2c.58-11.55-3.35-16.18-7.07-19.61l-.53-.5v-1c0-33,0-61.46-10.76-82.11-12-23-36.09-33.89-75.88-34.41Z" transform="translate(-56.6 -25.84)" style="fill:#303030"/><path d="M118.31,183.29s4.28,4.28,12.84,4S143.67,182,143.67,182s-3.62,8.23-11.53,8.89S118.31,183.29,118.31,183.29Z" transform="translate(-56.6 -25.84)" style="fill:#bfa78f;fill-rule:evenodd"/><ellipse cx="44.24" cy="115.64" rx="28.15" ry="35.97" style="fill:#fff"/><ellipse cx="104.54" cy="115.64" rx="28.15" ry="35.97" style="fill:#fff"/><circle class="eye" id="eye-left" cx="35.9" cy="121.66" r="10.5" style="fill:#303030"/><circle class="eye" cx="94.57" cy="121.66" r="10.5" style="fill:#303030"/><path d="M140.74,236.63h0c-16.92,0-29.43-4.38-29.43-18.42h0c0-4.22,4.12-7.64,9.21-7.64H160c3.6,0,6.53,2.42,6.53,5.42v7.23C166.55,234.48,154.32,236.63,140.74,236.63Z" transform="translate(-56.6 -25.84)" style="fill:#2d251d;fill-rule:evenodd"/><path d="M160,210.57h-39.5c-5.09,0-9.21,3.42-9.21,7.64,0,.07,0,.15,0,.22,7.57,2.29,17.6,3.2,29,3.2h0c9.87,0,19.24-.52,26.25-2.36V216C166.55,213,163.62,210.57,160,210.57Z" transform="translate(-56.6 -25.84)" style="fill:#fff"/></svg>';
|
||||
|
||||
document.head.insertAdjacentHTML('beforeend','<style>.sg { width: 35px; height: 35px; position: fixed; bottom: 10px; right: 10px; } .sg .eye { -webkit-transform: translateX(0px); transform: translateX(0px); } .sg:hover .eye { -webkit-transition: -webkit-transform 0.3s ease; transition: -webkit-transform 0.3s ease; transition: transform 0.3s ease; transition: transform 0.3s ease, -webkit-transform 0.3s ease; -webkit-transform: translateX(12px); transform: translateX(12px); }</style>');
|
||||
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href','https://twitter.com/steeevg');
|
||||
a.setAttribute('target','_blank');
|
||||
a.innerHTML = icon;
|
||||
|
||||
document.body.appendChild(a);
|
||||
})();
|
||||
Reference in New Issue
Block a user