Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

1

11.07.2006, 17:30

Brauche logischen Denkanstoß...

Hallo,

ich habe folgendes Problem:

Will in einem Fenster ein Viereck zeichnen mit zufälliger Farbe und an zufälliger Position. So weit, so gut.

Habe mir dafür eine Klasse geschrieben. Das wichtigste darin sind vier Funktionen: eine um die Farbe zu generieren, eine um die Position zu generieren,eine Funktion-B (egal, was sie macht) und eine um das Viereck zu zeichnen.

Also instnaziere ich in der Zeichenfunktion ein Object der Klasse (brauch ich des überhaut, denn die aufrufenden Funktion ist ja in der selben Klasse) und lasse dann dieses Object die beiden Random-Funktionen aufrufen. Asnchließend zeichne ich mit den gewonnen Daten das Viereck. So weit, so gut.

Nun mein Problem: Wenn der Benutzer auf das Viereck klickt soll eine Funktion-B aufgerufen werden. Habe also die Case-Abfrage in WndProc erweitert um WM_LBUTTONKLICK. Mittels dem Makro MAKEPOINTS wandele ich die Position des Cursors in Koordinaten um. Nun möchte ich diese Curosrdaten mit den Koordinaten des vorhin gezeichneten Vierecks vergleichen. Das Problem scheint zu sein, dass diese Funktion-B ja aber die generierten Koordinaten des Vierecks aus der Randomfunktion nicht kennt.

