Skip to content

Instantly share code, notes, and snippets.

@AnneFrankTP
Created June 3, 2015 18:27
Show Gist options
  • Save AnneFrankTP/f6a634dd6b960a33dd7e to your computer and use it in GitHub Desktop.
Save AnneFrankTP/f6a634dd6b960a33dd7e to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name TagPro Smooth Spectator Cam
// @version 1.1
// @author browncoat
// @description Smoothly pan the camera between players when spectating
// @include http://tagpro-*.koalabeast.com:*
// @include http://tangent.jukejuice.com*
// @include http://*.newcompte.fr*
// ==/UserScript==
tagpro.ready(function () {
// OPTIONS
// true: camera will 'smooth' whether you are playing or spectating
// false: camera will 'smooth' only when spectating
var smoothAsPlayerAsWell = false;
// "linear": camera will pan at a constant speed
// "ease_out": camera will smoothly slow down as it reaches its target (like a car coming to a stop)
// "elastic": camera will bounce slightly back and forth until settling on the target (like a spring)
var followType = "ease_out";
// Between 0 and 1. Closer to 1 means the camera will reach the target quicker.
var cameraSpeed = 0.3;
// END OPTIONS
var tr = tagpro.renderer;
var state = "snap";
var initialSet = false;
var targetX = 0;
var targetY = 0;
var cameraX = 0;
var cameraY = 0;
var accX = 0;
var accY = 0;
var linearCameraSpeed = cameraSpeed * 100;
var snapDistance = 10;
var startEaseThreshold = 80;
var FollowType = {EASE_OUT: "ease_out", LINEAR: "linear", ELASTIC: "elastic"};
// Override this to store the desired or 'target' position for the camera to follow
var centerContainerToPoint = tr.centerContainerToPoint;
tr.centerContainerToPoint = function (x, y) {
if (!initialSet) {
initialSet = true;
cameraX = targetX;
cameraY = targetY;
}
targetX = x;
targetY = y;
if (state == "snap") {
var xd = targetX - cameraX;
var yd = targetY - cameraY;
var distance = Math.sqrt(xd * xd + yd * yd);
if (distance > startEaseThreshold) {
state = "easing";
console.log("Start ease");
}
}
};
function checkSnap() {
// If the cam is close enough just snap to the target
if (Math.abs(targetX - cameraX) <= snapDistance && Math.abs(targetY - cameraY) <= snapDistance) {
cameraX = targetX;
cameraY = targetY;
state = "snap";
console.log("Ease stop");
}
}
// Override to run the smoothing function every render frame, after all other graphics have been updated
var updateGraphics = tr.updateGraphics;
tr.updateGraphics = function () {
updateGraphics();
if (smoothAsPlayerAsWell || tagpro.spectator) {
if (state == "snap") {
cameraX = targetX;
cameraY = targetY;
} else if (state == "easing") {
// Easing function
if (followType == FollowType.LINEAR) {
cameraX += Math.sign(targetX - cameraX) * linearCameraSpeed;
cameraY += Math.sign(targetY - cameraY) * linearCameraSpeed;
checkSnap();
} else if (followType == FollowType.EASE_OUT) {
cameraX += (targetX - cameraX) * cameraSpeed;
cameraY += (targetY - cameraY) * cameraSpeed;
checkSnap();
} else if (followType == FollowType.ELASTIC) {
accX += (targetX - cameraX) * cameraSpeed;
accY += (targetY - cameraY) * cameraSpeed;
accX *= 0.8;
accY *= 0.8;
cameraX += accX;
cameraY += accY;
// If the cam is close enough just snap to the target
var lowDistance = Math.abs(targetX - cameraX) <= snapDistance && Math.abs(targetY - cameraY) <= snapDistance;
var lowAcc = Math.abs(accX) <= snapDistance && Math.abs(accY) <= snapDistance;
if (lowDistance && lowAcc) {
cameraX = targetX;
cameraY = targetY;
state = "snap";
}
}
}
} else {
// Don't smooth if not spectating
cameraX = targetX;
cameraY = targetY;
}
// Run default tr.centerContainerToPoint - actually sets the camera position
// centerContainerToPoint(cameraX, cameraY);
var viewport = $('#viewport');
var vpWidth = viewport.outerWidth();
var vpHeight = viewport.outerHeight();
var resizeScaleFactor = (vpHeight / tr.canvas_height).toFixed(2);
tr.gameContainer.x = Math.round(vpWidth / 2 - (cameraX / tagpro.zoom * resizeScaleFactor));
tr.gameContainer.y = Math.round(vpHeight / 2 - (cameraY / tagpro.zoom * resizeScaleFactor));
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment