mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-16 13:10:00 -04:00
634 lines
18 KiB
JavaScript
634 lines
18 KiB
JavaScript
var camera, scene, renderer, spotlight;
|
|
var triangle, triEdges; // the object the user controls("spaceship"), there is only one 'triangle' in CUBEfield!
|
|
var plane; // ground landscape floor w/e
|
|
var xSpeed; // x (side to side) speed of the triangle
|
|
var zSpeed; // z speed of the triangle
|
|
var zOffset; // position of triangle
|
|
var camOffset; // camera offset is a little softer than xOffset
|
|
var stars;
|
|
var starSpeed;
|
|
var numCubes = 120;
|
|
var leftArrow, rightArrow, upArrow;
|
|
var timeElapse;
|
|
var cubeAdd; // need a way to add cubes at a steady rate
|
|
var score;
|
|
var phase; // -1 = pre-game screen, 0 = pause, 1 = in-game, (post-game = pre-game)
|
|
var composer;
|
|
var level; // level of difficulty (increases as game goes on)
|
|
var levelBreak; // timer for time break between levels
|
|
var width, height;
|
|
var rotStart = 0;
|
|
var mCubes; // array of Cube objects
|
|
// settings
|
|
var stnDiff = 0; // difficulty { rookie, skilled, master }
|
|
var stnBounce = 0; // bounce { none, some, too much }
|
|
var stnCam = 0; // camera { hawk, chase, 1st person }
|
|
var stnBlock = 0; // blocks { normal, falling, pop up }
|
|
// UI
|
|
var uiNewGame = document.getElementById( "newGame" );
|
|
var uiScore = document.getElementById( "score" );
|
|
var uiHScore = document.getElementById( "highScore" );
|
|
var uiInfo = document.getElementById( "info" );
|
|
var uiSettings = document.getElementById( "settings" );
|
|
var uiPause = document.getElementById( "pause" );
|
|
|
|
init();
|
|
animate();
|
|
|
|
// --- INITIALIZATION ---------------------------------------------------------
|
|
|
|
function init() {
|
|
// viewport
|
|
width = window.innerWidth;
|
|
height = window.innerHeight;
|
|
// init members
|
|
levelBreak = 0;
|
|
level = 0;
|
|
phase = -1;
|
|
score = 0;
|
|
camOffset = 0;
|
|
timeElapse = new Date().getTime();
|
|
totalElapse = 0;
|
|
zOffset = 0;
|
|
xSpeed = 0;
|
|
zSpeed = 0;
|
|
leftArrow = rightArrow = upArrow = false;
|
|
mCubes = [];
|
|
starSpeed = [];
|
|
stars = [];
|
|
|
|
// scene
|
|
scene = new THREE.Scene();
|
|
scene.fog = new THREE.Fog(0xa3a3a3, 5, 25);
|
|
|
|
// Renderer
|
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
|
renderer.setClearColor(0xffffff, 0);
|
|
renderer.setSize( width, height );
|
|
renderer.shadowMap.enabled = true;
|
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
var ambient = new THREE.AmbientLight(0xffffff);
|
|
scene.add(ambient);
|
|
|
|
// Camera
|
|
camera = new THREE.PerspectiveCamera( 15, width / height, 0.1, 1000 );
|
|
camera.position.set(0, 0.25, 2.0);
|
|
|
|
// Ground plane
|
|
var planeGeo = new THREE.PlaneBufferGeometry(300, 75, 20);
|
|
plane = new THREE.Mesh(planeGeo, new THREE.MeshStandardMaterial({ color: 0xffffff }));
|
|
plane.receiveShadow = true;
|
|
plane.rotation.x += -0.5 * Math.PI;
|
|
plane.position.y = -0.001;
|
|
scene.add(plane);
|
|
|
|
// Cubes
|
|
for (var c = 0; c < numCubes; c++) {
|
|
mCubes[ c ] = new Cube(scene);
|
|
}
|
|
|
|
// Player triangle
|
|
var triGeo = new THREE.Geometry();
|
|
|
|
// player triangle - vectors
|
|
triGeo.vertices.push(
|
|
new THREE.Vector3( 0.000, 0.000, -0.150 ),
|
|
new THREE.Vector3( -0.017, 0.000, 0.040 ),
|
|
new THREE.Vector3( 0.017, 0.000, 0.040 ),
|
|
new THREE.Vector3( 0.000, 0.013, 0.020 )
|
|
);
|
|
// player triangle - push faces
|
|
triGeo.faces.push( new THREE.Face3( 3, 0, 1 ) );
|
|
triGeo.faces.push( new THREE.Face3( 1, 2, 3 ) );
|
|
triGeo.faces.push( new THREE.Face3( 2, 0, 3 ) );
|
|
triangle = new THREE.Mesh(triGeo, new THREE.MeshBasicMaterial({ color: 0x646464 }));
|
|
triangle.castShadow = true;
|
|
triangle.position.y = -2.0;
|
|
scene.add(triangle);
|
|
|
|
// player triangle - edges
|
|
var edgeGeo = new THREE.EdgesGeometry(triGeo);
|
|
triEdges = new THREE.LineSegments(edgeGeo, new THREE.MeshBasicMaterial({ color: 0x000000 }));
|
|
scene.add(triEdges);
|
|
|
|
spotlight = new THREE.SpotLight( 0xffffff);
|
|
spotlight.position.set(0, 100, 0);
|
|
spotlight.target = triangle;
|
|
spotlight.castShadow = true;
|
|
spotlight.shadow.camera.near = 0.1;
|
|
spotlight.shadow.camera.far = 20;
|
|
spotlight.shadow.mapSize.width = window.innerWidth;
|
|
spotlight.shadow.mapSize.height = window.innerHeight;
|
|
scene.add(spotlight);
|
|
|
|
// stars (level 2 background)
|
|
initStars();
|
|
|
|
// init ui
|
|
uiScore.style.visibility = "hidden";
|
|
document.getElementById("highScore").innerHTML = (Math.floor(getCookie() / 100) / 10).toString();
|
|
|
|
setPreGame();
|
|
}
|
|
|
|
// Init stars
|
|
function initStars() {
|
|
stars = [];
|
|
|
|
// Texture/material
|
|
var texture = new THREE.TextureLoader().load('assets/images/star.png');
|
|
var material = new THREE.MeshBasicMaterial({ map: texture });
|
|
var geo = new THREE.BoxBufferGeometry(.5, .5, .1);
|
|
|
|
// Build stars
|
|
for (var i = 0; i < 10; i++) {
|
|
starSpeed[i] = [];
|
|
|
|
// Build mesh
|
|
stars[i] = new THREE.Mesh(geo, material);
|
|
|
|
// Set position/rotation
|
|
stars[i].position.z = 5;
|
|
stars[i].position.x = Math.random() * 20 - 10;
|
|
stars[i].position.y = Math.random() * 10;
|
|
stars[i].rotation.z = Math.random() * 2 * Math.PI;
|
|
|
|
// Set velocity
|
|
starSpeed[i][0] = Math.random() * 0.003 - 0.0015;
|
|
starSpeed[i][1] = Math.random() * 0.003 - 0.0015;
|
|
|
|
// Add to scene
|
|
scene.add(stars[i]);
|
|
}
|
|
}
|
|
|
|
// Set params/globals for new game
|
|
function gameReset() {
|
|
// UI
|
|
uiNewGame.style.visibility = "hidden";
|
|
uiInfo.style.visibility = "hidden";
|
|
uiScore.style.color = "#808080";
|
|
uiScore.style.visibility = "visible";
|
|
document.body.style.backgroundColor = "#A3A3A3";
|
|
uiSettings.classList.remove( "settingsVis" );
|
|
// Blur render
|
|
document.querySelector('canvas').style.filter = 'blur(0px)';
|
|
document.querySelector('canvas').style.cursor = 'none';
|
|
|
|
score = 0;
|
|
// camOffset = 0;
|
|
timeElapse = new Date().getTime();
|
|
zOffset = 0;
|
|
xSpeed = 0;
|
|
zSpeed = 0;
|
|
camera.position.z = 0;
|
|
|
|
// cubes
|
|
for( var c of mCubes ) {
|
|
c.reset(stnBlock, true, stnDiff);
|
|
}
|
|
|
|
// hide stars
|
|
for ( var s of stars ) {
|
|
s.position.z = 5;
|
|
}
|
|
|
|
var k = Math.PI - ( this.camera.rotation.z % ( 2*Math.PI ));
|
|
rotStart = ( Math.PI - Math.abs( k )) * Math.sign( k );
|
|
totalElapse = 0;
|
|
phase = 1;
|
|
}
|
|
|
|
// Reset game upon finish
|
|
function setPreGame() {
|
|
// UI
|
|
uiScore.style.color = "black";
|
|
document.body.style.backgroundColor = "#A3A3A3";
|
|
// Show UI
|
|
uiNewGame.style.visibility = "visible";
|
|
uiInfo.style.visibility = "visible";
|
|
uiSettings.classList.add( "settingsVis" );
|
|
// Blur render
|
|
document.querySelector('canvas').style.filter = 'blur(5px)';
|
|
document.querySelector('canvas').style.cursor = 'pointer';
|
|
// Triangle
|
|
triangle.material.color.setHex(0x646464);
|
|
triEdges.material.color.setHex(0x000000);
|
|
|
|
// cubes
|
|
for (var c of mCubes) {
|
|
c.updateDesign(0);
|
|
}
|
|
|
|
level = 0;
|
|
plane.material.color.setHex( 0xC8C8C8 );
|
|
scene.fog.color.setHex(0xA3A3A3);
|
|
|
|
// hide stars
|
|
for (var s of stars) {
|
|
s.position.z = 5;
|
|
}
|
|
}
|
|
|
|
// level effects/shaders
|
|
function newLevel() {
|
|
// Update level vars
|
|
levelBreak = new Date().getTime();
|
|
level++;
|
|
|
|
// Update design of cubes
|
|
for (var c of mCubes) {
|
|
c.updateDesign(level % 5);
|
|
}
|
|
|
|
// Update design of plane (ground)
|
|
switch (level % 5) {
|
|
|
|
case 0:
|
|
plane.material.color.setHex(0xC8C8C8);
|
|
scene.fog.color.setHex(0xA3A3A3);
|
|
triangle.material.color.setHex(0x646464);
|
|
triEdges.material.color.setHex(0x000000);
|
|
document.body.style.backgroundColor = "#A3A3A3";
|
|
break;
|
|
|
|
case 1:
|
|
plane.material.color.setHex(0x000000);
|
|
scene.fog.color.setHex(0x000000);
|
|
triangle.material.color.setHex(0x000000);
|
|
triEdges.material.color.setHex(0x00FF00);
|
|
document.body.style.backgroundColor = "#000000";
|
|
|
|
// show stars
|
|
for (var s of stars) {
|
|
s.position.z = -50;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
plane.material.color.setHex(0x969696);
|
|
scene.fog.color.setHex(0x969696);
|
|
triangle.material.color.setHex(0x000000);
|
|
triEdges.material.color.setHex(0x000000);
|
|
document.body.style.backgroundColor = "#969696";
|
|
|
|
// hide stars
|
|
for( var s of stars ) {
|
|
s.position.z = 5;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
plane.material.color.setHex(0xffffff);
|
|
scene.fog.color.setHex(0xffffff);
|
|
triangle.material.color.setHex(0x646464);
|
|
triEdges.material.color.setHex(0x000000);
|
|
document.body.style.backgroundColor = "#FFFFFF";
|
|
break;
|
|
|
|
case 4:
|
|
plane.material.color.setHex(0x969696);
|
|
scene.fog.color.setHex(0x969696);
|
|
triangle.material.color.setHex(0xFF326C);
|
|
triEdges.material.color.setHex(0xFFFFFF);
|
|
document.body.style.backgroundColor = "#969696";
|
|
}
|
|
}
|
|
|
|
// --- GAME LOOP --------------------------------------------------------------
|
|
function animate() {
|
|
requestAnimationFrame(animate);
|
|
|
|
// Time elapsed
|
|
var now = (new Date()).getTime();
|
|
var elapse = now - timeElapse;
|
|
timeElapse = now;
|
|
var rate = elapse / 100;
|
|
|
|
// Game state
|
|
switch (phase) {
|
|
|
|
// Pre-game
|
|
case -1:
|
|
// Demo mode in background
|
|
xSpeed *= 0.95;
|
|
zSpeed *= 0.95;
|
|
camOffset *= 0.95;
|
|
|
|
// Level speed
|
|
var levelSpeed = (level + 1) * rate * 0.5 + zSpeed;
|
|
|
|
// --- Camera -----------------------------------------------------------
|
|
// Camera rotation
|
|
camera.rotation.z = (camera.rotation.z + xSpeed * 1.5) * 0.7;
|
|
camera.rotation.z = Math.min(0.1, Math.max(-0.1, camera.rotation.z));
|
|
|
|
// Camera position
|
|
camera.position.x += xSpeed * rate * -10;
|
|
camera.position.z -= levelSpeed;
|
|
|
|
// Update player triangle and plane to match camera position
|
|
triangle.position.z = triEdges.position.z = plane.position.z = camera.position.z - 2.2;
|
|
triangle.position.x = triEdges.position.x = plane.position.x = camera.position.x;
|
|
|
|
// Update player triangle rotation to match camera rotation
|
|
triangle.rotation.y = camera.rotation.z;
|
|
triEdges.rotation.y = camera.rotation.z;
|
|
|
|
// Update spotlight
|
|
spotlight.position.set(triangle.position.x, triangle.position.y + 10, triangle.position.z);
|
|
|
|
|
|
updateCubes(rate * 0.2, levelSpeed);
|
|
break;
|
|
|
|
// Pause
|
|
case 0:
|
|
break;
|
|
|
|
// In-game
|
|
case 1:
|
|
// --- User Input -------------------------------------------------------
|
|
if (!rightArrow && !leftArrow) {
|
|
// No arrow key input
|
|
xSpeed *= 0.8;
|
|
} else {
|
|
// Arrow key input
|
|
if (leftArrow) {
|
|
xSpeed += 0.02 * rate;
|
|
}
|
|
if (rightArrow) {
|
|
xSpeed -= 0.02 * rate;
|
|
}
|
|
}
|
|
// Horizontal speed limits
|
|
xSpeed = Math.max(-0.5, Math.min(0.5, xSpeed));
|
|
// Forward speed
|
|
zSpeed = upArrow ? zSpeed + 0.025 * rate : zSpeed * 0.95;
|
|
zSpeed = Math.min(0.4, zSpeed);
|
|
|
|
// Level speed
|
|
var levelSpeed = (1 + level * 0.5) * rate * 0.5 * (1 + stnDiff * 1.5) + zSpeed + 0.05;
|
|
|
|
// --- Camera -----------------------------------------------------------
|
|
// Camera rotation
|
|
camera.rotation.z = (camera.rotation.z + xSpeed * 1.5) * 0.7;
|
|
camera.rotation.z = Math.min(0.1, Math.max(-0.1, camera.rotation.z));
|
|
|
|
// Camera position
|
|
camera.position.x += xSpeed * rate * -10;
|
|
camera.position.z -= levelSpeed;
|
|
|
|
// Update player triangle and plane to match camera position
|
|
triangle.position.z = triEdges.position.z = plane.position.z = camera.position.z + (stnCam == 0 ? -2.2 : (stnCam == 1 ? -1.2 : 0.2));
|
|
triangle.position.x = triEdges.position.x = plane.position.x = camera.position.x;
|
|
|
|
// Update player triangle rotation to match camera rotation
|
|
triangle.rotation.y = camera.rotation.z;
|
|
triEdges.rotation.y = camera.rotation.z;
|
|
triangle.rotation.z = camera.rotation.z * 2;
|
|
triEdges.rotation.z = camera.rotation.z * 2;
|
|
triangle.position.y = 0.01 - Math.abs(camera.rotation.z * 0.05);
|
|
triEdges.position.y = 0.01 - Math.abs(camera.rotation.z * 0.05);
|
|
|
|
// Update spotlight
|
|
spotlight.position.set(triangle.position.x, triangle.position.y + 10, triangle.position.z);
|
|
|
|
// --- Scoring ----------------------------------------------------------
|
|
// score = zOffset * ( 10 + level * 5 );
|
|
totalElapse += elapse;
|
|
uiScore.innerHTML = (Math.round(totalElapse / 100) / 10).toString();
|
|
|
|
|
|
// New level
|
|
if ((level + 1) * 30000 < totalElapse) {
|
|
newLevel();
|
|
}
|
|
|
|
// Break between levels (no cubes)
|
|
if (levelBreak != -1 && now - levelBreak > 5000) {
|
|
levelBreak = -1;
|
|
}
|
|
|
|
// Update position of cubes + add cubes or remove cubes
|
|
updateCubes(rate, levelSpeed);
|
|
}
|
|
|
|
// Update stars (if on right level)
|
|
if (level % 5 == 1) {
|
|
updateStars();
|
|
}
|
|
|
|
// Render
|
|
if (phase == 1) {
|
|
renderer.setClearColor(0xffffff, 0);
|
|
} else {
|
|
renderer.setClearColor(0xa3a3a3, 1);
|
|
}
|
|
renderer.render(scene, camera);
|
|
}
|
|
|
|
// --- UPDATE -----------------------------------------------------------------
|
|
|
|
// UPDATE stars
|
|
function updateStars() {
|
|
for (var s = 0; s < stars.length; s++) {
|
|
// Reset position of stars that go out of bounds
|
|
if (stars[ s ].position.x < -10 ||
|
|
stars[ s ].position.x > 10 ||
|
|
stars[ s ].position.y < 0 ||
|
|
stars[ s ].position.y > 10 )
|
|
{
|
|
stars[ s ].position.x = Math.random() * 20 - 10;
|
|
stars[ s ].position.y = Math.random() * 10;
|
|
}
|
|
// Update star position
|
|
stars[ s ].position.x += starSpeed[ s ][ 0 ];
|
|
stars[ s ].position.y += starSpeed[ s ][ 1 ];
|
|
stars[ s ].rotation.z += 0.003;
|
|
}
|
|
}
|
|
|
|
// UPDATE cubes
|
|
function updateCubes(rate, levelSpeed) {
|
|
for (var c of mCubes) {
|
|
var collision = c.update(rate, levelSpeed, triangle, levelBreak, level, stnBounce, stnBlock, stnDiff );
|
|
if (phase == 1 && collision) {
|
|
logHighscore();
|
|
phase = -1;
|
|
setPreGame();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// UPDATE camera position
|
|
function setCam() {
|
|
switch( stnCam ) {
|
|
case 0:
|
|
camera.position.x = 0;
|
|
camera.position.y = 0.25;
|
|
camera.position.z = 2.0;
|
|
break;
|
|
case 1:
|
|
camera.position.x = 0;
|
|
camera.position.y = 0.05;
|
|
camera.position.z = 0.40;
|
|
break;
|
|
case 2:
|
|
camera.position.x = 0;
|
|
camera.position.y = 0.025;
|
|
camera.position.z = 0.0;
|
|
}
|
|
}
|
|
// --- EVENT HANDLING ---------------------------------------------------------
|
|
|
|
// Window Resize
|
|
document.addEventListener('resize', (e) => {
|
|
width = window.innerWidth;
|
|
height = window.innerHeight;
|
|
// renderer
|
|
renderer.setSize( width, height );
|
|
// camera
|
|
camera = new THREE.PerspectiveCamera( 15, width / height, 0.1, 1000 );
|
|
setCam();
|
|
});
|
|
|
|
// Key Down
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.keyCode == null) {
|
|
// touch input event
|
|
if( e.pageX > width * 0.5 ) {
|
|
rightArrow = true;
|
|
}else {
|
|
leftArrow = true;
|
|
}
|
|
} else {
|
|
// key input event
|
|
var key = e.keyCode ? e.keyCode : e.which;
|
|
if (key == 37 ) {
|
|
leftArrow = true;
|
|
} else if ( key == 39 ) {
|
|
rightArrow = true;
|
|
} else if ( key == 80 ) { // (p)ause
|
|
pauseGameScreen();
|
|
} else if (key == 38) {
|
|
upArrow = true;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Key Up
|
|
document.addEventListener('keyup', (e) => {
|
|
if (e.keyCode == null) {
|
|
// touch input event
|
|
rightArrow = false;
|
|
leftArrow = false;
|
|
upArrow = false;
|
|
} else {
|
|
var key = e.keyCode ? e.keyCode : e.which;
|
|
if (key == 37) {
|
|
leftArrow = false;
|
|
} else if (key == 39) {
|
|
rightArrow = false;
|
|
} else if (key == 38) {
|
|
upArrow = false;
|
|
}
|
|
}
|
|
});
|
|
// pause screen
|
|
function pauseGameScreen() {
|
|
if( phase == 0 ) {
|
|
phase = 1;
|
|
uiPause.style.visibility = "hidden";
|
|
uiPause.style.opacity = 0.0;
|
|
}else if( phase == 1 ) {
|
|
phase = 0;
|
|
uiPause.style.visibility = "visible";
|
|
uiPause.style.opacity = 1.0;
|
|
}
|
|
}
|
|
// return to menu mouse click at pause screen
|
|
function returnToMenu() {
|
|
uiPause.style.opacity = 0.0;
|
|
uiPause.style.visibility = "hidden";
|
|
logHighscore();
|
|
rotOffset = (new Date()).getTime() % 50000;
|
|
phase = -1;
|
|
setPreGame();
|
|
}
|
|
|
|
// --- SETTINGS ---------------------------------------------------------------
|
|
|
|
// Difficulty settings click event
|
|
function updateDiff (target) {
|
|
stnDiff = target;
|
|
var opt = document.getElementById( "difficulty" ).getElementsByClassName( "select" );
|
|
for( var k = 0; k < 3; k++ )
|
|
opt[ k ].classList.remove( "focus" );
|
|
opt[ target ].classList.add( "focus" );
|
|
}
|
|
|
|
// Bounce settings click event
|
|
function updateBounce( target ) {
|
|
stnBounce = target;
|
|
var opt = document.getElementById( "bounce" ).getElementsByClassName( "select" );
|
|
for( var k = 0; k < 3; k++ )
|
|
opt[ k ].classList.remove( "focus" );
|
|
opt[ target ].classList.add( "focus" );
|
|
|
|
}
|
|
// camera settings click event
|
|
function updateCam( target ) {
|
|
stnCam = target;
|
|
var opt = document.getElementById( "camera" ).getElementsByClassName( "select" );
|
|
for( var k = 0; k < 3; k++ )
|
|
opt[ k ].classList.remove( "focus" );
|
|
opt[ target ].classList.add( "focus" );
|
|
setCam();
|
|
}
|
|
// blocks settings click event
|
|
function updateBlock( target ) {
|
|
stnBlock = target;
|
|
var opt = document.getElementById( "block" ).getElementsByClassName( "select" );
|
|
for( var k = 0; k < 3; k++ )
|
|
opt[ k ].classList.remove( "focus" );
|
|
opt[ target ].classList.add( "focus" );
|
|
for( var c of mCubes ) c.reset( stnBlock, false, stnDiff );
|
|
document.getElementById( "bounce" ).style.opacity = target > 0 ? "1.0" : "0.0";
|
|
}
|
|
|
|
// --- COOKIE highscore logging -----------------------------------------------
|
|
|
|
// Log highscore
|
|
function logHighscore() {
|
|
if( totalElapse > parseInt(getCookie()) || getCookie() == "" ) {
|
|
setCookie( totalElapse );
|
|
uiHScore.innerHTML = (Math.floor(totalElapse / 100) / 10).toString();
|
|
}else {
|
|
uiHScore.innerHTML = (Math.floor(getCookie() / 100) / 10).toString();
|
|
}
|
|
}
|
|
|
|
// Set highscore cookie
|
|
function setCookie(score) {
|
|
document.cookie = "highscore=" + score.toString() + "; ";
|
|
}
|
|
|
|
// Get highscore cookie
|
|
function getCookie() {
|
|
var name = "highscore=";
|
|
var ca = document.cookie.split(';');
|
|
for (var i=0; i<ca.length; i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0)==' ') {
|
|
c = c.substring( 1 );
|
|
}
|
|
if (c.indexOf(name) == 0) {
|
|
return c.substring(name.length, c.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|