#include <iostream>
#include <vector>
#include <conio.h>
#include <windows.h>
#include <ctime>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
const int WIDTH = 40;
const int HEIGHT = 20;
const char PLAYER_CHAR = '^';
const char BULLET_CHAR = '|';
const char ENEMY_CHAR = 'X';
const char BORDER_CHAR = '#';
const char LASER_CHAR = '-';
const int MAX_ENEMIES = 4;
const int ENEMY_MOVE_DELAY = 500; // Enemy move delay in milliseconds
const int ENEMY_BULLET_DELAY = 2000; // Enemy bullet fire delay in milliseconds
const int LASER_DURATION = 1000; // Laser active duration in milliseconds
struct Bullet {
int x, y;
};
struct Enemy {
int x, y;
bool movingRight;
int lastBulletTime;
};
struct Laser {
int startX, endX;
int activationTime;
};
void drawBorder(std::vector<std::vector<char>>& screenBuffer) {
for (int x = 0; x < WIDTH; ++x) {
screenBuffer[0][x] = BORDER_CHAR;
screenBuffer[HEIGHT - 1][x] = BORDER_CHAR;
}
for (int y = 0; y < HEIGHT; ++y) {
screenBuffer[y][0] = BORDER_CHAR;
screenBuffer[y][WIDTH - 1] = BORDER_CHAR;
}
}
bool check(char c)
{//¼ì²âij¸ö°´¼üÊÇ·ñ°´Ï£¬°´Ï¾͸ıäһϱäÁ¿
if(!KEY_DOWN(c))return true;
else return false;
}
void updateBullets(std::vector<Bullet>& bullets) {
for (auto it = bullets.begin(); it != bullets.end();) {
it->y--;
if (it->y < 1) {
it = bullets.erase(it);
} else {
++it;
}
}
}
void updateEnemyBullets(std::vector<Bullet>& enemyBullets) {
for (auto it = enemyBullets.begin(); it != enemyBullets.end();) {
it->y++;
if (it->y >= HEIGHT - 1) {
it = enemyBullets.erase(it);
} else {
++it;
}
}
}
void updateEnemies(std::vector<Enemy>& enemies, int& lastMoveTime) {
int currentTime = GetTickCount();
if (currentTime - lastMoveTime >= ENEMY_MOVE_DELAY) {
for (auto& e : enemies) {
if (e.movingRight) {
e.x++;
if (e.x >= WIDTH - 2) {
e.movingRight = false;
}
} else {
e.x--;
if (e.x <= 1) {
e.movingRight = true;
}
}
}
lastMoveTime = currentTime;
}
}
void updateEnemyBullets(std::vector<Bullet>& enemyBullets, std::vector<Enemy>& enemies) {
int currentTime = GetTickCount();
for (auto& e : enemies) {
if (currentTime - e.lastBulletTime >= ENEMY_BULLET_DELAY) {
enemyBullets.push_back({e.x, e.y + 1});
e.lastBulletTime = currentTime;
}
}
}
void draw(const std::vector<Bullet>& bullets, const std::vector<Bullet>& enemyBullets, const std::vector<Enemy>& enemies, int playerX, const Laser* laser, std::vector<std::vector<char>>& screenBuffer) {
for (auto& row : screenBuffer) {
std::fill(row.begin(), row.end(), ' ');
}
drawBorder(screenBuffer);
screenBuffer[HEIGHT - 2][playerX] = PLAYER_CHAR;
for (const auto& b : bullets) {
if (b.x >= 0 && b.x < WIDTH && b.y >= 0 && b.y < HEIGHT) {
screenBuffer[b.y][b.x] = BULLET_CHAR;
}
}
for (const auto& eb : enemyBullets) {
if (eb.x >= 0 && eb.x < WIDTH && eb.y >= 0 && eb.y < HEIGHT) {
screenBuffer[eb.y][eb.x] = BULLET_CHAR;
}
}
for (const auto& e : enemies) {
if (e.x >= 0 && e.x < WIDTH && e.y >= 0 && e.y < HEIGHT) {
screenBuffer[e.y][e.x] = ENEMY_CHAR;
}
}
if (laser) {
for (int x = laser->startX; x <= laser->endX; ++x) {
if (x >= 0 && x < WIDTH && HEIGHT - 2 >= 0) {
screenBuffer[HEIGHT - 2][x] = LASER_CHAR;
}
}
}
}
void renderScreen(const std::vector<std::vector<char>>& screenBuffer) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD cursorPos = {0, 0};
SetConsoleCursorPosition(hConsole, cursorPos);
for (const auto& row : screenBuffer) {
std::cout << std::string(row.begin(), row.end()) << std::endl;
}
}
bool checkCollision(const Bullet& bullet, const Enemy& enemy) {
return bullet.x == enemy.x && bullet.y == enemy.y;
}
void removeHitEnemies(std::vector<Enemy>& enemies, std::vector<Bullet>& bullets) {
for (auto it = enemies.begin(); it != enemies.end();) {
bool hit = false;
for (auto bIt = bullets.begin(); bIt != bullets.end();) {
if (checkCollision(*bIt, *it)) {
hit = true;
bIt = bullets.erase(bIt);
break;
} else {
++bIt;
}
}
if (hit) {
it = enemies.erase(it);
} else {
++it;
}
}
}
void removeHitEnemyBullets(std::vector<Bullet>& enemyBullets, int playerX) {
for (auto it = enemyBullets.begin(); it != enemyBullets.end();) {
if (it->y == HEIGHT - 2 && it->x == playerX) {
it = enemyBullets.erase(it);
} else {
++it;
}
}
}
void applyLaser(std::vector<Enemy>& enemies, const Laser& laser) {
for (auto it = enemies.begin(); it != enemies.end();) {
if (it->y == HEIGHT - 2 && it->x >= laser.startX && it->x <= laser.endX) {
it = enemies.erase(it);
} else {
++it;
}
}
}
int main() {
std::vector<Bullet> bullets;
std::vector<Bullet> enemyBullets;
std::vector<Enemy> enemies;
Laser* laser = nullptr;
int playerX = WIDTH / 2;
std::vector<std::vector<char>> screenBuffer(HEIGHT, std::vector<char>(WIDTH, ' '));
time_t lastEnemyTime = time(nullptr);
int lastMoveTime = GetTickCount();
int laserActivationTime = 0;
while (true) {
if (_kbhit()) {
char key = _getch();
if (check('a') && playerX > 1) {
playerX--;
} if (check('d') && playerX < WIDTH - 2) {
playerX++;
} if (check('w')) {
bullets.push_back({playerX, HEIGHT - 3});
} if (check('s')) {
if (laser) delete laser;
laser = new Laser{playerX - 2, playerX + 2, GetTickCount()};
} if (check('q')) {
break;
}
}
updateBullets(bullets);
updateEnemyBullets(enemyBullets);
updateEnemies(enemies, lastMoveTime);
updateEnemyBullets(enemyBullets, enemies);
removeHitEnemies(enemies, bullets);
removeHitEnemyBullets(enemyBullets, playerX);
if (laser) {
applyLaser(enemies, *laser);
if (GetTickCount() - laser->activationTime >= LASER_DURATION) {
delete laser;
laser = nullptr;
}
}
time_t currentTime = time(nullptr);
if (difftime(currentTime, lastEnemyTime) >= 5 && enemies.size() < MAX_ENEMIES) {
enemies.push_back({rand() % (WIDTH - 2) + 1, 1, rand() % 2, GetTickCount()});
lastEnemyTime = currentTime;
}
draw(bullets, enemyBullets, enemies, playerX, laser, screenBuffer);
renderScreen(screenBuffer);
Sleep(100);
}
if (laser) delete laser;
return 0;
}
03-15
1944
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)