slay the spire杀戮尖塔mod制作(2)卡牌

(许多代码是反编译学来的,如有雷同可能我参考的就是你的代码【doge】)

书接上文

准备工作完成,可以开始写东西了。

卡牌

制作卡牌需要继承CustomCard

先看构造方法

public CustomCard(String id, String name, String img, int cost, String rawDescription, AbstractCard.CardType type, AbstractCard.CardColor color, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, name, "status/beta", "status/beta", cost, rawDescription, type, color, rarity, target);
        this.textureImg = img;
        if (img != null) {
            this.loadCardImage(img);
        }

        this.initializeInherentMods();
    }

    public CustomCard(String id, String name, RegionName img, int cost, String rawDescription, AbstractCard.CardType type, AbstractCard.CardColor color, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, name, "status/beta", img.name, cost, rawDescription, type, color, rarity, target);
        this.initializeInherentMods();
    }

一般调用的是第一个

id即卡牌的id,name为卡牌名,img为卡绘路径,cost 费用,rawDescription 描述,type 类型(攻击能力技能),color卡色(即属于哪一卡池),rarity稀有度,target目标

搞个抽象类


public abstract class AbstractModCard extends CustomCard {
    
    public AbstractModCard(String id, String img, int cost, AbstractCard.CardType type, AbstractCard.CardColor color, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, CardCrawlGame.languagePack.getCardStrings(id).NAME, img, cost, CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION, type, color, rarity, target);
        initSwitches();
    }
   
    public void initSwitches(){
      //初始化一下这张卡
    }

    @Override
    public void upgrade() {
       //升级
    }

    @Override
    public void use(AbstractPlayer abstractPlayer, AbstractMonster abstractMonster) {
        //打出的效果
    }
    @Override
    public boolean canUse(AbstractPlayer p,AbstractMonster m){
        //什么时候能用?
        return super.canUse(p,m);
    }
   
}



实际上是读了本地化文件的东西,id写规范点就很舒服了

当然你完全可以多重载几次构造方法,比如默认使用自定义卡池,使用id通过字符串操作默认设置img路径(当然你得在对应的地方放卡绘)

类似这样

public static String getResPath(){
    return "ModResources/";
}
public static String getImgPath(){
    return getResPath() + "img/";
}
public static String makeCardImgPath(String cardName){
    return getImgPath() + "cards/" + cardName + ".png";
}
 public AbstractModCard(String id, String name, String img, int cost, String rawDescription, CardType type, CardColor color, CardRarity rarity, CardTarget target) {
        super(id, name, img, cost, rawDescription, type, color, rarity, target);
        initSwitches();
    }
    public AbstractModCard(String id, String img, int cost, AbstractCard.CardType type, AbstractCard.CardColor color, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, CardCrawlGame.languagePack.getCardStrings(id).NAME, img, cost, CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION, type, color, rarity, target);
        initSwitches();
    }
    public AbstractModCard(String id, int cost, AbstractCard.CardType type, AbstractCard.CardColor color, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, CardCrawlGame.languagePack.getCardStrings(id).NAME, ModInfo.makeCardImgPath(id.split(":")[1]), cost, CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION, type, color, rarity, target);
        initSwitches();
    }

    public AbstractModCard(String id, int cost, AbstractCard.CardType type, AbstractCard.CardRarity rarity, AbstractCard.CardTarget target) {
        super(id, CardCrawlGame.languagePack.getCardStrings(id).NAME, ModInfo.makeCardImgPath(id.split(":")[1]), cost, CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION, type, CardEnum.MY_CARD, rarity, target);
        initSwitches();
    }

    public AbstractModCard(String id, int cost, AbstractCard.CardType type, AbstractCard.CardRarity rarity) {
        super(id, CardCrawlGame.languagePack.getCardStrings(id).NAME, ModInfo.makeCardImgPath(id.split(":")[1]), cost, CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION, type, CardEnum.MY_CARD, rarity, CardTarget.NONE);
        initSwitches();
    }

以下代码使用了上述构造方法,不多说了

做张打防

代码

public class Strike extends AbstractModCard {
    public static final String ID = "Mod:Strike";
    public Strike() {
        super(ID,1,CardType.ATTACK,CardRarity.BASIC,CardTarget.ENEMY);
        //this.tags.add(BaseModCardTags.BASIC_STRIKE);
        this.baseDamage = 6;
    }
    public void use(AbstractPlayer p, AbstractMonster m){
        addToBot(new DamageAction(m,new DamageInfo(p,this.damage,this.damageTypeForTurn), AbstractGameAction.AttackEffect.SLASH_HORIZONTAL));
    }
    @Override
    //升级
    public void upgrade(){
        if(!this.upgraded){//只能升级一次
            upgradeName();//变个名(给个加号
            upgradeDamage(4);//伤害加4
        }
    }
}
public class Defend extends AbstractModCard {
    public static final String ID = "Mod:Defend";
    public Defend(){
        super(ID,1,CardType.SKILL,CardRarity.BASIC,CardTarget.SELF);
        this.tags.add(BaseModCardTags.BASIC_DEFEND);
        this.baseBlock = 5;
    }
    public void use(AbstractPlayer p, AbstractMonster m){
        addToBot(new GainBlockAction(p,this.block));
    }
    public void upgrade(){
        if(!this.upgraded){
            upgradeName();
            upgradeBlock(3);
        
        }
    }
}

