Resolve WES-192 "Fix progress screen"
This commit is contained in:
@@ -48,9 +48,7 @@ public class ChangeUserScreen : MonoBehaviour
|
||||
private void DisplayUsers()
|
||||
{
|
||||
foreach (Transform child in usersContainer)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
|
||||
List<User> users = UserList.GetUsers();
|
||||
currentUserIndex = UserList.IndexOf(UserList.GetCurrentUser().GetUsername());
|
||||
|
||||
@@ -24,7 +24,7 @@ public class CourseProgressCard : MonoBehaviour
|
||||
public PersistentDataController.SavedCourseProgress courseProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the list of courses so we can query the correct course
|
||||
/// Reference to the list of minigameCards so we can query the correct course
|
||||
/// </summary>
|
||||
public CourseList courseList;
|
||||
|
||||
|
||||
40
Assets/Accounts/Scripts/LearnableProgressCard.cs
Normal file
40
Assets/Accounts/Scripts/LearnableProgressCard.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle learnable progress card display
|
||||
/// </summary>
|
||||
public class LearnableProgressCard : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the progress so we can display a progress bar
|
||||
/// </summary>
|
||||
public PersistentDataController.SavedLearnableProgress progress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the list of minigameCards so we can query the correct course
|
||||
/// </summary>
|
||||
public Learnable learnable;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the thumbnail of the course
|
||||
/// </summary>
|
||||
public Image thumbnail;
|
||||
|
||||
/// <summary>
|
||||
/// UI refeerence to the title of the course
|
||||
/// </summary>
|
||||
public List<Image> stars;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
thumbnail.sprite = learnable.image;
|
||||
var starRewards = new float[] { 1.0f, 2.5f, 4.0f, };
|
||||
for (int i = 0; i < 3; i++)
|
||||
stars[i].color = starRewards[i] < progress.progress ? Color.white : Color.black;
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/LearnableProgressCard.cs.meta
Normal file
11
Assets/Accounts/Scripts/LearnableProgressCard.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7835fc450a6bbf24d95f0a19491fb8c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
@@ -53,9 +54,11 @@ public class MinigameProgressCard : MonoBehaviour
|
||||
|
||||
thumbnail.sprite = minigame.thumbnail;
|
||||
title.text = minigame.title;
|
||||
List<Score> highscores = minigameProgress.highestScores;
|
||||
int score = highscores.Count > 0 ? highscores[0].scoreValue : 0;
|
||||
highscore.text = $"Topscore: {score}";
|
||||
button.onClick.AddListener(selectActivity);
|
||||
List<Score> highscores = minigameProgress.highestScores;
|
||||
if (0 < highscores.Count)
|
||||
highscore.text = $"TOPSCORE: {highscores.Max((s) => s.scoreValue)}";
|
||||
else
|
||||
highscore.text = "(NOG) GEEN TOPSCORE";
|
||||
}
|
||||
}
|
||||
|
||||
130
Assets/Accounts/Scripts/PanelCourseProgress.cs
Normal file
130
Assets/Accounts/Scripts/PanelCourseProgress.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle course list progress display
|
||||
/// </summary>
|
||||
public class PanelCourseProgress : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the current user
|
||||
/// </summary>
|
||||
private User user;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the courses list
|
||||
/// </summary>
|
||||
public CourseList courseList;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a course card
|
||||
/// </summary>
|
||||
public GameObject courseCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all course cards
|
||||
/// </summary>
|
||||
public Transform coursesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the course info panel
|
||||
/// </summary>
|
||||
public GameObject courseInfo;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no course progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyCourses;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the title on the info panel
|
||||
/// </summary>
|
||||
public TMP_Text courseTitle;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the learnable card prefab
|
||||
/// </summary>
|
||||
public GameObject learnableCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the container for holding the learnable cards
|
||||
/// </summary>
|
||||
public Transform learnablesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the course progress bar on the info panel
|
||||
/// </summary>
|
||||
public SlicedSlider progressBar;
|
||||
|
||||
/// <summary>
|
||||
/// Current selected course
|
||||
/// </summary>
|
||||
private int selectedCourse = 0;
|
||||
|
||||
/// <summary>
|
||||
/// List of course backgrounds and indices
|
||||
/// </summary>
|
||||
private List<Tuple<Image, CourseIndex>> courseCards = new List<Tuple<Image, CourseIndex>>();
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
PersistentDataController.GetInstance().Load();
|
||||
user = UserList.GetCurrentUser();
|
||||
|
||||
var courses = user.GetCourses();
|
||||
courseInfo.SetActive(0 < courses.Count);
|
||||
emptyCourses.SetActive(courses.Count <= 0);
|
||||
int i = 0;
|
||||
foreach (var courseProgress in courses)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(courseCardPrefab, coursesContainer);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
CourseProgressCard cpc = instance.GetComponent<CourseProgressCard>();
|
||||
cpc.courseProgress = courseProgress;
|
||||
cpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
this.courseCards.Add(Tuple.Create(background, courseProgress.courseIndex));
|
||||
}
|
||||
if (0 < courses.Count)
|
||||
UpdateSelection(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the current selected course
|
||||
/// </summary>
|
||||
/// <param name="newCourse">Index to the new course</param>
|
||||
private void UpdateSelection(int newCourse)
|
||||
{
|
||||
courseCards[selectedCourse].Item1.color = Color.gray;
|
||||
selectedCourse = newCourse;
|
||||
courseCards[selectedCourse].Item1.color = Color.blue;
|
||||
|
||||
var progress = user.GetCourseProgress(courseCards[selectedCourse].Item2);
|
||||
var course = courseList.GetCourseByIndex(progress.courseIndex);
|
||||
courseTitle.text = course.title;
|
||||
progressBar.fillAmount = progress.progress;
|
||||
|
||||
foreach (Transform child in learnablesContainer)
|
||||
Destroy(child.gameObject);
|
||||
|
||||
for (int i = 0; i < course.theme.learnables.Count; i++)
|
||||
{
|
||||
GameObject instance = GameObject.Instantiate(learnableCardPrefab, learnablesContainer);
|
||||
var script = instance.GetComponent<LearnableProgressCard>();
|
||||
script.learnable = course.theme.learnables[i];
|
||||
script.progress = progress.learnables[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/PanelCourseProgress.cs.meta
Normal file
11
Assets/Accounts/Scripts/PanelCourseProgress.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba7d548c45e9ade4593922d9530cd56d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/Accounts/Scripts/PanelMinigameProgress.cs
Normal file
127
Assets/Accounts/Scripts/PanelMinigameProgress.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle minigame list progress display
|
||||
/// </summary>
|
||||
public class PanelMinigameProgress : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the current user
|
||||
/// </summary>
|
||||
private User user;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the minigames list
|
||||
/// </summary>
|
||||
public MinigameList minigameList;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a minigame card
|
||||
/// </summary>
|
||||
public GameObject minigameCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all the minigame cards
|
||||
/// </summary>
|
||||
public Transform minigamesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the minigame info panel
|
||||
/// </summary>
|
||||
public GameObject minigameInfo;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no minigame progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyMinigames;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the plot
|
||||
/// </summary>
|
||||
public ProgressGraph progressGraph;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the title of the minigame of the info panel
|
||||
/// </summary>
|
||||
public TMP_Text minigameTitle;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the text that will display when an empty minigame progress object is selected
|
||||
/// </summary>
|
||||
public GameObject emptyHighscore;
|
||||
|
||||
/// <summary>
|
||||
/// Current selected course
|
||||
/// </summary>
|
||||
private int selectedMinigame = 0;
|
||||
|
||||
/// <summary>
|
||||
/// List of course backgrounds and indices
|
||||
/// </summary>
|
||||
private List<Tuple<Image, MinigameIndex>> minigameCards = new List<Tuple<Image, MinigameIndex>>();
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
PersistentDataController.GetInstance().Load();
|
||||
user = UserList.GetCurrentUser();
|
||||
|
||||
var minigames = user.GetMinigames();
|
||||
minigameInfo.SetActive(minigames.Count > 0);
|
||||
emptyMinigames.SetActive(minigames.Count <= 0);
|
||||
int i = 0;
|
||||
foreach (var minigameProgress in minigames)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(minigameCardPrefab, minigamesContainer);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
MinigameProgressCard mpc = instance.GetComponent<MinigameProgressCard>();
|
||||
mpc.minigameProgress = minigameProgress;
|
||||
mpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
minigameCards.Add(Tuple.Create(background, minigameProgress.minigameIndex));
|
||||
}
|
||||
if (0 < minigames.Count)
|
||||
UpdateSelection(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the current selected course
|
||||
/// </summary>
|
||||
/// <param name="newMinigame">Index to the new course</param>
|
||||
private void UpdateSelection(int newMinigame)
|
||||
{
|
||||
minigameCards[selectedMinigame].Item1.color = Color.gray;
|
||||
selectedMinigame = newMinigame;
|
||||
minigameCards[selectedMinigame].Item1.color = Color.blue;
|
||||
|
||||
var progress = user.GetMinigameProgress(minigameCards[selectedMinigame].Item2);
|
||||
minigameTitle.text = minigameList.GetMinigameByIndex(progress.minigameIndex).title;
|
||||
|
||||
List<Score> latestScores = progress.latestScores;
|
||||
List<Score> highestScores = progress.highestScores;
|
||||
if (0 < highestScores.Count)
|
||||
{
|
||||
emptyHighscore.SetActive(false);
|
||||
progressGraph.gameObject.SetActive(true);
|
||||
progressGraph.Plot(latestScores.ConvertAll<double>((s) => (double)s.scoreValue), highestScores.Max((s) => s.scoreValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
emptyHighscore.SetActive(true);
|
||||
progressGraph.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/PanelMinigameProgress.cs.meta
Normal file
11
Assets/Accounts/Scripts/PanelMinigameProgress.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c17533febddc854f8b01bacf617d45f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
263
Assets/Accounts/Scripts/ProgressGraph.cs
Normal file
263
Assets/Accounts/Scripts/ProgressGraph.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle and draw a nice line graph to a Texture2D
|
||||
/// </summary>
|
||||
public class ProgressGraph : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// UI reference to the plot
|
||||
/// </summary>
|
||||
public RawImage progressGraph;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of the highscore marker to display on the graph
|
||||
/// </summary>
|
||||
public GameObject highscoreMarker;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of the axes tick marker to display on the graph
|
||||
/// </summary>
|
||||
public GameObject axesTickMarker;
|
||||
|
||||
/// <summary>
|
||||
/// Color of the graph line
|
||||
/// </summary>
|
||||
public Color lineColor;
|
||||
|
||||
/// <summary>
|
||||
/// Bckground color
|
||||
/// </summary>
|
||||
public Color backgroundColor;
|
||||
|
||||
/// <summary>
|
||||
/// Color of the text and axes grid
|
||||
/// </summary>
|
||||
public Color textColor;
|
||||
|
||||
/// <summary>
|
||||
/// Color of the highscore line
|
||||
/// </summary>
|
||||
public Color highscoreColor;
|
||||
|
||||
/// <summary>
|
||||
/// Left and right padding of the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_PADDING_X_PX = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Top and bottom padding of the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_PADDING_Y_PX = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Radius of the point on the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_POINT_RADIUS = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the line on the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_LINE_SIZE = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Plot points and a highscore on the graph
|
||||
/// </summary>
|
||||
/// <param name="scores">List of score values to plot</param>
|
||||
/// <param name="highscore">Highscore value (this will be plotted in a fancy color)</param>
|
||||
public void Plot(List<double> scores, double highscore)
|
||||
{
|
||||
// Remove previous marker(s)
|
||||
foreach (Transform child in progressGraph.gameObject.transform)
|
||||
Destroy(child.gameObject);
|
||||
|
||||
// Get texture reference
|
||||
Texture2D tex = progressGraph.texture as Texture2D;
|
||||
RectTransform rect = progressGraph.gameObject.transform as RectTransform;
|
||||
if (tex == null)
|
||||
{
|
||||
tex = new Texture2D(
|
||||
width: (int)rect.sizeDelta.x,
|
||||
height: (int)rect.sizeDelta.y,
|
||||
textureFormat: TextureFormat.ARGB32,
|
||||
mipCount: 3,
|
||||
linear: true
|
||||
);
|
||||
}
|
||||
tex.filterMode = FilterMode.Point;
|
||||
FillTexture(tex, backgroundColor);
|
||||
|
||||
// calculate positions and offsets
|
||||
int x0 = GRAPH_PADDING_X_PX, x1 = tex.width - GRAPH_PADDING_X_PX;
|
||||
int y0 = GRAPH_PADDING_Y_PX, y1 = tex.height - GRAPH_PADDING_Y_PX;
|
||||
double min = scores.Min();
|
||||
double max = scores.Max();
|
||||
|
||||
List<Tuple<int, int>> points = new List<Tuple<int, int>>();
|
||||
for (int i = 0; i < scores.Count; i++)
|
||||
{
|
||||
int _x = x0 + (scores.Count > 1 ? i * ((x1 - x0) / (scores.Count - 1)) : (x1 - x0) / 2);
|
||||
int _y = y0 + (int)((y1 - y0) * (min != max ? (scores[i] - min) / (max - min) : 0.5));
|
||||
points.Add(Tuple.Create(_x, _y));
|
||||
}
|
||||
|
||||
// Calculate scaling
|
||||
const int NUMBER_OF_AXES = 5;
|
||||
|
||||
double spacing = 0.0;
|
||||
if (min == max)
|
||||
{
|
||||
spacing = CalculateSpacing(highscore, NUMBER_OF_AXES);
|
||||
max = highscore + 2 * spacing;
|
||||
min = highscore - 2 * spacing;
|
||||
}
|
||||
|
||||
spacing = CalculateSpacing(max - min, NUMBER_OF_AXES);
|
||||
double begin = spacing * Math.Round(min / spacing);
|
||||
|
||||
// Draw axes
|
||||
double pixels_per_unit = (y1 - y0) / (max - min);
|
||||
double Y = begin;
|
||||
int y = y0 + (int)(pixels_per_unit * (Y - min));
|
||||
int total = 0;
|
||||
do
|
||||
{
|
||||
if (y0 <= y)
|
||||
{
|
||||
DrawLine(tex, x0, y, x1, y, 2, textColor);
|
||||
|
||||
GameObject tick = GameObject.Instantiate(axesTickMarker, rect);
|
||||
tick.GetComponent<RectTransform>().localPosition = new Vector3(-10 - rect.sizeDelta.y * rect.pivot.x, y - 25 - rect.sizeDelta.y * rect.pivot.y, 0);
|
||||
TMP_Text txt = tick.GetComponent<TMP_Text>();
|
||||
txt.text = $"{Y}";
|
||||
txt.color = textColor;
|
||||
}
|
||||
total += 1;
|
||||
Y += spacing;
|
||||
y = y0 + (int)(pixels_per_unit * (Y - min));
|
||||
|
||||
// Fail save
|
||||
if (2 * NUMBER_OF_AXES < total)
|
||||
break;
|
||||
} while (y <= y1);
|
||||
|
||||
|
||||
// Draw highscore
|
||||
if (min <= highscore && highscore <= max)
|
||||
{
|
||||
y = y0 + (int)(pixels_per_unit * (highscore - min));
|
||||
DrawLine(tex, x0, y, x1, y, GRAPH_LINE_SIZE, highscoreColor);
|
||||
GameObject marker = GameObject.Instantiate(highscoreMarker, rect);
|
||||
marker.GetComponent<RectTransform>().localPosition = new Vector3(tex.width - 50 - rect.sizeDelta.x * rect.pivot.x, y - 25 - rect.sizeDelta.y * rect.pivot.y, 0);
|
||||
}
|
||||
|
||||
// Draw points
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
Tuple<int, int> p = points[i];
|
||||
if (0 < i)
|
||||
{
|
||||
Tuple<int, int> q = points[i - 1];
|
||||
DrawLine(tex, p.Item1, p.Item2, q.Item1, q.Item2, GRAPH_LINE_SIZE, lineColor);
|
||||
}
|
||||
DrawPoint(tex, p.Item1, p.Item2, GRAPH_POINT_RADIUS, lineColor);
|
||||
}
|
||||
|
||||
// Apply to graph GameObject
|
||||
tex.Apply();
|
||||
progressGraph.texture = tex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate nice spacing
|
||||
/// </summary>
|
||||
/// <param name="mu">Either `max - min` if max != min, otherwise `highscore`</param>
|
||||
/// <param name="numberOfAxes">Number of horizontal axes grid lines shown on the graph</param>
|
||||
/// <returns>Spacing between each axes grid line</returns>
|
||||
private double CalculateSpacing(double mu, int numberOfAxes)
|
||||
{
|
||||
if (mu == 0)
|
||||
return 1.0;
|
||||
|
||||
double[] otherSpacings = { 0.5, 1.0, 2.0, 5.0 };
|
||||
|
||||
int mag = (int)Math.Floor(Math.Log10(Math.Abs(mu)));
|
||||
int MAG = (int)Math.Pow(10, mag);
|
||||
double spacing = MAG;
|
||||
foreach (double o in otherSpacings)
|
||||
{
|
||||
if (Math.Abs(mu - numberOfAxes * spacing) <= Math.Abs(mu - numberOfAxes * o * MAG))
|
||||
continue;
|
||||
spacing = o * MAG;
|
||||
}
|
||||
return spacing;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set all the pixels of a texture to a given color
|
||||
/// </summary>
|
||||
/// <param name="tex">Texture to fill</param>
|
||||
/// <param name="color">Color to set the texture to</param>
|
||||
private void FillTexture(Texture2D tex, Color color)
|
||||
{
|
||||
for (int y = 0; y < tex.height; y++)
|
||||
for (int x = 0; x < tex.width; x++)
|
||||
tex.SetPixel(x, y, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a point to a texture
|
||||
/// </summary>
|
||||
/// <param name="tex">Texture2D to plot point on</param>
|
||||
/// <param name="xc">Center x-pos</param>
|
||||
/// <param name="yc">Center y-pos</param>
|
||||
/// <param name="r">Radius (aka width and height)</param>
|
||||
/// <param name="color">Color of the point</param>
|
||||
private void DrawPoint(Texture2D tex, int xc, int yc, int r, Color color)
|
||||
{
|
||||
for (int y = yc - r; y < yc + r; y++)
|
||||
for (int x = xc - r; x < xc + r; x++)
|
||||
tex.SetPixel(x, y, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a line to a texture
|
||||
/// </summary>
|
||||
/// <param name="tex">Texture2D to plot line on</param>
|
||||
/// <param name="x0">Starting x-pos</param>
|
||||
/// <param name="y0">Strating y-pos</param>
|
||||
/// <param name="x1">Ending x-pos</param>
|
||||
/// <param name="y1">Ending y-pos</param>
|
||||
/// <param name="size">Size of the line (width)</param>
|
||||
/// <param name="color">Color of the line</param>
|
||||
private void DrawLine(Texture2D tex, int x0, int y0, int x1, int y1, int size, Color color)
|
||||
{
|
||||
int w = x1 - x0;
|
||||
int h = y1 - y0;
|
||||
|
||||
int length = Mathf.Abs(x1 - x0);
|
||||
if (Mathf.Abs(y1 - y0) > length)
|
||||
length = Mathf.Abs(h);
|
||||
|
||||
double dx = w / (double)length;
|
||||
double dy = h / (double)length;
|
||||
|
||||
double x = x0;
|
||||
double y = y0;
|
||||
double r = size / 2;
|
||||
for (int i = 0; i <= length; i++)
|
||||
{
|
||||
for (int j = (int)(y - r); j < y + r; j++)
|
||||
for (int k = (int)(x - r); k < x + r; k++)
|
||||
tex.SetPixel(k, j, color);
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/ProgressGraph.cs.meta
Normal file
11
Assets/Accounts/Scripts/ProgressGraph.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73c708fbc5395aa4b9765d4b6985bacc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -40,13 +40,13 @@ public class User
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all recently started courses
|
||||
/// Get a list of all recently started minigameCards
|
||||
/// </summary>
|
||||
/// <returns>A <c>List</c> of <c>Tuples</c>, containing the <c>CourseIndex</c>
|
||||
/// and a <c>float</c> holding the progress (value between 0 and 1) of the user in this course</returns>
|
||||
public List<Tuple<CourseIndex, float>> GetRecentCourses()
|
||||
{
|
||||
// TODO: return better results (for now only return all courses)
|
||||
// TODO: return better results (for now only return all minigameCards)
|
||||
List<Tuple<CourseIndex, float>> recentCourses = new List<Tuple<CourseIndex, float>>();
|
||||
foreach (var courseProgress in storedUserData.courses)
|
||||
{
|
||||
@@ -58,7 +58,7 @@ public class User
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all recommended courses
|
||||
/// Get a list of all recommended minigameCards
|
||||
/// </summary>
|
||||
/// <returns>A <c>List</c> of <c>Tuples</c>, containing the <c>CourseIndex</c>
|
||||
/// and a <c>float</c> holding the progress (value between 0 and 1) of the user in this course</returns>
|
||||
@@ -71,7 +71,7 @@ public class User
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: return better results (for now only return all courses)
|
||||
// TODO: return better results (for now only return all minigameCards)
|
||||
foreach (var courseProgress in storedUserData.courses)
|
||||
{
|
||||
CourseIndex idx = courseProgress.courseIndex;
|
||||
@@ -83,7 +83,7 @@ public class User
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the progress of all courses the user did
|
||||
/// Get the progress of all minigameCards the user did
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<SavedCourseProgress> GetCourses()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -25,60 +23,24 @@ public class UserProgressScreen : MonoBehaviour
|
||||
public Image avatar;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the user total playtime
|
||||
/// Reference to the courses panel
|
||||
/// </summary>
|
||||
public TMP_Text playtime;
|
||||
public GameObject coursesPanel;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of the highscore marker to display on the graph
|
||||
/// Reference to the minigame panel
|
||||
/// </summary>
|
||||
public GameObject highscoreMarker;
|
||||
public GameObject minigamesPanel;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a course card
|
||||
/// Reference to the courses tab button (to set nice color)
|
||||
/// </summary>
|
||||
public GameObject courseCardPrefab;
|
||||
public Image coursesTabButton;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all course cards
|
||||
/// Reference to the minigames tab button (to set nice color)
|
||||
/// </summary>
|
||||
public GameObject coursesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no course progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyCourses;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a minigame card
|
||||
/// </summary>
|
||||
public GameObject minigameCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all the minigame cards
|
||||
/// </summary>
|
||||
public GameObject minigamesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no minigame progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyMinigames;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the plot
|
||||
/// </summary>
|
||||
public RawImage progressGraph;
|
||||
|
||||
/// <summary>
|
||||
/// Current selected activity draw to the graph
|
||||
/// </summary>
|
||||
private int selectedActivity = -1;
|
||||
|
||||
/// <summary>
|
||||
/// List of activity backgrounds and indices
|
||||
/// </summary>
|
||||
private List<Tuple<Image, int>> activities = new List<Tuple<Image, int>>();
|
||||
|
||||
public Image minigamesTabButton;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
@@ -92,98 +54,29 @@ public class UserProgressScreen : MonoBehaviour
|
||||
// Set correct displayed items
|
||||
username.text = user.GetUsername();
|
||||
avatar.sprite = user.GetAvatar();
|
||||
playtime.text = $"Totale speeltijd: {user.GetPlaytime().ToString("0.00")}";
|
||||
|
||||
// Set graph inactive
|
||||
progressGraph.gameObject.SetActive(false);
|
||||
|
||||
int i = 0;
|
||||
// Display courses
|
||||
var courses = user.GetCourses();
|
||||
coursesContainer.SetActive(courses.Count > 0);
|
||||
emptyCourses.SetActive(courses.Count <= 0);
|
||||
foreach (var courseProgress in courses)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(courseCardPrefab, coursesContainer.transform.Find("Viewport").Find("Content").transform);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
CourseProgressCard cpc = instance.GetComponent<CourseProgressCard>();
|
||||
cpc.courseProgress = courseProgress;
|
||||
cpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
activities.Add(Tuple.Create(background, (int)courseProgress.courseIndex));
|
||||
}
|
||||
|
||||
// Display minigames
|
||||
var minigames = user.GetMinigames();
|
||||
minigamesContainer.SetActive(minigames.Count > 0);
|
||||
emptyMinigames.SetActive(minigames.Count <= 0);
|
||||
foreach (var minigameProgress in minigames)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(minigameCardPrefab, minigamesContainer.transform.Find("Viewport").Find("Content").transform);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
MinigameProgressCard mpc = instance.GetComponent<MinigameProgressCard>();
|
||||
mpc.minigameProgress = minigameProgress;
|
||||
mpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
activities.Add(Tuple.Create(background, (int)minigameProgress.minigameIndex));
|
||||
}
|
||||
DisplayCourses();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the current selected activity
|
||||
/// Switch to displaying the courses
|
||||
/// </summary>
|
||||
/// <param name="newActivity">Index to the new activity</param>
|
||||
private void UpdateSelection(int newActivity)
|
||||
public void DisplayCourses()
|
||||
{
|
||||
if (selectedActivity < 0)
|
||||
{
|
||||
progressGraph.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
activities[selectedActivity].Item1.color = Color.gray;
|
||||
}
|
||||
|
||||
selectedActivity = newActivity;
|
||||
activities[selectedActivity].Item1.color = Color.blue;
|
||||
if (selectedActivity < user.GetCourses().Count)
|
||||
{
|
||||
// TODO: create a better graph
|
||||
//DisplayCourseGraph((CourseIndex)activities[selectedActivity].Item2);
|
||||
// For now: just deactivate graph rendering
|
||||
progressGraph.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMinigameGraph((MinigameIndex)activities[selectedActivity].Item2);
|
||||
// TODO: remove line, this is only because courses deactivates the graph
|
||||
progressGraph.gameObject.SetActive(true);
|
||||
}
|
||||
coursesPanel.SetActive(true);
|
||||
coursesTabButton.color = Color.blue;
|
||||
minigamesPanel.SetActive(false);
|
||||
minigamesTabButton.color = Color.gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plot the graph of a course
|
||||
/// Switch to displaying the minigames
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the course</param>
|
||||
/// <remarks>TODO: create a better plot</remarks>
|
||||
private void DisplayCourseGraph(CourseIndex index) { }
|
||||
|
||||
/// <summary>
|
||||
/// Plot the graph of a minigame
|
||||
/// </summary>
|
||||
/// <param name="minigameIndex">Index of the minigame</param>
|
||||
/// <remarks>TODO: reworking </remarks>
|
||||
private void DisplayMinigameGraph(MinigameIndex minigameIndex) { }
|
||||
public void DisplayMinigames()
|
||||
{
|
||||
coursesPanel.SetActive(false);
|
||||
coursesTabButton.color = Color.gray;
|
||||
minigamesPanel.SetActive(true);
|
||||
minigamesTabButton.color = Color.blue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user