数据驱动编程 游戏GM的实现

原创 2015年11月18日 12:15:59
在学习《Unix编程艺术》,作者在介绍Unix设计原则时,其中有一条为“表示原则:把知识叠入数据以求逻辑质朴而健壮”。

我对这个原则很有共鸣,所以先学习了数据驱动编程相关的内容,这里和大家分享出来和大家一起讨论。


理论性的东西:(复制的)

数据驱动编程,也叫元编程。

数据驱动编程的核心出发点是相对于程序逻辑,人类更擅长于处理数据

数据比程序逻辑更容易驾驭,所以我们应该尽可能的将设计的复杂度从程序代码转移至数据

上传小刚的代码:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import tianlong.ConstValue;
import tianlong.common.GameConst;
import tianlong.system.Monster.Monster;
import tianlong.system.Monster.MonsterKit;
import tianlong.system.event.systemEvent.SystemEventFunction;
import tianlong.system.event.useAddEvent.UseAddUtil;
import tianlong.system.hero.Hero;
import tianlong.system.scene.IScene;
import tianlong.system.scene.Point;
import tianlong.system.scene.TileData;
import tianlong.util.write.WriteUtil;

import com.commons.message.IResponse;
import com.commons.message.Response;
/**
 * 
 * @author kevin chen
 * @Description:GM命令  反射技术  与 数据驱动思想
 * @date 2015年11月9日 上午11:44:38
 */
class GmOrder {
	/**这些GM方法所在的类*/
	private Object executeObj;
	/**gm的一些注释  用来说明该GM是干什么!*/
	private Intro intro ;
	/**方法名  对应GM命令的字符串*/
	private Method method;

	
	public GmOrder(Object executeObj,Method method,Intro intro) {
		this.executeObj = executeObj;
		this.method = method;
		this.intro = intro;
	}
	
	public String getIntroValue() {
		return intro.value();
	}

	public String getMethodParameterTypeStr() {
		Class<?>[] types = method.getParameterTypes();
		StringBuffer sb = new StringBuffer();
		for (int i = 1; i < types.length; i++) {
			Class<?> type = types[i];
			String typeName = type.getName();
			if(typeName.equalsIgnoreCase("java.lang.String")){
				sb.append(" string");
			}else{
				sb.append(" "+typeName);
			}
		}
		return sb.toString();
	}

	public void execute(Hero hero , Object[] args){
		try {
			args = dealArgs(hero,args);
			this.method.invoke(this.executeObj,args);
			hero.sendDebugMsg(hero, this.intro.value() +" GM命令执行成功!");
		} catch (Exception e) {
			hero.sendDebugMsg(hero, this.intro.value() +" GM命令执行失败!\n"+e.getMessage());
			e.printStackTrace();
		} 
	}
	
	/**处理参数  支持不同参数传入*/
	public Object[] dealArgs(Hero hero,Object[] args){
		Class<?>[] types = method.getParameterTypes();
		Object[] objs= new Object[types.length]; 
		objs[0] = hero;
		
		for (int i = 1; i < types.length; i++) {
			Class<?> type = types[i];
			String typeName = type.getName();
			if( i <= args.length ){
				if(typeName.equalsIgnoreCase("int")){
					objs[i] = Integer.parseInt(args[i-1].toString());
				}else if(typeName.equalsIgnoreCase("long")){
					objs[i] = Long.parseLong(args[i-1].toString());
				}else if(typeName.equalsIgnoreCase("boolean")){
					objs[i] = Boolean.parseBoolean(args[i-1].toString());
				}else if(typeName.equalsIgnoreCase("java.lang.String")){
					objs[i] = args[i-1].toString();
				}
			}else{
				if(typeName.equalsIgnoreCase("int")){
					objs[i] = 0;
				}else if(typeName.equalsIgnoreCase("long")){
					objs[i] = 0;
				}else if(typeName.equalsIgnoreCase("boolean")){
					objs[i] = false;
				}else if(typeName.equalsIgnoreCase("java.lang.String")){
					objs[i] = null;
				}
			}
		}
		return objs;
	}
	
	
}


