• 飞机打靶-C语言实践笔记


    先上效果图

    然后是完整代码

      1 #include<stdio.h>
      2 #include<conio.h> 
      3 #include<stdlib.h>
      4 #include<time.h>
      5 
      6 //打印飞机上下边框,长度为112,实际长度为110 
      7 void border(){
      8     int i;
      9     for (i = 112; i > 0 ; --i){
     10         printf("*");
     11     }
     12     printf("
    ");
     13 } 
     14 
     15 //产生80以内的靶子 
     16 int target(int judge){
     17     int i;
     18     static int s;
     19     if(!judge){
     20       srand((int)time(0));
     21       s=rand()%80;    
     22     }
     23     printf("*");
     24     for(i=109;i>s;--i){
     25         printf(" ");
     26     }
     27     printf("*");
     28     for(;i>0;--i){
     29         printf(" ");
     30     }
     31     printf("*
    ");
     32     return s;
     33 } 
     34 
     35 //打印含有飞机主体的6行 
     36 int air(int x, int a,int d){
     37     int i,sum;
     38     char t1[15]="    *    ",t2[15]="  * * *  ",
     39         t3[15]=" *  *  * ",t4[15]="    *    ",
     40         t5[15]="  *   *  ",t6[15]=" *      *";
     41     for(i=1;i<=6;++i){
     42         printf("*");
     43         //放缩 
     44         for(sum = 0; sum <= d-a-x;sum++){
     45            printf(" ");
     46         } 
     47         //打印飞机主体 
     48         switch(i){
     49             case 1 :printf("%s",t1);break;
     50             case 2 :printf("%s",t2);break;
     51             case 3 :printf("%s",t3);break;
     52             case 4 :printf("%s",t4);break;
     53             case 5 :printf("%s",t5);break;
     54             case 6 :printf("%s",t6);break;
     55         }
     56         //打印机体后部分空白
     57         for(;100-sum>=0;sum++){
     58            printf(" ");
     59         } 
     60         //结尾
     61         printf("*
    ");     
     62     }
     63     return d-a-x;
     64 } 
     65 
     66 //打印子弹 
     67 void air1(int x, int a,int d,int i){
     68     int sum;
     69     for(;i>0;--i){
     70         printf("*");
     71         //放缩 
     72         for(sum = 0; sum <= d-a-x+4;sum++){
     73            printf(" ");
     74         } 
     75         printf("|");
     76         //打印机体后部分空白
     77         for(;108-sum>=0;sum++){
     78            printf(" ");
     79         } 
     80         //结尾
     81         printf("*
    ");     
     82     }
     83 }
     84 //打印上半部分左右边框 
     85 void bordery1(int w, int s,int i){
     86     int a, b;
     87     for(;i>w-s;--i){
     88         printf("*");
     89         for(b=110;b>0;--b){
     90             printf(" ");
     91         }
     92         printf("*
    ");
     93     }
     94     
     95 }
     96 
     97 //打印下半部分左右边框 
     98 void bordery2(int w, int s){
     99     int i, b;
    100     for(i=w-s;i>0;--i){
    101         printf("*");
    102         for(b=110;b>0;--b){
    103             printf(" ");
    104         }
    105         printf("*
    ");
    106     }
    107 }
    108 int main(){
    109     int x=0,a=0,d=0,w=0,s=0,judge=0,i=20,z,b,y,grade=0;
    110     int control;
    111     while(1){
    112          control = getch();
    113     switch(control){
    114           case 'a':++a;break;
    115           case 'd':++d;break;
    116           case 'w':++w;break;
    117           case 's':++s;break;
    118     }
    119     if(w-s <0){
    120         --s;
    121     }
    122     if(w-s>2){
    123         ++s;
    124     }
    125     if(d-a-x <-1){
    126         --a;
    127     }
    128     if(d-a-x>100){
    129         ++a;
    130     }
    131     system("cls");
    132     border();
    133     judge=target(judge);
    134     bordery1(w,s,i);
    135     air(x,a,d);
    136     bordery2(w,s);
    137     border();
    138     if(control==' '){
    139         b=19;
    140         for(z=20;z>0;--z){
    141             system("cls");
    142             border();
    143             judge=target(judge);
    144             bordery1(w,s,z);
    145             --b;
    146             air1(x,a,d,3);
    147             bordery1(w,s,17-z);
    148             air(x,a,d);
    149             bordery2(w,s);
    150             border();
    151         }
    152         printf("s=%d  机头=%d
    ",104-judge,d-a);
    153         if(104-judge==d-a){
    154             ++grade;
    155             printf("得分:%d
    ",grade);
    156             judge=0;
    157         }
    158     } 
    159     }
    160     
    161 } 

     算法:1.将整个图案分为边框、飞机图案、靶图案、火线几个部分。其中飞机、靶、火线和边框结合为下:

    2.通过d-a-x计算飞机位置(按头部算),然后用这个数值循环画出火线图案。

    3.火线移动是改变火线在整个程序的纵向位置实现的(减少上半部分边框数量,等数量增加下半部分边框数量)。

    未解决问题:屏幕闪烁、随机靶位置可能过界、子弹发射不稳定

    2018/3/13

    部分库函数:

    l system("cls");  // 清屏 头文件#include <stdlib.h>  缺点屏幕闪烁计算时间长

    l rand()// 产生随机数 头文件#include<stdlib.h>因为rand()函数是按指定的顺序来产生整数,因此每次执行上面的语句都打印相同的两个值,所以说C语言的随机并不是真正意义上的随机,有时候也叫伪随机数

    l srandvoid srand(unsigned seed))//生成随机种子  头文件#include<stdlib.h>  随机数发生器的初始化函数。

    产生随机靶子模块解释:

    int target(int judge){
        int i;
        static int s;
        if(!judge){
          srand((int)time(0));
          s=rand()%70;    
        }
        printf("*");
        for(i=109;i>s;--i){
            printf(" ");
        }
        printf("*");
        for(;i>0;--i){
            printf(" ");
        }
        printf("*
    ");
        return s;
    }
    judge=target(judge);

    首次执行函数会产生随机靶子,judge用于接收产生的随机数值,并且在第二次调用函数时判断是否需要再次生成随机靶子(如果靶子被击中则让judge=0(Flase)  ,!Judge(Ture)执行rand函数再次生成随机数)

    添加功能:操作指引和温馨提醒

        int control,control2;
        //向用户介绍,和温馨提示
            printf("
    
    
    
    玩家您好:
      欢迎试玩飞机打靶游戏
    ");
            printf("  按WASD控制飞机方向,空格发射子弹
    
    
    "); 
            printf("温馨提示!
      由于屏幕闪烁严重,不要在夜间或暗处使用");
            printf("
      输入后等待程序响应再输入");
            printf("
    
    
    
    请确认输入方式为英文        (按任意键两次确认)");
            control2 = getch();
        while(control2){

    效果图:

    2018/3/24  补充

    更新--解决屏幕闪烁、靶子不稳定、子弹不真实问题

    #include<stdlib.h>
    #include <stdio.h>  
    #include <windows.h>  
    #include <conio.h> 
    #include "stdafx.h"
    #include <time.h>
    
    // 全局变量
    int width, hight;
    int borderWidth,borderHight;
    int positionX, positionY;
    int target;
    int score;
    
    
    
    //移动光标
    void gotoxy(int x, int y) {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD pos ;
        pos.X = x;
        pos.Y = y;
        SetConsoleCursorPosition(handle, pos);
    }
    
    //隐藏光标
    void HideCursor() {
        CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
        /*
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO CursorInfo;
        GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息  
        CursorInfo.bVisible = false; //隐藏控制台光标  
        SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
        */ 
    }
    
    void borderUD() {
        int i;
        for (i = borderWidth; i > 0; --i) {
            printf("*");
        }
        printf("
    ");
    }
    
    void borderLR() {
        int a, b;
        for (a = hight; a > 0; --a) {
            printf("*");
            for (b = width; b > 0; --b) {
                printf(" ");
            }
            printf("*
    ");
        }
    }
    
    // 生成新靶
    void aim1() {
        srand((int)time(0));
        target = 2 + rand() % (width-3) ;
        if (target > width)
            aim1();
    }
    
    //打印靶子
    void aim() {
        aim1();
        if (target > width)
            aim1();
        int i;
        printf("1");
        for (i = width; i > target+1; --i)
            printf(" ");
        printf("3");
        for (; i > 1; --i)
            printf(" ");
        printf("1
    ");
    }
    
    //打印飞机
    void air() {
        int i,a,b;
        a = width - 3;
        for (i = 0; i < 2; ++i) {
            printf("*");
            for (b = a; b > positionX;--b)
                printf(" ");
            switch (i) {
              case 0 :printf(" 0 "); break;
              case 1 :printf("000"); break;
            }
            for (; b > 0; --b)
                printf(" ");
            printf("*
    ");
        }
    }
    
    void fire() {
        int a, b,i;
        a = positionX - 1, b = hight + 1;
        printf("a");
        for (i = hight; i > 0; --i) {
            gotoxy(a, b);
            printf("2");
            Sleep(50);
            gotoxy(a, b);
            printf(" ");
            --b;
        }
        if (positionX == width - target + 1) {
            printf("a");
            gotoxy(width - target , 1);
            printf(" ");
            aim1();
            ++score;
            Sleep(100);
            gotoxy(width - target , 1);
            printf("3");
        }
    }
    
    
    //改变飞机位置
    void updateWithoutInput() {
        if (_kbhit()) {
            gotoxy(positionX - 2, hight + 2);
            printf("   ");
            gotoxy(positionX - 2, hight + 3);
            printf("   ");
            int a;
            a = _getch();
            if (a == 'a' || a == 'A')
                --positionX;
            if (a == 'd' || a == 'D')
                ++positionX;
            if (positionX <= 3)
                positionX = 3;
            if (positionX >= width - 1)
                positionX = width - 1;
            gotoxy(positionX-2, hight + 2);
            printf(" 0 ");
            gotoxy(positionX-2, hight + 3);
            printf("000");
            if (a == ' ')
                fire();
            //printf("%d %d ", positionX, width - target + 1);
            gotoxy(0, hight + 4);
            printf("
    
    得分:%d", score);
        }
    }
    
    //数据初始化
    void startup() {
        width = 50;
        hight = 20;
        borderWidth = width + 2;
        borderHight = hight + 2;
        target = 0;
        positionY = hight + 1;
        positionX = width / 2;
        HideCursor();
        score = 0;
    }
    
    //画面显示
    void show() {
        startup();
        borderUD();
        aim();
        borderLR();
        air();
        borderUD();
        getchar();
    }
    
    int main() {
        startup();
        show();
        while (1) {
            updateWithoutInput();
        }
        
        return 0;
    }

       屏幕闪烁解决方法:

    飞机、子弹、靶子:利用循环画出最初的游戏画面,然后利用光标移动函数,打印空格覆盖原有图案实现消失。

                                    再次利用光标移动函数,将光标移动到下次需要打印的地方,打印需要图案实现出现。

                                    反复消失、出现、消失、出现。就实现了动画移动效果。

    2018/4/6    完善

                                                                                               

  • 相关阅读:
    PHP将unicode转utf8最简法
    【搬运】systemctl 命令完全指南
    【转】Linux下apache/httpd服务启动与停止
    【转】Apache Digest验证
    Apache安装及配置ssl
    PHP获取某个表与其他表的关联关系算法
    Mysql查看版本,端口命令
    解决Windows下网络原因Composer安装失败问题
    kafka总结
    关于自增加
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/8554914.html
Copyright © 2020-2023  润新知