CSharp Objekte !zufällig! sichtbar machen
Hallo zusammen!
Ich habe mal wieder ein kleines Problemchen. Ich möchte diesmal mit C# eine Tix-Clock programmiren. Dazu habe ich insgesamt vier "Spalten" mit verschiedener Anzahl Blöcken erstellt (1x3, 3x3, 2x3, 3x3).
In jedem Block befindet sich eine Grafik, die bei Programmstart unsichtbar ist. Sobald das Programm gestartet wird wird ein Timer ausgelöst, der im Sekundentakt die Uhrzeit ausliest und dann die Uhrzeit ausgeben soll.
So weit so gut, aber leider klappt das alles noch nicht so ganz. Bei der Tix-Clock wird jede Sekunde auch ein neues, zufälliges "Muster" in jedem Block ausgegeben, welches natürlich auf der aktuellen Uhrzeit basiert.
Ich hab also zuerst versucht mittels Bedingungssätzen jedes mal ein neues Muster zu erzeugen, doch da habe ich schon nach kürzester Zeit den überblick verloren.
Meine Frage also: kann ich mehrere zufällige Objekte sichtbar machen, ohne eine gigantische if-Struktur aufzubauen?
Da ich noch keine zufälligen Strings generieren kann hab ich zuerst angefangen random Zahlen auszugeben.
Ich habe den Grafiken jeweils eindeutige Namen zugeteilt (daher die 4. Grafik in der 2. Spalte heißt z.B. Image2x4). Jetzt hatte ich mir erhofft über die zufällige Zahl direkt den Namen generieren zu können (was aber nicht klappte - hier nochmal der code).
So einfach war es nunmal leider nicht. Aber ich denke irgendwas derartiges muss es doch geben, oder irgendeine Alternative?
Falls ihr eine Idee habt, lasst mich es bitte wissen!
Schöne Grüße
stargazer
Ich habe mal wieder ein kleines Problemchen. Ich möchte diesmal mit C# eine Tix-Clock programmiren. Dazu habe ich insgesamt vier "Spalten" mit verschiedener Anzahl Blöcken erstellt (1x3, 3x3, 2x3, 3x3).
In jedem Block befindet sich eine Grafik, die bei Programmstart unsichtbar ist. Sobald das Programm gestartet wird wird ein Timer ausgelöst, der im Sekundentakt die Uhrzeit ausliest und dann die Uhrzeit ausgeben soll.
So weit so gut, aber leider klappt das alles noch nicht so ganz. Bei der Tix-Clock wird jede Sekunde auch ein neues, zufälliges "Muster" in jedem Block ausgegeben, welches natürlich auf der aktuellen Uhrzeit basiert.
Ich hab also zuerst versucht mittels Bedingungssätzen jedes mal ein neues Muster zu erzeugen, doch da habe ich schon nach kürzester Zeit den überblick verloren.
Meine Frage also: kann ich mehrere zufällige Objekte sichtbar machen, ohne eine gigantische if-Struktur aufzubauen?
Auslesen der Uhrzeit:
DateTime currentDate = DateTime.Now;
int dtHour = currentDate.Hour;
int dtMinute = currentDate.Minute;
int dtSecond = currentDate.Second;
DateTime currentDate = DateTime.Now;
int dtHour = currentDate.Hour;
int dtMinute = currentDate.Minute;
int dtSecond = currentDate.Second;
Da ich noch keine zufälligen Strings generieren kann hab ich zuerst angefangen random Zahlen auszugeben.
private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
{
Random random = new Random();
return random.Next(min, max);
}
Ich habe den Grafiken jeweils eindeutige Namen zugeteilt (daher die 4. Grafik in der 2. Spalte heißt z.B. Image2x4). Jetzt hatte ich mir erhofft über die zufällige Zahl direkt den Namen generieren zu können (was aber nicht klappte - hier nochmal der code).
String ch1 = new String;
int num0 = RandomNumber(1, 9);
ch1 = "Image2x" + num0;
int num0 = RandomNumber(1, 9);
ch1 = "Image2x" + num0;
if (dtHour == 15) {
if (num0 == 1) {
ch1.Visibility = Vilibility.Visible; }}
if (num0 == 1) {
ch1.Visibility = Vilibility.Visible; }}
So einfach war es nunmal leider nicht. Aber ich denke irgendwas derartiges muss es doch geben, oder irgendeine Alternative?
Falls ihr eine Idee habt, lasst mich es bitte wissen!
Schöne Grüße
stargazer
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 169867
Url: https://administrator.de/contentid/169867
Ausgedruckt am: 25.11.2024 um 16:11 Uhr
20 Kommentare
Neuester Kommentar
Hi stargazer,
Also ich bin mir nicht sicher, ob ich dich richtig verstanden habe.
Aber so ein "zufälliges" ändern der Sichtbarkeit von verschiedenen Objekten würde ich schon über ein Array machen, in dem sich die Objekte befinden.
Der Index ist dann zufällig und dadurch kommst du immer wieder an eins deiner Objekte ran.
Dann würde ich halt die Sichtbarkeit des Objektes auf true setzen und vor dem jeweiligen setzen auf true jede Sekunde hingehen und vorher komplett alles auf "false" setzen um den Ausgangszustand zurückzubekommen.
Also nochmal kurzfassung:
Jeder Spalte ein Array aus Blöcken zuweisen.
Alle Blöcke invisible setzen
Arrayindex per Zufall auswählen lassen und auf visible setzen ( du kannst natürlich auch zufällig viele Blöcke sichtbar machen über eine zweite Zufallszahl. Also eine Zufallszahl jeweils für den Index und eine Zufallszahl für die Anzahl der Durchgänge, in denen du einen zufälligen Block sichtbar machst )
Und das machst du einfach durchgehend, solltest aber vor jedem neuen Sichtbarmachen eben vorher alles "resetten".
Ich hoffe ich habe das Problem so halbwegs verstanden.
Wie hast du den Timer hingebogen? Du kannst die interne Klasse Timer benutzen, die dann in einem festgelegten Intervall ein Event "Tick" auslöst. So kannst du z.B. den Intervall auf 1000ms setzen und dann jedesmal deine Logik ausführen lassen.
Grüße
Jens
Also ich bin mir nicht sicher, ob ich dich richtig verstanden habe.
Aber so ein "zufälliges" ändern der Sichtbarkeit von verschiedenen Objekten würde ich schon über ein Array machen, in dem sich die Objekte befinden.
Der Index ist dann zufällig und dadurch kommst du immer wieder an eins deiner Objekte ran.
Dann würde ich halt die Sichtbarkeit des Objektes auf true setzen und vor dem jeweiligen setzen auf true jede Sekunde hingehen und vorher komplett alles auf "false" setzen um den Ausgangszustand zurückzubekommen.
Also nochmal kurzfassung:
Jeder Spalte ein Array aus Blöcken zuweisen.
Alle Blöcke invisible setzen
Arrayindex per Zufall auswählen lassen und auf visible setzen ( du kannst natürlich auch zufällig viele Blöcke sichtbar machen über eine zweite Zufallszahl. Also eine Zufallszahl jeweils für den Index und eine Zufallszahl für die Anzahl der Durchgänge, in denen du einen zufälligen Block sichtbar machst )
Und das machst du einfach durchgehend, solltest aber vor jedem neuen Sichtbarmachen eben vorher alles "resetten".
Ich hoffe ich habe das Problem so halbwegs verstanden.
Wie hast du den Timer hingebogen? Du kannst die interne Klasse Timer benutzen, die dann in einem festgelegten Intervall ein Event "Tick" auslöst. So kannst du z.B. den Intervall auf 1000ms setzen und dann jedesmal deine Logik ausführen lassen.
Grüße
Jens
Okay, alles klar. Ich glaube ich habe grad etwas Langeweile und hab mal nach der Uhr gegooglet.
Ich glaub ich probier das auchmal fix zu implementieren, aber ich werds denke ich statt mit irgendwelchen Buttons oder ähnlichen Dingen direkt mit nem Panel machen, in welches ich zeichne. Falls ich da heute Abend noch was mache und zu was komme, lass ich dich wissen, wie ichs gelöst habe.
Grüße
EDIT (ein paar Denkanstöße):
Anstelle von blanken int-Werten benutze ich lieber Enums.
Hiermit bekomme ich die Anzahl an Punkten, die im jeweiligen Feld dargestellt werden soll.
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
Und schlussendlich die Zeichenmethode. Über das bisschen Mathe um den Index fürs Zeichnen zu berechnen könntest du statt nen Index für die Zeichenmethode auch nen Index für nen Array benutzen.
Ich denke, dass dir das schonmal deutlich weiterhelfen sollte.
Falls du noch Rückfragen hast, dann lass michs wissen.
Grüße
Jens
Ich glaub ich probier das auchmal fix zu implementieren, aber ich werds denke ich statt mit irgendwelchen Buttons oder ähnlichen Dingen direkt mit nem Panel machen, in welches ich zeichne. Falls ich da heute Abend noch was mache und zu was komme, lass ich dich wissen, wie ichs gelöst habe.
Grüße
EDIT (ein paar Denkanstöße):
Anstelle von blanken int-Werten benutze ich lieber Enums.
enum Pos
{
HourFirst,
HourLast,
MinuteFirst,
MinuteLast
}
Hiermit bekomme ich die Anzahl an Punkten, die im jeweiligen Feld dargestellt werden soll.
private int getPointsToDraw(int charOfTime)
{
int pointsToDraw = 0;
switch (charOfTime)
{
case (int)Pos.HourFirst:
pointsToDraw = DateTime.Now.Hour / 10;
break;
case (int)Pos.HourLast:
pointsToDraw = DateTime.Now.Hour % 10;
break;
case (int)Pos.MinuteFirst:
pointsToDraw = DateTime.Now.Minute / 10;
break;
case (int)Pos.MinuteLast:
pointsToDraw = DateTime.Now.Minute % 10;
break;
}
return pointsToDraw;
}
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
private ArrayList randomizePositions(int numberofpositions, int numberofshownrecs)
{
Random rand = new Random(DateTime.Now.Millisecond);
ArrayList positions = new ArrayList();
int tmp = 0;
//get random position(s) for this field
for (int i = 0; i < numberofshownrecs; i++)
{
while (true)
{
tmp = rand.Next(0, numberofpositions);
if (!positions.Contains(tmp))
{
positions.Add(tmp);
break;
}
}
}
return positions;
}
Und schlussendlich die Zeichenmethode. Über das bisschen Mathe um den Index fürs Zeichnen zu berechnen könntest du statt nen Index für die Zeichenmethode auch nen Index für nen Array benutzen.
private void draw()
{
ArrayList positions = new ArrayList();
//fields for first char of hours ( 1*3 field )
positions = randomizePositions(3, getPointsToDraw((int)Pos.HourFirst));
for (int i = 0; i < positions.Count; i++)
{
g.FillRectangle(Brushes.Red, new Rectangle(_HOURSPOS_X,
(int)positions[i] *(_HEIGHT+_PLACEBETWEENITEMS)+_HOURSPOS_Y,
_WIDTH,
_HEIGHT));
}
//fields for the second char ( 3*3 field )
positions = randomizePositions(9, getPointsToDraw((int)Pos.HourLast));
for (int i = 0; i < positions.Count; i++)
{
g.FillRectangle(Brushes.Orange,
new Rectangle(_HOURSPOS_X + (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)),
(int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y,
_WIDTH,
_HEIGHT
));
}
//fields for the third char ( 2*3 field )
positions = randomizePositions(6, getPointsToDraw((int)Pos.MinuteFirst));
for (int i = 0; i < positions.Count; i++)
{
g.FillRectangle(Brushes.Black,
new Rectangle(_HOURSPOS_X + 4 * (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)),
(int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y,
_WIDTH,
_HEIGHT
));
}
//fields for the forth char ( 3*3 field )
positions = randomizePositions(9, getPointsToDraw((int)Pos.MinuteLast));
for (int i = 0; i < positions.Count; i++)
{
g.FillRectangle(Brushes.Blue,
new Rectangle(_HOURSPOS_X + 6 * (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)),
(int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y,
_WIDTH,
_HEIGHT
));
}
}
Ich denke, dass dir das schonmal deutlich weiterhelfen sollte.
Falls du noch Rückfragen hast, dann lass michs wissen.
Grüße
Jens
Ich habe hier mal mein Beispiel fix als *.exe hochgeladen, damit du dir visuell vorstellen kannst, was da passiert:
http://www.file-upload.net/download-3592987/TixClock.exe.html
Grüße
http://www.file-upload.net/download-3592987/TixClock.exe.html
Grüße
Zitat von @stargazer:
Ich gucke zur Zeit nach den arreys, aber hab deren Funktionsweise noch nicht so ganz verstanden. Ich werds einfach mal versuchen,
wenn Fragen aufkommen meld ich mich nochmal :D
Vielen Dank für die Hilfe!
stargazer
Ich gucke zur Zeit nach den arreys, aber hab deren Funktionsweise noch nicht so ganz verstanden. Ich werds einfach mal versuchen,
wenn Fragen aufkommen meld ich mich nochmal :D
Vielen Dank für die Hilfe!
stargazer
Heyho, also schon wieder ich.
Das hat mir jetzt keine Ruhe gelassen xD
Ich zeig dir nochmal eine Möglichkeit, wie man das mit z.B. PictureBoxen machen könnte.
- Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen
- anschließend werden die Positionen wie schon bekannt per Zufall gesetzt ( wie im "alten" Beispiel )
- die draw() Methode oder wie ich sie nannte musst du nun etwas anpassen. Dazu zeige ich dir fix noch ein paar Codefetzen.
Die im Designer erstellten PictureBox(en) in die arrays füllen ( ein Array pro Box )
private void initPictureBoxArrays()
{
hour1 = new PictureBox[3];
hour1 = pictureBox1;
hour1[1] = pictureBox2;
hour1[2] = pictureBox3;
hour2 = new PictureBox[9];
hour2 = pictureBox4;
hour2[1] = pictureBox5;
hour2[2] = pictureBox6;
hour2[3] = pictureBox7;
hour2[4] = pictureBox8;
hour2[5] = pictureBox9;
hour2[6] = pictureBox10;
hour2[7] = pictureBox11;
hour2[8] = pictureBox12;
min1 = new PictureBox[6];
min1 = pictureBox13;
min1[1] = pictureBox14;
min1[2] = pictureBox15;
min1[3] = pictureBox16;
min1[4] = pictureBox17;
min1[5] = pictureBox18;
min2 = new PictureBox[9];
min2 = pictureBox19;
min2[1] = pictureBox20;
min2[2] = pictureBox21;
min2[3] = pictureBox22;
min2[4] = pictureBox23;
min2[5] = pictureBox24;
min2[6] = pictureBox25;
min2[7] = pictureBox26;
min2[8] = pictureBox27;
}
Die resetView() Methode, die dir vor jedem neuen Schritt die default-Ansicht wieder herstellt
Er nimmt sich einfach alle PictureBox-Objekte, die in der Form existieren. Das erspart einiges an Arbeit im Vergleich zum manellen Setzen
private void resetView()
{
foreach (PictureBox pictb in this.Controls.OfType<PictureBox>())
{
pictb.Image = imageDefault;
}
}
Und nun die neue updateView()-Methode ( vorher draw-Methode ). Hier werden nun die Zufallszahlen nichtmehr zur Positionsberechnung ( wie oben ) verwendet, sondern sie geben den Index der PictureBox an, die verändert werden soll
private void updateView()
{
resetView();
ArrayList positions = new ArrayList();
//box1
positions = randomizePositions(3,getPointsToDraw((int)Pos.HourFirst));
for (int i = 0; i < positions.Count; i++)
{
hour1[(int)positions[i]].Image = imageSet;
}
//box2
positions = randomizePositions(9, getPointsToDraw((int)Pos.HourLast));
for (int i = 0; i < positions.Count; i++)
{
hour2[(int)positions[i]].Image = imageSet;
}
//box3
positions = randomizePositions(6, getPointsToDraw((int)Pos.MinuteFirst));
for (int i = 0; i < positions.Count; i++)
{
min1[(int)positions[i]].Image = imageSet;
}
//box4
positions = randomizePositions(9, getPointsToDraw((int)Pos.MinuteLast));
for (int i = 0; i < positions.Count; i++)
{
min2[(int)positions[i]].Image = imageSet;
}
}
Was für dich in dem Zusammenhang vielleicht noch interessant ist wäre wie man ne Bitmap benutzt um sie hier zu benutzen.
Ich habe dazu das Bild ( bmp ) als Ressource eingebunden ( Dann wird sie, wenn gewünscht in die *.exe gepackt und du hast nur eine Datei ).
-> Rechtsklick auf das Projekt -> Eigenschaften -> Ressourcen -> Hinzufügen -> Aus Datei oder so
Anschließend kannst du diese Ressourcen im Code nutzen über "Resources.XXX". Dafür ist es sinnvoll über die using-Direktive die Properties einzubinden. "using PROJEKTNAME.Properties;"
Jetzt kannst du ein Image zum Beispiel so initialisieren:
Image imageSet;
Image imageDefault;
public TixWithImages()
{
InitializeComponent();
imageSet = Resources.set; <<<<<<--------
imageDefault = Resources._default; <<<<<<--------
initPictureBoxArrays();
resetView();
timer.Start();
}
Sohoo, ###e, wenn das Wetter so schlecht ist, dass man mit SAT keinen Empfang hat und dann nach "Beschäftigung" sucht :D
Sorry, falls das schon zu ausführlich war, letzten Endes hast du ja jetzt ein komplett lauffähiges Programm.
Bitteschön,
"Jenna"
EDIT:
Du kannst natürlich statt da nen Image jedesmal zu setzen auch hingehen und die Sichtbarkeit ändern. Also du könntest auch generell überall nur ein Bild anzeigen lassen und dann statt die Bilder zu ändern das Element eben unsichtbar und sichtbar machen. Das wäre ja dann g enau das, was du eigentlich wolltest denke ich mal.
Zitat von @stargazer:
Hi Jenna!
Wow. Erstmal vielen Dank für diesen Code, werds gleich mal ausprobieren und versuchen zu verstehen :D
> - Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
> Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen ^^
Leider wahr. Fange demnächst mit meiner MATSE-Ausbildung an und hoffe, dass ich spätestens dann in der Lage bin sowas zu
schreiben ;)
Ich lese mich mal durch!
Schöne Grüße
stargazer
Hi Jenna!
Wow. Erstmal vielen Dank für diesen Code, werds gleich mal ausprobieren und versuchen zu verstehen :D
> - Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
> Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen ^^
Leider wahr. Fange demnächst mit meiner MATSE-Ausbildung an und hoffe, dass ich spätestens dann in der Lage bin sowas zu
schreiben ;)
Ich lese mich mal durch!
Schöne Grüße
stargazer
Na dann viel Spaß beim Durchlesen <:
Falls Rückfragen bleiben sollten, dann frag einfach.
Eine kurze Rückmeldung über einen Erfolg würde mich auch freuen ( damit man sieht, dass sich die "Arbeit" auch gelohnt hat ) ;)
Auf jeden Fall gern geschehen. Mich würde dennoch interessieren, ob die Lösung mit zweidimensionalen Arrays wirklich leichter und unkomplizierter sein sollte als nen verschieben der Boxen. Die komplette Logik, die man dafür braucht ist imho die gleiche Logik wie bei meinem Vorschlag des Zeichnens im Panel.
Also ein "kleiner" Denkanstoß von "dog" wäre nett, damit ich auch die Trivialität des Vorschlags mit den mehrdimensionalen Arrays verstehe (da ich sie aktuell nicht sehe, da in meinen Augen auch einfache Arrays, wie jetzt hier im zweiten Vorschlag genutzt wesentlich simpler erscheinen )
Das mit den anfangs immer gleichen Zufallszahlen liegt daran, dass es keine "echten" Zufallszahlen sind, sondern eine Zufallszahlensequenz ist, welche mit einem Startwert initialisiert wird. Dazu gibt es aber einiges auf Google glaube ich.
Stichwort "bessere Zufallszahlen C#" oder so. Ich habe leider gerade keine Zeit um mal drüberzugucken, hab doch grad gut was zu tun.
Wenn Beispielsweise der Zufallszahlengenerator mit einer Zeit initialisiert wird und du ohne, dass sich die Zeit ändert mehrfach eine Zufallszahl möchtest, so wird diese immer gleich sein ( wenn ich mich recht erinnere ).
Dass das "Nachbauen" nicht immer hinhaut kann dran liegen, dass deine Variablen anders deklariert sind oder du nur Variablennamen übernimmst, die du vorher nirgends benannt hast.
Wenn du also z.B.:
variable1 = "bla"; schreibst, aber nirgends
String variable1; deklariert hast, dann wirst du einen Fehler bekommen, dass die Variable unbekannt ist oder ähnliches.
Falls ich heute Abend noch Lust haben sollte versuche ich mir deine bisherige Leistung nochmal anzuschauen, ich kann aber nichts versprechen, da ich wie gesagt grad ziemlich was zu tun habe.
Grüße
"Jenna"
Stichwort "bessere Zufallszahlen C#" oder so. Ich habe leider gerade keine Zeit um mal drüberzugucken, hab doch grad gut was zu tun.
Wenn Beispielsweise der Zufallszahlengenerator mit einer Zeit initialisiert wird und du ohne, dass sich die Zeit ändert mehrfach eine Zufallszahl möchtest, so wird diese immer gleich sein ( wenn ich mich recht erinnere ).
Dass das "Nachbauen" nicht immer hinhaut kann dran liegen, dass deine Variablen anders deklariert sind oder du nur Variablennamen übernimmst, die du vorher nirgends benannt hast.
Wenn du also z.B.:
variable1 = "bla"; schreibst, aber nirgends
String variable1; deklariert hast, dann wirst du einen Fehler bekommen, dass die Variable unbekannt ist oder ähnliches.
Falls ich heute Abend noch Lust haben sollte versuche ich mir deine bisherige Leistung nochmal anzuschauen, ich kann aber nichts versprechen, da ich wie gesagt grad ziemlich was zu tun habe.
Grüße
"Jenna"
Ich glaube das Wichtigste überhaupt beim Programmieren ist, dass man vorher schon einen "Plan" hat, wie man was lösen möchte.
Ich würde die ganze Uhr mal in verschiedene Teilprobleme unterteilen:
- Anzahl an Punkten pro Box ermitteln
- Anordnung der Punkte per Zufall setzen
- Event, welches jeweils nach einer Sekunde ausgelöst wird und alles zeichnet.
Wenn du das geschafft hast kannst du dir Gedanken drüber machen, wie konkret du das Lösen möchtest
- Anzahl an Punkten pro Box ermitteln:
Für jede Ziffer der Uhrzeit den Wert bestimmen und mit diesem Wert dann die Anzahl der zu zeichnenden Quadrate in jeder Box festlegen
Hierzu einfach etwas Mathe:
Ist eine Zahl größer als 10 und man möchte wissen wie oft sie vorkommt teilt man durch 10. Getreu dem Motto "radieren wir einfach eine Stelle aus". Da C# beim Teilen von int-Variablen keinen Rest berücksichtigt ist das für uns schonmal gut.
Dadurch wird aus 11 / 10 = 1 oder aus 23 / 10 = 2
Die zweite Ziffer die wir wollen ist der Rest, der und bei dieser Teilung abhanden kommt. Diesen Rest bestimmen wir durch eine Modulu Operation.
Hier wird aus 11 % 10 = 1 Rest >1<
Oder aus 23 % 10 = 2 Rest >3<
Bei der Modulu Operation wird also nur der Rest als Ergebnis eingetragen.
- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der gespeichert ist den Zugriff auf die Position
for (int i = 0 ; i < array.Length ; i++ )
{
PositionDesPunktes = array[i];
}
- Event
TimerObjekt, ich denke, dass das keiner weiteren Klärung bedarf.
Grüße aus dem ( fast leeren ) Büro ^^
Ich würde die ganze Uhr mal in verschiedene Teilprobleme unterteilen:
- Anzahl an Punkten pro Box ermitteln
- Anordnung der Punkte per Zufall setzen
- Event, welches jeweils nach einer Sekunde ausgelöst wird und alles zeichnet.
Wenn du das geschafft hast kannst du dir Gedanken drüber machen, wie konkret du das Lösen möchtest
- Anzahl an Punkten pro Box ermitteln:
Für jede Ziffer der Uhrzeit den Wert bestimmen und mit diesem Wert dann die Anzahl der zu zeichnenden Quadrate in jeder Box festlegen
Hierzu einfach etwas Mathe:
Ist eine Zahl größer als 10 und man möchte wissen wie oft sie vorkommt teilt man durch 10. Getreu dem Motto "radieren wir einfach eine Stelle aus". Da C# beim Teilen von int-Variablen keinen Rest berücksichtigt ist das für uns schonmal gut.
Dadurch wird aus 11 / 10 = 1 oder aus 23 / 10 = 2
Die zweite Ziffer die wir wollen ist der Rest, der und bei dieser Teilung abhanden kommt. Diesen Rest bestimmen wir durch eine Modulu Operation.
Hier wird aus 11 % 10 = 1 Rest >1<
Oder aus 23 % 10 = 2 Rest >3<
Bei der Modulu Operation wird also nur der Rest als Ergebnis eingetragen.
- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der gespeichert ist den Zugriff auf die Position
for (int i = 0 ; i < array.Length ; i++ )
{
PositionDesPunktes = array[i];
}
- Event
TimerObjekt, ich denke, dass das keiner weiteren Klärung bedarf.
Grüße aus dem ( fast leeren ) Büro ^^
Also, wenn ich deinen Code so sehe solltest du zu aller erst wirklich versuchen dich mit grundlegenen Sachen wie der Schleifenprogrammierung auseinanderzusetzen etc.
Du solltest verstehen, dass man anstatt jedes Objekt einzeln zu bennen auch in ein Array ablegen kann und es dort über den Index ansteuern kann, statt über den Namen.
Zu deinem Code:
xaml, hmm. Okay, kenne ich in der Form auch noch nicht, aber grundlegend gibts ja die gleichen Methoden, man muss sie nur finden.
Folgendes:
-Arrays anlegen ( ist wirklich nahezu 1:1 wie ich es gemacht habe, halt.. nein, es ist 1:1 so ). Wo war die Schwierigkeit?
Instanzvariable:
Arrays initialisieren:
Array benutzen:
Also, schau dir das nochmal an.
Ich glaube wirklich, dass man noch mehr Hilfe garnicht geben kann.
Wie g ewohnt, bei Rückfragen einfach Fragen
Du solltest verstehen, dass man anstatt jedes Objekt einzeln zu bennen auch in ein Array ablegen kann und es dort über den Index ansteuern kann, statt über den Namen.
Zu deinem Code:
xaml, hmm. Okay, kenne ich in der Form auch noch nicht, aber grundlegend gibts ja die gleichen Methoden, man muss sie nur finden.
Folgendes:
-Arrays anlegen ( ist wirklich nahezu 1:1 wie ich es gemacht habe, halt.. nein, es ist 1:1 so ). Wo war die Schwierigkeit?
Instanzvariable:
System.Windows.Controls.Image block1,block2,block3,block4;
Arrays initialisieren:
private void initArrays()
{
block1 = new System.Windows.Controls.Image[3];
block1 = Image1x1;
block1[1] = Image1x2;
block1[2] = Image1x3;
block2 = new System.Windows.Controls.Image[9];
//uswusf
}
Array benutzen:
//Einfacher Test für 11:11
int num0 = RandomNumber(1, 4);
int num1 = RandomNumber(1, 10);
int num2 = RandomNumber(1, 6);
int num3 = RandomNumber(1, 10);
// dieser Aufruf ruft das Bild mit Index num0 auf und setzt die Sichtbarkeit
// Ist num0 = 1 wird das Bild mit Index 1 gesetzt etc ( Allerdings musst du dann deine Zufallszahlen
// bei 0 beginnen lassen.
block1[num0].Visibility = Visibility.Visible;
// dieser Aufruf ersetzt alles folgende:
if (num0 == 1)
Image1x1.Visibility = Visibility.Visible;
if (num0 == 2)
Image1x2.Visibility = Visibility.Visible;
if (num0 == 3)
Image1x3.Visibility = Visibility.Visible;
//entsprechend fortfahren, dann kannst du die methoden von mir nutzen und nach und nach einbauen
//die randomizePosition oder wie sie hieß ist dann dafür da, wenn du mehrere Positionen per Zufall bestimmen willst
Also, schau dir das nochmal an.
Ich glaube wirklich, dass man noch mehr Hilfe garnicht geben kann.
Wie g ewohnt, bei Rückfragen einfach Fragen
Zitat von @stargazer:
Hab nun alles so gemacht, wie es Sinn ergibt, es tritt jedoch ein runtime error auf ( Eine nicht behandelte Ausnahme des Typs
"System.NullReferenceException" ist in Tix Clock.exe aufgetreten ), weshalb ich doch die ganze Arrayerstellung in den
Timer versetzt habe. Nun fehlt mir nur noch eine Idee, um die Anzahl der sichtbaren Images für die Stunden festzulegen.
Hab nun alles so gemacht, wie es Sinn ergibt, es tritt jedoch ein runtime error auf ( Eine nicht behandelte Ausnahme des Typs
"System.NullReferenceException" ist in Tix Clock.exe aufgetreten ), weshalb ich doch die ganze Arrayerstellung in den
Timer versetzt habe. Nun fehlt mir nur noch eine Idee, um die Anzahl der sichtbaren Images für die Stunden festzulegen.
Hi,
das mit den Instanzvariablen hatte ich schonmal in einer Antwort erwähnt, dass du das beachten musst. Stichwort "Sichtbarkeit von Variablen"
Definierst du eine Variable in einer Methode, so handelt es sich um eine lokale Variable, die nach Beendigung der Methode entfernt wird und somit nur in der Methode, wo sie definiert wird benutzt werden kann.
Instanzvariablen, also Variablen, die du direkt in der Klasse definierst sind in jeder Methode sichtbar und jede Methode kann den Wert lesen / ändern.
System.NullReferenceException tritt auf, wenn du auf einen Index aus einem Array zugreifst, dem einfach noch nichts zugewiesen ist.
Eine IndexOutOfBoundsException tritt auf, wenn du auf einen Index außerhalb der Arraygrenzen zugreifen willst.
Solltest du allerdings alles durch googlen innerhalb von weniger als 30Sekunden finden.
Die Anzahl der Sichtbaren Images für die Stunden... Habe ich grundlegen auch schon alles erklärt und sogar Methoden geliefert, die genau das tun.
> enum Pos
> {
> HourFirst,
> HourLast,
> MinuteFirst,
> MinuteLast
> }
>
Hiermit bekomme ich die Anzahl an Punkten, die im jeweiligen Feld dargestellt werden soll.
> private int getPointsToDraw(int charOfTime)
> {
> int pointsToDraw = 0;
>
> switch (charOfTime)
> {
> case (int)Pos.HourFirst:
> pointsToDraw = DateTime.Now.Hour / 10;
> break;
> case (int)Pos.HourLast:
> pointsToDraw = DateTime.Now.Hour % 10;
> break;
> case (int)Pos.MinuteFirst:
> pointsToDraw = DateTime.Now.Minute / 10;
> break;
> case (int)Pos.MinuteLast:
> pointsToDraw = DateTime.Now.Minute % 10;
> break;
> }
> return pointsToDraw;
> }
>
Zitat von @Jenna86:
- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der
gespeichert ist den Zugriff auf die Position
- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der
gespeichert ist den Zugriff auf die Position
Zitat von @Jenna86:
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
> private ArrayList randomizePositions(int numberofpositions, int numberofshownrecs)
> {
> Random rand = new Random(DateTime.Now.Millisecond);
> ArrayList positions = new ArrayList();
> int tmp = 0;
>
> //get random position(s) for this field
> for (int i = 0; i < numberofshownrecs; i++)
> {
> while (true)
> {
> tmp = rand.Next(0, numberofpositions);
> if (!positions.Contains(tmp))
> {
> positions.Add(tmp);
> break;
> }
> }
> }
>
> return positions;
> }
>
Wie du die Methode aufrufst und benutzt findest du im Code weiter oben.
Sie bekommt zwei Parameter übergeben. Der erste Parameter gibt an, wieviele Felder eine zufällige Position bekommen sollen und der zweite Parameter gibt an, wieviele Felder zur Auswahl stehen.
Hast du also z.B. eine "2" für die Minuten, wo es "9" mögliche Felder gibt wird dir diese Methode ein Array der Größe "2" zurückgeben mit zwei zufälligen Positionen.
Also der Index 0, für die erste der zwei Zahlen hat z.B. eine "7", also soll der Punkt in Feld 7 gesetzt werden, wobei der zweite Index im Array, also "1" z.B. eine "2" enthält, wodurch dann der zweite Punkt an die Position "2" gezeichnet wird.
Punktnummer = Index --------- Indexinhalt = Position
array -> Position 7 meinethalben
array[1] -> Position 2
array[2] -> Position 5
so als Beispiel...
Das heißt ich habe drei Punkte die ich zeichnen soll ( weil das Array die Größe 3 hat ) und jeden dieser Punkte setze ich auf die Position, auf die das Array am entsprechenden Index "zeigt".
Noch ein Beispiel:
13:59Uhr
Die Methode getPointsToDraw(int charOfTime) wird für jeden Punkt benutzt um zu wissen, wie viele Punkte man für die Zahl zeichnen muss...
Ob ich nun als Parameter das Enum oder eine Zahl benutze ist geschmackssache.
int anzahlPunkteStelle0 = getPointsToDraw(0); liefert eine 1
int anzahlPunkteStelle1 = getPointsToDraw(1);liefert eine 3
Alternativ kannst du auch das Enum benutzen ( zur besseren Lesbarkeit )
int anzahlPunkteStelle0 = getPointsToDraw((int)Pos.HourFirst);
int anzahlPunkteStelle1 = getPointsToDraw((int)Pos.HourLast);
Der erste Name im Enum entspricht der 0, der zweite Name der 1 uswusf...
Grüße
Jenna
Heyho,
es war ja eine schwere Geburt, aber letzten Endes funktioniert es ja schonmal.
Jetzt kannst du ja versuchen noch mehr auf Verständnis zu setzen und dann geht dir das alles auch leichter von der Hand.
Gerne kannst du das Projekt nochmal hochladen, schaut ja optisch schonmal ganz nett aus ( auf Optik habe ich im Vergleich wohl ziemlich 'geschissen' ).
Die Lösung interessiert mich natürlich. Es besteht ja immer die Möglichkeit, dass man noch was lernen kann ( und wenn es durch das "Verbessern" von Code kommt ).
Schön, dass ich dir helfen konnte.
Dann wünsche ich dir viel Spaß mit C#, die Möglichkeiten sind ja quasi unendlich
Grüße
( ein vor lauter Code bald nichts mehr sehen könnender und deshalb gleich Feierabend-machender )
"Jenna"
es war ja eine schwere Geburt, aber letzten Endes funktioniert es ja schonmal.
Jetzt kannst du ja versuchen noch mehr auf Verständnis zu setzen und dann geht dir das alles auch leichter von der Hand.
Gerne kannst du das Projekt nochmal hochladen, schaut ja optisch schonmal ganz nett aus ( auf Optik habe ich im Vergleich wohl ziemlich 'geschissen' ).
Die Lösung interessiert mich natürlich. Es besteht ja immer die Möglichkeit, dass man noch was lernen kann ( und wenn es durch das "Verbessern" von Code kommt ).
Schön, dass ich dir helfen konnte.
Dann wünsche ich dir viel Spaß mit C#, die Möglichkeiten sind ja quasi unendlich
Grüße
( ein vor lauter Code bald nichts mehr sehen könnender und deshalb gleich Feierabend-machender )
"Jenna"