赛车游戏(还会更新)【2】
2026-08-13 10:39:38
发布于:广东
上一个有一点bug,修了一下;
CAR_MAX_X 可根据个人喜好调,越大赛道最大值越大(长度计算公式MAP_HEIGHT * game_hard * 2)
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <windows.h>
#include <ctime>
#include <vector>
#include <cstdio>
using namespace std;
// 常量定义
const int MAP_HEIGHT = 15;
const int MAP_WIDTH = 75;
const int MAX_SPEED = 5;
const int MIN_SPEED = 1;
const int TRACK_LEFT = 2;
const int TRACK_RIGHT = MAP_HEIGHT - 3;
const int CAR_INIT_X = 0; // 赛车初始X位置
const int CAR_MAX_X = 70; // 赛车最右侧边界(可改)
const int RESET_OFFSET = 70; // 每次重置终点线的递减值
// 全局变量
int game_hard = 1;
int carY = MAP_HEIGHT / 2;
int carX = CAR_INIT_X;
int speed = 1;
bool isFinish = false;
int baseEndLineX; // 基础终点线坐标(按公式计算)
int currentEndLineX; // 当前实际终点线坐标(含递减偏移)
int resetCount = 0; // 赛道重置次数
vector<vector<int> > map(MAP_HEIGHT, vector<int>(MAP_WIDTH, 0));
// 高效清屏
void clearScreen() {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = {0, 0};
DWORD written;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
DWORD size = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, ' ', size, coord, &written);
SetConsoleCursorPosition(hConsole, coord);
}
// 光标绘制
void drawChar(int x, int y, char c) {
COORD coord = {(SHORT)x, (SHORT)y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
cout << c;
}
// 计算基础终点线坐标(原始公式)
int calculateBaseEndLineX() {
return CAR_INIT_X + MAP_HEIGHT * game_hard * 2;
}
// 计算当前实际终点线坐标(基础值 - 重置次数×70)
int calculateCurrentEndLineX() {
int endX = baseEndLineX - resetCount * RESET_OFFSET;
// 确保终点线在有效范围内(最小X=10,最大X=CAR_MAX_X-5)
return max(min(endX, CAR_MAX_X - 5), 10);
}
// 初始化/重绘地图(支持终点线递减)
void initMap() {
// 1. 清空地图
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
map[y][x] = 0;
}
}
// 2. 绘制跑道边框(/ 和 -)
for (int x = 0; x < MAP_WIDTH; x++) {
map[TRACK_LEFT][x] = 1;
map[TRACK_RIGHT][x] = 1;
if (x % 3 == 0) map[MAP_HEIGHT-2][x] = 1;
}
// 3. 计算并绘制当前终点线
currentEndLineX = calculateCurrentEndLineX();
map[MAP_HEIGHT/2][currentEndLineX] = 3;
// 4. 生成障碍物(仅在终点线左侧生成)
srand((unsigned int)time(NULL));
int obstacleCount = 5 + game_hard;
for (int i = 0; i < obstacleCount; i++) {
int obsX = rand() % (currentEndLineX - 5) + 5;
int obsY = rand() % (TRACK_RIGHT - TRACK_LEFT - 1) + TRACK_LEFT + 1;
if (!(obsX == carX && obsY == carY)) {
map[obsY][obsX] = 2;
}
}
}
// 绘制完整地图
void drawMap() {
clearScreen();
// 第一步:绘制所有固定物体
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
if (map[y][x] == 1) {
drawChar(x, y, (y == MAP_HEIGHT-2) ? '-' : '/');
}
else if (map[y][x] == 2) {
drawChar(x, y, '#');
}
else if (map[y][x] == 3) {
drawChar(x, y, '|');
}
}
}
// 第二步:绘制赛车
drawChar(carX, carY, '*');
// 绘制游戏信息(显示终点线递减逻辑)
COORD infoCoord = {0, TRACK_RIGHT + 1};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), infoCoord);
cout << "========== 循环竞速赛车(终点线递减) ==========\n"
<< "当前速度:" << speed << " (最大速度:" << MAX_SPEED << ")\n"
<< "控制键:W(上) S(下) A(减速) D(加速) Q(退出)\n"
<< "基础终点线:" << baseEndLineX << " | 重置次数:" << resetCount << " | 递减偏移:" << resetCount * RESET_OFFSET << "\n"
<< "当前终点线:X=" << currentEndLineX << " | 赛车位置:X=" << carX << ", Y=" << carY << "\n"
<< "赛道边框(//-) 赛车(*) 障碍物(#) 终点线:|" << endl;
}
// 赛车移动逻辑(核心:修复to_string错误 + 终点线递减+循环赛道)
void moveCar() {
// 1. 检测是否到达最右侧(X=70)→ 循环重置
if (carX >= CAR_MAX_X) {
resetCount++; // 重置次数+1
carX = CAR_INIT_X; // 赛车移回最左侧(X=0)
initMap(); // 重绘地图(使用新的终点线)
// 修复:用sprintf替代to_string拼接弹窗信息
char resetMsg[256];
sprintf(resetMsg,
"已到达赛道终点!\n重置次数:%d\n新终点线:%d - %d×70 = %d",
resetCount, baseEndLineX, resetCount, currentEndLineX);
MessageBox(NULL, resetMsg, "循环赛道", MB_OK);
return; // 重置后跳过本次移动
}
// 2. 赛车自动向右前进
int newCarX = carX + speed;
if (newCarX <= CAR_MAX_X) {
carX = newCarX;
}
// 3. 检测终点:到达当前终点线即胜利
if (carX >= currentEndLineX) {
isFinish = true;
// 修复:用sprintf替代to_string拼接弹窗信息
char winMsg[256];
sprintf(winMsg,
"恭喜!到达终点!\n最终终点线:X=%d\n总重置次数:%d",
currentEndLineX, resetCount);
MessageBox(NULL, winMsg, "游戏胜利", MB_OK);
exit(0);
}
// 4. 检测碰撞
if (map[carY][carX] == 2) {
speed = 0;
MessageBox(NULL, "撞到障碍物了!速度清零!(按D加速继续)", "提示", MB_OK);
if (carX - 1 >= CAR_INIT_X) {
carX--;
}
}
}
// 手动控制逻辑
void controlCar() {
if (!_kbhit() || isFinish) return;
char key = _getch();
switch (key) {
case 'w': case 'W':
if (carY - 1 > TRACK_LEFT && map[carY - 1][carX] != 2 && map[carY - 1][carX] != 1) {
carY--;
}
break;
case 's': case 'S':
if (carY + 1 < TRACK_RIGHT && map[carY + 1][carX] != 2 && map[carY + 1][carX] != 1) {
carY++;
}
break;
case 'a': case 'A':
speed = max(speed - 1, MIN_SPEED);
break;
case 'd': case 'D':
speed = min(speed + 1, MAX_SPEED);
break;
case 'q': case 'Q':
exit(0);
break;
}
}
int main() {
// 关闭控制台快速编辑模式
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hInput, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE;
SetConsoleMode(hInput, mode);
// 输入难度
while (true) {
cout << "输入游戏难度(1~15):";
if (cin >> game_hard && game_hard >= 1 && game_hard <= 15) {
break;
}
cin.clear();
cin.ignore(1000, '\n');
cout << "请输入1~15之间的有效数字!" << endl;
}
// 初始化基础终点线坐标(仅计算一次)
baseEndLineX = calculateBaseEndLineX();
// 初始化当前终点线坐标
currentEndLineX = calculateCurrentEndLineX();
// 初始化地图
initMap();
// 游戏主循环
while (true) {
drawMap();
controlCar();
moveCar();
Sleep(16);
}
return 0;
}
点赞+关注不迷路
全部评论 1
NBNB!
5天前 来自 广东
0

























有帮助,赞一个