mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 03:42:27 +02:00
Add sounds and other improvements to tower defense
This commit is contained in:
parent
8b9eef19c1
commit
e2e0e9d96d
6 changed files with 169 additions and 45 deletions
Binary file not shown.
|
@ -18,7 +18,7 @@
|
|||
y: 1,
|
||||
z: 1
|
||||
};
|
||||
var BLOCK_LIFETIME = 10;
|
||||
var BLOCK_LIFETIME = 120;
|
||||
|
||||
var MUZZLE_SOUND_URL = Script.resolvePath("air_gun_1_converted.wav");
|
||||
var MUZZLE_SOUND_VOLUME = 0.5;
|
||||
|
@ -35,6 +35,7 @@
|
|||
}
|
||||
|
||||
this.launchBlock = function () {
|
||||
print("launch.js | Launching block");
|
||||
var cylinder = Entities.getEntityProperties(cylinderID, ["position", "rotation", "dimensions"]);
|
||||
var muzzlePosition = Vec3.sum(cylinder.position,
|
||||
Vec3.multiplyQbyV(cylinder.rotation, { x: 0.0, y: 0.5 * (cylinder.dimensions.y + BLOCK_DIMENSIONS.y), Z: 0.0 }));
|
||||
|
@ -45,6 +46,7 @@
|
|||
|
||||
Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "TD.block",
|
||||
modelURL: BLOCK_MODEL_URL,
|
||||
shapeType: "compound",
|
||||
//compoundShapeURL: BLOCK_COMPOUND_SHAPE_URL,
|
||||
|
@ -55,7 +57,8 @@
|
|||
position: muzzlePosition,
|
||||
rotation: Quat.multiply(cylinder.rotation, Quat.fromPitchYawRollDegrees(0.0, Math.random() * 360.0, 0.0)),
|
||||
velocity: muzzleVelocity,
|
||||
lifetime: BLOCK_LIFETIME
|
||||
lifetime: BLOCK_LIFETIME,
|
||||
script: Script.resolvePath("destructibleEntity.js")
|
||||
});
|
||||
|
||||
Audio.playSound(muzzleSound, {
|
||||
|
@ -66,14 +69,17 @@
|
|||
}
|
||||
|
||||
this.clickDownOnEntity = function () {
|
||||
print("launch.js | got click down");
|
||||
this.launchBlock();
|
||||
}
|
||||
|
||||
this.startNearTrigger = function () {
|
||||
print("launch.js | got start near trigger");
|
||||
this.launchBlock();
|
||||
}
|
||||
|
||||
this.startFarTrigger = function () {
|
||||
print("launch.js | got start far trigger");
|
||||
this.launchBlock();
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
(function() {
|
||||
return {
|
||||
preload: function(entityID) {
|
||||
Entities.editEntity(entityID, {
|
||||
localRenderAlpha: 0.2
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
|
@ -46,10 +46,11 @@ if (!Function.prototype.bind) {
|
|||
|
||||
var userData = Entities.getEntityProperties(this.entityID, 'userData').userData;
|
||||
var data = parseJSON(userData);
|
||||
if (data !== undefined && data.gameChannel) {
|
||||
this.gameChannel = data.gameChannel
|
||||
if (data !== undefined && data.gameChannel !== undefined && data.teamNumber !== undefined) {
|
||||
this.gameChannel = data.gameChannel;
|
||||
this.teamNumber = data.teamNumber;
|
||||
} else {
|
||||
print("targetEntity.js | ERROR: userData does not contain a game channel");
|
||||
print("targetEntity.js | ERROR: userData does not contain a game channel and/or team number");
|
||||
}
|
||||
},
|
||||
onCollide: function(entityA, entityB, collision) {
|
||||
|
@ -63,7 +64,8 @@ if (!Function.prototype.bind) {
|
|||
this.entityIDsThatHaveCollidedWithMe.push(entityB);
|
||||
Messages.sendMessage(this.gameChannel, JSON.stringify({
|
||||
type: "target-hit",
|
||||
entityID: this.entityID
|
||||
entityID: this.entityID,
|
||||
teamNumber: this.teamNumber
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
|
||||
function signalAC() {
|
||||
var userData = Entities.getEntityProperties(itemID, ["userData"]).userData;
|
||||
Messages.sendMessage(JSON.parse(userData).gameChannel, "START");
|
||||
Messages.sendMessage(JSON.parse(userData).gameChannel, JSON.stringify({
|
||||
type: 'start-game'
|
||||
}));
|
||||
}
|
||||
|
||||
this.startNearTrigger = signalAC;
|
||||
this.startFarTrigger = signalAC;
|
||||
this.clickDownOnEntity = signalAC;
|
||||
})
|
||||
})
|
||||
|
|
|
@ -29,38 +29,34 @@ var GAME_STATES = {
|
|||
};
|
||||
|
||||
var BASE_POSITION = findSurfaceBelowPosition(MyAvatar.position);
|
||||
var BUILD_TIME_SECONDS = 5;
|
||||
var BUILD_TIME_SECONDS = 60;
|
||||
var BUTTON_POSITION = { x: 0, y: 0, z: 0 };
|
||||
var BASES = [
|
||||
{
|
||||
position: { x: -20, y: 0, z: 0 },
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
spawnerPosition: { x: -20, y: 0, z: -1 },
|
||||
buttonPosition: { x: -20, y: 0, z: -1 },
|
||||
},
|
||||
{
|
||||
position: { x: 20, y: 0, z: 0 },
|
||||
color: { red: 0, green: 255, blue: 0 },
|
||||
spawnerPosition: { x: 20, y: 0, z: 1 },
|
||||
buttonPosition: { x: 20, y: 0, z: 1 },
|
||||
},
|
||||
{
|
||||
position: { x: 0, y: 0, z: -20 },
|
||||
color: { red: 0, green: 0, blue: 255 },
|
||||
spawnerPosition: { x: 1, y: 0, z: -20 },
|
||||
buttonPosition: { x: 1, y: 0, z: -20 },
|
||||
},
|
||||
{
|
||||
position: { x: 0, y: 0, z: 20 },
|
||||
color: { red: 255, green: 0, blue: 255 },
|
||||
spawnerPosition: { x: -1, y: 0, z: 20 },
|
||||
buttonPosition: { x: -1, y: 0, z: 20 },
|
||||
},
|
||||
];
|
||||
var BASES_SIZE = 20;
|
||||
var BASES_SIZE = 15;
|
||||
var TARGET_SIZE = 2;
|
||||
var BASES_HEIGHT = 6;
|
||||
var BASES_TRANSPARENCY = 0.2;
|
||||
var BASES = [
|
||||
{
|
||||
position: { x: -15, y: 0, z: 0 },
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
spawnerPosition: { x: -15 + BASES_SIZE/2, y: 0, z: -BASES_SIZE/2 },
|
||||
},
|
||||
{
|
||||
position: { x: 15, y: 0, z: 0 },
|
||||
color: { red: 0, green: 255, blue: 0 },
|
||||
spawnerPosition: { x: 15 - BASES_SIZE/2, y: 0, z: BASES_SIZE/2 },
|
||||
},
|
||||
{
|
||||
position: { x: 0, y: 0, z: -15 },
|
||||
color: { red: 0, green: 0, blue: 255 },
|
||||
spawnerPosition: { x: BASES_SIZE/2, y: 0, z: -15 + BASES_SIZE/2 },
|
||||
},
|
||||
{
|
||||
position: { x: 0, y: 0, z: 15 },
|
||||
color: { red: 255, green: 0, blue: 255 },
|
||||
spawnerPosition: { x: -BASES_SIZE/2, y: 0, z: 15 - BASES_SIZE/2 },
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
var CHANNEL_NAME = "tower-defense-" //+ Math.floor(Math.random() * 9999);
|
||||
|
@ -73,6 +69,13 @@ var bases = [];
|
|||
var entityIDs = [];
|
||||
var spawnerIDs = [];
|
||||
|
||||
var teamEntities = {
|
||||
0: {},
|
||||
1: {},
|
||||
2: {},
|
||||
3: {},
|
||||
};
|
||||
|
||||
var currentState = GAME_STATES.IDLE;
|
||||
|
||||
Messages.subscribe(CHANNEL_NAME);
|
||||
|
@ -85,6 +88,7 @@ if (this.EntityViewer) {
|
|||
var BEGIN_BUILDING_SOUND = SoundCache.getSound(Script.resolvePath("assets/sounds/letTheGamesBegin.wav"));
|
||||
var BEGIN_FIGHTING_SOUND = SoundCache.getSound(Script.resolvePath("assets/sounds/fight.wav"));
|
||||
var GAME_OVER_SOUND = SoundCache.getSound(Script.resolvePath("assets/sounds/gameOver.wav"));
|
||||
var TEN_SECONDS_REMAINING_SOUND = SoundCache.getSound(Script.resolvePath("assets/sounds/tenSecondsRemaining.wav"));
|
||||
|
||||
setup();
|
||||
|
||||
|
@ -123,7 +127,9 @@ function setup() {
|
|||
})
|
||||
};
|
||||
// Base block
|
||||
bases.push(Entities.addEntity(arenaProperties));
|
||||
var arenaID = Entities.addEntity(arenaProperties)
|
||||
bases.push(arenaID);
|
||||
teamEntities[i].arenaID = arenaID;
|
||||
|
||||
|
||||
const ROOF_HEIGHT = 0.2;
|
||||
|
@ -135,16 +141,29 @@ function setup() {
|
|||
registrationPoint: { x: 0.5, y: 0, z: 0.5 },
|
||||
dimensions: { x: BASES_SIZE, y: ROOF_HEIGHT, z: BASES_SIZE },
|
||||
color: BASES[i].color,
|
||||
script: Script.resolvePath('roofEntity.js'),
|
||||
userData: JSON.stringify({
|
||||
gameChannel: CHANNEL_NAME,
|
||||
})
|
||||
}
|
||||
// Player area
|
||||
bases.push(Entities.addEntity(roofProperties));
|
||||
var roofID = Entities.addEntity(roofProperties)
|
||||
bases.push(roofID);
|
||||
teamEntities[i].roofID = roofID;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
var t = teamEntities[i];
|
||||
Entities.deleteEntity(t.targetID);
|
||||
Entities.deleteEntity(t.spawnerID);
|
||||
for (var j = 0; j < t.bowIDs.length; ++j) {
|
||||
Entities.deleteEntity(t.bowIDs[j]);
|
||||
}
|
||||
Entities.deleteEntity(t.roofID);
|
||||
Entities.deleteEntity(t.arenaID);
|
||||
}
|
||||
while (bases.length > 0) {
|
||||
Entities.deleteEntity(bases.pop());
|
||||
}
|
||||
|
@ -155,16 +174,33 @@ function cleanup() {
|
|||
Entities.deleteEntity(entityIDs[i]);
|
||||
}
|
||||
entityIDs = [];
|
||||
for (var i = 0; i < spawnerIDs.length; ++i) {
|
||||
Entities.deleteEntity(spawnerIDs[i]);
|
||||
}
|
||||
spawnerIDs = [];
|
||||
|
||||
print("============= Script Stopping =============");
|
||||
Script.stop();
|
||||
}
|
||||
|
||||
Messages.messageReceived.connect(function(channel, message, senderID) {
|
||||
print("Recieved: " + message + " from " + senderID);
|
||||
function parseJSON(json) {
|
||||
try {
|
||||
return JSON.parse(json);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Messages.messageReceived.connect(function(channel, messageJSON, senderID) {
|
||||
print("Recieved: " + messageJSON + " from " + senderID);
|
||||
if (channel === CHANNEL_NAME) {
|
||||
switch (message) {
|
||||
case "START":
|
||||
var message = parseJSON(messageJSON);
|
||||
if (message === undefined) {
|
||||
print("towerDefense.js | Received non-json message");
|
||||
return;
|
||||
}
|
||||
switch (message.type) {
|
||||
case 'start-game':
|
||||
if (currentState != GAME_STATES.IDLE) {
|
||||
print("Got start message, but not in idle state. Current state: " + currentState);
|
||||
return;
|
||||
|
@ -185,9 +221,11 @@ Messages.messageReceived.connect(function(channel, message, senderID) {
|
|||
script: Script.resolvePath("targetEntity.js"),
|
||||
userData: JSON.stringify({
|
||||
gameChannel: CHANNEL_NAME,
|
||||
teamNumber: i
|
||||
}),
|
||||
});
|
||||
entityIDs.push(targetID);
|
||||
teamEntities[i].targetID = targetID;
|
||||
|
||||
// Create box spawner
|
||||
var spawnerID = Entities.addEntity({
|
||||
|
@ -198,9 +236,13 @@ Messages.messageReceived.connect(function(channel, message, senderID) {
|
|||
color: BASES[i].color,
|
||||
script: Script.resolvePath("launch.js"),
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
wantsTrigger: true
|
||||
},
|
||||
gameChannel: CHANNEL_NAME,
|
||||
})
|
||||
});
|
||||
teamEntities[i].spawnerID = targetID;
|
||||
spawnerIDs.push(spawnerID);
|
||||
Audio.playSound(BEGIN_BUILDING_SOUND, {
|
||||
volume: 1.0,
|
||||
|
@ -210,6 +252,12 @@ Messages.messageReceived.connect(function(channel, message, senderID) {
|
|||
|
||||
currentState = GAME_STATES.BUILD;
|
||||
|
||||
Script.setTimeout(function() {
|
||||
Audio.playSound(TEN_SECONDS_REMAINING_SOUND, {
|
||||
volume: 1.0,
|
||||
position: BASE_POSITION
|
||||
});
|
||||
}, (BUILD_TIME_SECONDS - 10) * 1000);
|
||||
Script.setTimeout(function() {
|
||||
print("============ Done building, FIGHT =============");
|
||||
|
||||
|
@ -228,17 +276,74 @@ Messages.messageReceived.connect(function(channel, message, senderID) {
|
|||
}
|
||||
|
||||
// Spawn bows
|
||||
for (var i = 0; i < BASES.length; ++i) {
|
||||
var position = Vec3.sum(BASE_POSITION, BASES[i].position);
|
||||
position.y += BASES_HEIGHT + 1;
|
||||
teamEntities[i].bowIDs = [];
|
||||
|
||||
for (var j = 0; j < 4; ++j) {
|
||||
teamEntities[i].bowIDs.push(Entities.addEntity({
|
||||
position: position,
|
||||
"collisionsWillMove": 1,
|
||||
"compoundShapeURL": Script.resolvePath("bow/bow_collision_hull.obj"),
|
||||
"created": "2016-09-01T23:57:55Z",
|
||||
"dimensions": {
|
||||
"x": 0.039999999105930328,
|
||||
"y": 1.2999999523162842,
|
||||
"z": 0.20000000298023224
|
||||
},
|
||||
"dynamic": 1,
|
||||
"gravity": {
|
||||
"x": 0,
|
||||
"y": -1,
|
||||
"z": 0
|
||||
},
|
||||
"modelURL": Script.resolvePath("bow/bow-deadly.fbx"),
|
||||
"name": "TD.Hifi-Bow",
|
||||
"rotation": {
|
||||
"w": 0.9718012809753418,
|
||||
"x": 0.15440607070922852,
|
||||
"y": -0.10469216108322144,
|
||||
"z": -0.14418250322341919
|
||||
},
|
||||
"script": Script.resolvePath("bow/bow.js"),
|
||||
"shapeType": "compound",
|
||||
"type": "Model",
|
||||
"userData": "{\"grabbableKey\":{\"grabbable\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.0813,\"y\":0.0452,\"z\":0.0095},{\"x\":-0.3946,\"y\":-0.6604,\"z\":0.4748,\"w\":-0.4275}],\"LeftHand\":[{\"x\":-0.0881,\"y\":0.0259,\"z\":0.0159},{\"x\":0.4427,\"y\":-0.6519,\"z\":0.4592,\"w\":0.4099}]}}}"
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}, BUILD_TIME_SECONDS * 1000);
|
||||
break;
|
||||
case "STOP":
|
||||
case 'target-hit':
|
||||
print("Got target-hit for: ", message.teamNumber);
|
||||
if (currentState !== GAME_STATES.FIGHT) {
|
||||
return;
|
||||
}
|
||||
print("game is over");
|
||||
Audio.playSound(GAME_OVER_SOUND, {
|
||||
volume: 1.0,
|
||||
position: BASE_POSITION
|
||||
});
|
||||
currentState = GAME_STATES.GAME_OVER;
|
||||
cleanup();
|
||||
currentState = GAME_STATES.IDLE;
|
||||
|
||||
// Delete the entities for the team that lost
|
||||
var t = teamEntities[message.teamNumber];
|
||||
Entities.deleteEntity(t.targetID);
|
||||
Entities.deleteEntity(t.spawnerID);
|
||||
Entities.deleteEntity(t.roofID);
|
||||
Entities.deleteEntity(t.arenaID);
|
||||
|
||||
// TODO If more than 1 team is still alive, don't cleanup
|
||||
// Do a full cleanup after 10 seconds
|
||||
Script.setTimeout(function() {
|
||||
cleanup();
|
||||
currentState = GAME_STATES.IDLE;
|
||||
}, 10 * 1000);
|
||||
break;
|
||||
default:
|
||||
print("towerDefense.js | Ignoring unknown message type: ", message.type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue