easyx滚动条

最近在用easyx做小游戏的时候需要滚动文本来查看历史消息,果断csdn,github,baidu一番,无果,但这点问题怎么能拦住我们大学牲!索性自己搓一个自己能用的就行。

首先,我们需要创建一个绘图窗口并且指定输出文本区域,利用initgraph()能很轻松达成这点:

int main()
{
	initgraph(720, 800, 1);//分别为绘制窗口的宽,高,是否显示控制台窗口,第三个参数为非零即显示
	setbkcolor(WHITE);//设置背景颜色为白色
	cleardevice();//刷新画布(用先前设置的背景颜色予以填充画布)
	setlinecolor(BLACK);//设置画线颜色
	line(0, 500, 720, 500);//随便拉条线设置文字输出区域
    while(1);//防止窗口一闪而过
    return 0;
}

 然后我们需要输出文本,虽然easyx已经自带了outtextxy(),drawtext(),等文字输出函数,但是每次输出都要指定坐标,并且无法删除上一次的输出,会造成字幕重叠,很是麻烦,所以,我们干脆自己构造一个输出函数:

int outputnum=0;//设置一个输出语句y坐标全局变量
int interfacex=720;//设置窗口宽度
int interfacey=800;//设置窗口高度

void display(string text1, int color)//输出,参数分别为待输出语句和颜色
{
	const char *text = text1.c_str();
	if (outputnum >= 500)//如果当前输出语句已经占满画布,删除当前画布所有语句
	{
		outputnum = 0;
		clearrectangle(-1, -1, interfacex, 500);
		setfillcolor(WHITE);
		fillrectangle(-1, -1, interfacex, 500);
	}
	settextstyle(18, 0, "仿宋");
	settextcolor(color);//输出颜色
	outtextxy(8, outputnum, text);//输出语句
	outputnum += 22;
}

很好!我们已经有了一个完美(?)的文本输出函数!然后呢,我们回到最初的目的,滚动输出文本,现在只能文本输出到一定数量全部消失然后重新输出,有问题,大问题。

如果我们需要滚动输出历史文本,那么第一肯定是要储存历史文本,本来是想用链表存取历史语句的,但是后来发现有点杀鸡用牛刀了,一个全局string字符组就能解决:

int num=0;//字符组最大下标控制
string history0[]={""};//储存历史文本
int history1[]=0;//储存历史文本颜色

void savetxt(string text, int color)
{
	const char *text1 = text.c_str();
	if (strlen(text1) >= 78) {//如果语句长度超过当前画布interfacex
		string text3 = text.substr(78);//擦去前段
		string text2 = text.erase(78, strlen(text1) - 78);//擦去后段
		if (num >= 72){
			for (int i = 0; i < 72; i++){//如果字符组装满了,挤掉最前面一条
				history0[i] = history0[i + 1];
				history1[i] = history1[i + 1];
			}
			history0[71] = text2;
			history1[71] = color;
		}
		else {
			history0[num] = text2;
			history1[num] = color;
			num++;//每储存一条,数组下标加1
		}
		savetxt(text3, color);
	}
	else{
		if (num >= 72){
			for (int i = 0; i < 72; i++){
				history0[i] = history0[i + 1];
				history1[i] = history1[i + 1];
			}
			history0[71] = text;
			history1[71] = color;
		}
		else{
			history0[num] = text;
			history1[num] = color;
			num++;
		}
	}
}

很好!我们已经完成了至关重要的一步!储存每一句输出的文本!,现在要做的就是输出它,我个人是当前屏幕输出23排最合适,有需要更改display的outputnum上限即可,然后用一个for循环控制输出这23句话:


int minhis = 0;
int maxhis = minhis + 23;

void output()
{
	int numhis = 0;
	while (1)
	{
		if (num > numhis&&num > 23)//只有在文本大于23句,且有新文本存入的情况下才控制for循环输出下移一位
		{
			numhis = num;
			maxhis++;
			minhis++;
			//if (num == 72)num = 73;
		}
		BeginBatchDraw();
		maxhis = minhis + 23;
		for (int j = minhis; j < maxhis; j++)
			display(history0[j], history1[j]);
		EndBatchDraw();
	}
}

最后,我们需要用用户输入来控制输出文本的前滚或回滚,那么,再构造一个scrolltxt()函数并把输出函数也集成进去吧:

