You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中有没有获取键盘按键输入的函数或语句 用于控制终端方块移动

终端方块移动功能实现方案

核心问题:C标准库默认的输入函数为行缓冲模式,必须按下回车才会返回输入结果,无法满足实时控制需求,需要修改终端属性实现无缓冲、无回显的即时按键读取。

实现逻辑

  1. 程序启动时修改终端配置,关闭行缓冲和输入回显,按键按下即可立刻读取
  2. 编写主循环,每轮循环按顺序执行:清屏 → 读取按键 → 更新方块坐标 → 绘制画布 → 帧间隔延迟
  3. 程序退出前恢复终端原始配置,避免终端使用异常
  4. 补充边界校验逻辑,避免方块移出预设的16行24列画布范围

可运行参考代码(Linux/macOS 平台)

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#define ROWS 16
#define COLS 24

// 你原来的宏定义可以保留使用
#define dot ->
#define or ||
#define and &&
#define pointer *

typedef struct Square {
    float x, y;
    float w, h;
    char c;
} Square;

void draw_squares(Square pointer pointer, int);
Square pointer create_square(float, float, float, float, char);
// 新增终端配置相关函数
void set_terminal_mode();
void reset_terminal_mode();
int get_key_press();

int main(void) {
    int square_count = 3;
    Square pointer pointer squares = malloc(sizeof(Square pointer) * square_count);
    squares[0] = create_square(14, 11, 4, 4, '#');
    squares[1] = create_square(8, 6, 4, 3, '@');
    squares[2] = create_square(1, 1, 3, 7, '&');

    // 初始化终端模式
    set_terminal_mode();

    // 主循环,按q退出
    int running = 1;
    while (running) {
        // 清屏
        printf("\033[H\033[2J");

        // 读取按键
        int key = get_key_press();
        Square pointer control_sq = squares[0]; // 控制#号方块
        switch (key) {
            case 'w':
                if (control_sq dot y > 0) control_sq dot y -= 1;
                break;
            case 's':
                if (control_sq dot y + control_sq dot h < ROWS) control_sq dot y += 1;
                break;
            case 'a':
                if (control_sq dot x > 0) control_sq dot x -= 1;
                break;
            case 'd':
                if (control_sq dot x + control_sq dot w < COLS) control_sq dot x += 1;
                break;
            case 'q':
                running = 0;
                break;
        }

        // 绘制画布
        draw_squares(squares, square_count);
        // 控制帧率,约30帧
        usleep(33000);
    }

    // 恢复终端配置
    reset_terminal_mode();

    // 释放内存
    for (int i = 0; i < square_count; i++) {
        free(squares[i]);
    }
    free(squares);

    return 0;
}

void draw_squares(Square pointer pointer squares, int len) {
    for(int y = 0; y < ROWS; ++ y) {
        for(int x = 0; x < COLS; ++ x) {
            char ch = ' ';
            for(int ix = 0; ix < len; ++ ix) {
                Square pointer s = squares[ix];
                if(
                    (s dot x) <= x and (s dot x + s dot w) > x and
                    (s dot y) <= y and (s dot y + s dot h) > y
                ) {
                    ch = s dot c;
                    break;
                }
            }
            putchar(ch);
        }
        putchar('\n');
    }
}

Square pointer create_square(float x, float y, float w, float h, char c) {
    Square pointer sq = malloc(sizeof(Square));
    sq dot x = x;
    sq dot y = y;
    sq dot w = w;
    sq dot h = h;
    sq dot c = c;
    return sq;
}

// 以下为终端操作相关实现
static struct termios orig_termios;

void set_terminal_mode() {
    tcgetattr(STDIN_FILENO, &orig_termios);
    struct termios new_termios = orig_termios;
    new_termios.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
}

void reset_terminal_mode() {
    tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
}

int get_key_press() {
    char c;
    if (read(STDIN_FILENO, &c, 1) == 1) {
        return c;
    }
    return 0;
}

Windows 平台适配说明

将终端相关代码替换为以下内容即可:

  • 头文件引入替换为 #include <conio.h> 和 <windows.h>
  • 删掉set_terminal_mode、reset_terminal_mode、get_key_press函数实现
  • 主循环中读取按键的逻辑替换为:
    int key = 0;
    if (_kbhit()) {
        key = _getch();
    }
    
  • 清屏逻辑替换为 system("cls")
  • 延迟函数替换为 Sleep(33)

内容的提问来源于stack exchange,提问作者Muffinz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 04:09:03