From List to Graphical Interface - c#

I'm creating a shop inside my game to buy virtual goods.
Main Shop Page
Each group has its own items. I've created a view where only one item is visible each time, with buttons to go to the previous and next item.
Specific group selection Menu - Teams
The question is that I don't know how to show the list where I have the items, in that last window and make that touching the buttons previous/next the list shows the different items.
Each item inside the list is called inventory[x] (x = the number in the loop) and has the properties itemName and itemDescription.
How can I make the code communicate with the graphical user interface?
I've created 6 inventory lists (each one for one type of unlockable virtual good) and I use GameSparks API for online features such a player profile.
The lists are declared at the beginning of the script:
public static List<Inventario> inventarioEquipos = new List<Inventario>(); //Inventory for Teams
public static List<Inventario> inventarioPelotas = new List<Inventario>(); //Inventory for Balls
public static List<Inventario> inventarioModos = new List<Inventario>(); //Inventory for Modes
public static List<Inventario> inventarioVitores = new List<Inventario>(); //Inventory for Cheers
public static List<Inventario> inventarioCampos = new List<Inventario>(); //Inventory for Fields
public static List<Inventario> inventarioFondos = new List<Inventario>(); //Inventory for Backgrounds
In the Awake method I call:
Info_Botones ("Equipos"); //I call this function for each group, to load its items and show how many items of a total of X the player owns. If you look at the first picture, will see below TEAMS: 1/2. That's what this function is for (besides to load all the unlockables in separated lists).
Info_Botones ("Pelotas");
Info_Botones ("Modos");
Info_Botones ("Vitores");
Info_Botones ("Campos");
Info_Botones ("Fondos");
The code of the main function is as follows:
private void Info_Botones(string tipoDeInventario) { //"tipoDeInventario" means InventoryType and I use it to pass to the function which type of inventory I want to load (Teams, Balls, Modes, Cheers, Fields or Backgrounds)
int numero = 0;
new LogEventRequest()
.SetEventKey("INVENTARIO")
.SetEventAttribute("TAG_TYPE", tipoDeInventario)
.Send((response) =>
{
if (!response.HasErrors)
{
List<object> entryList = response.ScriptData.GetObjectList("result") as List<object>;
for (int i = 0; i < entryList.Count; i++)
{
Dictionary<string, object> entry = entryList[i] as Dictionary<string, object>;
int itemId = i;
string itemName = (entry["name"]).ToString();
string itemDescription = (entry["description"]).ToString();
int itemPrice = int.Parse((entry["currency1Cost"].ToString()));
string itemInteractable = (entry["interactable"]).ToString();
Inventario inv = new Inventario(itemId, itemName, itemDescription, itemPrice, itemInteractable);
if(tipoDeInventario == "Equipos") {
inventarioEquipos.Add(inv);
if (inventarioEquipos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Pelotas") {
inventarioPelotas.Add(inv);
if (inventarioPelotas[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Modos") {
inventarioModos.Add(inv);
if (inventarioModos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Vitores") {
inventarioVitores.Add(inv);
if (inventarioVitores[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Campos") {
inventarioCampos.Add(inv);
if (inventarioCampos[i].itemInteractable == "False") {
numero++;
}
} else if(tipoDeInventario == "Fondos") {
inventarioFondos.Add(inv);
if (inventarioFondos[i].itemInteractable == "False") {
numero++;
}
} else {
}
}
if(tipoDeInventario == "Equipos") {
txtBtnCantidadEquipos.text = numero.ToString() + "/" + inventarioEquipos.Count;
} else if(tipoDeInventario == "Pelotas") {
txtBtnCantidadPelotas.text = numero.ToString() + "/" + inventarioPelotas.Count;
} else if(tipoDeInventario == "Modos") {
txtBtnCantidadModos.text = numero.ToString() + "/" + inventarioModos.Count;
} else if(tipoDeInventario == "Vitores") {
txtBtnCantidadVitores.text = numero.ToString() + "/" + inventarioVitores.Count;
} else if(tipoDeInventario == "Campos") {
txtBtnCantidadCampos.text = numero.ToString() + "/" + inventarioCampos.Count;
} else if(tipoDeInventario == "Fondos") {
txtBtnCantidadFondos.text = numero.ToString() + "/" + inventarioFondos.Count;
} else {
}
}
else
{
Debug.Log("ERROR AL OBTENER VG DEL JUGADOR: " + response.Errors.JSON);
}
});
}

I've achieved it using IF condictions. If anyone needs the code, ask for it and I will share it (I'm not at home right now).
Thanks!

Related

how to make a grid with the local space Unity?

I am gridding around an object but I need the grid to align in the local space of the pivot object
the code that i have
private void createColum()
{
for (int i =0; i<gridGame.Count;i++)
{
if(gridGame[i] == gridGame[0])
{
gridGame[i].localPosition = gridGame[0].localPosition;
}
if(gridGame[i]!= gridGame[0])
{
gridGame[i].localPosition = new Vector3(gridGame[i-1].localPosition.x + distX,gridGame[0].localPosition.y, gridGame[0].localPosition.z);
}
if(i +1 > limiteFila)
{
if(i%limiteFila==0)
{
gridGame[i].localPosition = new Vector3(gridGame[0].position.x, gridGame[0].position.y , gridGame[i-Mathf.RoundToInt(limiteFila)].position.z + distY);
}else
{
gridGame[i].position = new Vector3(gridGame[i-1].position.x + distX, gridGame[0].position.y , gridGame[i-1].position.z);
}
}
gridGame[i].rotation = gridGame[0].rotation;
}
}
with this the grid of objects is formed but only in taking the world space
picture of how you are at this moment
I'm not sure if this will help, but you can turn the grid into a child object and leave the worldPositionStays as false, to do so use the SetParent(Transform parent, bool worldPositionStays). For example as a reference for your script.
private void createColum()
{
for (int i =0; i<gridGame.Count;i++)
{
if(gridGame[i] == gridGame[0])
{
gridGame[i].localPosition = gridGame[0].localPosition;
gridGame[i].transform.SetParent(this.transform, false);
}
if(gridGame[i]!= gridGame[0])
{
gridGame[i].localPosition = new Vector3(gridGame[i-1].localPosition.x + distX,gridGame[0].localPosition.y, gridGame[0].localPosition.z);
}
if(i +1 > limiteFila)
{
if(i%limiteFila==0)
{
gridGame[i].localPosition = new Vector3(gridGame[0].position.x, gridGame[0].position.y , gridGame[i-Mathf.RoundToInt(limiteFila)].position.z + distY);
}else
{
gridGame[i].position = new Vector3(gridGame[i-1].position.x + distX, gridGame[0].position.y , gridGame[i-1].position.z);
}
}
gridGame[i].rotation = gridGame[0].rotation;
}
}

Performance issue with C# if statement

I do have below function which taking more time for execution can someone help to write it properly,its getting while importing data for validation purpose
public void MapReferences(Company company, ISession session, List<Contract> contracts, List<Employee> employees, List<CompanySettingsMap> companies, List<Contact> contacts, IList<ImportEmployeeOrgProfileBatchItem> importedOrgProfileData, int lineNum = 2)
{
var dateConvertor = new DateConverter();
DateTime date;
foreach (var item in importedOrgProfileData)
{
item.CompanyId = company.Id;
item.LineNumber = lineNum;
item.CompanyReference = company?.Reference;
Employee employee = new Employee();
Contact contact = new Contact();
#region " Organisation Validation"
if (string.IsNullOrEmpty(item.Organisation))
{
item.CanContinue = false;
item.ErrorsList.Add("Invalid Organisation");
}
else
{
var allcontact = contacts.Where(x => x.Company.Id == company.Id && x.Reference.ToLower() == item.Organisation.ToLower()).ToList();
if (allcontact.Count > 1)
{
item.ErrorsList.Add("More than one contact found matching with organisation");
}
else
{
contact = allcontact.FirstOrDefault();
}
if (contact != null)
{
item.AgencyId = contact.Id;
item.AgencyReference = contact.Reference;
}
else
{
item.ErrorsList.Add("Contact not found matching with organisation");
item.CanContinue = false;
}
}
#endregion
if(string.IsNullOrEmpty(item.PostCode))
{
item.ErrorsList.Add("Postcode is required");
item.CanContinue = false;
}
#region " Employee Number Validation"
if (string.IsNullOrEmpty(item.EmployeeNumber) || item.EmployeeNumber.Length < 8)
{
item.CanContinue = false;
item.ErrorsList.Add("Invalid Employee Number");
}
else
{
string employeenumber = item.EmployeeNumber.Substring(0, 8);
employee = employees.Where(x => !string.IsNullOrEmpty(x.ExternalReference) && x.ExternalReference.ToLower().StartsWith(employeenumber.ToLower())).FirstOrDefault();
if (employee != null)
{
item.EmployeeId = employee.Id;
item.EmployeeExternalRef = employee.ExternalReference;
if (company.IsPayrollEnabled && employee.PayrollGroup?.Id != null)
{
item.PayrollGroupId = employee.PayrollGroup?.Id;
var payrollGroup = session.Query<PayrollGroup>().Where(x => x.Id == employee.PayrollGroup.Id).FirstOrDefault();
if (payrollGroup != null)
{
item.Payroll = payrollGroup.Description.ToString();
}
}
}
else
{
item.StarterDeclaration = Interfaces.HMRC.StarterDeclaration.OnlyJob;
item.TaxCode = session.Query<PayeSetting>().Single(x => x.Year == GovernmentTaxYearEndDate(DateTime.Today).Year).DefaultTaxCode;
item.EmployeeExternalRef = item.EmployeeNumber;
item.ChangeLogList.Add("Employee " + item.EmployeeNumber + " will be created");
item.CanContinue = true;
}
}
#endregion
#region " Validate Contract(Assignment number) "
if (string.IsNullOrEmpty(item.ContractNumber))
{
item.CanContinue = false;
item.ErrorsList.Add("Invalid Contract Number");
}
else
{
if (dateConvertor.TryConvertFromString(item.ContractStartDateString, out date))
{
item.ContractStartDate = date;
}
if (dateConvertor.TryConvertFromString(item.ContractEndDateString, out date))
{
item.ContractEndDate = date;
}
var contract = contracts.Where(x => !string.IsNullOrEmpty(x.ContractReference) && x.ContractReference.ToLower() == item.ContractNumber.ToLower()).FirstOrDefault();
if (employee == null && contract != null)
{
item.ContractReference = contract.ContractReference;
item.ErrorsList.Add("Contract can not be created because contract with reference " + contract.ContractReference + " is already assigned to other employee");
item.CanContinue = false;
}
else if (contract != null)
{
if (contract.Employee.Id == employee.Id)
{
item.ContractId = contract.Id;
item.ContractReference = contract.ContractReference;
}
else
{
item.ErrorsList.Add("Contract with reference " + contract.ContractReference + " is already assigned to other employee");
item.CanContinue = false;
}
}
else
{
item.ContractReference = item.ContractNumber;
if (contact == null)
{
item.ErrorsList.Add("Contract can not be created automatically because matching contact not found");
item.CanContinue = false;
}
else
{
item.ChangeLogList.Add("Contract " + item.ContractNumber + " will be created");
}
}
}
#endregion
#region " Parse and Assign Dates to date fields "
if (dateConvertor.TryConvertFromString(item.StartDateInPositionString, out date))
{
item.StartDateInPosition = date;
}
if (dateConvertor.TryConvertFromString(item.IncrementalDateString, out date))
{
item.IncrementalDate = date;
}
if (dateConvertor.TryConvertFromString(item.FixedTermEndDateString, out date))
{
item.FixedTermEndDate = date;
}
if (dateConvertor.TryConvertFromString(item.WtrOptOutDateString, out date))
{
item.WtrOptOutDate = date;
}
if (dateConvertor.TryConvertFromString(item.AdjustedServiceDateString, out date))
{
item.AdjustedServiceDate = date;
}
if (dateConvertor.TryConvertFromString(item.NHSEntryDateString, out date))
{
item.NHSEntryDate = date;
}
if (dateConvertor.TryConvertFromString(item.BirthDateString, out date))
{
item.BirthDate = date;
}
if (dateConvertor.TryConvertFromString(item.DateFirstHiredString, out date))
{
item.DateFirstHired = date;
}
else if (!item.EmployeeId.HasValue)
{
item.DateFirstHired = DateTime.Today.Date;
}
#endregion
if (!string.IsNullOrEmpty(item.Title))
{
item.Title = item.Title.Replace(".", "");
}
if (string.IsNullOrEmpty(item.MaritalStatus))
{
item.MaritalStatus = "U";
}
item.Payroll = string.Empty;
lineNum++;
item.Errors = item.ErrorsList.Count > 0 ? String.Join("|", item.ErrorsList.Distinct()) : string.Empty;
item.ChangeLog = item.ChangeLogList.Count > 0 ? String.Join("|", item.ChangeLogList) : string.Empty;
}
}
A good rule of thumb is that if you have copy/pasted code then you should have put it in a function, you could make one function for the date checking then call that, a lot of compilers and translators will then just hold that little bit in memory and repeatedly call it rather than all the lines you have there.
for the sake of readable code, maybe each region should be a separate function?
Shift your temp employee and contact object declarations outside the loop, as it is you have a memory declaration and memory assignation in each loop, moving it outside means you just have the assignation inside the loop (the parser/translator should do this automatically in c# but not always)
Shift everything that is not unique to that particular item to outside of the loop, the taxcode year for example means for every item that hits that else conditional then you are doing a linq query. Incidentally I have noticed great speed and memory gains to be made if you use for loops instead of linq, but they are less readable.
Item.CanContinue isn't used anywhere, maybe each object could handle it's own validation or you could have a static function that checks an object for issues and adds the issues to the list.
one example:
bool chkStringNotNull(string data, ref item, string ErrorMsg)
{
if(String.IsNullOrEmpty(data)) {
item.ErrorsList.Add(ErrorMsg);
return false;
}
return true;
}
Of course you would need to refactor to use item as a ref.

Image index not always changes

So, I'm trying to code simple memory game in Windows Forms but I've met a simple problem that somehow I can't pass.
This is a single button code(they all look very similar):
Match CheckForMatches = new Match();
private void Pathfinder_Click(object sender, EventArgs e)
{
CheckForMatches.AddButton(Pathfinder);
CheckForMatches.Matched();
}
(where CheckForMatches object is shared between all buttons in given form)
And here are called methods codes:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
firstButtonPressed.ImageIndex = 0; //uncovering card
}
else
{
secondButtonPressed = newButton;
secondButtonPressed.ImageIndex = 0;
Thread.Sleep(1000);
}
}
public bool Matched()
{
if (firstButtonPressed != null && secondButtonPressed != null )
{
if (firstButtonPressed.Name != secondButtonPressed.Name)
{
if (firstButtonPressed.Text == secondButtonPressed.Text)
{
DisposeButtons();
return true;
}
else
{
NullButtons();
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
Now this method call one of two others, depending if last 2 clicked buttons are a pair or not(basing on their name and text):
This in case of succes disposes buttons and null Match class variables:
public void DisposeButtons()
{
firstButtonPressed.Dispose();
secondButtonPressed.Dispose();
firstButtonPressed = null;
secondButtonPressed = null;
}
This is case of failure covers cards and also nulls Match class variables:
public void NullButtons()
{
firstButtonPressed.ImageIndex = 1; //covering cards
secondButtonPressed.ImageIndex = 1;
firstButtonPressed = null;
secondButtonPressed = null;
}
The point is, no matter where I place Thread.Sleep(1000), user can never see second card he choses. He always see the first one and then, when he choses second one, either both cards are disposed(app is freezing due to that delay) or the first one becomes covered, without uncovering the second one.
EDIT:
I added output to debugger window, so now method AddButton looks like this:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
Debug.WriteLine("Before index chaning: " + firstButtonPressed.ImageIndex);
firstButtonPressed.ImageIndex = 0; //uncovering card
Debug.WriteLine("After index chaning: " + firstButtonPressed.ImageIndex);
}
else
{
secondButtonPressed = newButton;
Debug.WriteLine("Before index chaning: " + secondButtonPressed.ImageIndex);
secondButtonPressed.ImageIndex = 0;
Debug.WriteLine("After index chaning: " + secondButtonPressed.ImageIndex);
Thread.Sleep(1000);
}
}
I can see there, that ImageIndex buttons' property actually changes between 1 and 0. However, in practice, it's only visible when first if block of this method is called. I would be grateful for answering why and how to change that.
Okay, I found out maybe not best solution, but it works. I simply forced button to refresh.
Correct form of AddButton method is:
public void AddButton(Button newButton)
{
if (firstButtonPressed == null)
{
firstButtonPressed = newButton;
Debug.WriteLine("Before index changing: " + firstButtonPressed.ImageIndex);
firstButtonPressed.ImageIndex = 0; //uncovering card
Debug.WriteLine("After index changing: " + firstButtonPressed.ImageIndex);
}
else
{
secondButtonPressed = newButton;
Debug.WriteLine("Before index changing: " + secondButtonPressed.ImageIndex);
secondButtonPressed.ImageIndex = 0;
secondButtonPressed.Refresh();
Debug.WriteLine("After index changing: " + secondButtonPressed.ImageIndex);
Thread.Sleep(500);
}
}
I hope it will be useful for someone one day.

Song picking system

I am trying to do a song picking UI in my project. Everytime u click on a button in the game it sends int to this function. Is there a better way to structure this code so i don't have to write IF statements for every single song?
public void SongPick(int song)
{
if (song == 0)
{
audioSource.clip = musicArray[0];
}
if (song == 1)
{
audioSource.clip = musicArray[1];
}
if (song == 2)
{
audioSource.clip = musicArray[2];
}
audioSource.Play();
string currentMusic = musicArray[song].name;
songName.text = "PLAYING: " + currentMusic;
}
Assuming song always references the correct index in musicArray you definitely don't need an ever-growing if statement.
public void SongPick(int song) {
if (song < musicArray.length) {
audioSource.clip = musicArray[song];
}
audioSource.Play();
string currentMusic = musicArray[song].name;
songName.text = "PLAYING: " + currentMusic;
}

C# how to create class instance for entire GUI

I am making a simple reservation system that uses a GUI for input and display with a class for all the logic and storing of available/taken seats. My problem I do not know how to create on instance of the class when the form loads to be used by the entire GUI. I have, however done this with the button click, but every time the button is clicked the stored data in the class is reset. How do I create an instance of the class when the form loads that will not reset the data whenever the button is clicked. Below is the code for my GUI with a work around for my data being reset. Thanks for the help and if I missed a related topic while searching before posting please let me know.
namespace AirLine
{
public partial class ReservationSystem : Form
{
public ReservationSystem()
{
InitializeComponent();
radioFirst.Checked = true; // start program with button checked
}
private void buttonBook_Click(object sender, EventArgs e)
{
Label[] labelFirst = new Label[] { labelFirst1, labelFirst2, labelFirst3, labelFirst4, labelFirst5 };
Label[] labelEcon = new Label[] { labelEcon1, labelEcon2, labelEcon3, labelEcon4, labelEcon5 };
CheckBox[] checkFirst = new CheckBox[] { checkFirst1, checkFirst2, checkFirst3, checkFirst4, checkFirst5 };
CheckBox[] checkEcon = new CheckBox[] { checkEcon1, checkEcon2, checkEcon3, checkEcon4, checkEcon5 };
Reservation res = new Reservation();
int x;
int i = 0; // counter for bool update
int k = 0; // counter for manual seat slecetion FirstClass
int c = 0; // counter for manual seat selection Econ
int j = 0; // counter to reset unchecked boxes
while (i < checkFirst.Length) //update fseats bool
{
if (checkFirst[i].Checked == true) //if box chceked correspsonding bool change to true
{
res.reserveFirstClassSeat(i);
}
if (checkEcon[i].Checked == true) //if box chceked correspsonding bool change to true
{
res.reserveEconomyClassSeat(i);
}
++i; // tick i
}
//booking of first avialible seat
try
{
string firstname = textFirst.Text;
string lastname = textLast.Text;
int age = Convert.ToInt32(textAge.Text);
string name = firstname + lastname + age;
if (textFirst.Text != "" && textLast.Text != "" && Enumerable.Range(1, 150).Contains(age)) //validate user input
{
if (radioFirst.Checked == true) //User selected first class
{
if (res.isFirstClassAvailable() == false && res.isEconomyClassAvailable() == true)
{
System.Windows.Forms.MessageBox.Show("First Class is full, Only Economy left"); // if first class is full inform user
}
if (res.isFirstClassAvailable() == true ) // verify a seat is open in first class
{
x = res.nextAvailableFirstClassSeat(); // store next availible seat number
res.reserveFirstClassSeat(x); // resevere next availible seat
checkFirst[x].Checked = true; // check checkbox of seat
labelFirst[x].Text = name; //Change label to reflect name and age of passenger
}
}
if (radioEcon.Checked == true) //User selected Econ class
{
if (res.isFirstClassAvailable() == true && res.isEconomyClassAvailable() == false)
{
System.Windows.Forms.MessageBox.Show("Economy is full, Only First Class left"); // if econ is full inform user
}
if (res.isEconomyClassAvailable() == true) // verify a seat is open in first class
{
x = res.nextAvailableEconomyClassSeat(); // store next availible seat number
res.reserveEconomyClassSeat(x); // resevere next availible seat
checkEcon[x].Checked = true; // check checkbox of seat
labelEcon[x].Text = name; //Change label to reflect name and age of passenger
}
}
}
else // if input is not valid
{
System.Windows.Forms.MessageBox.Show("Please Check Name, Age, and Seat #");
}
}
catch (FormatException)
{
System.Windows.Forms.MessageBox.Show("Please Check Name, Age, and Seat #");
}
// manual check of seat
try
{
string firstname = textFirst.Text;
string lastname = textLast.Text;
int age = Convert.ToInt32(textAge.Text);
string name = firstname + lastname + age;
if (textFirst.Text != "" && textLast.Text != "" && Enumerable.Range(1, 150).Contains(age)) //validate user input
{
if (radioManual.Checked == true)
{
while (k < checkFirst.Length)
{
if (checkFirst[k].Checked == true && labelFirst[k].Text == "Open") // see if box was checked and label is still "Open"
{
res.reserveFirstClassSeat(k);
labelFirst[k].Text = name;
}
++k;
}
while (c < checkEcon.Length)
{
if (checkEcon[c].Checked == true && labelEcon[c].Text == "Open")
{
res.reserveEconomyClassSeat(c);
labelEcon[c].Text = name;
}
++c;
}
}
}
else // if input is not valid
{
System.Windows.Forms.MessageBox.Show("Please Check Name, Age, and Seat #");
}
}
catch (FormatException)
{
System.Windows.Forms.MessageBox.Show("Please Check Name, Age, and Seat #");
}
if (res.isFirstClassAvailable() == false && res.isEconomyClassAvailable() == false) // if flight is full inform user
System.Windows.Forms.MessageBox.Show("Flight is Full");
{ // clear text boxes
textFirst.Text = "";
textLast.Text = "";
textAge.Text = "";
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
Label[] labelFirst = new Label[] { labelFirst1, labelFirst2, labelFirst3, labelFirst4, labelFirst5 };
Label[] labelEcon = new Label[] { labelEcon1, labelEcon2, labelEcon3, labelEcon4, labelEcon5 };
CheckBox[] checkFirst = new CheckBox[] { checkFirst1, checkFirst2, checkFirst3, checkFirst4, checkFirst5 };
CheckBox[] checkEcon = new CheckBox[] { checkEcon1, checkEcon2, checkEcon3, checkEcon4, checkEcon5 };
int j = 0;
while (j < checkFirst.Length)
{
if (checkFirst[j].Checked == false)
{
labelFirst[j].Text = "Open";
}
if (checkEcon[j].Checked == false)
{
labelEcon[j].Text = "Open";
}
++j;
}
}
}
}
To use the instance of myClass in the entire GUI do the following.
public partial class MainWindow : Window
{
MyClass myClass;
public MainWindow()
{
myClass = new MyClass();
InitializeComponent();
}
}

Categories