@Target(value={ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
@interface Intro {
	String value();
}


public class GmOrderManager {
	private Map<String,GmOrder> gmOrders = new HashMap<String, GmOrder>();
	
	private GmOrderManager(){}
	
	private static final class Sington{
		protected static  GmOrderManager instance = new GmOrderManager();
	}
	
	public static GmOrderManager getInstance(){
		return Sington.instance;
	}
	
	/**服务器启动初始化GM命令*/
	public void startServer(){
		Method[] methods = this.getClass().getDeclaredMethods();
		for(Method method : methods){
			Intro intro = method.getAnnotation(Intro.class);
			if(intro != null){
				GmOrder gmOrder = new GmOrder(this,method ,intro);
				gmOrders.put(method.getName().toLowerCase(), gmOrder);
			}
		}
	}
	
	public void executeGmOrder(Hero hero,String orderStr,Object[] objs){
		GmOrder gmOrder = gmOrders.get(orderStr);
		if(gmOrder == null){
			hero.sendDebugMsg(hero, "没有该gm命令!");
			return ;
		}
		gmOrder.execute(hero, objs);
	}
	
	@Intro("查看gm命令")
	void showOrder(Hero hero){
		StringBuffer sb = new StringBuffer("所有GM命令列表:\n");
		for (Iterator<Entry<String, GmOrder>> iterator = gmOrders.entrySet().iterator(); iterator.hasNext();) {
			Entry<String, GmOrder> entry = iterator.next();
			String orderStr = entry.getKey();
			GmOrder gmOrder = entry.getValue();
			String introValue = gmOrder.getIntroValue();
			String typeStr = gmOrder.getMethodParameterTypeStr();
			sb.append(introValue).append("\t").append(orderStr).append("\t").append(typeStr).append("\n");
		}
		hero.sendDebugMsg(hero, sb.toString());
		
	}
	
	@Intro("查询gm命令")
	void findOrder(Hero hero,String name){
		StringBuffer sb = new StringBuffer("GM命令查询结果:\n");
		for (Iterator<Entry<String, GmOrder>> iterator = gmOrders.entrySet().iterator(); iterator.hasNext();) {
			Entry<String, GmOrder> entry = iterator.next();
			String orderStr = entry.getKey();
			boolean flag = false;
			if(orderStr.contains(name)){
				flag = true;
			}
			GmOrder gmOrder = entry.getValue();
			String introValue = gmOrder.getIntroValue();
			if(introValue.contains(name)){
				flag = true;
			}
			String typeStr = gmOrder.getMethodParameterTypeStr();
			if(flag){
				sb.append(introValue).append("\t").append(orderStr).append("\t").append(typeStr).append("\n");
			}
		}
		hero.sendDebugMsg(hero, sb.toString());
	}
	
	@Intro("添加某种道具!")
	void addtool(Hero hero,int itemId,int count,int bind){
		if(count==0){
			count = 1;
		}
		UseAddUtil.add(hero, GameConst.TOOL, count, itemId, bind, false, 0, false);
	}
	
	@Intro("添加某种装备")
	void addequip(Hero hero,int itemId,int count,int bind){
		if(count==0){
			count = 1;
		}
		UseAddUtil.add(hero, GameConst.EQUIP, count, itemId, bind, false, 0, false);
	}
	
	@Intro("当前玩家角色升级")
	void upLevel(Hero hero,int level){
		
	}
	
	@Intro("增加当前玩家经验")
	void addExp(Hero hero,int addExp){
		hero.addExp(addExp);
	}
	
	@Intro("跳场景")
	void jumpScence(Hero hero,int scenceId, int x, int y){
		
	}
	
	@Intro("创建怪物")
	void createMonster(Hero hero,int monsterModelId, int num){
		Monster monster = MonsterKit.createMonster(monsterModelId, hero.getPoint(), 0);
		hero.getIScene().addMonster(monster);
	}
	

	
	@Intro("增加当前玩家属性")
	void addHeroAttr(Hero hero,int attrId,int addAttrValue){
		
	}
	
	@Intro("增加当前玩家某种货币的数量")
	void addMoney(Hero hero,int moneyNum,int moneyType){
		UseAddUtil.add(hero, moneyType, moneyNum, 0, true);
	}
	

}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

GM8283:28位可编程数据选通Channel-Link发送器

窗体顶端 GM8283:28位可编程数据选通Channel-Link发送器 产品概述       GM8283型28位并串转换预加重LVDS发送器主要用于视频/图像传输中的发送部分;它可将并行输...
  • lily688
  • lily688
  • 2015年07月04日 17:06
  • 218

用nginx+uwsgi+redis实现游戏GM聊天功能

原始需求一个客服GM能够加所有游戏服内的玩家为好友,并能进行聊天。具体功能如下: * GM上、下线 * 加游戏玩家为好友 * 删游戏玩家为好友 * GM发送聊天消息 * 玩家推送聊天消息 ...

实体-组件-系统(ECS)实现数据驱动的游戏框架

ECS实现数据驱动的游戏框架

游戏外挂技术:编程实现内存检索(检索内存中指定数据)

1.目标,通过程序检索植物大战僵尸雪的值,并将雪的值修改(这个时候得使用dll的方式才能够实现): 2.打开MemSearch工具。截图如下: 上面(0x20337520)是通过M...

游戏制作工具--GM,适合初学者

  • 2009年04月07日 12:43
  • 3.9MB
  • 下载

第7章 事件驱动编程:编写一个视频游戏

/* * hello.c * purpose show the minimal calls needed to use curses * outline initialize, draw s...
  • teffi
  • teffi
  • 2016年12月14日 19:02
  • 111

游戏GM后台客服工具包

  • 2011年01月18日 14:52
  • 14.12MB
  • 下载

GM汽车诊断仪MDI驱动

  • 2017年11月20日 23:26
  • 107.64MB
  • 下载

内核编程学习笔记(004) 对某某游戏的驱动双开的分析及其学习

目前网络游戏,由于外(和谐)挂盛行,在游戏中加了很多很多的防护校验,我们耳熟能详的有TP,NP,HS,xtrap,apex等,在游戏加载前都可以看到它们的身影。作为一个初学内核驱动的菜鸟,看着高手们辗...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据驱动编程 游戏GM的实现
举报原因:
原因补充:

(最多只允许输入30个字)