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

ugoessner

Frischling

  • »ugoessner« ist der Autor dieses Themas

Beiträge: 52

Wohnort: Wedemark OT-Mellendorf

Beruf: Systeminformatiker

  • Private Nachricht senden

1

08.05.2016, 16:59

Bild mit der Maus verschieben

Hallo Leute,

ich habe hier ein kleines Progrämchen mit der SDL geschrieben.
Es funktioniert auch.
Das Bild wird oben links in der Ecke angezeigt.

Jetzt will ich das Bild mit der Maus verschieben und das funktioniert nicht.

Hier mal der Quelltext:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<cstdlib>
#include<SDL/SDL.h>
#include<SDL_image.h>
#include<iostream>
#include<memory>

int main(int, char **)
{
    SDL_Surface *Screen=nullptr;
    SDL_Surface *Image=nullptr;
    SDL_Rect *Image_Rect=new SDL_Rect;
    SDL_Rect *Screen_Rect=new SDL_Rect;
    SDL_Rect *BackGround=new SDL_Rect;
    SDL_Event *Event=new SDL_Event;

    bool Run=true;

    atexit(SDL_Quit);

    if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)<0)
    {
        std::cerr << "SDL konnte nicht initialisiert werden: " << SDL_GetError() << std::endl;
    }

    Screen=SDL_SetVideoMode(1280, 720, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);

    if(!Screen)
    {
        std::cerr << "VideoMode konnte nicht gesetzt werden: " << SDL_GetError() << std::endl;
    }

    BackGround->x=0;
    BackGround->y=0;

    Image=IMG_Load("Bilder/face-smile.png");

    if(!Image)
    {
        std::cerr << "Bild konnte nicht geladen werden: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    Image_Rect->w=Image->w;
    Image_Rect->h=Image->h;
    Image_Rect->x=0;
    Image_Rect->y=0;

    while(Run)
    {
        SDL_PollEvent(Event);
        switch(Event->type)
        {
            case SDL_KEYDOWN: switch(static_cast<int>(Event->key.keysym.sym))
            {
                case SDLK_ESCAPE:
                {
                    Run=false;
                } break;
            } break;

            case SDL_MOUSEBUTTONDOWN:;
            {
                if(Event->type==SDL_MOUSEMOTION && Event->button.x>=Image_Rect->x && Event->button.x<=Image->w && Event->button.y>=Image_Rect->y && Event->button.y<=Image_Rect->h+Image_Rect->y)
                {
                    Image_Rect->x+=Event->motion.xrel;
                    Image_Rect->y+=Event->motion.yrel;
                }
            }

            default:;
        }

        Screen_Rect->w=Image->w;
        Screen_Rect->h=Image->h;
        BackGround->w=Screen->w;
        BackGround->h=Screen->h;

        SDL_FillRect(Screen, BackGround, 4294967295);
        SDL_BlitSurface(Image, 0, Screen, Image_Rect);
        SDL_Flip(Screen);
    }

    delete Event;
    delete Image_Rect;
    delete Screen_Rect;
    delete BackGround;

    SDL_Quit();
    SDL_FreeSurface(Image);
    SDL_FreeSurface(Screen);
}


Was läuft da falsch?
#define __miniMAL 0x00

2

08.05.2016, 17:44

Auszug aus deiner if-Bedingungen

C-/C++-Quelltext

1
2
3
... Event->button.x<=Image->w ...
// vs.
... Event->button.y<=Image_Rect->h+Image_Rect->y 


Dürfte zu mindestens mal eine Ursache sein!
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

ugoessner

Frischling

  • »ugoessner« ist der Autor dieses Themas

Beiträge: 52

Wohnort: Wedemark OT-Mellendorf

Beruf: Systeminformatiker

  • Private Nachricht senden

3

08.05.2016, 18:20

Danke schon mal.

Ich hab jetzt button durch motion ersetzt.
Funktioniert aber immer noch nicht.
#define __miniMAL 0x00

4

08.05.2016, 19:32

Ich hab jetzt button durch motion ersetzt.
Funktioniert aber immer noch nicht.

Hört sich jetzt nicht so an, als ob dir dein Fehler bewusst geworden ist.

