基于GEC6818开发板的C/C++贪吃蛇小游戏

本文详细介绍了如何使用GEC6818开发板编写一款C/C++贪吃蛇游戏。从主要头文件引入,全局变量设定,到各个关键函数线程的实现,包括显示图片、触屏响应、坐标显示、游戏开始与结束页面等功能的实现,以及自定义font.h文件等。游戏流程涵盖开始界面、游戏界面和结束界面。
摘要由CSDN通过智能技术生成

 1.需要的主要头文件

#include <iostream>
#include <pthread.h>    //线程头文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h> //linux系统输入头文件
#include <unistd.h>      //sleep()等延迟函数头文件
#include <vector>        //容器
#include <sys/mman.h>    //触摸屏的有关函数
#include<string.h>
#include<sys/unistd.h>
#include <stdlib.h>
#include <strings.h>
#include<time.h>        //用于生成随机因子
#include <random>
#include <algorithm>
#include<fstream>        //文件IO有关类
#include "font.h"        //自己定义的头文件,输入在开发板上输入文字
using namespace std;

2.相关宏,全局变量(可以根据自己需要进行修改)

//小蛇运动空间
#define minX 0
#define maxX 600  
#define minY 0
#define maxY 480
//开发板宏
#define LCD_DEV_PATH "/dev/fb0"
#define MMAP_OFFSET   0
//互斥锁,用于控制小蛇的运动和暂停
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
bool shouldMove = false;//为ture的小蛇时候可以运动

int Fraction;
//小蛇结构体
struct pos
{
    int x;
    int y;
};
//获得触屏的坐标
typedef struct touchinfo
{
    int s_x,s_y;
    struct timeval s_time;
    
    int e_x,e_y;
    struct timeval e_time;
}Info;
//食物坐标
int fodx;
int fody;
// 蛇的移动方向
enum Direction {UP, DOWN, LEFT, RIGHT}; 
// 初始化为向右移动
Direction snakeDirection = RIGHT; 
// 蛇的移动速度,默认为1.4s
int snakeSpeed = 140000; 

int ts_x = 0;
int ts_y = 0;
int tsfd;
//速度等级(初始为7级)
int Grade; 
//容器存储小蛇的身体
vector<pos> snakevector;
//初始化一节蛇身(即蛇头)
pos pos3={10,0};

3.相关函数线程

//显示图片大小,w:款,h:高,图片显示的坐标(x,y),bmpname:图片的路径和名字
int show_anybmp(int w,int h,int x,int y,const char *bmpname);
//显示固定图片大小
int Displaylist(const char* bmp_path);
//清屏
void ClearScreen();
//开始游戏
void game_start( int fd);
//结束游戏
void game_end(int fd);
//获得坐标
Info getTouch(int fd);
//坐标显示
int Slide(Info info);
//进入游戏
void EnteringTheGame(int fd);
//控制蛇的移动
void *snakemove(void *arg);
//获得蛇的坐标,并进行控制
void *readts(void *arg);
//lcd屏相关初始化
struct LcdDevice *init_lcd(const char *device);
//buf:需要显示的字;fontSize:字体大小;(x,y):字显示的起始位置,color1:字的颜色
void test(const char* buf, int fontSize, int x, int y, int color1);
//buf:需要显示的字;fontSize:字体大小;x:覆盖的长度;y:覆盖的宽度;(x2,y2):覆盖起始位置,color1:字的颜色
void test1(char* buf, int fontSize, int x, int y,int x2,int y2,int color1)
//分数存档
void Archive();

4实现

a.显示固定大小图片

//显示固定图片大小(480*800)
int Displaylist(const char* bmp_path)//需要显示的图片路径和名字
{
    int lcd = open(LCD_DEV_PATH,O_RDWR);
    if(lcd == -1)
    {
        perror("打开显示器失败!");
        return -1;
    }

    int* mmap_start_p = (int *)mmap(NULL,
                               800*480*4,
                               PROT_READ|PROT_WRITE,
                               MAP_SHARED,
                               lcd,
                               MMAP_OFFSET);
    if(mmap_start_p == (int *)MAP_FAILED)
    {
        perror("映射失败!");
        return -1;
    }

    int bmp = open(bmp_path,O_RDONLY);
    if(bmp == -1)
    {
        perror("打开图片失败!");
        return -1;
    }

    int bmp_w,bmp_h;
    int skip;

    // 判断图片格式
    char magic[2];
    read(bmp, magic, 2);
    lseek(bmp, 0, SEEK_SET);

    if (memcmp(magic, "BM", 2) == 0) 
    {
        // BMP格式图片
        lseek(bmp, 18, SEEK_SET);
        if(read(bmp,&bmp_w,sizeof(int)) == -1)
        {
            perror("读取图片宽度失败!");
            return -1;
        }
        if(read(bmp,&bmp_h,sizeof(int)) == -1)
        {
            perror("读取图片高度失败!");
            return -1;
        }

        // 判断图片宽度是不是4的倍数
        if(bmp_w*3%4 == 0)
        {
            skip = 0;
        }
        else
        {
            skip = 4-(bmp_w*3%4);
        }
    }
    else if (memcmp(magic, "\xFF\xD8", 2) == 0) 
    {
        // JPG格式图片,暂不支持
        perror("暂不支持 JPG 格式图片!");
        return -1;
    }
    else 
    {
        perror("无法识别的图片格式!");
        return -1;
    }

    char rgb[bmp_w*bmp_h*3 + skip*bmp_h];

    lseek(bmp, 54, SEEK_SET);

    if(read(bmp, rgb, bmp_w*bmp_h*3 + skip*bmp_h) == -1)
    {
        perror("读取图片像素点失败!");
        return -1;
    }

    int zoomout_line_skip = 3 * (bmp_w % 1);
    printf("%d------\n",zoomout_line_skip);
    for(int y = 0, n = 0; y < bmp_h / 1; y++)
    {
        for(int x = 0; x < bmp_w / 1; x++, n += 3 * (1)) 
        {
            if ((bmp_h -  y) >= 1 && (bmp_h -  y) < 481 && x >= 0 && x < 800)
            {
                *(mmap_start_p + 800 * (bmp_h - 1 - y) + x) =   rgb[n] << 0 | 
                                                                rgb[n + 1] << 8 |
                                                                rgb[n + 2] << 16;
            }
        }

        n += zoomout_line_skip;
        n += skip;
        n += (bmp_w * 3 * (1 - 1));
    }

    return 0;
}

b.清屏(全屏)

void ClearScreen()
//void ClearScreen(int w,int h)
{
        int lcd = open("/dev/fb0", O_RDWR);
        if (lcd =
  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值