Rewrite loading screen to use class semantics, refs #5387.

Add config option to display the loading screen stage description.
Add tip functions for future use, refs D1730.
Harmonize coordinates.

Differential Revision: https://code.wildfiregames.com/D2418
This was SVN commit r23150.
This commit is contained in:
elexis 2019-11-12 15:54:09 +00:00
parent 235e238f9d
commit c16eddaedc
11 changed files with 183 additions and 123 deletions

View File

@ -361,6 +361,9 @@ aidifficulty = 3 ; Difficulty level, from 0 (easiest) to 5 (har
aibehavior = "random" ; Default behavior of the AI (random, balanced, aggressive or defensive) aibehavior = "random" ; Default behavior of the AI (random, balanced, aggressive or defensive)
settingsslide = true ; Enable/Disable settings panel slide settingsslide = true ; Enable/Disable settings panel slide
[gui.loadingscreen]
progressdescription = false ; Whether to display the progress percent or a textual description
[gui.session] [gui.session]
camerajump.threshold = 40 ; How close do we have to be to the actual location in order to jump back to the previous one? camerajump.threshold = 40 ; How close do we have to be to the actual location in order to jump back to the previous one?
timeelapsedcounter = false ; Show the game duration in the top right corner timeelapsedcounter = false ; Show the game duration in the top right corner

View File

@ -0,0 +1,51 @@
/**
* This class will display the progress of the map loading by animating a progress bar.
* Optionally it displays the current stage of the loading screen.
*/
class ProgressBar
{
constructor()
{
this.progressbar_right = Engine.GetGUIObjectByName("progressbar_right");
this.progressbar_right_width = this.progressbar_right.size.right - this.progressbar_right.size.left;
this.progressbar = Engine.GetGUIObjectByName("progressbar");
this.progressbar.onGameLoadProgress = this.onGameLoadProgress.bind(this);
this.progressBarSize = this.progressbar.size.right - this.progressbar.size.left - this.progressbar_right_width / 2;
this.progressText = Engine.GetGUIObjectByName("progressText");
this.showDescription = Engine.ConfigDB_GetValue("user", this.ConfigKey) == "true";
this.percentArgs = !this.showDescription && {};
}
onGameLoadProgress(progression, description)
{
// Make the progessbar finish a little early so that the player can see it finish
if (progression >= 100)
return;
// Show 100 when it is really 99
let progress = progression + 1;
this.progressbar.caption = progress;
if (this.showDescription)
this.progressText.caption = description;
else
{
this.percentArgs.percentage = progress;
this.progressText.caption = sprintf(this.CaptionFormat, this.percentArgs);
}
let increment = Math.round(progress * this.progressBarSize / 100);
let size = this.progressbar_right.size;
size.left = increment;
size.right = increment + this.progressbar_right_width;
this.progressbar_right.size = size;
}
}
ProgressBar.prototype.CaptionFormat =
translateWithContext("loading screen progress", "%(percentage)s%%");
ProgressBar.prototype.ConfigKey =
"gui.loadingscreen.progressdescription";

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<object type="image" sprite="LoadingProgressBarBackground">
<object name="progressbar" type="progressbar" style="LoadingProgressbar" size="56 5 456 100%-5">
<object name="progressbar_left" size="-8 0 8 100%" type="image" sprite="LoadingProgressBarLeft"/>
<object name="progressbar_right" size="8 0 24 100%" type="image" sprite="LoadingProgressBarRight"/>
<object name="progressText" type="text" style="LoadingBarText"/>
</object>
</object>

View File

@ -0,0 +1,14 @@
/**
* This class is concerned with chosing and displaying quotes from historical figures.
*/
class QuoteDisplay
{
constructor()
{
Engine.GetGUIObjectByName("quoteText").caption =
translate(pickRandom(
Engine.ReadFileLines(this.File).filter(line => line)));
}
}
QuoteDisplay.prototype.File = "gui/text/quotes.txt";

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<object name="quoteText" type="text" style="LoadingText" z="100"/>

View File

@ -0,0 +1,52 @@
/**
* This class is concerned with chosing and displaying hints about how to play the game.
* This includes a text and an image.
*/
class TipDisplay
{
constructor()
{
this.tipImage = Engine.GetGUIObjectByName("tipImage");
this.tipTitle = Engine.GetGUIObjectByName("tipTitle");
this.tipText = Engine.GetGUIObjectByName("tipText");
this.tipFiles = listFiles(this.TextPath, ".txt", false);
this.displayRandomTip();
}
displayRandomTip()
{
let tipFile = pickRandom(this.tipFiles);
if (tipFile)
this.displayTip(tipFile);
else
error("Failed to find any matching tips for the loading screen.");
}
displayTip(tipFile)
{
this.tipImage.sprite =
"stretched:" + this.ImagePath + tipFile + ".png";
let tipText = Engine.TranslateLines(Engine.ReadFile(
this.TextPath + tipFile + ".txt")).split("\n");
this.tipTitle.caption = tipText.shift();
this.tipText.caption = tipText.map(text =>
text && sprintf(this.BulletFormat, { "tiptext": text })).join("\n\n");
}
}
/**
* Directory storing txt files containing the gameplay tips.
*/
TipDisplay.prototype.TextPath = "gui/text/tips/";
/**
* Directory storing the PNG images with filenames corresponding to the tip text files.
*/
TipDisplay.prototype.ImagePath = "loading/tips/";
// Translation: A bullet point used before every item of list of tips displayed on loading screen
TipDisplay.prototype.BulletFormat = translate("• %(tiptext)s");

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object size="0 0 520 392">
<object type="image" sprite="LoadingTipImage">
<object name="tipImage" size="4 4 516 516" type="image">
<object name="tipImageCover" type="image" sprite="LoadingTipImageCover"/>
</object>
</object>
</object>
<object size="580 3 900 389" type="image" sprite="LoadingTipText">
<object name="tipTitle" size="30 30 100% 50" type="text" style="LoadingTipTitleText"/>
<object name="tipText" size="30 50 100%-30 100%" type="text" style="LoadingTipText"/>
</object>
</object>

View File

@ -0,0 +1,17 @@
/**
* This class choses the title of the loading screen page.
*/
class TitleDisplay
{
constructor(data)
{
let loadingMapName = Engine.GetGUIObjectByName("loadingMapName");
loadingMapName.caption = sprintf(
data.attribs.mapType == "random" ? this.Generating : this.Loading,
{ "map": translate(data.attribs.settings.Name) });
}
}
TitleDisplay.prototype.Generating = translate("Generating “%(map)s”");
TitleDisplay.prototype.Loading = translate("Loading “%(map)s”");

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<object name="loadingMapName" type="text" style="LargeTitleText"/>

View File

@ -1,97 +1,16 @@
/** var g_LoadingPage;
* Path to a file containing quotes of historical figures.
*/
var g_QuotesFile = "gui/text/quotes.txt";
/**
* Directory storing txt files containing the gameplay tips.
*/
var g_TipsTextPath = "gui/text/tips/";
/**
* Directory storing the PNG images with filenames corresponding to the tip text files.
*/
var g_TipsImagePath = "loading/tips/";
var g_Data;
var g_EndPieceWidth = 16;
function init(data) function init(data)
{ {
g_Data = data; g_LoadingPage = {
"initData": data,
"progressBar": new ProgressBar(),
"quoteDisplay": new QuoteDisplay(),
"tipDisplay": new TipDisplay(),
"titleDisplay": new TitleDisplay(data)
};
Engine.SetCursor("cursor-wait"); Engine.SetCursor("cursor-wait");
let tipFile = pickRandom(listFiles(g_TipsTextPath, ".txt", false));
if (tipFile)
{
let tipText = Engine.TranslateLines(Engine.ReadFile(g_TipsTextPath + tipFile + ".txt")).split("\n");
Engine.GetGUIObjectByName("tipTitle").caption = tipText.shift();
Engine.GetGUIObjectByName("tipText").caption = tipText.map(
// Translation: A bullet point used before every item of list of tips displayed on loading screen
text => text && sprintf(translate("• %(tiptext)s"), { "tiptext": text })
).join("\n\n");
Engine.GetGUIObjectByName("tipImage").sprite = "stretched:" + g_TipsImagePath + tipFile + ".png";
}
else
error("Failed to find any matching tips for the loading screen.");
// janwas: main loop now sets progress / description, but that won't
// happen until the first timeslice completes, so set initial values.
let loadingMapName = Engine.GetGUIObjectByName("loadingMapName");
if (data)
{
let mapName = translate(data.attribs.settings.Name);
switch (data.attribs.mapType)
{
case "skirmish":
case "scenario":
loadingMapName.caption = sprintf(translate("Loading “%(map)s”"), { "map": mapName });
break;
case "random":
loadingMapName.caption = sprintf(translate("Generating “%(map)s”"), { "map": mapName });
break;
}
}
Engine.GetGUIObjectByName("progressText").caption = "";
let progressbar = Engine.GetGUIObjectByName("progressbar");
progressbar.caption = 0;
progressbar.onGameLoadProgress = displayProgress;
Engine.GetGUIObjectByName("quoteText").caption = translate(pickRandom(Engine.ReadFileLines(g_QuotesFile).filter(line => line)));
}
function displayProgress(progression, description)
{
// Make the progessbar finish a little early so that the user can actually see it finish
if (progression >= 100)
return;
// Show 100 when it is really 99
let progress = progression + 1;
Engine.GetGUIObjectByName("progressbar").caption = progress; // display current progress
Engine.GetGUIObjectByName("progressText").caption = progress + "%";
// Displays detailed loading info rather than a percent
// Engine.GetGUIObjectByName("progressText").caption = description;
// Keep curved right edge of progress bar in sync with the rest of the progress bar
let middle = Engine.GetGUIObjectByName("progressbar");
let rightSide = Engine.GetGUIObjectByName("progressbar_right");
let middleLength = (middle.size.right - middle.size.left) - (g_EndPieceWidth / 2);
let increment = Math.round(progress * middleLength / 100);
let size = rightSide.size;
size.left = increment;
size.right = increment + g_EndPieceWidth;
rightSide.size = size;
} }
/** /**
@ -100,7 +19,6 @@ function displayProgress(progression, description)
*/ */
function reallyStartGame() function reallyStartGame()
{ {
Engine.SwitchGuiPage("page_session.xml", g_Data); Engine.SwitchGuiPage("page_session.xml", g_LoadingPage.initData);
Engine.ResetCursor(); Engine.ResetCursor();
} }

View File

@ -1,10 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
==========================================
- LOADING SCREEN -
==========================================
-->
<objects> <objects>
<script directory="gui/common/"/> <script directory="gui/common/"/>
@ -12,38 +6,22 @@
<object type="image" style="ModernWindow"> <object type="image" style="ModernWindow">
<!-- LOADING SCREEN progress bar --> <object size="50%-256 4 50%+256 36">
<object size="50%-256 4 50%+256 36" type="image" sprite="LoadingProgressBarBackground"> <include file="gui/loading/ProgressBar.xml"/>
<object name="progressbar"
type="progressbar"
style="LoadingProgressbar"
size="56 5 456 100%-5"
>
<object name="progressbar_left" size="-8 0 8 100%" type="image" sprite="LoadingProgressBarLeft"/>
<object name="progressbar_right" size="8 0 24 100%" type="image" sprite="LoadingProgressBarRight"/>
<object name="progressText" type="text" style="LoadingBarText"/>
</object>
</object> </object>
<!-- LOADING SCREEN TEXT --> <object size="50%-256 36 50%+256 50%-196">
<object name="loadingMapName" size="50%-256 36 50%+256 50%-196" type="text" style="LargeTitleText"/> <include file="gui/loading/TitleDisplay.xml"/>
<!-- LOADING SCREEN TIP IMAGE-->
<object size="50%-452 50%-196 50%+68 50%+196" type="image" sprite="LoadingTipImage">
<object name="tipImage" size="4 4 516 516" type="image">
<object name="tipImageCover" type="image" sprite="LoadingTipImageCover"/>
</object>
</object> </object>
<!-- LOADING SCREEN TIP TEXT--> <object size="50%-452 50%-196 50%+452 50%+196">
<object size="50%+128 50%-193 50%+448 50%+193" type="image" sprite="LoadingTipText"> <include file="gui/loading/TipDisplay.xml"/>
<object name="tipTitle" size="30 30 100% 50" type="text" style="LoadingTipTitleText"/>
<object name="tipText" size="30 50 100%-30 100%" type="text" style="LoadingTipText"/>
</object> </object>
<!-- LOADING SCREEN QUOTE (needs increased z value to overcome the transparent area of the tip image above it --> <object size="50%-448 50%+230 50%+448 100%-16">
<object size="50%-448 50%+230 50%+448 100%-16" z="20"> <include file="gui/loading/QuoteDisplay.xml"/>
<object name="quoteText" type="text" style="LoadingText"/>
</object> </object>
</object> </object>
</objects> </objects>