gpt4 book ai didi

c++ - : when we press and hold,程序只做一次怎么办?

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:02 26 4
gpt4 key购买 nike

我正在用 C++ 制作游戏机,但遇到了问题。当我按下 SPACE 时,我游戏中的汽车会跳起来。当我按住键盘时,我的车会跳很多次。我想:当我按住 SPACE 键盘时,我的车只跳一次。

如何做到这一点?

我已经阅读了很多关于 GetAsyncKeyState() 的主题,但我不知道如何在我的游戏中使用它。

  if ( _kbhit() )

{

char key = _getch();

if ((key == 75) && (car.position.x > 2))
{
car.position.x -= 3;
}
else if ((key == 77) && (car.position.x < 24))
{
car.position.x += 3;
}
else if ((key == 32) && (car.position.y > 2))
{
car.position.y -= 5;
}
}

最佳答案

下面我有一个示例软件,它是一种从输入流中“过滤”重复空格字符的可能方法。

这个想法依赖于使用两个线程。

Thrd1 从名为 ssIn 的字符串流中读取数据。 (在您的代码中替换为 cin。)

Thrd1(过滤器)检测并丢弃连续的空格字符,并且只将第一个(多个空格字符)发送到 thrd2。

Thrd2 - 从 thrd1 填充的单个字符缓冲区中读取,thrd1 永远不会看到连续的空格字符。

第二个由一对信号量(不是互斥量)同步。

在我的示例中,为方便起见,我使用了我的 Posix 信号量版本。我不知道您是否有 Posix,但我相信您会很容易地在 Web 上找到许多示例 C++ 信号量,甚至在 SO 中,并且大多数仅使用 C++ 功能。


请注意,这只是 1 个测试……在“j”之后插入了 1,000,000 个空格的字母表。这不是一个彻底的测试。可能还有其他问题需要处理。我已经对输入错误行为进行了严厉的处理。断言将帮助您确定问题。

“thrd2”代表您对这个例子的立足点。 Thrd2 接收过滤后的流。


#include "../../bag/src/dtb_chrono.hh"
using namespace std::chrono_literals; // support suffixes like 100ms, 2s, 30us
using std::chrono::duration_cast;

#include <iostream>
using std::cout, std::flush, std::endl;
//using std::cin;

#include <thread>
using std::thread, std::this_thread::sleep_for;

#include <string>
using std::string;

#include <sstream>
using std::stringstream;

// Posix Process Semaphore, local mode, unnamed, unlocked
#ifndef DTB_PPLSEM_HH
#include "../../bag/src/dtb_pplsem.hh"
using DTB::PPLSem_t;
#endif

// string ops
#ifndef DTB_SOPS_HH
#include "../../bag/src/dtb_sops.hh"
using DTB::SOps_t;
#endif

#include <cassert>



