Click 'N' Slide - Wie soll ich vorgehen ?



  • Hallo!
    Ich möchte ein sogenanntes Click 'N' Slide Spiel programmieren in der Oberflächenprogrammierung im Borland...
    Das ist das Schiebespiel, wo ein Kästchen frei ist und die anderen verschoben werden müssen, um ein fertiges Bild herauzubekommen.

    Nur weiß ich jetzt nicht ganz, wie ich vorgehen soll...
    Soll ich Buttons nehmen oder gibts ne bessere Lösung ?
    Die Fläche beträgt 4x4, und ich möchte kleine Fotostücke einfügen.
    Nur wenn ich lauter Images oder Buttons anordne, ist das glaube ich zu viel Schreibarbeit.
    Könnt ihr mir vielleicht weiterhelfen ?
    Es muss nicht elegenat sein, besser wärs, wenns nicht elegant ist und ich verstehe es anschließend.
    Und wenn ihr Ideen habt, wie würdet ihr es angehen und wie sieht das dann aus ?

    Ich danke im Voraus ! 🙂



  • Du könntest ein einzelnes TImage nehmen und deine Fotostückchen mit Image->Canvas->CopyRect(...) kopieren und dann auch herumschieben.



  • Hallo

    Du kannst auch für jedes Teil ein TImage nehmen, und die TImages verschieben. Dazu must du im Grunde nur den Mouse-Event abfangen und auswerten.

    bis bald
    akari



  • akari schrieb:

    Hallo

    Du kannst auch für jedes Teil ein TImage nehmen, und die TImages verschieben. Dazu must du im Grunde nur den Mouse-Event abfangen und auswerten.

    bis bald
    akari

    Soweit hatte ichs schon, aber habe Schwierigkeiten beim abfangen und auswerten, da meine Methode, die ich machen wollte, so viel Schreibarbeit ist, dass ich es lieber gelassen habe. Da muss es doch eine ganz einfache Methode geben, oder ?

    Nanyuki schrieb:

    Du könntest ein einzelnes TImage nehmen und deine Fotostückchen mit Image->Canvas->CopyRect(...) kopieren und dann auch herumschieben.

    Kann irgendwie das "Canvas" nicht finden... 😞 😕 Was ist das denn ?

    Erstmals danke für die Antworten, vielleicht habt ihr ja noch ne Idee, wies am schnellsten und besten ginge.



  • Hallo

    Soweit hatte ichs schon, aber habe Schwierigkeiten beim abfangen und auswerten, da meine Methode, die ich machen wollte, so viel Schreibarbeit ist, dass ich es lieber gelassen habe. Da muss es doch eine ganz einfache Methode geben, oder ?

    Ja gibt es. Du gibts jedem TImage in die Tag-Eigenschaft einen eindeutigen Wert, anhand du es indentifizieren kannst (Die Urversion des Spiels besteht ja auch aus 15 Kacheln, die von 1 bis 15 durchnummeriert sind). Jetzt weist du allen TImages die selben Mouse-Eventmethode zu und weißt in der Methode welche TImage geklickt wurde (siehe auch FAQ - Komponenten benutzen)

    Kann irgendwie das "Canvas" nicht finden... 😞 😕 Was ist das denn ?

    Cancas ist eine Eigenschaft von TImage vom Typ TCanvas.

    bis bald
    akari



  • Danke.
    Wie funktioniert das genau mit den Tags ?

    Gebe ich zuerst den Images einen Tag Wert (1-16) und tausche diese Werte dann untereinander aus, oder wie geht das genau ?



  • Hallo

    Nein du tauscht nicht die Tags aus, die bleiben bei ihren TImages. Sondern du verschiebst ja die TImages selber und damit die Tags auch.

    bis bald
    akari



  • Ok, danke !
    Habe jetzt versch. Methoden probiert, die jedoch sehr aufwendig sind und auch nicht richtig funktionierten, wie ich es möchte...

    Wie würdet ihr es machen, um möglichst wenig Zeilen schreiben zu müssen ?



  • Hab was gefunden, was ich mal vor Ewigkeiten geschrieben hab.
    Ist allerdings auch nicht so das wahre und auch nur 33.
    Die einzelnen Bilder sind 100
    100px groß.

    Unit1.h

    //---------------------------------------------------------------------------
    
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
       TButton *btnmix;
       void __fastcall btnmixClick(TObject *Sender);
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
       __fastcall TForm1(TComponent* Owner);
      TImage *img[9];
      short frei;
      short bildnr[9];
      void __fastcall ImgClick(TObject *Sender);
      bool __fastcall check();
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    Unit1.cpp

    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include <algorithm>
    #include <jpeg.hpp>
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btnmixClick(TObject *Sender)
    {
       srand(time(NULL));
       TJPEGImage *jpg;
       short x=0,y=0;
       for(short i=0;i<9;i++) bildnr[i]=i+1;
       std::random_shuffle(bildnr,bildnr+9);
       for(short i=0;i<9;i++)
       {
          if(img[i]==NULL) img[i]=new TImage(this);
          img[i]->Visible = true;
          if(bildnr[i]==1)
          {
             img[i]->Visible = false;
             frei=i+1;
          }
          img[i]->Parent = Form1;
          img[i]->OnClick = ImgClick;
          img[i]->Tag = bildnr[i];
          jpg = new TJPEGImage();
          jpg->LoadFromFile(IntToStr(bildnr[i])+".jpg");
          img[i]->Picture->Assign(jpg);
          delete jpg;
          img[i]->Left = x;
          img[i]->Top = y;
          x+=100;
          if(!(x%300))
          {
             y+=100;
             x=0;
          }
       }
    }
    void __fastcall TForm1::ImgClick(TObject *Sender)
    {
       TImage *timg = dynamic_cast <TImage*>(Sender);
       short pos=(timg->Left%300/100)+1*(timg->Top%300/100)*3+1;
       if(((pos-1)/3==(frei-1)/3)&&(pos-1==frei||pos+1==frei)||pos-3==frei||pos+3==frei)
       {
          timg->Left = ((frei-1)*100)%300;
          timg->Top = ((frei-1)/3)*100;
          std::swap(bildnr[frei-1],bildnr[pos-1]);
          frei=pos;
          if(check())
          {
             img[0]->Visible = true;
             Application->MessageBoxA("Geschafft","Nachricht",MB_OK);
          }
       }
    }
    bool __fastcall TForm1::check()
    {
       unsigned co=0;
       while(co<9&&img[co]->Tag==bildnr[co]) co++;
       return co==9;
    }
    


  • Danke, aber das ist mir eindeutig zu hoch, geht das nicht einfacher ?



  • Das geht natürlich einfacher mit etwas mehr Zeilen. 😉



  • Ich möchte es anders machen:

    Ich erzeuge die Buttons ~(Habe ich von einem Lehrer bekommen)~, weiß aber nicht, wie ich sie letztentlich verschieben kann.

    Ich danke für eure Hilfe, hier der Code:

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    TButton *Button[4][4];
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        int left = 10;
    	int top = 10;
    	int width = 100;
    	int height = 100;
    
    	// dynamisch 16 Buttons erzeugen:
    	for (int zeile = 0; zeile < 4; zeile++)
    	{
    		for (int spalte = 0; spalte < 4; spalte++)
    		{
    			// einzelnen Buttons erzeugen:
    			Button[zeile][spalte] = new TButton(Form1);
    			Button[zeile][spalte]->Parent = Form1;
    
    			// Name-Eigenschaft zuweisen
    			Button[zeile][spalte]->Name = "Button" + IntToStr(zeile)  + IntToStr(spalte);
    
    			// Abmessungen und Position vorgeben:
    			Button[zeile][spalte]->Width = width;
    			Button[zeile][spalte]->Left = left + spalte * (width + 2);
    			Button[zeile][spalte]->Height = height;
    			Button[zeile][spalte]->Top = top + zeile * (height + 2);
    
    			// Ereignis-Routine für MouseDownEvent zuweisen:
    			Button[zeile][spalte]->OnMouseDown = Button1MouseDown;
    		}
    	}
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    
    }
    //---------------------------------------------------------------------------
    


  • Schau dir mal den folgenden Link an:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39246.html

    Du mußt die drei Ereignisse OnMouseDown, OnMouseMove und OnMouseUp implementieren und deinen Bedürfnissen anpassen.



  • Das versteh ich irgendwie net.
    Das muss ja irgendwie einfacher gehen, doer nicht ?
    Wie würdet ihr es machen bei meinem Programm ?



  • Und wie kommst du jetzt darauf TButton zu verwenden ?
    Ist etwas schwieriger dort Bilder reinzubekommen.
    Dafür kannst du doch TBitBtn oder TSpeedButton nehmen.



  • Das kann ich ja Nachträglich auch noch machen. Momentan hat eh jeder Button seine eigene Nummer. Wenn ich diese Struktur habe, möchte ich nur den Buttons ein anderes Caption geben...



  • OnMouseDown, OnMouseMove und OnMouseUp brauchst du garnicht.
    Du musst nur deinen Buttons ein OnClick zuweisen.
    Dadrin fragst du ab, ob das "freie Feld" neben dem Button liegt.
    Wenn ja dann setzt du die Position des gedrückten Buttons auf das "freie Feld".



  • Ich komm einfach nicht dahinter, wie das aussehen soll...


Anmelden zum Antworten