Making patterns in a 2D array
I want to make patterns using projectors at the bottom of the screen that shoot projectiles up in a pattern.
Now I'm not sure what's the best approach for it, but right now what I'm trying to do is using a 2D array to store the pattern in, but I also want to be able to assign a color to each 'projectile'. Also I'm trying to look for a better way to assign the pattern to an array other than hardcoding it. By maybe loading it in but I'm not sure how to do that.
Here's an example of how It's supposed to shoot projecitles, where the X is where he doesn't shoot and O is where it shoots
XXXOOOXXX
OOOXXXOOO
XXXOOOXXX
XOOOXOOOX
XXOOOOOXX
And in stead of putting every single point in an array by hand, I was wondering if there was a way to put in in a file somewhere and load patterns in. As well as maybe being able to assign colors to each projectile.
Answer by Onithec4t · Nov 30, 2015 at 05:20 PM
You can create a projectile class like this:
public class Projectile{
bool shoot;
Color color;
}
and make an array or a list of this object, like
List<Projectile> projectiles = new List<Projectile>();
Then, you can read your data from a csv file with a script like this: http://wiki.unity3d.com/index.php?title=CSVReader
Or you can build a custom inspector to insert your data.
At this point I have 11 'Projectors' lined up horizontally and I'm trying to make them all have a list of projectiles to shoot, maximum 11 $$anonymous$$inimum 6 projectiles in a loop. So basically I would have a 2D array of [11,6] - [11,11]. $$anonymous$$y problem is that I don't really know precisely how to get a list of Projectiles filled for every projector, in a simple way other than hardcoding it.
I'm not sure if I understood, but maybe you wanna make a list of list, like this?
List> projectiles = new List>();
BTW you can consider the procedural way, using a Random.Range(x,y) and u can control just the x and the y
Those are the projectors I have lined up, and they all need to shoot projectiles up. They all shoot at the same time (If there's something to shoot in their array, so they all shoot the next item in the array at the same time)
So I hope that makes it a little bit clearer of what I'm trying to make
If I do what you said in the latest reply, I have to make an object of every individual projectile of the pattern, which is not handy, how can I do this better? How can I assign the values to a Projecitile easier
Answer by Fattie · Nov 30, 2015 at 07:21 PM
It's incredibly hard to do this, unless you're a naturally gifted programmer and can "think in algorithms".
Here's an example of a routine that makes really beautiful patterns.
In answer to your specific question, sure, deal in int[,]
to pass around such concepts.
"look for a better way to assign the pattern to an array other than hardcoding it" Sure, start with simple routines which do things like "mirror" patterns from one of your quadrants.
/*
Makes pretty patterns .. in the abstract
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public static class Pretty
{
public static int ColorInt() // just a color code, 1 to 10
{
return Random.Range(1,11);
}
// ChallengePattern is a random pattern with only one color having three-count
// (for the most challenge) the others have a higher count.
// Compare PatternOfInts which is simple and symmetrical (example use: foyer)
public static int[,] ChallengePattern(int kount)
{
if ( kount < 4 ) {Debug.Log("just too hard"); Debug.Break();}
int fullCountOfItems = kount*kount;
// step one, make a list of our colors in a random order.
// in fact, we know that the codes range from 1 to 10
int[] orderOfColors = Pretty.TheNumbers1To10Shuffled();
int[] countOfColors = Pretty.DecideCountsTotalBeing( fullCountOfItems );
// attention...
if ( countOfColors.SumArray() != fullCountOfItems )
{Debug.Log("Algorithm woe, oh oh."); Debug.Break();}
// don't forget to just let the GemInfo know what is happening:
Grid.gemInfo.RememberCounts( orderOfColors, countOfColors );
// now simply load a linear list like that.
List<int> linear = new List<int>();
for ( int t=0; t<10; ++t )
{
int whichColor = orderOfColors[t];
int howManyOfThatColor = countOfColors[t];
for (int k=0; k< howManyOfThatColor; ++k )
linear.Add( whichColor );
}
countOfColors.DebugShow();
linear.ToArray().DebugShow();
// finally, merely shuffle that linear list, and load to the square
linear = linear.OrderBy(Rx => Random.value).ToList();
linear.ToArray().DebugShow();
int[,] rr = linear.ToArray().Squareize();
return rr;
}
public static int[] DecideCountsTotalBeing(int desiredTotal)
{
// for example, if the total is 50, we might go..
// 3, 7, 10, 30
// or perhaps
// 3, 5, 12, 15, 15
// we do want to START WITH A THREE because that's how the game works.
// TBC we "know" there are ten slots (at most),
// (the game simply has ten colors and that's it)
if ( desiredTotal < 20 ) {Debug.Log("just too hard"); Debug.Break();}
int[] result = new int[10];
int traverse = 0;
int remaining = desiredTotal;
// we always start with 3!!
int thisTime = 3;
result[traverse] = thisTime;
++traverse;
remaining -= 3;
// the second one (only) can be reasonably small
thisTime = Random.Range(5,9);
result[traverse] = thisTime;
++traverse;
remaining -= thisTime;
// after this, ensure they are at least 7 in size
while ( remaining > 7 && traverse < 10 )
{
// thisTime = Random.Range(9,20); // means 9 through 19
thisTime = Random.Range(9,17); // means 9 through 16
// that value tunes well...
if ( thisTime > remaining )
thisTime = remaining;
result[traverse] = thisTime;
++traverse;
remaining -= thisTime;
}
// ensure that we got enough.
int total = result.SumArray();
if ( total < desiredTotal )
{
// Note that if we need to adjust one, we just adjust the "fourth one".
// It makes absolutely no difference which one you adjust,
// but it should be one that is not-zero.
// the last one is often zero, so, don't just adjust the last one.
// The adjustment number might be small -- say "2" -- in which case
// if you apply it to a zero item, you'd get a small count.
// (Of course, do not adjust the special three-count item, ie item zero.)
int stillNeeded = desiredTotal - total;
int lastOne = result[3];
// in this algorithm, the fourth one works perfectly in all cases.
lastOne = lastOne + stillNeeded;
result[3] = lastOne;
}
return result;
}
public static int[] TheNumbers1To10Shuffled()
{
List<int> ints = new List<int>();
for (int load=1; load<=10; ++load)
ints.Add(load);
return ints.OrderBy(Rx => Random.value).ToArray();
// to unit test, what about...
// Pretty.TheNumbers1To10Shuffled().DebugShow();
}
public static int[] IndicesUpToWhateverShuffled( int whatever )
{
List<int> ints = new List<int>();
for (int load=0; load<whatever; ++load)
ints.Add(load);
return ints.OrderBy(Rx => Random.value).ToArray();
// to unit test, what about...
// Pretty.TheNumbers1To10Shuffled().DebugShow();
}
// PatternOfInts is a simple symmetrical pattern
public static int[,] PatternOfInts(int kount)
{
// identical to PatternWithStrings,
// but result is ints 1 to 10 (matching our available gem codes)
if ( kount < 1 ) { Debug.Log("woe"); Debug.Break(); }
int[,] rr = new int[kount,kount];
int half = kount/2;
if (kount % 2 > 0) ++half;
int highestIndex = kount-1;
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
rr[across,down] = Pretty.ColorInt();
// in fact, diagonally mirror that quadrant...
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
{
if ( across >= down )
rr[down,across] = rr[across,down];
}
// in fact, make a diagonal line always
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
{
if ( across == down )
rr[across,down] = rr[0,0];
}
// fill the other three qudrants
// mirror across...
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
rr[ highestIndex -across, down ] = rr[ across, down ];
// mirror down...
for ( int across = 0; across < kount; ++across )
for ( int down = 0; down < half; ++down )
rr[ across, highestIndex -down ] = rr[ across, down ];
return rr;
}
public static void Log( this string[,] squarray )
{
int kount = squarray.GetLength(0);
string res = "\n\n";
for ( int across = 0; across < kount; ++across )
{
string line = "";
for ( int down = 0; down < kount; ++down )
line = line +" " +squarray[across,down];
res = res + line + "\n";
}
res = res + "\n\n";
Debug.Log(res);
}
}
Your answer
Follow this Question
Related Questions
Unity List of Color array not showing in inspector? 3 Answers
Setting an Objects Colour using a variable Color from an array? 0 Answers
Sprite renderer colors + Instigate 1 Answer
Creating an array of Color32 arrays 1 Answer
Get value from array in unity: debug works, value's changing, but color not changing 0 Answers