Skip to content

Commit 65a4fe7

Browse files
author
Mathias
committed
- Added proof of concept menu (currently this can be classified as aesthetic torture!) in index.html
- Moved the entire game to game.html. - Added public functions for switching between animations in ModelRender. - MapParser now nicely formats entity values into JSON objects. - Added an util class for handling mouse events similiarly to how Keyboard.js handles keyboard events. - Implemented player-shooting-animation and player-reload-animation in Player.js - Fixed floating point errors in collision detection
1 parent c17579d commit 65a4fe7

11 files changed

+426
-169
lines changed

CollisionDetection.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ cs.CollisionDetection = (function() {
2828
//models[0] is the geometry of the entire map
2929
recursiveHullCheck(mapData.models[0].iHeadNodes[0], 0, 1,
3030
vStart, vEnd, traceObj);
31-
31+
3232
//If ratio is still 1 we never collided with anything
33-
if(traceObj.ratio == 1.0) {
33+
if(traceObj.ratio === 1.0) {
3434
return vEnd;
3535
}
3636
//Collision found
@@ -216,7 +216,8 @@ cs.CollisionDetection = (function() {
216216
var x = pos[0];
217217
var y = pos[1];
218218
var z = pos[2];
219-
return trace(pos, [x, y, z-1], false)[2] >= z;
219+
var t = trace(pos, [x, y, z-1], false);
220+
return Math.abs(t[2] - z) < 0.000001;
220221
}
221222
};
222223
})();

MapParser.js

+71-1
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,84 @@ cs.MapParser = (function () {
8080
//Split into an array of entities
8181
var entitiesArray = sEntities.split("}\n{");
8282

83+
//Helper formatters
84+
var identity = function(x) { return x; };
85+
var parseList = function(formatter) {
86+
return function(x) {
87+
var list = [];
88+
for(var o in x.split(" ")) {
89+
list.push(formatter(o));
90+
}
91+
return list;
92+
};
93+
};
94+
//A map from key to value formatters.
95+
var formatters = {
96+
MaxRange: parseInt,
97+
classname: identity,
98+
light: parseInt,
99+
message: identity,
100+
skyname: identity,
101+
sounds: parseInt,
102+
wad: function(x) { return x.split(";"); },
103+
model: function(x) {
104+
//Most entities have a value of the form *N where N is an integer
105+
//But some entities have a string value instead,
106+
//(i.e path to models in case of hostages)
107+
if(x[0] === "*")
108+
return parseInt(x.substr(1));
109+
return identity;
110+
},
111+
renderamt: parseInt,
112+
rendercolor: new parseList(parseInt),
113+
rendermode: parseInt,
114+
skin: parseInt,
115+
angles: new parseList(parseInt),
116+
delay: parseInt,
117+
distance: parseInt,
118+
dmg: parseInt,
119+
health: parseInt,
120+
lip: parseInt,
121+
locked_sentence: parseInt,
122+
locked_sound: parseInt,
123+
movesnd: parseInt,
124+
origin: new parseList(parseInt),
125+
renderfx: parseInt,
126+
speed: parseInt,
127+
stopsnd: parseInt,
128+
unlocked_sentence: parseInt,
129+
unlocked_sound: parseInt,
130+
wait: parseInt,
131+
_light: new parseList(parseInt),
132+
pitch: parseInt,
133+
angle: parseInt,
134+
spawnflags: parseInt,
135+
target: identity,
136+
deceleration: parseInt,
137+
targetname: identity,
138+
explodemagnitude: parseInt,
139+
explosion: parseInt,
140+
material: parseInt,
141+
spawnobject: parseInt,
142+
texture: identity,
143+
acceleration: parseInt,
144+
killtarget: identity,
145+
triggerstate: parseInt,
146+
_fade: parseFloat
147+
};
148+
83149
var entityLump = Array(entitiesArray.length);
84150
for(var i = 0; i < entitiesArray.length; ++i) {
85151
//Get key
86152
var sKeyVal = entitiesArray[i].split("\"");
87153
var map = {};
88154
//Create a mapping from key => value
89155
for(var j = 1; j < sKeyVal.length; j += 4) {
90-
map[sKeyVal[j]] = sKeyVal[j+2];
156+
var key = sKeyVal[j];
157+
var value = sKeyVal[j+2];
158+
var formatter = formatters[key];
159+
if(!formatter) console.log("Unknown entity name: " + key);
160+
else map[key] = formatter(value);
91161
}
92162
entityLump[i] = map;
93163
}
File renamed without changes.

ModelRender.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ cs.ModelRender = function(gl, player) {
4343
STUDIO_RLOOP: 0x8000
4444
};
4545

46-
this.sequenceIndex = 1;
47-
46+
var sequenceIndex = 0;
4847
var frame = 0;
49-
48+
var customFPS = null;
5049
var vertexBuffer = gl.createBuffer();
50+
var animationQueue = [];
51+
var previous = new Date().getTime();
5152

5253
var fragmentShader =
5354
" precision mediump float;" +
@@ -401,13 +402,25 @@ cs.ModelRender = function(gl, player) {
401402
if(dt > 0.1) {
402403
dt = 0.1;
403404
}
404-
frame += dt * sequence.fps;
405+
frame += dt * (customFPS || sequence.fps);
405406

406407
if(sequence.numFrames <= 1) {
407408
frame = 0;
408409
}
409410
else {
410-
frame -= Math.floor(frame / (sequence.numFrames - 1)) * (sequence.numFrames - 1);
411+
var newFrame = frame - Math.floor(frame / (sequence.numFrames - 1)) * (sequence.numFrames - 1);
412+
//Did we just restart our animation?
413+
if(newFrame < frame) {
414+
//Do we have an animation queued up?
415+
if(animationQueue.length != 0) {
416+
//Yep. Set index and requested fps
417+
newFrame = 0;
418+
var anim = animationQueue.shift();
419+
sequenceIndex = anim.index;
420+
customFPS = anim.fps;
421+
}
422+
}
423+
frame = newFrame;
411424
}
412425
return frame;
413426
};
@@ -424,7 +437,6 @@ cs.ModelRender = function(gl, player) {
424437
transforms[n] = vectorTransform([vertices[i], vertices[i+1], vertices[i+2]], transformations[model.transformIndices[n]]);
425438
}
426439

427-
var k = 0;
428440
for(var i = 0; i < model.numMesh; ++i) {
429441
var mesh = model.mesh[i];
430442
var texture = player.textures[DataReader.readSignedShort(player.data, player.header.skinIndex + 2*mesh.skinRef)];
@@ -460,10 +472,6 @@ cs.ModelRender = function(gl, player) {
460472

461473
//Add vertex
462474
var vertex = transforms[vertIndex];
463-
++k;
464-
if(k === 130) {
465-
var g = 0;
466-
}
467475

468476
buffer.push(vertex[0]);
469477
buffer.push(vertex[1]);
@@ -490,8 +498,6 @@ cs.ModelRender = function(gl, player) {
490498
}
491499
};
492500

493-
var previous = new Date().getTime();
494-
495501
this.render = function(){
496502
gl.useProgram(shaderProgram);
497503

@@ -504,7 +510,7 @@ cs.ModelRender = function(gl, player) {
504510
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, cs.pMatrix);
505511
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, cs.mvMatrix);
506512

507-
var sequence = player.sequences[this.sequenceIndex];
513+
var sequence = player.sequences[sequenceIndex];
508514
var transformations = setupBones(frame, sequence);
509515

510516
for(var i = 0; i < player.header.numBodyParts; ++i) {
@@ -520,4 +526,10 @@ cs.ModelRender = function(gl, player) {
520526
gl.disableVertexAttribArray(shaderProgram.vertexPositionAttribute);
521527
gl.disableVertexAttribArray(shaderProgram.texCoordAttribute);
522528
};
529+
530+
this.queueAnimation = function(sequenceIndex, fps) {
531+
//If no fps was provided, use the default
532+
fps = fps || player.sequences[sequenceIndex].fps;
533+
animationQueue.push({index: sequenceIndex, fps: fps});
534+
};
523535
};

Player.js

+33-11
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ cs.Player = function(gl, x, y, z, data) {
1313
this.xAngle = 0;
1414
this.speed = 5;
1515
//X and Y direction. Not necessarily normalized
16-
var dir = [0, 0];
16+
var dir = [0, 0, 0];
1717
var playerData = cs.PlayerParser.parse(gl, data);
1818
var playerRender = new cs.ModelRender(gl, playerData);
1919

@@ -23,14 +23,13 @@ cs.Player = function(gl, x, y, z, data) {
2323

2424
this.move = function() {
2525
var onGround = cs.CollisionDetection.isOnGround(this.position());
26-
27-
//TODO: If not on the ground the formulas for newX and newY should be changed
28-
var normalDir = [0, 0];
29-
vec2.normalize(normalDir, dir);
26+
var normalDir = [0, 0, 0];
27+
vec3.normalize(normalDir, dir);
28+
3029
//Move forward
3130
var newX = this.x + this.speed*normalDir[0]*Math.cos(this.yAngle);
3231
var newY = this.y - this.speed*normalDir[0]*Math.sin(this.yAngle);
33-
var newZ = this.z;
32+
var newZ = this.z + 18*dir[2];
3433

3534
//Strafe
3635
newY -= this.speed*normalDir[1]*Math.cos(Math.PI - this.yAngle);
@@ -39,9 +38,10 @@ cs.Player = function(gl, x, y, z, data) {
3938
//Apply gravity if we're not on the ground. TODO: Accelerate instead of subtracting a constant
4039
if(!onGround) {
4140
newZ -= cs.config.GRAVITY;
41+
dir[2] = Math.max(0, dir[2] - 0.1);
4242
}
4343

44-
newPosition = cs.CollisionDetection.move([this.x, this.y, this.z + cs.config.MAX_Z_CHANGE], [newX, newY, newZ], true);
44+
newPosition = cs.CollisionDetection.move([this.x, this.y, this.z + cs.config.MAX_Z_CHANGE], [newX, newY, newZ]);
4545

4646
this.x = newPosition[0];
4747
this.y = newPosition[1];
@@ -69,8 +69,26 @@ cs.Player = function(gl, x, y, z, data) {
6969
if(this.xAngle > PI_HALF) {
7070
this.xAngle = PI_HALF;
7171
}
72+
};
73+
74+
this.render = function() {
75+
return playerRender.render();
7276
}
7377

78+
MouseJS.on("left", function(e) {
79+
//Player is shooting. Set shooting animation
80+
playerRender.queueAnimation(3, 125);
81+
}, function(e) {
82+
//No longer shooting. Set idle animation once the current animation has finished
83+
playerRender.queueAnimation(0);
84+
});
85+
86+
KeyboardJS.on("r", function(event, keys, combo) {
87+
//Play reload animation
88+
playerRender.queueAnimation(1);
89+
playerRender.queueAnimation(0);
90+
}, function(event, keys, combo) {});
91+
7492
//Handle w and s keys
7593
KeyboardJS.on("w,s", function(event, keys, combo){
7694
//Is w down?
@@ -110,10 +128,6 @@ cs.Player = function(gl, x, y, z, data) {
110128
}
111129
});
112130

113-
this.render = function() {
114-
return playerRender.render();
115-
}
116-
117131
//Handle a and d keys
118132
//Symmetric to the handling of w and s
119133
KeyboardJS.on("a,d", function(event, keys, combo){
@@ -146,4 +160,12 @@ cs.Player = function(gl, x, y, z, data) {
146160
}
147161
}
148162
});
163+
164+
KeyboardJS.on("space", function(event, keys, combo) {
165+
//Cannot access outer scope, so we have to do the jump code in here :(
166+
var d = dir[2];
167+
if(d < 0.0001 && d > -0.0001) {
168+
dir[2] = 1;
169+
}
170+
}, function(event, keys, combo) {});
149171
}

0 commit comments

Comments
 (0)