C语言面向接口编程 游戏开发案例

1 甲方框架

在企业开发的过程中,往往甲方只需要搭建整体框架,并提供接口声明,具体的功能实现又乙方完成

例如,要开发一款游戏,甲方搭建的框架以及涉及的接口声明如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//初始化游戏	//参数1:玩家指针	参数2:人物姓名
typedef void(*INIT_GAME)(void** player, char* name);

//核心战斗 若战斗胜利返回1,失败返回0	//参数1:玩家		参数2:副本难度
typedef int(*FIGHT_GAME)(void* player, int gameDiff);

//查看玩家信息	
typedef void(*PRINT_GAME)(void* player);

//退出游戏
typedef void(*EXIT_GAME)(void* player);

//甲方框架
void playGame(INIT_GAME init, FIGHT_GAME fight, PRINT_GAME printGame, EXIT_GAME exitGame)
{
    
    
	
	void* player = NULL;
	char buf[1024];

	printf("请输入玩家的姓名:");
	scanf("%s", buf);

	//初始化游戏
	init(&player, buf);

	//游戏难度设定
	int diff = -1;
	printf("请选择游戏难度:\n");
	printf("1、简单\n");
	printf("2、中等\n");
	printf("3、困难\n");
	scanf("%d", &diff);

	//战斗
	int ret = fight(player, diff);

	if (ret == 0)
	{
    
    
		printf("游戏结束,请再接再厉!\n");
	}
	else
	{
    
    
		printf("恭喜胜利!\n");

		//查看当前玩家状态
		printf("当前玩家状态为:\n");
		printGame(player);
	}

	//退出游戏
	exitGame(player);

}

int main() {
    
    
	

	return EXIT_SUCCESS;
}

上面的框架是一个回调函数,函数指针的在定义的时候,相当于给出了接口,因为能看到函数的返回值和参数。可以在VS中生成一下(即编译链接),如果没有语法错误,说明甲方的框架搭建完成,接下来是让乙方实现功能。
甲方需要哪些功能模块,往往不是自己单独确定,而是需要和乙方商量确定,换句话说,具体需求的确定,是双方沟通交流的结果。

2 乙方功能实现

乙方根据上面的框架,实现各个函数的具体功能。

新建一个名为gameCompany1.h的文件,这里Company1表示第一家乙方公司,因为乙方可能有多家游戏厂商,下面的函数中,若名字里有COMPANY1,也表示来自第一家乙方公司的函数,gameCompany1.h的内容如下:

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct Player 
{
    
    
	char name[64];
	int exp;		//经验
	int level;		//等级
};

//初始化游戏	//参数1:玩家指针	参数2:人物姓名
void INIT_GAME_COMPANY1(void** player, char* name);

//核心战斗 若战斗胜利返回1,失败返回0	//参数1:玩家		参数2:副本难度
int FIGHT_GAME_COMPANY1(void* player, int gameDiff);

//查看玩家信息	
void PRINT_GAME_COMPANY1(void* player);

//退出游戏
void EXIT_GAME_COMPANY1(void* player);

接下来新建一个名为gameCompany1.c的文件,实现上述接口,内容如下:

#include "gameCompany1.h"

//初始化游戏	//参数1:玩家指针	参数2:人物姓名
void INIT_GAME_COMPANY1(void** player, char* name)
{
    
    
	//分配内存
	struct Player* pl = malloc(sizeof(struct Player));
	if (pl == NULL)
	{
    
    
		return;
	}
	*player = pl;

	strcpy(pl->name, name);		//姓名赋值
	pl->exp = 0;				//开局经验为0
	pl->level = 0;				//开局等级为0
}

//获得的经验奖励	//参数1:胜率	参数2:难度
int getExp(int winRate, int diff)
{
    
    
	int random = rand() % 100 + 1;
	if (random <= winRate)
	{
    
    
		//胜利
		return diff * 10;
	}
	else
	{
    
    
		//失败
		return 0;
	}
}

