贪吃蛇(七)方向和屏幕刷新

由于用户玩游戏的时候,程序需要一边接收用户的输入,一边需要刷新屏幕,此时就需要引用线程来解决此问题。

实现思路

linux线程库pthread,只需要创建pthread_t 类型的线程变量,然后将线程变量与函数进行绑定即可,不需要额外的调用。

#include"curses.h"
#include "stdlib.h"
#include "pthread.h"


struct SnakeNode
{
  int row;
  int col;
  struct SnakeNode* next; 
};


int key;  // user input
struct SnakeNode* head = NULL;
struct SnakeNode* tail = NULL;

void addNode();
void mapinit();



void snakeinit()
{
  // free 
  struct SnakeNode* p;
  while(head != NULL)
  {
    p = head;
    head = head->next;
    free(p);
  }
  head = (struct SnakeNode*)malloc(sizeof(struct SnakeNode));
  head->row = 2;
  head->col = 2;
  head->next = NULL;
  tail = head;

  addNode();
  addNode();
}

void addNode()
{  
  struct SnakeNode* node = (struct SnakeNode*)malloc(sizeof(struct SnakeNode));
  node->row = tail->row;
  node->col = tail->col + 1;
  node->next = NULL;
  tail->next = node;
  tail = node;
}

void deleteNode()
{
  struct SnakeNode* p;
  p = head;
  head = head->next;
  free(p);
}

void moveSnake()
{
  addNode();
  deleteNode();
  // if snake is over.
  if(tail->row == 0 || tail->col == 0 || tail->row >= 20 || tail->col >= 19)
  {
    snakeinit();
  }
}

void cursesinit()
{
   
  initscr();
  keypad(stdscr,1);
}

int hasSnake(int row,int col)
{
  struct SnakeNode* p = head;
  while(p!=NULL)
  {
    if(row == p->row && col == p->col)
	return 1;
    p = p->next;
  }
  return 0; 
}


void mapinit()
{
  int row;
  int col;
  move(0,0);
  for(row = 0;row < 20;row++)
  {
   // one
   if(row == 0 || row == 19)
   {
     for(col = 0;col < 19;col++)
        printw("--");
   }
   // two
   else
   {
     for(col = 0;col < 20;col++)
     {
        if(col == 0 || col == 19 ) printw("|");
	else if(hasSnake(row,col))
	{
	  printw("[]");
	}
	else
	{
	  printw("  "); 
	}
     }
   }

    printw("\n");
  }

  printw("By hongzhe key:%d\n",key);
}


void refreshScreen()
{
  while(1)
  {
	moveSnake(); // snake forward 
	mapinit();   // fresh map
	refresh();   // fresh screen
	usleep(500000);	// sleep(0.5)
  }
  return;
}


void changeDir()
{
  
  while(1)
  {
    key = getch();
    switch(key)
    {
      case KEY_DOWN:
	printw("\rDOWN\t");
	break;
      case KEY_RIGHT:
	printw("\rRIGHT\t");
	break;
      case KEY_LEFT:
	printw("\rLEFT\t");
	break;
      case KEY_UP:
	printw("\rUP\t");
	break;

    }
  }
  return;
}

int main()
{
  pthread_t t1;
  pthread_t t2;
 
  cursesinit();  
  snakeinit();
  mapinit();
  

  pthread_create(&t1,NULL,refreshScreen,NULL);
  pthread_create(&t2,NULL,changeDir,NULL);

  while(1);

  getch();  
  endwin();
  return 0;
}


学习打卡

在这里插入图片描述

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cd2w1001

看了觉得好,就请我喝瓶水吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值