C语言骰子游戏:不使用clear实现单骰子滚动动画
解决方案:局部刷新骰子动画(无需清屏)
不用system("clear")清空整个屏幕,我们可以用ANSI终端控制序列精准控制光标位置,只刷新骰子区域,保留余额、提示等其他界面内容。
核心思路
- 利用ANSI转义序列将光标移回上一个骰子的起始位置
- 覆盖输出新的骰子ASCII图形,实现滚动动画
- 动画结束后固定显示目标骰子
修改后的完整代码
// DICE GAME #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include "rand.h" #define DICE_LINES 5 // 每个骰子占5行 struct user { int bet; int guess; int balance; } user; struct ASCII { char ASCII[60]; } ascii[6]; // 提前初始化骰子ASCII图形,避免重复赋值 void init_dice_ascii() { strcpy(ascii[0].ASCII, "---------\n|\t|\n| O\t|\n|\t|\n---------\n"); strcpy(ascii[1].ASCII, "---------\n|O\t|\n|\t|\n| O|\n---------\n"); strcpy(ascii[2].ASCII, "---------\n|O\t|\n| O |\n| O|\n---------\n"); strcpy(ascii[3].ASCII, "---------\n|O O|\n|\t|\n|O O|\n---------\n"); strcpy(ascii[4].ASCII, "---------\n|O O|\n| O |\n|O O|\n---------\n"); strcpy(ascii[5].ASCII, "---------\n|O O|\n|O O|\n|O O|\n---------\n"); } void dice_animation(int target_guess) { // 循环展示1-6点的骰子滚动动画 for (int i = 0; i < 6; i++) { printf("%s", ascii[i].ASCII); usleep(200000); // 调整为200毫秒,动画更流畅 // ANSI转义:光标向上移动5行,回到当前骰子的起始位置 printf("\033[%dA", DICE_LINES); // 清除当前行到行尾的内容,避免残留字符 for (int j = 0; j < DICE_LINES; j++) { printf("\033[K\n"); } // 再次将光标移回起始行 printf("\033[%dA", DICE_LINES); } // 动画结束,显示目标骰子 printf("******************\n"); printf("%s", ascii[target_guess-1].ASCII); } int _random(int max, int min); int DICE, bet_return, random_return; void error() { if (user.guess < 1 || user.guess > 6) { printf("Your guess should be within 1 to 6\n"); printf("Your guess i.e : %d is INVALID\n", user.guess); } else if (user.bet > user.balance) { printf("Your bet :%d exceeds your balance:%d\n", user.bet, user.balance); } else if (bet_return == 0 || random_return == 0) { exit(0); } else { exit(0); } } void game_logic() { printf("GENERATING A RANDOM NUMBER ......\n"); DICE = _random(6, 0); dice_animation(user.guess); printf("Random Number : %d Your guess : %d\n",DICE,user.guess); if (user.guess == DICE) { user.balance += (user.bet * 3); printf("CORRECT GUESS :+%d\n", user.bet * 3); } else { user.balance -= (user.bet * 3); printf("WRONG GUESS :-%d\n",user.bet * 3); if (user.balance < 0) { printf("CURRENTLY IN DEBT\n"); } } } int main() { init_dice_ascii(); user.balance = 1000; do { printf("-------------------------------------\n"); printf("BALANCE : %d\n", user.balance); printf("Please place a bet:\n"); bet_return = scanf("%d",&user.bet); if (user.bet <= user.balance && bet_return == 1) { printf("Please guess a number from 1 to 6:\n"); random_return = scanf("%d",&user.guess); switch (user.guess) { case 1: case 2: case 3: case 4: case 5: case 6: game_logic(); break; default: error(); continue; break; } } else { error(); continue; } } while (user.balance > 0 && bet_return != 0 && random_return != 0); }
关键修改说明
- 提取骰子初始化函数:把骰子ASCII图形的初始化移到
init_dice_ascii,避免每次调用动画重复执行字符串拷贝 - ANSI光标控制:
\033[%dA:将光标向上移动指定行数(这里是骰子的5行,回到上一个骰子的起始位置)\033[K:清除当前行从光标到末尾的内容,确保旧骰子的残留字符被完全清除
- 优化动画流畅度:把
sleep(1)换成usleep(200000),让动画滚动速度更快更自然 - 修正参数匹配:原代码调用
dice_animation(user.guess)但函数无参数,现在补充target_guess参数保证逻辑正确
内容的提问来源于stack exchange,提问作者IllTime00qw
相关产品推荐
相关产品推荐

