Linux终端图形库编程
/*
*drawWin.c
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/times.h>
#include<sys/types.h>
#include<unistd.h>
#include<ncurses.h> #define TBool int
#define True 1
#define False 0
#define SHAPE_FOOD '@' //food type
#define SHAPE_SNAKE '#' //snake body
#define GAMEWIN_YLEN 20
#define GAMEWIN_XLEN 60
#define LOGWIN_YLEN 7
#define LOGWIN_XLEN (GAMEWIN_XLEN)
#define LOGBUF_NUM (LOGWIN_YLEN - 2)
#define LOGBUF_LEN (GAMEWIN_XLEN - 2)
#define MAXLEVEL 12 #define GetSnakeTail(s) ((s)->head->front) WINDOW *logwin; //declare a windows for displaying message
#define INITRUNLOG() logwin = newlogw()
#define RUNLOG(str) runlog(logwin, str)
#define DESTROYRUNLOG() delwin(logwin) int g_level; //level of player WINDOW* newgamew();
WINDOW* newlogw();
void runlog(WINDOW* win, char *str);
void cleanline(WINDOW *win, int y, int x); int main()
{
initscr(); //初始化,进入ncurses模式
raw(); //禁止行缓冲,可以立刻见到结果
noecho(); //不在终端上显示控制字符,比如Ctrl+c
keypad(stdscr, TRUE); //运行用户在终端上使用键盘
curs_set(); //设置光标是否可见,0不可见,1可见,2完全可见
refresh(); //将虚拟屏幕上的内容写到显示屏上,并刷新 g_level = ;
INITRUNLOG(); //创建log窗口,就是就是调用自定义函数newlogw() //打印游戏提示
RUNLOG(" press 'q' or 'Q' to quit.");
RUNLOG(" press 'w/s/a/d' or 'W/S/A/D' to move the snake.");
RUNLOG("info:"); WINDOW *gwin = newgamew(); //创建游戏窗口,具体由自定义函数newgamew()实现 mvwprintw(gwin, GAMEWIN_YLEN/, GAMEWIN_YLEN/, "%s", "hello world");
wrefresh(gwin); getch(); //getch()和getchar()不一样 delwin(gwin); //清除游戏窗口,并释放存储窗口数据结构的内存和信息
DESTROYRUNLOG(); //清除信息展示窗口
endwin(); //退出ncurses模式 return ;
} WINDOW* newlogw()
{
//参数依次定义窗口的高,宽,起始位置(y,x)
WINDOW *win = newwin(LOGWIN_YLEN, LOGWIN_XLEN, GAMEWIN_YLEN + , ); //参数依次为:已知的窗口指针, (0,0)是字符莫瑞诺的行列起始位置
box(win, , );
mvwprintw(win, , , " LOG ");
wrefresh(win); //刷新指定的窗口 return win;
} WINDOW *newgamew()
{
WINDOW *win = newwin(GAMEWIN_YLEN, GAMEWIN_XLEN, , );
box(win, , );
mvwprintw(win, , , " GAME ");
mvwprintw(win, GAMEWIN_YLEN - , , " Level: %d ", g_level);
mvwprintw(win, GAMEWIN_YLEN - , , " Speed: %d ", (int)(g_level/));
wrefresh(win);
return win;
} void runlog(WINDOW *win, char *str)
{
static char logbuf[LOGBUF_NUM][LOGBUF_LEN] = {};
static int index = ;
strcpy(logbuf[index], str); int i = ; for (; i < LOGBUF_NUM; ++i)
{
cleanline(win, i+, );
mvwprintw(win, i+, , logbuf[(index + i) % LOGBUF_NUM]);
wrefresh(win);
}
index = (index + LOGBUF_NUM - ) % LOGBUF_NUM;
} void cleanline(WINDOW *win, int y, int x)
{
char EMPTYLINE[LOGBUF_LEN] = {};
memset(EMPTYLINE, ' ', LOGBUF_LEN-);
mvwprintw(win, y, x, EMPTYLINE);
wrefresh(win);
}
getch()函数:
getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
在keypad(stdscr, TRUE)中,stdscr是指一个虚拟窗口,我们所有的操作会先写在stdscr上,然后通过refresh函数将stdscr里的图像显示到屏幕上。
refresh()函数
在我们使用printw时,实际上这个数据被打印到一个叫作“stdscr”的虚拟窗口上,没有被直接输出到屏幕上。printw()函数的作用是不断将一些显示标记和相关的数据结构写在虚拟显示器上,并将这些数据写入 stdscr 的缓冲区内。所以,为了显示这些缓冲区中的数据我们必须使用 refresh()函数告诉 curses 系统将缓冲区的内容输出到屏幕上。这种机制可以使程序员不断在虚拟屏幕上写入数据,而调用 refresh()函数时让一切看起来似乎是一次完成的。因为 refresh()函数只核查窗口和数据中变动的部分,这种富有弹性的设计提供了一个高效的反馈机制。但是这有时很打击初学者的积极性。因为对于初学者来说忘记在输出后调用refresh()函数是很恼人的错误。不过不用很担心,多人也经常犯这样的错误。
然后我们看看INITRUNLOG(): 它实质上是个宏定义,定义了logwin = newlogw(),这里调用了自定义函数newlogw,创建了游戏的信息展示窗口。
窗口(Window)机制是整个 CURSES 的核心概念。你应该已经通过前面的例子看到了所有的函数都是默认在输出“窗口”(stdscr)操作。即使如果你现在设计一个最简单的图形用户界面(GUI),你都需要用到窗口。使用窗口的一个最主要的原因是:通过窗口机制,你可以将屏幕分割为不同的部分,并且同时在不同的区域内分别操作。这样做的可以提高工作效率。另外一个原因是:你应当始终在你的程序中追求一种更好的、更易于管理的设计方式。如果你要设计一个大型的、复杂的用户界面,事先设计好这些部分将会提高你的办事效率。
newwin()函数和box()函数:
在WINDOW* newlogw()函数中可以看到,一个窗口的建立是从newwin()开始的。虽然我们建立了一个窗口,但无法看见它,这和HTML中的div有点相似,你不给div标签添加样式的话,在网页上也是什么都看不见。所以我们得用box函数给已知的窗口加上边框。
mvwprintw()函数:
在指定的窗口中,指定的坐标(y,x)输出指定的内容。
Linux终端图形库编程的更多相关文章
- 【linux草鞋应用编程系列】_6_ 重定向和VT100编程
一.文件重定向 我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
- 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)
<Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...
- linux makefile: c++ 编程_基础入门_如何开始?
学习android 终究还是需要研究一下其底层框架,所以,学习c++很有必要. 这篇博客,算是linux(ubuntu) 下学习 c++ 的一个入门. 刚开始学习编程语言的时候,最好还是使用命令行操作 ...
- 嵌入式linux的网络编程(1)--TCP/IP协议概述
嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...
- Linux下的编程实战【转】
一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...
- Linux 高性能服务器编程——Linux服务器程序规范
问题聚焦: 除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范. 工欲善其事,必先利其器,这篇主要来探 ...
- 《Linux/Unix系统编程手册》 时间子系统
Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...
- 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll
关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...
随机推荐
- SQL ------------- 最大与最小函数
sql max() 函数 求最大值,可以查询汉字,字母,日期,数字 注意:字母和汉字按照 a-z 依次查找,第一个最大的就是需要的 比如:有两个字母或汉字都是 ...
- c++中获得对象类型 typeid 与 type_info
复杂部分略去,摘录要素如下: 1.typeid是C++的关键字之一,等同于sizeof这类的操作符. 2.typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件type ...
- Prometheus 监控目标运行状态并邮件通知
Prometheus 监控目标运行状态并邮件通知 邮件服务安装:https://www.cnblogs.com/xiangsikai/p/9809654.html 告警规则示例:https://pro ...
- Web应急:门罗币恶意挖矿
门罗币(Monero 或 XMR),它是一个非常注重于隐私.匿名性和不可跟踪的加密数字货币.只需在网页中配置好js脚本,打开网页就可以挖矿,是一种非常简单的挖矿方式,而通过这种恶意挖矿获取数字货币是黑 ...
- spring boot 在eclipse里启动正常,但打包后启动不起来
现象描述: spring boot 在eclipse里启动正常,但打包后启动不起来. 错误日志如下: D:\Project>java -jar MKKY_CMS.jar . ____ _ __ ...
- ASP.NET Core In Process Hosting on IIS with ASP.NET Core 2.2(转载)
ASP.NET Core 2.2 has been out for a while now and with it come some significant improvements to the ...
- EF启程--概念理解(数据库连接)
简介:Entity Framework 是一种支持 .NET 开发人员使用 .NET 对象处理数据库的对象关系映射程序 (O/RM). 它不要求提供开发人员通常需要编写的大部分数据访问代码. 其中有E ...
- Python——Scrapy爬取链家网站所有房源信息
用scrapy爬取链家全国以上房源分类的信息: 路径: items.py # -*- coding: utf-8 -*- # Define here the models for your scrap ...
- Loadsh 常用方法总结以及在vue中使用Loadsh
Loadsh 常用方法总结以及在vue中使用Loadsh Lodash 是一个一致性.模块化.高性能的 JavaScript 实用工具库.处理复杂数组,对比等可以直接采用该库,也方便快捷. 官方网站 ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之五
转自:http://blog.csdn.net/eaglex/article/details/6458541 维特比算法(Viterbi Algorithm) 找到可能性最大的隐藏序列 通常我们都有一 ...