/*
*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终端图形库编程的更多相关文章

  1. 【linux草鞋应用编程系列】_6_ 重定向和VT100编程

    一.文件重定向     我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...

  2. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  3. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  4. linux makefile: c++ 编程_基础入门_如何开始?

    学习android 终究还是需要研究一下其底层框架,所以,学习c++很有必要. 这篇博客,算是linux(ubuntu) 下学习 c++ 的一个入门. 刚开始学习编程语言的时候,最好还是使用命令行操作 ...

  5. 嵌入式linux的网络编程(1)--TCP/IP协议概述

    嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...

  6. Linux下的编程实战【转】

    一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...

  7. Linux 高性能服务器编程——Linux服务器程序规范

    问题聚焦:     除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范.     工欲善其事,必先利其器,这篇主要来探 ...

  8. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  9. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

随机推荐

  1. SpringMVC参数传递方案

    SpringMVC参数传递方案 登录 @PostMapping("/login") @ResponseBody public Map login(String username, ...

  2. sentry之二:sentry配置钉钉和email

    springboot+springcloud后台项目配置日志采集 gradle: compile 'com.getsentry.raven:raven-logback:8.0.2' compile ' ...

  3. Sentry异常捕获平台

    本文包括Sentry平台的介绍,以及环境搭建两部分,更多细节请查阅官方文档. 简介 Sentry是一个实时事件的日志聚合平台.它专门监测错误并提取所有有用信息用于分析,不再麻烦地依赖用户反馈来定位问题 ...

  4. java中的泛型【T】与通配符【?】概念入门

    使用泛型的目的是利用Java编译机制,在编译过程中帮我们检测代码中不规范的有可能导致程序错误的代码.例如,我们都知道List容器可以持有任何类型的数据,所以我们可以把String和Integer等类型 ...

  5. MySQL 只能做小项目?松哥要说几句公道话!

    松哥上学那会,很多人对 MySQL 有一些偏见,偏见主要集中在以下几方面: MySQL 不支持事务(事实上 MyISAM 有表锁,但是效率比较低) MySQL 存储的数据量比较小,适合小项目,大项目还 ...

  6. json工具类(二)——google包

    package com.ruoyi.common.utils.json; import java.util.List; import com.google.gson.Gson; import com. ...

  7. 配置 SSL、TLS 以及 HTTPS 来确保 Elasticsearch、Kibana、Beats 和 Logstash 的安全

    配置主机hosts文件 192.168.75.20 filebeat.local kibana.local logstash.local 192.168.75.22 node2.elastic.tes ...

  8. idea2019注册码

    都9012年了,怎么还能忍受用低版本的编辑器呢, IntelliJ IDEA 2019破解教程拿走不谢 下载工具 Mac版idea下载链接: 链接:https://pan.baidu.com/s/1m ...

  9. android studio学习----Failed to resolve: com.android.support:design:22.1.1

    这个目前好像没有合适的办法,唯一可行的就是 点击那个提示  进行SDK Manager下载就可以了 但是天朝的网啊,我试了很多次,突然的可以下载,运气啊 类似这一系列问题解决办法就是  重新更新SDK ...

  10. shell中sort用法

    1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@rocrocket progr ...