void scrolltxt(){
	ExMessage msg;
	while (1){
		msg = getmessage(EM_MOUSE);
		if (msg.message == WM_MOUSEWHEEL && num > 24){
			if (msg.x > 0 && msg.x < 720 && msg.y < 505 && msg.y > 0 && msg.wheel > 0){
				minhis--;
				if (minhis <= 0) minhis = 0;
				//cout << "maxhis: " << maxhis << " " << "minhis: " << minhis << endl;
			}
			else if (msg.x > 0 && msg.x < 720 && msg.y < 505 && msg.y > 0 && msg.wheel < 0){
				minhis++;
				if (minhis >= 49) minhis = 49;
				if (maxhis >= num) minhis = num - 23;
				//cout << num << endl;
				//cout << "maxhis: " << maxhis << " " << "minhis: " << minhis << endl;
			}
		}
		if (num > numhis&&num > 23)
		{
			numhis = num;
			maxhis++;
			minhis++;
			if (num == 72)num = 73;
		}
		BeginBatchDraw();
		maxhis = minhis + 23;
		for (int j = minhis; j < maxhis; j++)
			display(history0[j], history1[j]);
		EndBatchDraw();
	}
}

 但这样的话我们无法实时输入文本,所以,为了贴合需求,我是把输出与更新文本分成了两个线程并发执行的,在这里我们只完成滚动输出的效果,其余例如把scrolltxt抽象一个控件类型等在这里就不赘述了。我个人的代码如下:

#include "head.h"
#include <easyx.h>
#include <iostream>
using namespace std;

int interfacex = 720;
int interfacey = 650;
int outputnum = 0;
int num=0;
int minhis = 0;
int maxhis = minhis + 23;
string history0[72] = {""};
int history1[72] = {0};

void display(string text1, int color)
{ 
	const char *text = text1.c_str();
	if (outputnum >= 500)
	{
		outputnum = 0;
		clearrectangle(-1, -1, interfacex, 500);
		setfillcolor(WHITE);
		fillrectangle(-1, -1, interfacex, 500);
	}
	settextstyle(18, 0, "仿宋");
	settextcolor(color);
	outtextxy(8, outputnum, text);
	outputnum += 22;
}
void savetxt(string text, int color)
{
	const char *text1 = text.c_str();
	if (strlen(text1) >= 78) {//如果字符长度超过当前画布interfacex
		string text3 = text.substr(78);//擦去前段
		string text2 = text.erase(78, strlen(text1) - 78);//擦去后段
		if (num >= 72)
		{
			for (int i = 0; i < 72; i++)
			{
				history0[i] = history0[i + 1];
				history1[i] = history1[i + 1];
			}
			history0[71] = text2;
			history1[71] = color;
		}
		else {
			history0[num] = text2;
			history1[num] = color;
			num++;
		}
		savetxt(text3, color);
	}
	else
	{
		if (num >= 72)
		{
			for (int i = 0; i < 72; i++)
			{
				history0[i] = history0[i + 1];
				history1[i] = history1[i + 1];
			}
			history0[71] = text;
			history1[71] = color;
		}
		else 
		{
			history0[num] = text;
			history1[num] = color;
			num++;
		}
	}
}
void shuchu()
{
	int numhis=0;
	while (1)
	{
		if (num > numhis&&num > 23)
		{
			numhis = num;
			maxhis++;
			minhis++;
			if (num == 72)num = 73;
		}
		BeginBatchDraw();
		maxhis = minhis + 23;
		for (int j = minhis; j < maxhis; j++)
			display(history0[j], history1[j]);
		EndBatchDraw();
	}
}
void scrolltxt()
{
	ExMessage msg;
	while (1)
	{
		msg = getmessage(EM_MOUSE);
		if (msg.message == WM_MOUSEWHEEL&&num>24)
		{
			if (msg.x > 0 && msg.x < 720 && msg.y < 505 && msg.y > 0 && msg.wheel > 0)
			{
				minhis--;
				if (minhis <=0 ) minhis = 0;
				cout << "maxhis: " << maxhis << " " << "minhis: " << minhis << endl;
			}
			else if (msg.x > 0 && msg.x < 720 && msg.y < 505 && msg.y > 0 && msg.wheel < 0)
			{
				minhis++;
				if (minhis >= 49) minhis = 49;
				if (maxhis >= num) minhis = num-23;
				cout << num << endl;
				cout << "maxhis: " << maxhis << " " << "minhis: " << minhis << endl;
			}
		}
	}
}
int main()
{
	initgraph(720,800,1);
	setbkcolor(WHITE);
	cleardevice();
	setlinecolor(BLACK);
	line(0, 500, 720, 500);
	CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)shuchu,NULL,NULL,NULL);
	for (int i = 0;i < 40; i++)
	{
		string str = to_string(i);
		savetxt(str, RED);
		Sleep(10);
	}
	scrolltxt();
}

以上。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值