//核心战斗 若战斗胜利返回1,失败返回0	//参数1:玩家		参数2:副本难度
int FIGHT_GAME_COMPANY1(void* player, int gameDiff)
{
    
    
	//转换数据类型
	struct Player* pl = player;		//之后只需要对pl进行操作

	int addExp = 0;					//给玩家增加的经验变量

	//根据难度确定经验变量的取值
	switch (gameDiff)
	{
    
    
		//不同难度有不同的胜率,获胜的情况下,相应的经验奖励也不同
	case 1:
		addExp = getExp(90, 1);
		break;
	case 2:
		addExp = getExp(50, 2);
		break;
	case 3:
		addExp = getExp(30, 3);
		break;
	default:
		break;
	}

	//更新玩家的经验和等级
	pl->exp += addExp;
	pl->level = pl->exp / 10;		//经验除以10得到等级

	//根据获得的经验来判断是否胜利
	if (0 == addExp)
	{
    
    
		//游戏失败
		return 0;
	}
	else
	{
    
    
		//游戏胜利
		return 1;
	}
}

//查看玩家信息	
void PRINT_GAME_COMPANY1(void* player)
{
    
    
	//转换数据类型
	struct Player* pl = player;		//之后只需要对pl进行操作

	//打印
	printf("玩家的姓名:%s\n", pl->name);
	printf("当前的经验:%d\n", pl->exp);
	printf("当前的等级:%d\n", pl->level);
}

//退出游戏
void EXIT_GAME_COMPANY1(void* player)
{
    
    
	if (player == NULL)
	{
    
    
		return;
	}
	free(player);
	player = NULL;
}

3 测试

乙方实现功能之后,需要使用甲方给的框架来测试,内容如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<time.h>
#include "gameCompany1.h"								//导入乙方的函数声明

//初始化游戏	//参数1:玩家指针	参数2:人物姓名
typedef void(*INIT_GAME)(void** player, char* name);

//核心战斗 若战斗胜利返回1,失败返回0	//参数1:玩家		参数2:副本难度
typedef int(*FIGHT_GAME)(void* player, int gameDiff);

//查看玩家信息	
typedef void(*PRINT_GAME)(void* player);

//退出游戏
typedef void(*EXIT_GAME)(void* player);

//甲方框架
void playGame(INIT_GAME init, FIGHT_GAME fight, PRINT_GAME printGame, EXIT_GAME exitGame)
{
    
    

	void* player = NULL;
	char buf[1024];

	printf("请输入玩家的姓名:");
	scanf("%s", buf);

	//初始化游戏
	init(&player, buf);

	//游戏难度设定
	int diff = -1;
	printf("请选择游戏难度:\n");
	printf("1、简单\n");
	printf("2、中等\n");
	printf("3、困难\n");
	scanf("%d", &diff);

	//战斗
	int ret = fight(player, diff);

	if (ret == 0)
	{
    
    
		printf("游戏结束,请再接再厉!\n");
	}
	else
	{
    
    
		printf("恭喜胜利!\n");

		//查看当前玩家状态
		printf("当前玩家状态为:\n");
		printGame(player);
	}

	//退出游戏
	exitGame(player);

}

int main() {
    
    
	srand((unsigned int)time(NULL));		//设置随机数种子

	//将乙方写的函数名,作为参数传入
	playGame(INIT_GAME_COMPANY1, FIGHT_GAME_COMPANY1, PRINT_GAME_COMPANY1, EXIT_GAME_COMPANY1);

	return EXIT_SUCCESS;
}

结果:
在这里插入图片描述
至此,测试成功!

4 甲乙对接

乙方测试成功后,可以将函数封装成动态库提交给甲方,甲乙双方对接确认结果后,甲方支付尾款。如果有第二家乙方公司实现了上述的所有功能,可以将所有函数声明写在gameCompany2.h中,然后按照同样的流程。

尽管游戏的功能比较简单,我们还是已经掌握了面向接口编程。

猜你喜欢

转载自blog.csdn.net/weixin_44457930/article/details/128938002