A party game for horrible people
A cross-browser, cross-OS platform for video chat applications
All HTML/JS/CSS
How to deal with multiple card sets?
Lay out card sets on the server and deliver them with Go (Google App Engine hosted because REASONS)
https://hangouts-against-humanity.appspot.com/white?sets=base+first+second
https://hangouts-against-humanity.appspot.com/black?sets=base+first+second
Many items to watch:
gapi.hangout.data.getState()
> Object {
Holmes : 'Elementary, my dear Watson',
Terminator : 'Hasta la vista, baby'
}
gapi.hangout.data.submitDelta({
foo: 'bar',
lorem: 'ipsum'
});
gapi.hangout.data.getState();
> Object {
Holmes : 'Elementary, my dear Watson',
Terminator : 'Hasta la vista, baby',
foo : 'bar',
lorem : 'ipsum'
}
gapi.hangout.data.submitDelta({}, ['Holmes', 'Terminator']);
> undefined
gapi.hangout.data.getState();
> Object {
foo : 'bar',
lorem : 'ipsum'
}
gapi.hangout.data.getValue('foo');
> 'bar'
gapi.hangout.data.setValue('foo', 'baz');
> undefined
gapi.hangout.data.getState();
> Object { foo : 'baz' , lorem : 'ipsum' }
gapi.hangout.data.clearValue('foo');
> undefined
gapi.hangout.data.getState();
> Object { lorem : 'ipsum' }
gapi.hangout.data.onStateChanged.add(function(ev) {
console.log(ev.state);
});
ev = {
addedKeys: [ Metadata for all added/changed keys in this update ],
removedKeys: [ All removed keys in this update ],
state: { Key-value store of the current shared State },
metadata: [ Metadata for all keys in the state ]
}
Watch all items I want to track for game state:
gapi.hangout.data.onStateChanged.add(function(evt) {
var questionChanged = false,
readerChanged = false;
angular.forEach(evt.addedKeys, function(metadata) {
questionChanged = (metadata.key === QUESTIONKEY ? true : questionChanged);
readerChanged = (metadata.key === READERKEY ? true : readerChanged);
});
if(questionChanged || readerChanged) {
$rootScope.$apply(function() {
gameState.question = evt.state[QUESTIONKEY];
gameState.reader = evt.state[READERKEY];
});
}
});
function AmICurrentReader() {
return gameState.reader === LOCAL_PARTICIPANT_ID;
}
function CurrentQuestion() {
return gameState.question;
}
$scope.$watch(AmICurrentReader, function(IAmCurrentReader) {
if(IAmCurrentReader) {
// You're the reader, do the right thing
}
});
$scope.$watch(CurrentQuestion, function(newQuestion) {
// Question has changed, update the viewmodel
});
gapi.hangout.getStartData();
gapi.hangout.hasAgeRestriction();
gapi.hangout.onChangeTopic.add(eventHandler);
gapi.hangout.getEnabledParticipants();
> [ Array of Participants who have enabled the application ]
participant = {
id : 'Unique Identifier for this Participant in this Hangout',
displayIndex: '0-based index of participant in the filmstrip',
person: {
id: 'Google+ ID of person',
displayName: 'Display name of participant',
image: {
url: 'URL of participant's avatar'
}
}
}
gapi.hangout.getLocalParticipant();
> { The Participant who is running the app }
gapi.hangout.getParticipantById(HANGOUT_ID);
> { The Participant who is identified by HANGOUT_ID };
gapi.hangout.onApiReady.add(function(eventObj) {
if (eventObj.isApiReady) {
angular.bootstrap(document, ['ModuleName']);
}
});
gapi.hangout.av.muteParticipantMicrophone(HANGOUT_ID);
gapi.hangout.av.isAudible();
gapi.hangout.av.onMicrophoneMute.add(function() { ... });
gapi.hangout.av.effects.createImageResource('http://google.com/favicon.ico');
gapi.hangout.av.effects.createAudioResource('http://myapp.com/wah-waaah.wav');
googleFavIconResource.showOverlay({
position: { x: 0.5, y : 0.5 },
rotation: Math.PI / 2,
scale: {
magnitude: 0.1,
reference: gapi.hangout.av.effects.ScaleReference.WIDTH
}
}
googleFavIconResource.showFaceTrackingOverlay({
trackingFeature: gapi.hangout.av.effects.FaceTrackingFeature.MOUTH_CENTER,
offset: { x: 0, y: 0 },
rotateWithFace: true,
rotate: 0,
scaleWithFace: true,
scale: {
magnitude: 0.15,
reference: gapi.hangout.av.effects.ScaleReference.HEIGHT
}
});
wahWaaahResource.createSound({ localOnly: false, loop: true, volume: 0.5 });
wahWaaahSound.play();