C++ Odtwarzanie dźwięku po metodzie onMouseMove 6782 18

O temacie

Autor Wonski

Zaczęty 17.09.2015 roku

Wyświetleń 6782

Odpowiedzi 18

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Witam, mam problem z odtwarzaniem dźwięku w programie.
Zanim go przedstawię, polecam się zapoznać się z tym fragmentem kodu:

void __fastcall TForm1::grajMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
        sndPlaySound("wav/moveon_snd.wav", SND_ASYNC);
        graj -> Picture -> LoadFromFile("img/graj_moveon_185x85px.bmp");

        WDF -> Picture -> LoadFromFile("img/WDF_norm_185x85px.bmp");
        sterowanie -> Picture -> LoadFromFile("img/sterowanie_norm_185x85px.bmp");
        nakarmdev -> Picture -> LoadFromFile("img/nakarmdev_norm_185x85px.bmp");
        autor -> Picture -> LoadFromFile("img/autor_norm_185x85px.bmp");
        wyjscie -> Picture -> LoadFromFile("img/wyjscie_norm_185x85px.bmp");
}

Chciałbym by dźwięk odtwarzał się tylko jeden raz po najechaniu myszką na dany image.
Gdy najadę kursorem na dany image to dźwięk odtwarza się prawidłowo. Problem jest natomiast taki, że gdy myszka znajduje się nieruchomo na image to po ruszeniu myszki, dźwięk jest znowu odtwarzany, co nie powinno mieć miejsca.

Pozdrawiam i proszę o rady, jak rozwiązać ten problem.
Dodam, że pracuję w Builderze.
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Może dodaj po prostu zmienną typu bool sprawdzającą, czy dźwięk został odtworzony?

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Jako osobną funkcję?
Stosowanie tego w ciele metody onmove nie ma sensu bo ona wykonuje się od nowa za każdym razem po interakcji kursora z obiektem.
No chyba, że źle Cie zrozumiałem :D

Myślałem wcześniej by dać dać tą instrukcję w if, ale też nie wyszło tak jak chciałem
 


Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer

Wonski
Gry (themodders@telegram)

C++ Odtwarzanie dźwięku po metodzie onMouseMove
#4 2015-09-17, 19:30(Ostatnia zmiana: 2015-09-17, 19:35)
Nie rozumiem...
skoro utworzę zmienną bool w ciele klasy to będzie ona funkcjonowała dla jednego obiektu (tzn, bedzie poprawnie funkcjonowała dla jednego obiektu) a do oskryptowania mam jeszcze 5 innych. No chyba, że mam utworzyć funkcję bool której argumentem będzie wskaźnik na TImage.
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Nie wiem jak wygląda hierarchia klas u ciebie.
Albo w klasie TForm1 zrobisz zmienna bool isPlayed i w metodzie TForm1::grajMouseMove
Cytuj
if (!isPlayed)
{
   sndPlaySound("wav/moveon_snd.wav", SND_ASYNC);
   isPlayed = true;
}
Wtedy muzyka ci się włączy tylko raz na tylko jednym obrazku.
Jeśli chcesz, by dla każdego obrazka, muzyka odtwarza się raz (czyli dla 5 obrazków odtworzysz w sumie 5 razy), to wtedy pomyślimy.
Metoda TForm1::grajMouseMove ma bardzo złą nazwę. Mieszasz nazewnictwo polskie i angielski w nazwie metodzie. Powinna ona być albo po angielsku albo polsku. I nie tylko ona: pisz nazwy albo po polsku albo po angielsku, nigdy nie mieszaj!
Drugi problem w metodzie TForm1::grajMouseMove jest to, że wczytujesz obrazki. Czemu tam, skoro nazwa metody sugeruje, by coś odtwarzała po przesunięciu myszki?
Czy wykorzystujesz gdziekolwiek w tej metodzie następujące parametry TObject *Sender, TShiftState Shift,
      int X, int Y? ;)

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Twój sposób kiepsko działa. Dźwięk odtwarza się po najechaniu na image tylko raz. Ale po ponownym najechaniu już nie.

Nie rozumiem jaki to problem, że w metodzie MouseMove wczytuję obrazy. Chcę by po najechaniu kursora na Image ten zmienił atrybut Picture na inny i odtworzył przy tym dźwięk. Metoda MouseMove jest jedyną sensowną do wykorzystania przy tym zadaniu.

Nie wykorzystuję na razie reszty atrybutów tej metody, nie miałem na razie takiej potrzeby :)
 

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
Nie masz jakiegoś "onMouseEnter" albo "onMouseHover"?
 
