Könnte mir mal bitte jemand erläutern, wie ich das machen soll, dass man auch direkt in "mittlere" Navigationspunkte navigieren kann? Die While-schleife läuft ja so schnell durch, dass die Aktion bei jedem Tastendruck mehrmals durchgeführt wird.
Ich hab schon versucht, das ganze mit dem Timer zu lösen, ist aber alles nicht besonders was geworden...
Soo... jetzt wie versprochen dazu was...
Das Problem ist ja, dass du einfach seltener auf Tastendrücke reagieren musst. Du brauchst also eine Möglichkeit, nur auf Tastendrücke zu reagieren, wenn du vorher einige Zeit nicht reagiert hast.
Und weil ich zu faul war mir was neues auszudenken hab ich lediglich ein System was ich immer nutze leicht abgeändert damit es auf dein Game passt:
|
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
|
// *.hpp -------------------------------------------------------------------------
#include <memory>
#define g_Keys Input::_Keycontrol::Instance()
namespace Input
{
class _Keycontrol
{
private:
_Keycontrol(): _TimeDiff(0.0f)
{
memset(_Keys, 0, sizeof (_Keys));
memset(_Oldkeys, 0, sizeof (_Oldkeys));
memset(_TimeElapsed, 0, sizeof (_TimeElapsed));
}
_Keycontrol(const _Keycontrol& _copy)
{}
~_Keycontrol()
{}
const _Keycontrol& operator = (const _Keycontrol& _copy)
{return _copy;}
bool _isActive() const
{return (true);} // Wenn du testen willst, ob das Game im Vordergrund ist muss das hier hin
public:
static _Keycontrol& Instance()
{
static _Keycontrol _instance;
return _instance;
}
void Update(float TimeDiff);
bool KeyPressed(int vKey) const;
bool KeyReleased(int vKey) const;
bool KeyDown(int vKey) const;
bool KeyDownDelayed(int vKey);
private:
bool _Oldkeys[SDLK_LAST];
bool _Keys[SDLK_LAST];
float _TimeElapsed[SDLK_LAST];
float _TimeDiff;
};
};
// *.cpp -------------------------------------------------------------------------
#include "*.hpp"
namespace Input
{
void _Keycontrol::Update(float TimeDiff)
{
_TimeDiff=TimeDiff;
memcpy_s( _Oldkeys, sizeof(_Oldkeys), _Keys, sizeof(_Keys));
for (int i=0; i<SDLK_LAST; ++i)
{
_Keys[i] = g_pFramework->keyDown (i);
if (_Keys[i] && !_Oldkeys[i])
_TimeElapsed[i]=0.1f;
else if (_Keys[i])
_TimeElapsed[i] += _TimeDiff;
}
}
bool _Keycontrol::KeyPressed(int vKey) const
{
if (!_isActive())
return false;
return (_Keys[vKey] && !(_Oldkeys[vKey]));
}
bool _Keycontrol::KeyReleased(int vKey) const
{
if (!_isActive())
return false;
return (!(_Keys[vKey]) && _Oldkeys[vKey]);
}
bool _Keycontrol::KeyDown(int vKey) const
{
if (!_isActive())
return false;
return (_Keys[vKey]);
}
bool _Keycontrol::KeyDownDelayed(int vKey)
{
if (!_isActive())
return false;
if (_Keys[vKey] && (_TimeElapsed[vKey] >=0.1f))
{
_TimeElapsed[vKey]=0.0f;
return true;
}
return false;
}
};
|
Jetzt muss das ganze nur noch mit dem Menu zusammenarbeiten:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
|
void CMenu::show( bool ingame )
{
// ...
while(m_isShowing)
{
g_pFramework->update();
g_Keys.Update(g_pTimer->getElapsed()); // <- das is wichtig, könnte man auch direkt bei CFramework::update() mit integrieren...
|
Nachdem jetzt technisch alles klar ist muss man nur noch die Tastenauswertung vom Menu anpassen:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
|
void CMenu::processEvents()
{
//Nach oben
if(g_Keys.KeyDownDelayed(SDLK_UP)) // <- dieses Schema bei allen Sachen, die verzögert & mehrfach reagieren sollen
// ...
if(g_Keys.KeyReleased(SDLK_RETURN)) // <- dieses (wahlweise auch mit KeyPressed(...) wenn es um nen einmaligen Tastendruck geht
|
Und da ich das alles (mehr oder weniger
) getestet hab kann ich dir jetzt schon sagen, dass nachdem dann das Menu halbwegs passt noch ne Menge Arbeit bei den Aktionen die hinter der Menuwahl stehen zu bewältigen ist