Linux下c语言简易贪吃蛇的实现

操作方式:wasd切换方向,q退出。

Makefile

test:test.c
	gcc -pthread -o $@ $^
.PHONY:clean
clean:
	rm -rf *.o test

snake.h

/*
 * snake.h
 *
 *  Created on: 2021/04/13
 *      Author: wangyuwei
 */

#ifndef SNAKE_H_
#define SNAKE_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

#define WIDE 80
#define HIGH 30

struct FOOD{
    int X;
    int Y;
}food;

struct BODY{
    int X;
    int Y;
};

struct SNAKE{
    struct BODY body[HIGH*WIDE];
    int size;
}snake;

int timeU=500000;
int kx=0;
int ky=0;
void initFood(void);
void initSnake(void);
void setUI(void);
void showGame(void);
void getInput(void);
void playGame(void);
void gameEnd(void);
#endif /* SNAKE_H_ */

test.c文件

/*
 * test5.c
 *
 *  Created on: 2021/04/13
 *      Author: wangyuwei
 */

#include "snake.h"

static char key;
int main()
{
    pthread_t t1;
    pthread_create(&t1,NULL,getInput,NULL);
    setUI();
    srand(time(NULL));
    initFood();
    initSnake();
    playGame();
    //getInput();
    return 0;
}
void initFood(void)
{
    food.X=rand()%76+2;//2-78
    food.Y=rand()%26+2;//2-28
}
void initSnake(void)
{
    //memset(snake.body,0,sizeof(int)*WIDE*HIGH);
    snake.body[0].X=40;
    snake.body[0].Y=15;/*蛇头*/
    //snake.body[15][40]=9;
    snake.body[1].X=39;
    snake.body[1].Y=15;/*蛇尾*/
    //snake.body[15][39]=8;
    snake.size=2;
}
void setUI(void)
{
    /* 屏幕设置 */
    printf("\033[2J");            // 清屏
    system("stty -icanon");       // 关缓冲
    system("stty -echo");         // 关回显
    fprintf(stdout,"\033[?25l");  // 关闭鼠标显示

}
void showGame(void)
{
    fprintf(stdout,"\033[1;1H");
    fflush(stdout);

    int screen[HIGH][WIDE]={0};

    //食物
    screen[food.Y][food.X]=10;
    //蛇头
    screen[snake.body[0].Y][snake.body[0].X]=9;
    //蛇尾
    for(int k=1;k<snake.size;k++)
    {
        screen[snake.body[k].Y][snake.body[k].X]=8;
    }
    //画墙
    for(int i=0;i<HIGH;i++)
    {
        for(int j=0;j<WIDE;j++)
        {
            screen[0][j]=7;//横线
            screen[HIGH-1][j]=7;
            screen[i][0]=6;//竖线
            screen[i][WIDE-1]=6;
        }
    }

    for(int i=0;i<HIGH;i++)
    {
        for(int j=0;j<WIDE;j++)
        {
            if(screen[i][j]==10)
            {
                fprintf(stdout,"#");
            }
            if(screen[i][j]==9)
            {
                fprintf(stdout,"@");
            }
            if(screen[i][j]==8)
            {
                fprintf(stdout,"*");
            }
            if(screen[i][j]==7)
            {
                fprintf(stdout,"_");
            }
            if(screen[i][j]==6)
            {
                fprintf(stdout,"|");
            }
            if(screen[i][j]==0)
            {
                fprintf(stdout," ");
            }

        }
        fprintf(stdout,"\n");
    }
}
void getInput(void)
{
    key='d';
    while(1)
    {
        int keytmp = fgetc(stdin);
        if(key!=keytmp)
        {
            key=keytmp;
        }
        if(key=='q')
        {
            gameEnd();
            break;
        }
    }

}
void playGame(void)
{
    while(snake.size<(HIGH-1)*(WIDE-1))
    {
        showGame();
        switch(key)
        {
            case 'w':
                kx=0;ky=-1;
                break;
            case 'a':
                kx=-1;ky=0;
                break;
            case 's':
                kx=0;ky=1;
                break;
            case 'd':
                kx=1;ky=0;
                break;
            default:
                break;
        }
        //判断是否撞墙
        if(snake.body[0].X==0||snake.body[0].X==WIDE-1
           ||snake.body[0].Y==0||snake.body[0].Y==HIGH-1)
        {
            gameEnd();
        }
        //判断是否撞到蛇身
        for(int i=1;i<snake.size;i++)
        {
            if(snake.body[0].X==snake.body[i].X&&snake.body[0].Y==snake.body[i].Y)
            {
                gameEnd();
            }
        }
        //判断是否撞到食物
        if(snake.body[0].X==food.X&&snake.body[0].Y==food.Y)
        {
            initFood();
            snake.size++;
            if(timeU>=200000)
            {
                timeU-=50000;
            }
        }
        for(int i=snake.size-1;i>0;i--)
        {
            snake.body[i].X=snake.body[i-1].X;
            snake.body[i].Y=snake.body[i-1].Y;
        }
        snake.body[0].X=snake.body[0].X+kx;
        snake.body[0].Y=snake.body[0].Y+ky;
		showGame();
        usleep(timeU);
    }
}
void gameEnd(void)
{

    /* 恢复终端设置 */
    system("stty icanon");          // 恢复缓冲
    system("stty echo");            // 恢复回显
    fprintf(stdout,"\033[?25h");    // 恢复鼠标显示

    /* 尾部处理 */
    fprintf(stdout,"\033[200;1H");  // 定位光标到最后一行
    exit(0);                        // 退出程序
}

效果图

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值