Update realtime score audience display for 2016.

This commit is contained in:
Patrick Fairbank
2016-08-12 21:41:38 -07:00
parent 80ab6264d8
commit f6351e7f63
6 changed files with 110 additions and 56 deletions

View File

@@ -100,7 +100,7 @@ func (arena *Arena) Setup() {
arena.matchTiming.AutoDurationSec = 15
arena.matchTiming.PauseDurationSec = 2
arena.matchTiming.TeleopDurationSec = 135
arena.matchTiming.EndgameTimeLeftSec = 20
arena.matchTiming.EndgameTimeLeftSec = 30
arena.AllianceStations = make(map[string]*AllianceStation)
arena.AllianceStations["R1"] = new(AllianceStation)

View File

@@ -12,6 +12,12 @@ import (
"text/template"
)
type RealtimeScoreFields struct {
Score int
TowerStrength int
DefensesStrength [5]int
}
// Renders the audience display to be chroma keyed over the video feed.
func AudienceDisplayHandler(w http.ResponseWriter, r *http.Request) {
if !UserIsReader(w, r) {
@@ -94,10 +100,10 @@ func AudienceDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
return
}
data = struct {
RedScore int
BlueScore int
}{mainArena.redRealtimeScore.Score(mainArena.blueRealtimeScore.CurrentScore.Fouls),
mainArena.blueRealtimeScore.Score(mainArena.redRealtimeScore.CurrentScore.Fouls)}
RedScoreFields *RealtimeScoreFields
BlueScoreFields *RealtimeScoreFields
}{mainArena.redRealtimeScore.ScoreFields(mainArena.blueRealtimeScore.CurrentScore.Fouls),
mainArena.blueRealtimeScore.ScoreFields(mainArena.redRealtimeScore.CurrentScore.Fouls)}
err = websocket.Write("realtimeScore", data)
if err != nil {
log.Printf("Websocket error: %s", err)
@@ -154,10 +160,10 @@ func AudienceDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
}
messageType = "realtimeScore"
message = struct {
RedScore int
BlueScore int
}{mainArena.redRealtimeScore.Score(mainArena.blueRealtimeScore.CurrentScore.Fouls),
mainArena.blueRealtimeScore.Score(mainArena.redRealtimeScore.CurrentScore.Fouls)}
RedScoreFields *RealtimeScoreFields
BlueScoreFields *RealtimeScoreFields
}{mainArena.redRealtimeScore.ScoreFields(mainArena.blueRealtimeScore.CurrentScore.Fouls),
mainArena.blueRealtimeScore.ScoreFields(mainArena.redRealtimeScore.CurrentScore.Fouls)}
case _, ok := <-scorePostedListener:
if !ok {
return
@@ -216,3 +222,14 @@ func AudienceDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
}
}
}
// Calculates the integer score, tower strength, and defenses strength for the given realtime snapshot.
func (realtimeScore *RealtimeScore) ScoreFields(opponentFouls []Foul) *RealtimeScoreFields {
scoreSummary := scoreSummary(&realtimeScore.CurrentScore, opponentFouls, mainArena.currentMatch.Type)
var defensesStrength [5]int
for i := 0; i < 5; i++ {
defensesStrength[i] = 2 - realtimeScore.CurrentScore.AutoDefensesCrossed[i] -
realtimeScore.CurrentScore.DefensesCrossed[i]
}
return &RealtimeScoreFields{scoreSummary.Score, scoreSummary.TowerStrength, defensesStrength}
}

View File