C-/C++-Quelltext

1
2
3
if(Event->type == SDL_MOUSEMOTION && 
   Event->button.x >= Image_Rect->x && Event->button.x <= Image->w /* <-- da fehlt doch noch was! */ &&
   Event->button.y >= Image_Rect->y && Event->button.y <= Image_Rect->h + Image_Rect->y)
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

ugoessner

Frischling

  • »ugoessner« ist der Autor dieses Themas

Beiträge: 52

Wohnort: Wedemark OT-Mellendorf

Beruf: Systeminformatiker

  • Private Nachricht senden

5

08.05.2016, 19:54

bei Image->w hab ich schon durch Image_Rect->w ersetzt

Hier noch mal der komplette Code:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include<cstdlib>
#include<SDL/SDL.h>
#include<SDL_image.h>
#include<iostream>
#include<memory>

int main(int, char **)
{
    SDL_Surface *Screen=nullptr;
    SDL_Surface *Image=nullptr;
    SDL_Rect *Image_Rect=new SDL_Rect;
    SDL_Rect *Screen_Rect=new SDL_Rect;
    SDL_Rect *Nocheins=new SDL_Rect;
    SDL_Rect *Nochnocheins=new SDL_Rect;
    SDL_Rect *BackGround=new SDL_Rect;
    SDL_Event *Event=new SDL_Event;

    bool Run=true;

    atexit(SDL_Quit);

    if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)<0)
    {
        std::cerr << "SDL konnte nicht initialisiert werden: " << SDL_GetError() << std::endl;
    }

    Screen=SDL_SetVideoMode(1280, 720, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);

    if(!Screen)
    {
        std::cerr << "VideoMode konnte nicht gesetzt werden: " << SDL_GetError() << std::endl;
    }

    BackGround->x=0;
    BackGround->y=0;

    Image=IMG_Load("/home/ugoessner-mint/Dokumente/SDL/Bilder/face-smile.png");

    if(!Image)
    {
        std::cerr << "Bild konnte nicht geladen werden: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    Image_Rect->w=Image->w;
    Image_Rect->h=Image->h;
    Image_Rect->x=0;
    Image_Rect->y=0;

    while(Run)
    {
        SDL_PollEvent(Event);
        switch(Event->type)
        {
            case SDL_KEYDOWN: switch(static_cast<int>(Event->key.keysym.sym))
            {
                case SDLK_ESCAPE:
                {
                    Run=false;
                } break;
            } break;

            case SDL_MOUSEBUTTONDOWN:
            {
                if(Event->type==SDL_MOUSEMOTION &&
                   Event->motion.x>=Image_Rect->x &&
                   Event->motion.x<=Image_Rect->w+Image_Rect->x &&
                   Event->motion.y>=Image_Rect->y &&
                   Event->motion.y<=Image_Rect->h+Image_Rect->y)
                {
                    Image_Rect->x+=Event->motion.xrel;
                    Image_Rect->y+=Event->motion.yrel;
                    std::cout << "stimmt ";
                }

                if(Event->type==SDL_MOUSEBUTTONUP)
                {
                    if(Event->type==SDL_MOUSEBUTTONDOWN)
                    {
                        Run=false;
                    }
                }
            } break;

            default:;
        }

        Nochnocheins->x=500;
        Nochnocheins->y=400;
        Nocheins->x=200;
        Nocheins->y=400;
        Screen_Rect->w=Image->w;
        Screen_Rect->h=Image->h;
        BackGround->w=Screen->w;
        BackGround->h=Screen->h;

        SDL_FillRect(Screen, BackGround, SDL_MapRGBA(Screen->format, 255, 0, 255, 255));
        SDL_BlitSurface(Image, 0, Screen, Nocheins);
        SDL_BlitSurface(Image, 0, Screen, Nochnocheins);
        SDL_BlitSurface(Image, 0, Screen, Image_Rect);
        SDL_Flip(Screen);
    }

    delete Event;
    delete Nocheins;
    delete Nochnocheins;
    delete Image_Rect;
    delete Screen_Rect;
    delete BackGround;

    SDL_Quit();
    SDL_FreeSurface(Image);
    SDL_FreeSurface(Screen);
}
.
Funktioniert immer noch nicht.

