控制台飞机大战:飞机在底部左右移动,按空格开火,敌机从顶部下落,打中就得分。用二维字符画实现,纯标准 C。
1. 游戏世界:字符画
用 20×20 的字符画作为"屏幕":玩家飞机 ^,子弹 |,敌机 *。每帧清屏重绘:
#define W 20
#define H 20
char screen[H][W + 1];
void put(int y, int x, char ch) {
if (y >= 0 && y < H && x >= 0 && x < W) screen[y][x] = ch;
}
void render(void) {
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) printf("%c", screen[y][x]);
printf("\n");
}
}
2. 飞机、子弹与敌机
飞机用横坐标表示,子弹和敌机各一个数组(最多 20 个)。每步:子弹上移、敌机下移、检测碰撞:
int px = W / 2; // 玩家横坐标
int bullets[20], bcnt = 0; // 子弹的 y 坐标(-1 表示空)
int enx[20], eny[20], ecnt = 0;
void update(void) {
for (int i = 0; i < bcnt; i++) bullets[i]--;
for (int i = 0; i < ecnt; i++) {
eny[i]++;
for (int j = 0; j < bcnt; j++)
if (bullets[j] == eny[i] && j < 20) {
// 命中:清除子弹和敌机
}
}
}
3. 完整代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define W 20
#define H 20
char screen[H][W + 1];
int px = W / 2;
int bullets[20], bcnt = 0;
int enx[20], eny[20], ecnt = 0;
int score = 0, lives = 3;
void put(int y, int x, char ch) {
if (y >= 0 && y < H && x >= 0 && x < W) screen[y][x] = ch;
}
void render(void) {
system("clear"); // Windows: system("cls")
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) printf("%c", screen[y][x]);
printf("\n");
}
printf("得分 %d 生命 %d a左 d右 空格开火 q退出\n", score, lives);
}
void spawn_enemy(void) {
if (ecnt < 20 && (rand() % 3 == 0)) {
enx[ecnt] = rand() % W;
eny[ecnt] = 0;
ecnt++;
}
}
int main(void) {
srand((unsigned)time(NULL));
char key;
while (lives > 0) {
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) screen[y][x] = ' ';
screen[y][W] = '\0';
}
render();
scanf(" %c", &key);
if (key == 'q') break;
if (key == 'a' && px > 0) px--;
if (key == 'd' && px < W - 1) px++;
if (key == ' ') { if (bcnt < 20) bullets[bcnt++] = H - 2; }
for (int i = 0; i < bcnt; i++) bullets[i]--;
spawn_enemy();
for (int i = 0; i < ecnt; i++) eny[i]++;
for (int i = 0; i < ecnt; i++)
if (eny[i] >= H) { eny[i] = enx[i] = -1; lives--; }
for (int i = 0; i < ecnt; i++) {
for (int j = 0; j < bcnt; j++) {
if (bullets[j] >= 0 && bullets[j] == eny[i] && enx[i] >= 0) {
score += 10;
bullets[j] = -1;
enx[i] = eny[i] = -1;
break;
}
}
}
// 碰撞:敌机到玩家行
for (int i = 0; i < ecnt; i++)
if (eny[i] == H - 1 && enx[i] == px) { enx[i] = eny[i] = -1; lives--; }
put(H - 1, px, '^');
for (int i = 0; i < bcnt; i++)
if (bullets[i] >= 0) put(bullets[i], px + 0, '|');
for (int i = 0; i < ecnt; i++)
if (enx[i] >= 0 && eny[i] >= 0) put(eny[i], enx[i], '*');
}
printf("游戏结束,得分: %d\n", score);
return 0;
}
4. 运行与常见问题
保存为 plane.c,编译运行。常见问题:①敌机叠在一起——生成时检查是否已有敌机占位;②子弹打不到敌机——子弹从 H-2 出发,敌机坐标要匹配;③子弹越界——坐标减到负数后不再绘制。
💡 改进方向:①敌机自动左右移动;②多种敌机类型;③双发/连发子弹;④爆炸动画;⑤关卡速度提升。