#include "graphics.h"
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
WINDOW * g_win=NULL;
GRAPHICS_COLOR g_fore_color=GCCyan;//默认的前景颜色
GRAPHICS_COLOR g_back_color=GCRed;//默认背景颜色
int g_style=A_BOLD;
#define CURRENT_ATTRIBUTE C_ATTR(g_style, g_fore_color, g_back_color)
int readkey()
{
int n, flags;
int ch=getc(stdin);
if(ch==27)
{
flags=fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags|O_NONBLOCK);
ch=getc(stdin);
if(ch==91)
{
ch=getc(stdin);
switch(ch)
{
case 'D':
ch=KEYLEFT;
break;
case 'C':
ch=KEYRIGHT;
break;
case 'B':
ch=KEYDOWN;
break;
case 'A':
ch=KEYUP;
break;
default:
ch=0;
}
}
else
{
ch=27;
}
fcntl(STDIN_FILENO, F_SETFL, flags);
}
return ch;
}
GRAPHICS_COLOR get_fore_color()
{
return g_fore_color;
}
//设置前景颜色
void set_fore_color(GRAPHICS_COLOR color)
{
g_fore_color=color;
}
//设置背景颜色
void set_back_color(GRAPHICS_COLOR color)
{
g_back_color=color;
}
void update_attribute(void)
{
wattrset(g_win, CURRENT_ATTRIBUTE);
}
void clear_screen(int x, int y, int w, int h)
{
int i, j;
wattrset(g_win, CURRENT_ATTRIBUTE);
for(i=0; i<h; i++)
{
wmove(g_win, i+y, x);
for(j=0; j<w; j++)
{
waddch(g_win, ' ');
}
}
touchwin(g_win);
wnoutrefresh(g_win);
}
bool init_graphics(void)
{
setlocale(LC_ALL, "");
g_win=initscr();
if(g_win==NULL)
{
printf("call initscr() failed!\n");
return false;
}
cbreak();
noecho();
if(has_colors())
{
int i,j,k;
start_color();
for(i=0, k=0; i<GCCount; i++)
{
for(j=0; j<GCCount; j++)
{
init_pair(++k, i, j);
}
}
}
curs_set(0);
return true;
}
//绘制地图
/**
在graphics.h 中
#define START_X 5
#define START_Y 5
*/
void snake_draw_map(void)
{
set_fore_color(GCWhite);//设置前景颜色
update_attribute();
//1.将光标移动起始坐标
wmove(g_win,5,5);
//2.在当前光标的位置绘制符号
waddstr(g_win,TLC_FRAME);
//3.刷新窗口
wrefresh(g_win);
}
void snake_init_game(void)
{
set_back_color(GCBlack);//修改成黑色
update_attribute();//更新属性
clear_screen(0,0,COLS,LINES);//清屏
wrefresh(g_win); //刷新窗口
signal(SIGALRM,snake_update);//指定定时器处理函数
snake_set_ticker(500);//设置定时时间为 500ms
srand(time(NULL));//设置随机数的种子
food.dx = rand() % (HIGHT - START_X - 2) + START_X + 1;
food.dy = rand() % (WIDTH - START_Y - 2) + START_Y + 1;
snake_draw_food(food.dx,food.dy);//绘制第一个食物
}
//定时器处理函数
void snake_update(int sig)
{
//随机食物的位置.包括 x 坐标与 y 坐标
/**
HIGHT = 30
WIDTH = 100
START_X = 5
START_Y = 5
食物的x坐标的随机范围 [6,29]
食物的y坐标的随机范围 [6,99]
*/
}
//在(x,y)坐标位置绘制食物
void snake_draw_food(int x,int y)
{
set_fore_color(GCYellow);//设置前景颜色
update_attribute();//更新属性
wmove(g_win,x,y);//将光标移动到(x,y)位置
waddstr(g_win,FOOD);//在光标所在的位置打印 FOOD
wrefresh(g_win);//刷新窗口
}
int snake_set_ticker(int n_msecs)
{
struct itimerval new_timeset;
long n_sec, n_usecs;
n_sec = n_msecs / 1000 ;
n_usecs = ( n_msecs % 1000 ) * 1000L ;
new_timeset.it_interval.tv_sec = n_sec;
new_timeset.it_interval.tv_usec = n_usecs;
n_msecs = 1;
n_sec = n_msecs / 1000 ;
n_usecs = ( n_msecs % 1000 ) * 1000L ;
new_timeset.it_value.tv_sec = n_sec ;
new_timeset.it_value.tv_usec = n_usecs ;
return setitimer(ITIMER_REAL, &new_timeset, NULL);
}
void exit_graphics(void)
{
endwin();
}