@@ -53,17 +53,17 @@ type Foul struct {
}
type ScoreSummary struct {
AutoPoints int
DefensePoints int
GoalPoints int
ScaleChallengePoints int
TeleopPoints int
FoulPoints int
BonusPoints int
Score int
Breached bool
Captured bool
OpponentTowerStrength int
AutoPoints int
DefensePoints int
GoalPoints int
ScaleChallengePoints int
TeleopPoints int
FoulPoints int
BonusPoints int
Score int
Breached bool
Captured bool
TowerStrength int
}
// Returns a new match result object with empty slices instead of nil.
@@ -186,7 +186,7 @@ func scoreSummary(score *Score, opponentFouls []Foul, matchType string) *ScoreSu
numTechFouls++
}
}
summary.OpponentTowerStrength = eventSettings.InitialTowerStrength + numTechFouls - score.AutoLowGoals -
summary.TowerStrength = eventSettings.InitialTowerStrength + numTechFouls - score.AutoLowGoals -
score.AutoHighGoals - score.LowGoals - score.HighGoals
// Calculate bonuses.
@@ -203,7 +203,7 @@ func scoreSummary(score *Score, opponentFouls []Foul, matchType string) *ScoreSu
summary.BonusPoints += 20
}
}
if score.Challenges+score.Scales == 3 && summary.OpponentTowerStrength <= 0 {
if score.Challenges+score.Scales == 3 && summary.TowerStrength <= 0 {
summary.Captured = true
if matchType == "elimination" {
summary.BonusPoints += 25

View File

@@ -38,13 +38,13 @@ html {
vertical-align: middle;
}
#redTeams {
float: left;
border-right: 1px solid #222;
}
#blueTeams {
float: right;
border-left: 1px solid #222;
}
#blueTeams {
float: left;
border-right: 1px solid #222;
}
.score {
width: 0px;
height: 100%;
@@ -86,7 +86,8 @@ html {
border: 1px solid #222;
}
.score-number {
width: 60%;
float: left;
width: 45%;
margin: 0px 5px;
text-align: center;
font-family: "FuturaLTBold";
@@ -95,23 +96,33 @@ html {
color: #fff;
opacity: 0;
}
.assist {
.score-fields {
float: left;
width: 22px;
height: 12px;
margin: 10px 4px;
background-color: #fff;
opacity: 0.3;
width: 20%;
padding-top: 10px;
text-align: center;
opacity: 0;
}
.trussCatch {
float: left;
.tower {
font-size: 20px;
font-family: "FuturaLTBold";
margin: 0px 5px;
color: #fff;
opacity: 0.3;
}
[data-on=true] {
opacity: 1;
.defense {
font-size: 0;
}
.defense>progress {
width: 20px;
height: 6px;
margin: 2px 0;
-webkit-appearance: none;
}
.defense>progress::-webkit-progress-bar {
background-color: rgba(0, 0, 0, 0);
border: 1px solid white;
}
.defense>progress::-webkit-progress-value {
background-color: #fff;
}
#logo {
position: relative;

View File

@@ -52,8 +52,14 @@ var handleMatchTime = function(data) {
// Handles a websocket message to update the match score.
var handleRealtimeScore = function(data) {
$("#redScoreNumber").text(data.RedScore);
$("#blueScoreNumber").text(data.BlueScore);
$("#redScoreNumber").text(data.RedScoreFields.Score);
$("#redTower").text(data.RedScoreFields.TowerStrength);
$("#blueScoreNumber").text(data.BlueScoreFields.Score);
$("#blueTower").text(data.BlueScoreFields.TowerStrength);
for (var i = 0; i < 5; i++) {
$("#redDefense" + (i + 1)).attr("value", data.RedScoreFields.DefensesStrength[i]);
$("#blueDefense" + (i + 1)).attr("value", data.BlueScoreFields.DefensesStrength[i]);
}
};
// Handles a websocket message to populate the final score data.
@@ -127,8 +133,9 @@ var transitionBlankToIntro = function(callback) {
var transitionIntroToInMatch = function(callback) {
$("#logo").transition({queue: false, top: "35px"}, 500, "ease");
$(".score").transition({queue: false, width: "230px"}, 500, "ease", function() {
$(".score").transition({queue: false, width: "260px"}, 500, "ease", function() {
$(".score-number").transition({queue: false, opacity: 1}, 750, "ease");
$(".score-fields").transition({queue: false, opacity: 1}, 750, "ease");
$("#matchTime").transition({queue: false, opacity: 1}, 750, "ease", callback);
});
};
@@ -147,9 +154,10 @@ var transitionBlankToInMatch = function(callback) {
$("#centering").transition({queue: false, bottom: "0px"}, 500, "ease", function() {
$(".teams").transition({queue: false, width: "75px"}, 100, "linear", function() {
$("#logo").transition({queue: false, top: "35px"}, 500, "ease");
$(".score").transition({queue: false, width: "230px"}, 500, "ease", function() {
$(".score").transition({queue: false, width: "260px"}, 500, "ease", function() {
$("#eventMatchInfo").show();
$(".score-number").transition({queue: false, opacity: 1}, 750, "ease");
$(".score-fields").transition({queue: false, opacity: 1}, 750, "ease");
$("#matchTime").transition({queue: false, opacity: 1}, 750, "ease", callback);
var height = -$("#eventMatchInfo").height();
$("#eventMatchInfo").transition({queue: false, bottom: height + "px"}, 500, "ease", callback);
@@ -160,6 +168,7 @@ var transitionBlankToInMatch = function(callback) {
var transitionInMatchToIntro = function(callback) {
$(".score-number").transition({queue: false, opacity: 0}, 300, "linear");
$(".score-fields").transition({queue: false, opacity: 0}, 300, "linear");
$("#matchTime").transition({queue: false, opacity: 0}, 300, "linear", function() {
$("#logo").transition({queue: false, top: "50px"}, 500, "ease");
$(".score").transition({queue: false, width: "120px"}, 500, "ease");
@@ -170,6 +179,7 @@ var transitionInMatchToIntro = function(callback) {
var transitionInMatchToBlank = function(callback) {
$("#eventMatchInfo").transition({queue: false, bottom: "0px"}, 500, "ease");
$("#matchTime").transition({queue: false, opacity: 0}, 300, "linear");
$(".score-fields").transition({queue: false, opacity: 0}, 300, "linear");
$(".score-number").transition({queue: false, opacity: 0}, 300, "linear", function() {
$("#eventMatchInfo").hide();
$("#logo").transition({queue: false, top: "50px"}, 500, "ease");

View File

@@ -16,19 +16,6 @@
<body style="background-color: {{.EventSettings.DisplayBackgroundColor}};">
<div id="centering">
<div id="matchOverlay">
<div class="teams" id="redTeams">
<span class="valign-cell">
<span id="redTeam1"></span><br />
<span id="redTeam2"></span><br />
<span id="redTeam3"></span>
</span>
</div>
<div class="score" id="redScore">
<div class="score-number" id="redScoreNumber">&nbsp;</div>
</div>
<div class="score" id="blueScore">
<div class="score-number pull-right" id="blueScoreNumber">&nbsp;</div>
</div>
<div class="teams" id="blueTeams">
<span class="valign-cell">
<span id="blueTeam1"></span><br />
@@ -36,6 +23,35 @@
<span id="blueTeam3"></span>
</span>
</div>
<div class="score" id="blueScore">
<div class="score-fields">
<div class="tower" id="blueTower">&nbsp;</div>
<div class="defense"><progress max="2" value="2" id="blueDefense5"></progress></div>
<div class="defense"><progress max="2" value="2" id="blueDefense4"></progress></div>
<div class="defense"><progress max="2" value="2" id="blueDefense3"></progress></div>
<div class="defense"><progress max="2" value="2" id="blueDefense2"></progress></div>
<div class="defense"><progress max="2" value="2" id="blueDefense1"></progress></div>
</div>
<div class="score-number" id="blueScoreNumber">&nbsp;</div>
</div>
<div class="score" id="redScore">
<div class="score-fields pull-right">
<div class="tower" id="redTower">&nbsp;</div>
<div class="defense"><progress max="2" value="2" id="redDefense1"></progress></div>
<div class="defense"><progress max="2" value="2" id="redDefense2"></progress></div>
<div class="defense"><progress max="2" value="2" id="redDefense3"></progress></div>
<div class="defense"><progress max="2" value="2" id="redDefense4"></progress></div>
<div class="defense"><progress max="2" value="2" id="redDefense5"></progress></div>
</div>
<div class="score-number pull-right" id="redScoreNumber">&nbsp;</div>
</div>
<div class="teams" id="redTeams">
<span class="valign-cell">
<span id="redTeam1"></span><br />
<span id="redTeam2"></span><br />
<span id="redTeam3"></span>
</span>
</div>
<div id="eventMatchInfo">
<span>{{.EventSettings.Name}} 2016</span>
<span class="pull-right" id="matchName"></span>