[英]Movement of Object in a game in C++
所以我正在为学校项目制作游戏。 你可能对这个很熟悉。 它的打砖块,或用球破坏砖块并被平台偏转的游戏。
目前我被困在一个点上。 我知道如何使用 _getch() 移动我的平台,但是当我放入一个球时,它也在按键上移动。 我无法弄清楚如何在有或没有任何按键的情况下同时运行它。 或者,如果有办法跳过每次按键,直到它被注册。
到目前为止,这是我的代码。 球的运动并不完整,它现在只是一个原型。 任何帮助,将不胜感激。
我正在使用我学校提供的图形库,但您可以使用 C++ 图形库。
#include <iostream>
#include "myconsole.h"
#include "mygraphics.h"
#include <conio.h>
#include <string>
using namespace std;
void rect() {
COLORREF White = RGB(255, 255, 255);
COLORREF Blue = RGB(135, 206, 235);
// x1 y x2 y
myRect(400, 475, 550, 480, Blue, Blue);
_getch();
}
void circle() {
COLORREF Red = RGB(255, 0, 0);
myEllipse(0, 50, 300, 350, Red, Red);
_getch();
}
void moverect() {
COLORREF White = RGB(255, 255, 255);
COLORREF Blue = RGB(135, 206, 235);
char _x;
const char _r = 'd';
const char _l = 'a';
int x1 = 400;
int x2 = 550;
int by1 = 455;
int by2 = 475;
int m = 48;
while (1) {
_x = _getch();
system("cls");
if (_x == _r) {
if (x2 < 970) {
x1 += 10;
x2 += 10;
for (int i = 0; i < 10; i++) {
myRect(x1++, 475, x2++, 480, Blue, Blue);
}
}
else
myRect(x1, 475, x2, 480, Blue, Blue);
}
else if (_x == _l) {
if (x1 > 0) {
x1 -= 10;
x2 -= 10;
for (int i = 0; i < 10; i++) {
myRect(x1--, 475, x2--, 480, Blue, Blue);
}
}
else
myRect(x1, 475, x2, 480, Blue, Blue);
}
myEllipse(463, by1 -= 10, 487, by2 -= 10, White, White);
}
}
int main() {
{
moverect();
return 0;
}
}
由于您似乎正在使用 Windows 和 Microsoft Visual C++ 您可以使用_kbhit()
,它会告诉您是否按下了某个键。 请注意,这不是标准的 C++。
这可能看起来像:
if (_kbhit()) {
_x = _getch();
}
else {
_x = -1;
}
或者,其他人提到了线程,尽管 John 也注意到_getch()
也不是标准的 C++,但我认为介绍线程的一些概念可能会有所帮助。有多种方法可以用线程来做,但我会展示我的想法成为最简单的方法。
首先我们将创建一个 class,这是为了隐藏一个包含最新字符的变量。 我们希望它隐藏,这样当从主线程读取它时,会消耗最新的字符(设置为 -1),这样当我们下一次调用 function 时,如果尚未输入另一个字符,function 将返回 -1。
请注意,如果两个线程同时从一个变量读取和写入,则会发生未定义的行为,因此我们将使用一个原子变量,因为它是在两个线程尝试同时访问它时定义的。 或者互斥体存在,它们速度较慢,但允许锁定和解锁更复杂的类型,以便一次只有一个线程可以访问它们。
class LatestChar {
public:
/// initialize latest character to -1
LatestChar() :
latest_char{ -1 }
{}
/// returns latest character or -1 if there is no latest character
int getLatestChar() {
// get latest character
int temp_latest_char{ latest_char };
// consume latest character (so if this is called again, -1 is returned)
latest_char = -1;
// return latest character
return temp_latest_char;
}
private:
/// equal to latest character or -1 when there is no character to get
///
/// this is atomic because it might be read from the main thread at the same
/// time it is written from the getch thread.
std::atomic_int latest_char;
};
接下来我们需要创建调用_getch()
的线程。 这是一个成员变量,将在构造函数中声明,它将开始运行并获取最新的字符并重复。
class LatestChar {
public:
/// initialize latest character to -1,
/// and starts thread that gets the latest character
LatestChar() :
...,
getch_thread([this] {
while (true) {
latest_char = _getch();
}
})
{}
...
private:
...
/// this thread loops until told to stop, and updates the latest character
std::thread getch_thread;
};
快完成了,我们现在需要在程序结束时重新加入线程,我们将使用另一个原子变量,这次是 boolean,表示一个标志,表示“嘿,我们已经完成获取字符,完成你正在做的事情,然后加入主线程。
请注意,getch 线程只会在读取一个字符后检查这一点,因此当您关闭程序时,您可能需要再输入一个字符,另一种方法是调用 std::terminate() 之类的东西,这将强制停止整个程序,当可以避免时,这可能是不希望的。
我们将在构造函数中将标志初始化为false(确保它在getch线程之前初始化,否则getch线程可能会在设置为false之前检查该值。它们的初始化顺序与它们的顺序相同在 class 定义中声明。),在线程中检查它,并在析构函数中将其设置为 true,然后还调用连接 function,它将等待线程完成并将连接连接回 main。
class LatestChar {
public:
/// initialize latest character to -1, end thread flag to false,
/// and starts thread that gets the latest character
LatestChar() :
...,
end_thread{ false },
getch_thread([this] {
while (!end_thread) {
latest_char = _getch();
}
})
{}
/// sets end thread flag to true and joins getch thread with main thread
~LatestChar() {
end_thread = true;
getch_thread.join();
}
...
private:
...
/// this flag tells the getch thread to stop, like at the end of a program,
/// _getch() will need to receive a character before this is checked
///
/// this is atomic because it might be read from the getch thread at the
/// same time it is written from the main thread.
///
/// make sure this is initialized before the getch thread begins
std::atomic_bool end_thread;
...
};
最后,让我们实例化 class 并调用 function。
// somewhere not in a loop
LatestChar latest_char;
...
// somewhere is a loop
_x = latest_char.getLatestChar();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.