Popisuje się ciągle menda jedna...

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
W Builderze 6 nie mam takich eventów dla obiektu klasy TImage. Ale to żadna przeszkoda, nie muszę tego skryptować z poziomu Buildera, choć tak byłoby znacznie wygodniej. Mogę to po prostu zrobić z poziomu notatnika.
Masz jakiś konkretny pomysł?
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
A OnMouseUp i OnMouseDown? W OnMouseUp aktywujesz dźwięk, w OnMouseDown dezaktywujesz. Albo sprawdź kiedy dokładnie wywoływane są metody OnMouseUP i OnMouseDown.

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Adanos
 OnMouseDown to zdarzenie jest wykonywane w trakcie naciśnięcia przycisku myszy
OnMouseUp jest wykonywane w trakcie puszczenia już wciśniętego przycisku myszy

Nie zadziała


Heh
Niby taki prosty problem do rozwiązania a jednak trzeba trochę gimnastyki  :D
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
A masz współrzędne danego obrazka? Jeśli tak, to możesz sprawdzać, czy myszka znajduje się na obrazku czy jest poza.

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Tak, mogę określić położenie Image na formie za pomocą atrybutów Left i Top, choć właśnie tego rozwiązania chciałem uniknąć, bo to jednak jest trochę zachodu.
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
No jest, ale na razie nic mi nie przychodzi innego do głowy.
A ten TObject *Sender nie określa, na jakim obiekcie jest wywołane zdarzenie? Jeśli tak, to wtedy za pomocą TObject *Sender można by było sprawdzić, czy zdarzenie zostało wywołane na obrazku, czy gdzieś indziej.

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Nie wydaje mi się by tak było.
Przecież OnMouseMove to jest metoda a metody nie da się wykonać samej. Metoda musi przecież zostać wywołana przez obiekt tej samej klasy (no chyba, że mamy metodę wirtualną).
Szczerze to nwm do czego służy ten wskaźnik, ale nie wydaje mi się by to był wskaźnik do innego eventu, no bo przecież jest typu TObject, czyli może pasować do praktycznie każdego obiektu z biblioteki vcl.
 


Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
No ale przecież onMouseMove wykonuje się tylko i wyłącznie na obiekcie przez który ta metoda została wywołana, więc po co sprawdzać czy to zdarzenie zostało wywołane na obrazku czy gdziekolwiek indziej?
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Jeśli zdarzenie zostało wywołane po raz pierwszy na obrazku, to chcesz by włączyła się muzyka. Jeśli dalej ruszasz myszką na obrazku, to nie chcesz by się włączała muzyka. Jeśli zmienisz obiekt, wyjdziesz poza obrazek, to zmienną boolowską wyłączysz tak, żeby następny razem jak najedziesz myszką na ten sam obrazek włączyła się znowu muzyka.

Ja to tak widzę.

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer

Wonski
Gry (themodders@telegram)

C++ Odtwarzanie dźwięku po metodzie onMouseMove
#18 2015-09-18, 17:01(Ostatnia zmiana: 2015-09-18, 17:08)
Heh :D

Rozwiązałem problem. Bez gimnastykowania.
Adanos, wykorzystałem Twój warunek z zmienną bool IsPalyed. Jedyne co dodałem to event onmousemove dla formy (głównego okna). W samej metodzie dla formy dodałem instrukcję:
IsPlayed = false;

Dzięki temu, gdy kursor przesunie się poza TImage to automatycznie wejdzie na formę, czyli uruchomi się zdarzenie onMouseMove dla Form1. Samo to zdarzenie ustawi zmienną bool na flase, dzięki czemu warunek if dla image zostanie ponownie aktywowany.
Co więcej, mogę stosować jedną zmienną bool dla wszystkich 6 obiektów TImage.

Ominąłem najczarniejszy scenariusz, gdzie musiałbym zczytywać współrzędne kursora, co byłoby cholernie nieoptymalne.
Czyli okazało się, że to faktycznie jest takie proste na jakie wyglądało.

Dzięki wielkie za pomoc :D

Edit:
W moim programie Image mają niewielkie przerwy między sobą. Problem jest taki, że podczas szybszego ruchu myszką, kursor nie zjeżdża na formę, tylko automatycznie przeskakuje na kolejny image. Co z kolei sprawia, że zmienna IsPlayed się nie resetuje.
Chyba nie obejdzie się bez tablicy zmiennych boolowskich.
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry