计时器与多线程(无聊应试向)

计时器与多线程总结(无聊应试向)

文章目录

  • 计时器与多线程总结(无聊应试向)
    • 一.preparation
    • 二.计时器
      • 1.单线程
        • ①显示一个计时器
        • ②长脚的钟表
      • 2.多线程
        • ①用键盘让你的计时器满地图跑
        • ②逻辑(流程图显示)
    • 三.examples
      • 1.逐步完善一个滚动的小球
        • ①让小球自己从下向上运动,实现边界检测
        • ②实现键盘控制
      • 2.简易山寨低配原始炮台

​ C++要结课考试了 ,接下来会写一系列无聊的应试向blog,在复习的时候顺便写写blog,不过也会力求一些趣味性

一.preparation

​ 后面的程序我都要调用一个自建文件,大家可以自己起个名,我命名为“base.cpp"(#include"base.cpp",记得在用”base.cpp"的时候把base.cpp和你的程序文件放在一个文件夹里面)

//光标移动到指定坐标处
void gotoxy(int x,int y)
{
     
	HANDLE h;//句柄,对象的索引
	COORD c;//结构体,坐标值
	c.X=x;
	c.Y=y;
	h=GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(h,c);
}

//隐藏光标
void hide_cursor()
{
     
	HANDLE	h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor_info;
	GetConsoleCursorInfo(h_GAME,&cursor_info); 
	cursor_info.bVisible=false;					//不显示光标
	SetConsoleCursorInfo(h_GAME,&cursor_info); 
}

//显示光标
void show_cursor()				
{
     
	HANDLE	h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor_info;
	GetConsoleCursorInfo(h_GAME,&cursor_info); 
	cursor_info.bVisible=true;					//显示光标
	SetConsoleCursorInfo(h_GAME,&cursor_info); 
}

//设置文本颜色
void color(int a)
{
     
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}


二.计时器

1.单线程

①显示一个计时器

#include
#include
#include
#include
#include
#include //格式化输出头文件
#include"base.cpp"

using namespace std;
class timing
{
     
private:

    int time_print;//要在屏幕上显示的事件

    clock_t time_update;//记录实时时间的变量
public:
    timing()
    {
     
        time_print=0;
        time_update=clock();//开始计时了
        hide_cursor();//隐藏光标
    }
    void move_clock()
    {
     

        if(clock()-time_update>2000)
        {
     
            gotoxy(10,10);
            ++time_print;
            cout<<setw(3)<<setfill('0')<<time_print;
            time_update=clock();//重新记录当下时间
        }
    }
    void General()//总线程
    {
     
        while(true)
        {
     

            move_clock();
        }

    }
    ~timing()
    {
     
        show_cursor();
    }

};
int main()
{
     

    timing t;
    t.General();
    return 0;
}

②长脚的钟表

#include
#include
#include
#include
#include
#include //格式化输出头文件
#include"base.cpp"

using namespace std;
class timing
{
     
private:

    int time_print;//要在屏幕上显示的事件
    int x,y;
    clock_t time_update;//记录实时时间的变量
public:
    timing()
    {
     
        time_print=0;
        time_update=clock();//开始计时了
        hide_cursor();//隐藏光标
        x=1;
        y=1;
    }
    void move_clock()
    {
     

        if(clock()-time_update>2000)
        {
        gotoxy(x,y);
            cout<<"   ";//先把原先那个地方的清除掉


            ++time_print;
            ++x;
            ++y;
            gotoxy(x,y);
            cout<<setw(3)<<setfill('0')<<time_print;
            time_update=clock();//重新记录当下时间
        }
    }
    void General()//总线程
    {
     
        while(true)
        {
     

            move_clock();
        }

    }
    ~timing()
    {
     
        show_cursor();
    }

};
int main()
{
     

    timing t;
    t.General();
    return 0;
}

2.多线程

①用键盘让你的计时器满地图跑

此处两个线程,一个是计时器,一个是键盘交互

//秒表计时器-多线程(键盘控制)
#include 
#include 
#include 
#include 
#include 
#include "base.cpp"
using namespace std;

class timing
{
     
private:
    clock_t time_update1;//计时器输出的线程
    clock_t time_update2;//键盘控制的线程
    int x,y;//坐标
    int time_print;//输出的时间
public:
    timing()
    {
     
        x=0,y=0;//坐标初始化
        time_update1=clock();
        time_update2=clock();
        hide_cursor();

    }

    void move_clock()
    {
     
        if(clock()-time_update1>1000)
        {
     

            draw();
            ++time_print;
            time_update1=clock();
        }

    }
    void move_keyboard()
    {
     
        if(clock()-time_update2>50)//这里的时间决定了灵敏度
        {
     
            Erase();
            if(GetAsyncKeyState(VK_ESCAPE))exit(0);
            if(GetAsyncKeyState(VK_UP))--y;//注意坐标系y往上坐标变小
            if(GetAsyncKeyState(VK_DOWN))++y;
            if(GetAsyncKeyState(VK_RIGHT))++x;
            if(GetAsyncKeyState(VK_LEFT))--x;
            draw();
            time_update2=clock();
		//注意先擦除再绘制的基本逻辑
        }
    }
    void draw()
    {
     
        gotoxy(x,y);
        cout<<setw(3)<<setfill('0')<<time_print;//格式化输出
    }
    void Erase()
    {
     
        gotoxy(x,y);
        cout<<"   ";

    }
    void General()
    {
     
        while(true)
        {
     
            move_clock();
            move_keyboard();
        }
    }
    ~timing()
    {
     
        show_cursor();
    }
};

int main()
{
     
    timing t;
    t.General();
    return 0;
}

②逻辑(流程图显示)

Created with Raphaël 2.2.0 ... 计时器1 线程1 计时器2 线程2 ... yes no yes no
//这个流程图是typora内置的flowchart语法画的,我画的有点难看┭┮﹏┭┮
//现在发现了一个在线画图神器process on,里面的flowchart流程图可以直接拖拽
//以后我就在那里截图配合我的Picgo图床,真香!

三.examples

1.逐步完善一个滚动的小球

①让小球自己从下向上运动,实现边界检测

//自主运动的小球
#include 
#include 
#include 
#include 
#include 
#include "base.cpp"
using namespace std;

class ball
{
     
private:
    int x,y;//坐标
    clock_t time_update;
public:
    ball()
    {
     
        x=39;
        y=12;//先让小球显示在屏幕中央
        time_update=clock();
        hide_cursor();
    }
    void draw()
    {
     
      gotoxy(x,y);
      cout<<"●";

    }
    void Erase()
    {
     
        gotoxy(x,y);
        cout<<"  ";//小球占两个字符,要cout两个空格

    }
    void move_clock()
    {
     
        if(clock()-time_update>100)//调这个数字可以控制小球的速度
        {
     
            Erase();
            --y;
            if(y<0)
            {
     
                y=12;
            }
            draw();
            time_update=clock();//更新计时器一定不能忘! 否则看到的就是不断闪现的老电视!
        }

    }
    void General()
    {
     
        while(true)
        {
     

            move_clock();
        }
    }
    ~ball()
    {
     
        show_cursor();
    }
};
int main()
{
     
    ball B1;
    B1.General();
    return 0;
}

要注意先擦除后绘制的逻辑!!!

可以多设几个变量实现自由落体的噢!

手残党弱弱提示class 后面的类后面不要加括号,这个习惯老改不掉

②实现键盘控制

//自主运动的小球
#include 
#include 
#include 
#include 
#include 

#include "base.cpp"
using namespace std;

