[英]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.