Sag mir mal bitte was da noch falsch ist.
Ist bestimmt wieder ganz einfach aber ich komme nicht drauf.
#define __miniMAL 0x00

6

08.05.2016, 20:04

Den einen Fehler hast beseitigt.

Jetzt ist mir noch was aufgefallen

C-/C++-Quelltext

1
2
3
4
5
6
SDL_PollEvent(Event);
switch(Event->type)
{
   case SDL_MOUSEBUTTONDOWN:
   {
      if(Event->type==SDL_MOUSEMOTION && ...


Tritt der Case Fall ein kann die If-Bedingung nie erfüllt werden!
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

7

08.05.2016, 20:06

Wie kann denn das Event SDL_MOUSEMOTION und gleichzeitig SDL_MOUSEBUTTONDOWN sein? Du musst diese beiden Events separat behandeln: Lege dir eine bool-Variable an, welche bei einem Mausdruck/Loslassen auf true/false gesetzt wird.
Zudem gibt es eine Variable, welche die aktuelle Cursorposition enthält.
Bei einer Bewegung nimmst du die Differenz aus der neuen Position und jener gespeicherten Cursorposition und aktualisierst wieder die Positionsvariable. Die Differenz addierst du auf die Bildposition.

Noch etwas: die Objekte musst du nicht mit new/delete verwalten, die lassen sich einfach auf dem automatischen Speicher anlegen (dh. als lokale Variable, ohne new und einem Zeiger, was btw. auch extrem unsicher ist und auf keinen Fall zu empfehlen ist).

ugoessner

Frischling

  • »ugoessner« ist der Autor dieses Themas

Beiträge: 52

Wohnort: Wedemark OT-Mellendorf

Beruf: Systeminformatiker

  • Private Nachricht senden

8

10.05.2016, 18:43

Ich habe jetzt wie folgt geändert:

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
    int CursorPosition_x_alt {0};
    int CursorPosition_y_alt {0};
    int CursorPosition_x_neu {0};
    int CursorPosition_y_neu {0};

            case SDL_MOUSEBUTTONDOWN:
            {
                clicked=true;
                CursorPosition_x_alt=Event->button.x;
                CursorPosition_y_alt=Event->button.y;
            } break;

            case SDL_MOUSEBUTTONUP:
            {
                clicked=false;
            } break;

            case SDL_MOUSEMOTION:
            {
                CursorPosition_x_neu=Event->motion.x;
                CursorPosition_y_neu=Event->motion.y;
            }

            default: break;
        }

        if(clicked)
        {
            if(Event->motion.x>=Image_Rect->x &&
               Event->motion.x<=Image_Rect->w+Image_Rect->x &&
               Event->motion.y>=Image_Rect->y &&
               Event->motion.y<=Image_Rect->h+Image_Rect->y)
            {
                Image_Rect->x+=CursorPosition_x_alt-CursorPosition_x_neu;
                Image_Rect->y+=CursorPosition_y_alt-CursorPosition_y_neu;
            }
        }

        Screen_Rect->w=Image->w;
        Screen_Rect->h=Image->h;
        BackGround->w=Screen->w;
        BackGround->h=Screen->h;

        SDL_FillRect(Screen, BackGround, SDL_MapRGBA(Screen->format, 255, 0, 255, 255));
        SDL_BlitSurface(Image, Image_Rect, Screen, Screen_Rect);
        SDL_Flip(Screen);
    }
Wenn ich das Bild anklicke und ziehe, dann verschwindet es nach einer kurzen Verzögerung aus Bildschirm je nach dem in welche Richtung ich es bewegt habe raus.
Was ist da noch falsch?
#define __miniMAL 0x00

9

10.05.2016, 19:08

Du rechnest mit der Differenz der aktuellen Cursorposition und der Cursorposition, welche beim Klick gegeben war; du musst bei jedem SDL_MOUSEMOTION CursorPosition_alt auf CursorPosition_neu setzen und CursorPosition_neu auf Event->motion und die Differenz von neu und alt auf die Bildposition addieren.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Techel« (10.05.2016, 19:14)


Werbeanzeige