设计模式(一)--观察者模式实践--简单沙盒游戏应用

设计模式--观察者模式实践--简单沙盒游戏应用

什么是观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
详细的介绍,可以参照下面的文章。
观察者模式(Java代码)

本文主要讲解一个简单的沙盒游戏中的应用。

沙盒游戏实践

要做什么

我需要做一个小游戏,游戏的大致就是有一个N*N的棋盘,里面会有玩家操作的英雄,以及随机刷出来的陷阱,宝藏,怪物及终点。这些物品的位置随机的,玩家不知道,玩家需要操作英雄找到重点,即算过关。由于主旨演示观察者模式,所以游戏设计从简。
游戏界面示意图

代码实现

  • 创建观察者

创建一个观察者抽象类,里面定义了这个观察者所在的位置,以及判定是否触发观察者事件的判断方法、观察者实际的事件处理抽象方法。

abstract class Observer {
    Integer x;
    Integer y;

    abstract void update(int x, int y);

    boolean inRange(int x, int y){
        return x == this.x && y == this.y;
    }
}

创建怪物观察者对象,怪物位置在生成时,随机指定位置。实现怪物的事件方法。以下同理,创建宝藏,陷阱,终点对象。

public class Monster extends Observer {

    Monster(int x, int y){
        super.x = x;
        super.y = y;
    }
    @Override
    public void update(int x, int y) {

        if(inRange(x,y)){
            System.out.println("attacked by Monster !");
        }
    }
}

宝藏

public class Treasure extends Observer {

    Treasure(int x, int y){
        super.x = x;
        super.y = y;
    }

    @Override
    public void update(int x, int y) {

        if(inRange(x,y)){
            System.out.println("oh, my treasures !");
        }
    }
}

陷阱

public class Trap extends Observer {

    Trap(int x, int y){
        super.x = x;
        super.y = y;
    }

    @Override
    public void update(int x, int y) {

        if(inRange(x,y)){
            System.out.println("oh, it's a trap!");
        }
    }
}

终点

public class Goal extends Observer {

    Trap(int x, int y){
        super.x = x;
        super.y = y;
    }

    @Override
    public void update(int x, int y) {

        if(inRange(x,y)){
            System.out.println("congratulations, you win ! ");
        }
    }
}

创建被观察者抽象类,记录被观察者位置,观察者列表,以及加入和删除观察者方法。唤醒观察者,并处理处理事件。

abstract public class Subject {
    private List<Observer> observerList = new ArrayList<>();
    Integer x;
    Integer y;

    public void attachObserver(Observer observer){
        this.observerList.add(observer);
    }

    public void dettachObserver(Observer observer){
        this.observerList.remove(observer);
    }

    public void notifyObserver(){
        for(Observer observer : observerList){
            observer.update(this.x,this.y);
        }
    }
}

创建玩家操作的英雄类。提供了玩家可以发出的指令,以及英雄作出的处理。每次操作之后,都会唤醒观察者。

public class Hero extends Subject {

    Hero(int x, int y){
        this.x = x;
        this.y = y;
    }

    public void moveLeft(){
        System.out.println("move left");
        if(this.x > 1){
            this.x--;
            doMove();
            notifyObserver();
        }
    }

    public void moveRight(){
        System.out.println("move right");

        if(this.x < 5){
            this.x++;
            doMove();
            notifyObserver();
        }
    }

    public void moveUp(){
        System.out.println("move up");

        if(this.y > 1){
            this.y--;
            doMove();
            notifyObserver();
        }
    }

    public void moveDown(){
        System.out.println("move down");

        if(this.y < 5){
            this.y++;
            doMove();
            notifyObserver();
        }
    }

    private void doMove(){
        System.out.println("my current location is ("+this.x+","+this.y+")");
    }
}

我们写一个简单的测试类来测试我们的观察者模式。

public class Test {

    public static void main(String[] args){

        // 创建英雄,英雄的位置,可以在初始时随机指定,此处刷在棋盘左上角
        Hero hero = new Hero(1,1);
        // 创建怪物实例,位置也可随机指定,此处固定在1,2
        // 以下类似创建陷阱,宝藏,终点
        Monster monster = new Monster(1,2);
        Trap trap = new Trap(3,2);
        Treasure treasure = new Treasure(2,1);
        Goal goal = new Goal(3,1);

        // 将观察者加入观察者列表
        hero.attachObserver(monster);
        hero.attachObserver(trap);
        hero.attachObserver(treasure);
        hero.attachObserver(goal);
        
        // 一系列玩家操作
        hero.moveRight();
        hero.moveDown();
        hero.moveLeft();
        hero.moveRight();
        hero.moveRight();
        hero.moveUp();

    }
}

游戏输出结果

move right
my current location is (2,1)
oh, my treasures !
move down
my current location is (2,2)
move left
my current location is (1,2)
attacked by Monster !
move right
my current location is (2,2)
move right
my current location is (3,2)
oh, it's a trap!
move up
my current location is (3,1)
congratulations, you win ! 

主要是说明观察者模式,没有给出UI实现。希望可以帮助理解观察者模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值