`
Linkcqu
  • 浏览: 14611 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

圣斗士星矢的状态(State)模式和观察者(Observer)模式

UI 
阅读更多

星矢:动画片《圣斗士星矢》的男猪脚,超级小强,怎么打也打不死。
雅典娜:动画片《圣斗士星矢》的女猪脚,自称女神,手下有88个男人为他卖命。


状态模式:为了方便的控制状态的变化,避免一堆IF/ELSE,以及状态规则改变的时避免代码改动的混乱。
观察者模式:一个被观察者一动,多个观察者跟着动,经常用于界面UI。

话说星矢和很强的某斗士甲对打,雅典娜在一边看,星矢总是挨揍,每次挨揍完之后星矢的状态总是会发生一些变化:

正常--挨打--瀕死--挨打--小宇宙爆发--挨打--瀕死--挨打--女神护体--挨打(星矢无敌了,打也没用,战斗结束)--正常

以上状态转变用状态模式来表现,一个Saiya类代表星矢,一个SaiyaState代表他的状态,SaiyaState下面有多个子类,分别代表星矢的多种状态,如正常NORMAL、瀕死DYING、小宇宙爆发UNIVERSE、女神护体GODDESS,即把状态抽象成对象,在每种状态里面实现被打的时候所需要更改的状态,这样就避免了每次被打都要进行一次IF/ELSE的判断。


Java代码
public class Saiya extends Observable {
//定义星矢的四种状态
public final SaiyaState NORMAL = new NormalState(this);

public final SaiyaState DYING = new DyingState(this);

public final SaiyaState GODDESS = new GoddessState(this);

public final SaiyaState UNIVERSE = new UniverseState(this);

private SaiyaState state=NORMAL;

private SaiyaState laststate=null;

public void hit(){
//调用当前状态的被打方法 反过来改变自己的状态
state.hit();
}
public String status(){
//当前状态名
return state.status();
}

protected void setState(SaiyaState state){
laststate=this.state;
this.state=state;
//观察者模式
setChanged();
notifyObservers("星矢状态变化");
}

public String getlastStatus(){
return laststate.status();
}
public class Saiya extends Observable {
//定义星矢的四种状态
public final SaiyaState NORMAL = new NormalState(this);
public final SaiyaState DYING = new DyingState(this);
public final SaiyaState GODDESS = new GoddessState(this);
public final SaiyaState UNIVERSE = new UniverseState(this);
private SaiyaState state=NORMAL;
private SaiyaState laststate=null;
public void hit(){
//调用当前状态的被打方法 反过来改变自己的状态
state.hit();
}
public String status(){
//当前状态名
return state.status();
}
protected void setState(SaiyaState state){
laststate=this.state;
this.state=state;
//观察者模式
setChanged();
notifyObservers("星矢状态变化");
}
public String getlastStatus(){
return laststate.status();
}


星矢的状态

Java代码
public abstract class SaiyaState {
protected Saiya saiya;

public SaiyaState(Saiya saiya) {
this.saiya = saiya;
}

public String status(){
String name=getClass().getName();
return name.substring(name.lastIndexOf(".")+1);
}
//星矢被打了
public abstract void hit();
}
public abstract class SaiyaState {
protected Saiya saiya;
public SaiyaState(Saiya saiya) {
this.saiya = saiya;
}
public String status(){
String name=getClass().getName();
return name.substring(name.lastIndexOf(".")+1);
}
//星矢被打了
public abstract void hit();
}


在每种状态里面实现被打的时候所需要更改的状态,例如小宇宙爆发状态下被打

Java代码
public class UniverseState extends SaiyaState {

/**
* @param saiya
*/
public UniverseState(Saiya saiya) {
super(saiya);

}

/* 小宇宙爆发状态被打进入瀕死状态
*
*/

public void hit() {
saiya.setState( saiya.DYING);

}

}
public class UniverseState extends SaiyaState {
/**
* @param saiya
*/
public UniverseState(Saiya saiya) {
super(saiya);
}
/* 小宇宙爆发状态被打进入瀕死状态
*
*/
public void hit() {
saiya.setState( saiya.DYING);
}
}


雅典娜在一边看,星矢每次被打她都要给星矢加油,她是个观察者,星矢是被观察者,这里星矢实现java.util.Observable,每次被打hit就notifyObservers,雅典娜就加油。

Java代码
public class Athena implements Observer {

/* 我是雅典娜 我是观察者
*
*/
public void update(Observable arg0, Object arg1) {
System.out.println("雅典娜说:星矢加油啊!!!");
}

}
public class Athena implements Observer {
/* 我是雅典娜 我是观察者
*
*/
public void update(Observable arg0, Object arg1) {
System.out.println("雅典娜说:星矢加油啊!!!");
}
}


总的来看 这个过程就是这样子:

Java代码
public class StateMain {
public static void main(String[] args) {

Saiya saiya = new Saiya();
Observer athena = new Athena();
saiya.addObserver(athena);
System.out.println("星矢最初的状态是:" + saiya.status());
for (int i = 0; i < 5; i++) {
System.out.println("星矢被揍了" + (i + 1) + "次");
saiya.hit();
System.out.println("星矢现在的状态是:" + saiya.status());
}
}
}
public class StateMain {
public static void main(String[] args) {
Saiya saiya = new Saiya();
Observer athena = new Athena();
saiya.addObserver(athena);
System.out.println("星矢最初的状态是:" + saiya.status());
for (int i = 0; i < 5; i++) {
System.out.println("星矢被揍了" + (i + 1) + "次");
saiya.hit();
System.out.println("星矢现在的状态是:" + saiya.status());
}
}
}



结果星矢在雅典娜的帮助下,有惊无险的战胜了很强的某斗士甲:


Java代码
星矢最初的状态是:NormalState
星矢被揍了1次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:DyingState
星矢被揍了2次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:UniverseState
星矢被揍了3次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:DyingState
星矢被揍了4次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:GoddessState
星矢被揍了5次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:NormalState
星矢最初的状态是:NormalState
星矢被揍了1次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:DyingState
星矢被揍了2次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:UniverseState
星矢被揍了3次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:DyingState
星矢被揍了4次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:GoddessState
星矢被揍了5次
雅典娜说:星矢加油啊!!!
星矢现在的状态是:NormalState


总结:状态模式的缺点就是会弄出很多子类,如果状态没那么复杂,状态规则改变的可能性比较小的话就不要用了

 

分享到:
评论

相关推荐

    圣斗士星矢——黄金十二宫(游戏+源码)重发

    《圣斗士星矢——黄金十二宫》是一款以经典动漫《圣斗士星矢》为背景的游戏,结合了丰富的剧情和战斗元素。这次提供的资源包括游戏的可执行文件"seiya.exe"以及游戏源码"SeiyaSource.rar",这对于想要深入理解游戏...

    圣斗士星矢——VB黄金十二宫(游戏+源码)

    在这款游戏中,开发者利用VB的控件、函数和过程,模拟了圣斗士星矢中的黄金十二宫场景,玩家可以通过控制角色,挑战各个宫殿的守卫,体验原作的冒险历程。 游戏的源码是理解VB编程思想和技巧的重要窗口。通过对源码...

    圣斗士星矢ol完整云服务器架设.txt

    完整云服务器架设

    【翻译】圣斗士星矢:圣域传说 制作介绍 特效合成等1

    本文主要介绍了《圣斗士星矢:圣域传说》这部动画电影在制作过程中采用的特效合成技术以及内部工具的开发和应用。随着3D图形技术的发展,动画制作的管线构建和管理变得越来越重要。东映动画数字影像部针对这一需求,...

    圣斗士网站

    "圣斗士网站"就是这样一款以经典动漫《圣斗士星矢》为主题的网页设计项目,旨在为粉丝们提供一个交流、分享与回忆的平台。本文将深入探讨如何运用网页设计技巧和工具,如Dreamweaver,来打造这样一个充满激情与力量...

    圣斗士星失天界篇花絮

    圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮

    游戏素材(圣斗士格斗图)

    圣斗士星矢是一部经典的日本动漫,其角色拥有各种独特的技能和战斗风格,因此在游戏化的过程中,这些元素将被转化为可交互的游戏资源。 "afrodita"、"andromeda"、"Aioria"和"14124"是压缩包内的子文件名,这些名称...

    圣斗士星矢 Matlab Game.zip:圣斗士星斗格斗游戏-matlab开发

    用户应该运行saintseiya_att_sel.m 来开始格斗游戏。 用户可以随机获得一个圣人和一个敌人,并开始一对一的战斗。 每个圣人都有一个宇宙和生命(HP)属性。... 他们的中文名字是:星矢紫龙冰河瞬态一辉穆阿

    OBLOG 圣斗士

    首先,模板中的“圣斗士”主题意味着它可能包含了与《圣斗士星矢》动漫相关的视觉元素,如角色插图、动漫风格的图形以及与故事相关的色彩搭配。这样的设计不仅能够吸引动漫爱好者,还可以为网站增添独特的个性和情感...

    连连看,关卡版

    - 不断的版本更新和优化,可能会增加新的关卡、新的游戏模式或新的挑战,保持游戏的新鲜感。 - 社区互动和分享功能,允许玩家分享自己的成绩和经验,增加游戏的社交性。 总的来说,连连看关卡版在保留了经典游戏...

    算法实验报告 勇闯十二宫

    于是青铜圣斗士星矢决定冒死突破十二宫。 守卫十二宫的黄金圣斗士能在强大的星矢面前坚持的时间是不同的,星矢想让所有黄金圣斗士平均等待的时间最短,请问黄金圣斗士的最短平均等待时间是多少?

    圣斗士星矢测验:在React Alura入侵期间进行的简单测验

    具有样式组件的示例应用 此示例介绍了如何使用与样式不同的样式解决方案,还支持通用样式。... 在这种情况下,我们使用 。 为此,我们扩展了并将服务器端渲染的样式注入到&lt;head&gt; ,并且还添加了babel-plugin-...

    天使之翼2代(chinese)

    《天使之翼2代》(又称《圣斗士星矢:黄金传说最后的任务》)是基于日本知名漫画《圣斗士星矢》改编的游戏。玩家在游戏中扮演不同的圣斗士,通过一系列战斗,挑战强大的敌人,体验原作的故事线。游戏的故事情节紧密...

    Xiuno BBS 高负载安全论坛 v2.1.0 Build20130830

    Xiuno 这个名字来源于圣斗士星矢白羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    xiuno bbs 手机版插件 v1.3

    xiuno 这个名字来源于圣斗士星矢山羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    matlab开发-圣西山塔布加姆齐普

    在本项目中,“matlab开发-圣西山塔布加姆齐普”指的是利用MATLAB这一强大的数值计算和编程环境来开发一个名为“圣西山塔布加姆齐普”的游戏,这款游戏似乎与圣斗士星矢("圣西娅打斗游戏")的世界观有关。...

    星座黄金圣斗士经典广告词.doc

    这篇文档虽然以《星座黄金圣斗士经典广告词》为标题,但实际上它是一种创意写作,将知名动漫角色“圣斗士星矢”中的角色与广告语结合,创造了一系列幽默诙谐的场景。这些广告词涉及了各种产品,如服装、食品、个人...

    xiuno bbs 手机版插件 v1.3.zip

    xiuno 这个名字来源于圣斗士星矢山羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    你已经死了!动漫界八大杀手人物盘点收集.pdf

    例如,夜神月(《死亡笔记》)、冥王哈迪斯(《圣斗士星矢》)、飞影(《幽游白书》)、健次郎(《北斗神拳》)和鲁鲁修(《叛逆的鲁鲁修》)等,都是动漫中知名的杀手或类似角色。 2. **夜神月**:作为《死亡笔记...

    李炎恢DreamWeaver视频教程的素材和源码

    至于"圣斗士星矢"和"火影忍者疾风传",这些可能是动漫主题的网页项目,你可以从中学习如何创建动态和引人入胜的粉丝站点,包括如何插入多媒体内容如视频和音频,以及如何构建社区论坛或评论系统。 最后,"专题:...

Global site tag (gtag.js) - Google Analytics