class ball
{
     
private:
    int x,y;//坐标
    int choice;
    clock_t time_update1;
    clock_t time_update2;//第二个线程
public:
    ball()
    {
     
        x=39;
        y=12;//先让小球显示在屏幕中央
        time_update1=clock();
        time_update2=clock();
        hide_cursor();
    }
    void draw()
    {
     
      gotoxy(x,y);
      cout<<"●";

    }
    void Erase()
    {
     
        gotoxy(x,y);
        cout<<"  ";//小球占两个字符,要cout两个空格

    }
    void move_clock()
    {
     
        if(clock()-time_update1>200)//调这个数字可以控制小球的速度
        {
     
            Erase();
            switch(choice)
            {
     

                case 1:--y;if(y<0)y=24;break;
                case 2:++y;if(y>24)y=0;break;
                case 3:--x;if(x<0)x=78;break;
                case 4:++x;if(x>78)x=0;break;
            }
            draw();
            time_update1=clock();//更新计时器一定不能忘! 否则看到的就是不断闪现的老电视!
        }

    }
    void move_keyboard()
    {
     
        if(clock()-time_update2>200)
        {
     
            if(GetAsyncKeyState(VK_ESCAPE))exit(0);
            if(GetAsyncKeyState(VK_UP))choice=1;
            if(GetAsyncKeyState(VK_DOWN))choice=2;
            if(GetAsyncKeyState(VK_LEFT))choice=3;
            if(GetAsyncKeyState(VK_RIGHT))choice=4;
            time_update2=clock();
        }
    }
    void General()
    {
     
        while(true)
        {
     

            move_clock();
            move_keyboard();
        }
    }
    ~ball()
    {
     
        show_cursor();
    }
};
int main()
{
     
    ball B1;
    B1.General();
    return 0;
}

但是这个程序好像按了一下按键小球就停不下来…

而改成上面那个计时器的那种把坐标变换和按键判断放在一个线程里的就没问题,我也不知道为啥

2.简易山寨低配原始炮台

HH是炮台,是●炮弹

#include 
#include 
#include 
#include 
#include 
#include "base.cpp"
using namespace std;
struct S
{
     
    int x;
    int y;
};
class test
{
     
private:
    int x;
    int y;
    clock_t t1,t2,t3;
    list<S> a;
    list<S>::iterator p,p1;
public:
    test()
    {
     
        x=10;
        y=10;
        t1=clock();
        t2=clock();
        t3=clock();
    }
    void draw1(int x,int y)
    {
     
        gotoxy(x,y);
        cout<<"HH";
    }
    void draw2(int x,int y)
    {
     
        gotoxy(x,y);
        cout<<"●";
    }
    void Erase(int x,int y)
    {
     
        gotoxy(x,y);
        cout<<"  ";
    }
    void move1()//炮台
    {
     
        if(clock()-t1>50)
        {
     
            draw1(x,y);
            t1=clock();
        }
    }
    void move2()//键盘
    {
     
        if(clock()-t2>50)
        {
     
            Erase(x,y);
            if(GetAsyncKeyState(VK_ESCAPE))exit(0);
            if(GetAsyncKeyState(VK_UP))--y;
            if(GetAsyncKeyState(VK_DOWN))++y;
            if(GetAsyncKeyState(VK_LEFT))--x;
            if(GetAsyncKeyState(VK_RIGHT))++x;
            if(GetAsyncKeyState(VK_SPACE))
            {
     
                S t;
                t.x=x;
                t.y=y-1;
                a.push_back(t);
            }
            draw1(x,y);
            t2=clock();
        }

    }
    void move3()//炮弹
    {
     
        if(clock()-t3>50)
        {
     
            for(p=a.begin();p!=a.end();)
            {
     
                Erase(p->x,p->y);
                --(p->y);
                if(p->y<0)
                {
     
                    p=a.erase(p);
                }
                else
                {
     
                    draw2(p->x,p->y);
                    ++p;
                }
            }
            t3=clock();
        }
    }
    void move()
    {
     
        while(true)
        {
     
            move1();
            move2();
            move3();
        }
    }
};
int main()
{
     
	test t;
	t.move();
	return 0;
}

​ 此处共三个线程

你可能感兴趣的:(C++入门,多线程)