实际上卡牌使用后一般会触发一个action来实现想要的效果。

如打击使用DamageAction造成伤害,防使用GainBlockAction来获取格挡

addToBot方法就是将一个action放在底部,等待其他action完成再进行。

同理也可以使用addToTop方法放在顶部优先执行。

自己也可以自定义action(先挖个坑

卡绘

打防的卡绘不要忘记加上,在正确的路径中放图片,图片的名字也要跟自己在代码中填的一样。

同时,一张卡需要两张分辨率不一样的图片,如打击需要配一张Strike.png(250×190)和一张Strike_p.png(500×380)

本地化

cards.json

{
   "Mod:Strike":{
   "NAME" :"打击",
    "DESCRIPTION": "造成 !D! 点伤害。"
  },
  "Mod:Defend":{
    "NAME": "防御",
    "DESCRIPTION": "获得 !B! 点 格挡 。"
  }
}

!D!对应baseDamage值

!B!对应baseBlock值

NL 换行

遇到关键词(keyword)时

如"格挡"为在游戏中会被解释的关键词,需要两边专门空一格出来

如文本 :  ...获得 格挡 后....         

( !D! 之类的同理)

注册

还记得那个注册类吗?我们的自定义内容都必须先注册才能被成功加载!

假设我们的注册类为Main

@SpireInitializer
public class Main{
   public static void initialize(){
        new Main();
    }
}

我们在前文自定义了卡池MY_CARD,需要先注册才能使用

需要有卡牌的模板,建议直接拿官方的图来改

belike:

这里需要调用BaseMod.addColor

先来看看这个方法

​
public static void addColor(AbstractCard.CardColor color, Color everythingColor, String attackBg, String skillBg, String powerBg, String energyOrb, String attackBgPortrait, String skillBgPortrait, String powerBgPortrait, String energyOrbPortrait, String cardEnergyOrb) {
        addColor(color, everythingColor, everythingColor, everythingColor, everythingColor, everythingColor, everythingColor, everythingColor, attackBg, skillBg, powerBg, energyOrb, attackBgPortrait, skillBgPortrait, powerBgPortrait, energyOrbPortrait, cardEnergyOrb);
    }

​

各个参数分别为:要添加的卡色、颜色、攻击模板、技能模板、能力模板、能量球显示(就是左下角显示你有多少费的)、攻击模板(大)、技能模板(大)、能力模板(大)、卡面能量球(大)、卡面能量球(小)

有大小之分是因为你选中一张卡它会变答辩

拿官方的图做参考,自己ps设计一下像素大小就可以了(只是练习照搬就可以)

@SpireInitializer
public class Main{
    public Main(){
        BaseMod.subscribe(this);
        BaseMod.addColor(MY_CARD,Color.BLUE,......);//后面路径上面已说过,自己填
    }
    public static void initialize(){
        new Main();
    }
}

添加完颜色,可以注册本地化了

为了方便可以写个静态方法

public static String makeLocalizationPath(String lang,String content){
    return getResPath() + "localization/" + lang + "/" + content + ".json";
}

@Override
    public void receiveEditStrings() {
        if (Settings.language == Settings.GameLanguage.ZHS) {
            lang = "ZHS";
        } else {
            lang = "ENG";
        }
        BaseMod.loadCustomStringsFile(CardStrings.class, ModInfo.makeLocalizationPath(lang, "cards"));
        //BaseMod.loadCustomStringsFile(CharacterStrings.class, ModInfo.makeLocalizationPath(lang, "characters"));
        //BaseMod.loadCustomStringsFile(RelicStrings.class, ModInfo.makeLocalizationPath(lang, "relics"));
        //BaseMod.loadCustomStringsFile(PotionStrings.class, ModInfo.makeLocalizationPath(lang, "potions"));
        //BaseMod.loadCustomStringsFile(PowerStrings.class, ModInfo.makeLocalizationPath(lang, "powers"));
        //BaseMod.loadCustomStringsFile(UIStrings.class,ModInfo.makeLocalizationPath(lang, "UIs"));
    }

 注释起来的之后会用到

如果不打算做别的语言可以不用细致划分

注册卡牌

@Override
    public void receiveEditCards() {
        BaseMod.addCard(new Strike());
        BaseMod.addCard(new Defend());
    }

也可以一键注册

@Override
    public void receiveEditCards() {
        String cardsClassPath = "xxx.cards";//填卡牌类的路径
        (new AutoAdd(ModInfo.MOD_NAME)).packageFilter(cardsClassPath).setDefaultSeen(true).any(AbstractCard.class, (info, card) -> {
            BaseMod.addCard(card);
        });
    }

拿下!!

未完待续。。。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值