namespace DTB
{
class T946_t
{
public:
int operator()(int argc, char* argv[]) // functor entry
{ return exec(argc, argv); }

private:
// uses compiler provided default ctor and dtor

// Posix Process Semaphore, local mode (unnamed, unshared)
// initial value unlocked
PPLSem_t th1Sem;
PPLSem_t th2Sem;
char kar = '\n';
bool done = false;
size_t m_rdy;

thread* th1;
string th1Log;

thread* th2;
string th2Log;

stringstream ssIn; // debug - replaces cin

stringstream ss1DR; // th1 delay'd report
stringstream ss2DR; // th2 delay'd report

// utilities
SOps_t sops; // string ops - digiComma

int exec(int , char** )
{
// test init: insert a possible user input into ssIn
init_ssIn();

int retVal = 0;
Time_t start_ns = HRClk_t::now();

th1Sem.lock(); // block until threads are ready
th2Sem.lock(); // block

// start ---------vvvvvvvvvvvvvvvvvvv
th1 = new thread(&T946_t::thrd1, this);
assert(nullptr != th1);
while (0 == (m_rdy & 0x01))
std::this_thread::sleep_for(10ms);

// start ---------vvvvvvvvvvvvvvvvvv
th2 = new thread(&T946_t::thrd2, this);
assert(nullptr != th2);
while (0 == (m_rdy & 0x02))
std::this_thread::sleep_for(10ms);

th1Sem.unlock();

// spin wait for threads to complete
while (!done)
{
std::this_thread::sleep_for(100ms);
}

th1->join();
th2->join();
cout << "\n join()'s complete";

auto duration_ns = duration_cast<NS_t>(HRClk_t::now() - start_ns).count();

cout << "\n T901_t::exec() duration "
<< sops.digiComma(duration_ns) << " ns" << endl;

// output the delay'd reports
cout << ss1DR.str() << ss2DR.str() << endl;

return retVal;
}

void init_ssIn()
{
ssIn << "abcdefghij";
for (int i=0; i<1000001; ++i) ssIn << ' ';
std::string::size_type k = ssIn.str().size();
ssIn << "klmnopqrstuvwxyz";
// a..j
cout << "\n ssIn: '" << ssIn.str().substr(0, 10)
<< " ...spaces... " << ssIn.str().substr(k, 16) << "'"
<< "\n ssIn.str().size(): "
<< sops.digiComma(ssIn.str().size()) << endl;
}

void thrd1()
{
uint64_t th1Count = 0;
uint64_t th1Skips = 0;
char lkar = '\0';
m_rdy |= 0x01; // sync msg to main

do {

getNextKar(lkar); // read from input (ssIn or cin)

th1Sem.lock(); // wait for thrd2 to give permission
{
if(' ' == lkar) // current input kar
{
if(' ' == kar) // previous kar
{
// filter out back-to-back space chars
th1Skips += 1;
th1Sem.unlock(); // skip the handshake, no char to send,
// give self permission-to-proceed
continue;
}
}

// else, not a duplicate space
th1Count += 1;
kar = lkar; // write to input of thrd2
th1Log += lkar; // log
lkar = ' ';
}
th2Sem.unlock(); // give thrd2 permission-to-proceed

if (ssIn.eof())
{
done = true;
break;
}

}while(!done);

ss1DR
<< "\n th1Count " << sops.digiComma(th1Count)
<< "\n th1Skips " << sops.digiComma(th1Skips)
<< "\n th1Log " << th1Log
<< "\n thrd1 exit " << endl;
}


// read from ssIn for development
// read from cin for app
void getNextKar(char& lkar)
{
// ssIn >> lkar; // reads 1 char, but skips multiple blank chars
// lkar = ssIn.get(); returns an integer (not a char)
(void)ssIn.get (lkar);

if(ssIn.fail())
{
if(ssIn.eof()) return; // not a fail
assert(0); // harsh exit, might want something gentler
}
}


void thrd2()
{
uint64_t th2Count = 0;
m_rdy |= 0x02; // sync msg to main

do {
th2Sem.lock(); // wait for thrd1 to give permission
char t = kar;
th1Sem.unlock(); // give permission-to-proceed to thrd1

// simulate application - no duplicate spaces from input
th2Log += t;
th2Count += 1;
// end of sim

}while(!done);

ss2DR
<< "\n th2Count " << sops.digiComma(th2Count)
<< "\n th2Log " << th2Log
<< "\n thrd2 exit " << endl;
}

}; // class T946_t

} // namespace DTB


int main(int argc, char* argv[]) { return DTB::T946_t()(argc, argv); }

输出如下:

  ssIn: 'abcdefghij ...spaces... klmnopqrstuvwxyz'
ssIn.str().size(): 1,000,027

join()'s complete
T901_t::exec() duration 120,421,582 ns

th1Count 28
th1Skips 1,000,000
th1Log abcdefghij klmnopqrstuvwxyz
thrd1 exit

th2Count 28
th2Log abcdefghij klmnopqrstuvwxyz
thrd2 exit

100 万个字符输入的持续时间为 120 毫秒。

关于c++ - : when we press and hold,程序只做一次怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55166316/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com