Java来实现DLC

        我发现很多游戏有DLC,当你基础的游戏模块玩的没有意思的时候,开发者可以开发出新的dlc版本,或者可以开发API给玩家,让玩家自定义的开发自己想要的游戏,突然想试试用java来实现这个功能.

        目标:本体可以加载jar文件并且执行jar文件下指定的class类

step1 创建了一个共享的接口库

并且随便创建了3个接口

分别为IGame,相当于这个游戏的api

package com.games.apis;

public interface IGame {
    void whenPlayerTakeDamager(IPlayer player);
    void addPlayer(IPlayer player);
    IPlayer getPlayer(int id);
}

IPlayer,类似玩家,怪物等

package com.games.apis;

public interface IPlayer {
    int getId();

}

IGameRoom 游戏的具体规则(这个类就是dlc需要修改的类)

package com.games.apis;

public interface IGameRoom {
    void whenInit(IGame game);
    void whenStart(IGame game);
    void whenFrame(IGame game);
    void whenStop(IGame game);
}

为了开发方便直接上传到本地库中

step2 创建游戏本地

并且实现了Room和Player类 只是大致的实现了一下

import com.games.apis.IPlayer;

public class Player implements IPlayer {
    public final int id;

    public Player(int id) {
        this.id = id;
    }

    @Override
    public int getId() {
        return this.id;
    }
}
package com.games;

import com.games.apis.IGame;
import com.games.apis.IGameRoom;
import com.games.apis.IPlayer;

import java.util.ArrayList;
import java.util.List;

public class Room implements IGame {

    private List<IPlayer> allPlayerList = new ArrayList<>();


    @Override
    public void whenPlayerTakeDamager(IPlayer iPlayer) {
        System.out.println(iPlayer.getId() +"Room.whenPlayerTakeDamager ");
    }

    @Override
    public void addPlayer(IPlayer iPlayer) {
        allPlayerList.add(iPlayer);
    }

    @Override
    public IPlayer getPlayer(int i) {
        for (int j = 0; j < allPlayerList.size(); j++) {
            if(allPlayerList.get(j).getId() == i){
                return allPlayerList.get(j);
            }
        }
        return null;
    }
}

如何加载jar文件等下再说

step3 创建具体的实现dlc的项目

引用共享库后创建一个类

具体的ExploedRoom

package com.games;

import com.games.apis.IGame;
import com.games.apis.IGameRoom;
public class ExploedRoom implements IGameRoom{

    @Override
    public void whenInit(IGame iGame) {
        new OtherHelp().tesssst1();
        System.out.println("whenInit = " + iGame);
    }

    @Override
    public void whenStart(IGame iGame) {
        iGame.whenPlayerTakeDamager(iGame.getPlayer(2));
        System.out.println("whenStart = " + iGame);
    }

    @Override
    public void whenFrame(IGame iGame) {
        System.out.println("whenFrame = " + iGame);
    }

    @Override
    public void whenStop(IGame iGame) {
        System.out.println("whenStop = " + iGame);
    }
}

为了测试是否可以自动引用加载其它的类我增加了一个OtherHelp的类

package com.games;

public class OtherHelp {
    public void tesssst1(){
        System.out.println("哈哈哈阿斯顿");
    }
}

package成一个jar包就行

step4 如何加载jar

再回到本地的项目中

实现Main方法

import com.games.Player;
import com.games.Room;
import com.games.apis.IGameRoom;
import com.games.java.net.ClsLoad;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarFile;

public class Main {
    String jarFilePath = "G:\\jw_workspace\\dlcTest\\testPlationApi\\dlc1\\target\\dlc1-1.0-SNAPSHOT.jar";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        new Main().test1();
    }

    private void test1() throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        ClsLoad classLoader = new ClsLoad(new URL[]{});
        URL jarUrl = new File(jarFilePath).toURI().toURL();
        classLoader.addURL(jarUrl);
        Class<?> loadedClass = classLoader.loadClass("com.games.ExploedRoom");
        IGameRoom o = (IGameRoom) loadedClass.getDeclaredConstructor().newInstance();
        Room room = new Room();
        Player p1 = new Player(1);
        Player p2 = new Player(2);
        Player p3 = new Player(3);
        room.addPlayer(p1);
        room.addPlayer(p2);
        room.addPlayer(p3);

        o.whenInit(room);
        o.whenStart(room);
        o.whenFrame(room);
        o.whenStop(room);
        System.out.println(1);
    }
}

这里为啥是CLsLoad是因为addURL这个方法是protected权限的,所以我自己弄了一个ClsLoad的类

package com.games.java.net;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;

public class ClsLoad extends URLClassLoader{
    public ClsLoad(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    public ClsLoad(URL[] urls) {
        super(urls);
    }

    public ClsLoad(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
        super(urls, parent, factory);
    }

    public ClsLoad(String name, URL[] urls, ClassLoader parent) {
        super(name, urls, parent);
    }

    public ClsLoad(String name, URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
        super(name, urls, parent, factory);
    }

    @Override
    public void addURL(URL url) {
        super.addURL(url);
    }


}

主要是开发addURL的权限

一切准备就绪之后运行结果

之后只要将共享API 提供给其它人开发出来的jar可以结合本体运行了,

大致的思路就是这样

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值