ALSO: Wie übergebe ich die am besten? (Ist vermutlich total einfach die Lösung, aber ich komm auf keinen grünen Zweig :( ). Zeiger? Parameter?

Wenn ich das ganze blöd erklärt habe und/oder ihr mein Problem nicht kapiert habt, melden dann gibt es weitere Infos.

mfg spacegaier

2

11.07.2006, 17:36

wenn de die funktionen schon in ner klasse hast, kannste ja auch ne membervariable RECT viereck oder wasweisich machen und dann kann jede funktion drauf zugreifen...
oder hab ich das problem misverstanden`?

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

3

11.07.2006, 17:50

Ja, ich poste mal Code (ist nicht das erste mal, dass dieser Code hier auftaucht):

Klasse: Funktion-B = Delete_small_rect();

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class smallrect
{
private:

    RECT    rect_to_draw;

    const static int s_width  = 10;
    const static int s_height = 10;

    int i_mcolor_r;
    int i_mcolor_g;
    int i_mcolor_b;

public:

    void RandomColor();
    
    void CalculateRect();

    static void Draw_small_rect();

    static void Delete_small_rect();
};


die Funktionen dazu:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void smallrect::CalculateRect()
{
    RECT    mainrect;                               //Rect für den Clientbereich

    
    GetClientRect(hWnd,&mainrect);                  //Größe des Clientbereich holen

    
    int i_xPosition = random(0,mainrect.right);     //einen x-Wert aus der Breite des Clientbereich generieren

    int i_yPosition = random(0,mainrect.bottom);    //einen y-Wert aus der Höhe des Clientbereich generieren

    
    rect_to_draw.top        = i_yPosition;
    rect_to_draw.left       = i_xPosition;
    rect_to_draw.bottom     = i_yPosition - s_height;
    rect_to_draw.right      = i_xPosition - s_width;
}

void smallrect::Draw_small_rect()
{
    HDC hDC = GetDC(hWnd);
    
    smallrect s_rc;
    
    s_rc.RandomColor();
    s_rc.CalculateRect();
    
    HBRUSH hBR = CreateSolidBrush(RGB(s_rc.i_mcolor_r,s_rc.i_mcolor_g,s_rc.i_mcolor_b));

    FillRect(hDC,&s_rc.rect_to_draw,hBR);

    DeleteObject(hBR);
    ReleaseDC(hWnd,hDC);
}

void smallrect::Delete_small_rect()
{   
    smallrect s_rc;
    
    POINTS  points = MAKEPOINTS(lParam);

    if(points.x > s_rc.rect_to_draw.left && points.x < s_rc.rect_to_draw.right && points.y > s_rc.rect_to_draw.bottom && points.y > s_rc.rect_to_draw.top)    {
        HDC hDC = GetDC(hWnd);
        RECT rc;
        GetClientRect(hWnd,&rc);
        FillRect(hDC,&rc,CreateSolidBrush(RGB(255,255,255)));
        ReleaseDC(hWnd,hDC);
    }       

}


FEHLER:: In der if-Abfrage der Delete_small_rect()-Funktion, da die Varibeln keine Werte haben.

Delete_small_rect() wird von WndProc aufgerufen.

FRAGE:: Wie kann ich nun am besten die in der Random-Funktion gewonnen Werte an die Delete_small_rect()-Funktion übergeben?

CW_Kovok

Alter Hase

Beiträge: 836

Wohnort: nähe Bonn

Beruf: Schüler

  • Private Nachricht senden

4

11.07.2006, 18:28

wie mein vorredner schon sagte, einfach in der Klasse mitspeichern
Was es alles gibt, das ich nich brauche - Aristoteles

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

5

11.07.2006, 18:41

Also, wenn ich das richtig sehe, legst du in CalculateRect fest, welches Rechteck von deinem smallrect Objekt benutzt werden soll. Diese Berechnung findet in Draw_small_rect implizit statt.

Wenn du auf diese Weise mehrere Quadrate zeichnest, hast du lediglich die letzen Koordinaten noch zur Verfügung, d.h. wenn du direkt nach dem Zeichnen gleich Delete_small_rect aufrufst, und dort die schon berechneten Koordinaten benutzt, wird das letze Rechteck wieder gelöscht.

Das gilt aber nur unter der Voraussetzung, dass du in der Implementation der Draw Methode nicht nochmal eine Instanz der eigenen Klasse anlegst. (das ist in der Tat nicht nötig und allermeistens sogar ungeschickt) Dort kannst du die CalculateRect Methode direkt aufrufen und muss dann natürlich auch das eigene rect_to_draw benutzen.

Wenn du pro smallrect Objekt auch immer nur ein Quadrat zeichnest, kannst du dir auf diese Weise alle Positionen von Quadraten merken und diese dann hinterher auch gezielt wieder löschen, wenn du darauf klickst. Du musst dann nur alle deine smallrects durchsuchen ob die Mausposition im Quadrat liegt und z.B. beim ersten gefundenen die Delete Methode aufrufen.

Also in Pseudocode:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void smallrect::DrawOnce ()
{
  ComputeRect ();
  Draw ();
}

bool smallrect::PointIsInside (int x, int y)
{
  return rect_to_draw.contains (x, y);
}

void OnClick (int x, int y)
{
  for (draw_rect in all_smallrect)
  {
    if (draw_rect.PointIsInside (x, y))
      draw_rect.Erase ();
  }
}


Für jedes Rechteck, dass gezeichnet werden soll, ruft man hier einmal DrawOne auf; im Gegensatz zu einem smallrect, dass bei jedem Draw sein Rechteck neu festlegt. Mit der zweiten Variante ist dein Problem so erstmal nicht zu lösen, ausser du merkst dir dort auch noch alle Quadrate, die du gezeichnet hast (als eigene Objekte), um diese dann hinterher wieder zu löschen.

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

6

11.07.2006, 21:51

verwend in der Delete_small_rect() doch einfach anstatt s_rc.rect_to_draw.left, rect_to_draw.top.
rect_to_draw ist doch ne Membervariable der Klasse und da Delete_small_rect() ne Memberfunktion ist kannst die Variable doch verwenden, auch wenn sie private ist.
Wo liegt also das Problem?

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

7

12.07.2006, 19:47

@ rrklaffehn: Des habe ich noch net so ganz geschnallt. Könntest du (odre jemand anders) des nochmal etwas aufdröseln? Für den Anfang wäre ich sdchon zufrieden, wenn man nur ein Viereck richtig malen und löschen könnte. Später wären dann mehrere schön.

@Stefan L: Stimmt.

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

8

13.07.2006, 12:17

Was genau hast du nicht verstanden?

Wenn du nur ein Rechteck zeichnen/löschen willst musst du eigentlich nur das temporäre smallrect Objekt aus deiner Draw Methode ausbauen. Dann sollte der Rest einfach genug sein.

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

9

13.07.2006, 14:53

Das Problem ist, dass ich in meiner Draw-Methode mittels eines Klassenobjektes meine beiden Random-Funktionen aufrufe -> die Koordinaten und Farben sind nur dem Objekt in dieser Funktion bekannt (oder?). Ich muss diese also irgendwo, irgendwie speichern, um sie der Delete-Funktion mitteilen zu können, damit dieses testen kann, ob man in das Viereck geklickt hat.

Wie mach ich des am besten (erst einmal mit einem Viereck)? Pointer?

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

10

13.07.2006, 16:45

Du machst folgendes (sinngemäß):

C-/C++-Quelltext

1
2
3
4
5
6
7
void smallrect::Draw ()
{
  smallrect temp_rect;
  temp_rect.ComputeRectAndColor (); // Koordinaten in einen anderen smallrect bestimmen


  DrawRect (temp_rect);
}

Sprich, du erzeugst in deiner Draw Methode temporär Koordinaten die du dann zeichnest. Wenn Draw beendet ist, sind die Koordinaten und Farben wieder weg. Ich meine (und einige Andere hier):

C-/C++-Quelltext

1
2
3
4
5
void smallrect::Draw ()
{
  ComputeRectAndColor (); // Koordinaten in diesem smallrect bestimmen

  DrawRect (*this);
}

Wenn du das so machst, ist in dem smallrect Objekt, aus dem du die Draw Methode aufrufst, selbst schon gespeichert, wo das Rechteck liegt. Du muss dir also nur dieses smallrect Objekt merken, um später wieder an die Koordinaten zu kommen.

Der Parameter der DrawRect Methode, die ich benutze, ist nur dazu da, den Unterschied der beiden Implementationen nochmal deutlich zu machen. In "Real-World" ist das nichtmal eine Methode wert.

Noch besser wäre sogar, die ComputeRectAnColor Methode schon im Konstruktor von smallrect zu benutzen, weil es seine Position und Farbe dann nicht mehr ändert, sooft du es auch zeichnest. Für mehrere Rechtecke brauchst du dann eben mehrere smallrect Objekte.

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige