中介者模式在游戏开发中的应用

中介者模式:

定义一个接口用来封装一群对象的互动行为。中介者通过移除对象之间引用,来减少它们之间的耦合度,并且能改变它们之间的互动独立性。

意图:

通过中介者来解决对象之间的通信,使一个对象在不需要知道其它对象的具体信息的情况下通过中介者与之通信,同时通过引用中介者来减少系统对象之间的关系,提高对象的可复用性和可扩展性

需求描述

创建一个简单的小游戏游戏包含MotionSystem(运动系统,控制底部砖块的运动)、ConstructionSystem(建造系统,生成创建立方块)、TimingSystem(计时系统,用于管理游戏时间)、CountSystem(计数系统,用于判定游戏结果),具体关系图如下所示;Midiator作为中介者处理各个系统之间的相互调用。


在这里插入图片描述

Demo如下:

在这里插入图片描述

首先创建每个系统的基类系统IGameSystem.cs:

public interface IGameSystem {
    void OnStart ();
    void OnUpdate ();
    void OnEnd ();
}

运动系统的具体实现,用于控制地面地板的来回运动MotionSystem.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MotionSystem : IGameSystem {
    private Mediator m_mediator;
    private Transform floorTransform;
    private float speed = 2;
    public MotionSystem (Mediator mediator){
        this.m_mediator = mediator;
        floorTransform = GameObject.Find ("Floor").transform;
    }
    public  void OnEnd () {

        floorTransform.GetComponent<Rigidbody> ().velocity = Vector2.zero;
    }
    public  void OnStart () {
        floorTransform.GetComponent<Rigidbody> ().velocity = new Vector3 (speed * 1, 0, 0);
    }
    public  void OnUpdate () {
        if (floorTransform != null) {

            if (Camera.main.WorldToViewportPoint (floorTransform.transform.position).x >= 1) {
                floorTransform.GetComponent<Rigidbody> ().velocity = new Vector3 (speed * -1, 0, 0);
            }
            if (Camera.main.WorldToViewportPoint (floorTransform.transform.position).x <= 0) {
                floorTransform.GetComponent<Rigidbody> ().velocity = new Vector3 (speed * 1, 0, 0);
            }
            
        }
    }
}

计时系统的具体实现,用于控制游戏的倒计时 TimingSystem.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimingSystem : IGameSystem {
	private Text CountDownText;
	private float timeCount = 15;
	private Mediator m_mediator;
	private bool isEnd = false;
	public TimingSystem (Mediator mediator)  {
		this.m_mediator = mediator;
		CountDownText = GameObject.Find ("CountDownText").GetComponent<Text> ();
	}
	public  void OnEnd () {
		isEnd = true;
	}
	public  void OnStart () {
		timeCount = 15;
		isEnd = false;
	}
	public  void OnUpdate () {
		if (isEnd) return;
		timeCount -= Time.deltaTime;
		CountDownText.text = ((int) timeCount).ToString ();
		if (timeCount <= 0) {
			m_mediator.End();
		}
	}
}

建造系统的具体实现,用于游戏过程中立方体的创建 ConstructionSystem.cs:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ConstructionSystem : IGameSystem {
  private Mediator mediator;
  public List<GameObject> gameobjectList = new List<GameObject> ();
  public ConstructionSystem (Mediator mediator) {
    this.mediator = mediator;
  }

  private GameObject BuildGameObject () {
    Vector3 temp = Camera.main.ScreenToWorldPoint (
    new Vector3 (Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));
    temp = new Vector3 (temp.x, 3, 0);

    GameObject obj = MonoBehaviour.Instantiate (Resources.Load<GameObject> ("CubePrefab"));
    obj.transform.position = temp;

    gameobjectList.Add (obj);

    return obj;
  }
  public void OnEnd () {
    for (int i = 0; i < gameobjectList.Count; i++) {
      // gameobjectList[i].gameObject.SetActive (false);
      gameobjectList[i].GetComponent<Rigidbody> ().Sleep ();
    }

  }
  public void OnStart () {
    
    for (int i = 0; i < gameobjectList.Count; i++) {
      gameobjectList[i].gameObject.SetActive (false);
    }
    gameobjectList.Clear ();
  }

  public void OnUpdate () {
    GameObject obj = null;
    if (Input.GetMouseButtonDown (0)) {
      obj = BuildGameObject ();
    }
    if (obj != null) {
      if (obj.transform.position.y < -6) {
        Debug.Log ("超出");
      }
    }
  }
}

计数系统的具体实现,用于在游戏结束时结算游戏结果 CountSystem.cs:

计数系统通过中介者和建造系统交换信息
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CountSystem : IGameSystem {
	private Text scoreText;

	private int currentCount = 0;
	private Mediator m_mediator;

	public CountSystem (Mediator mediator) {
		this.m_mediator = mediator;
		scoreText = GameObject.Find ("CountText").GetComponent<Text> ();
	}
	public int CurrentCount {
		get { return currentCount; }
	}
	public void OnUpdate () {
		
	}
	public void OnEnd () {
		for (int i = 0; i < m_mediator.constructionSystem.gameobjectList.Count; i++)
		{
			if (m_mediator.constructionSystem.gameobjectList[i].transform.position.y>-3){
				currentCount++;
			}
		}
		scoreText.text = "当前总数:" + currentCount.ToString () + "\n"+"按空格重新开始";
	}
	public void OnStart () {
		currentCount = 0;
		scoreText.text = currentCount.ToString ();
	}
}

中介者的实现 BaseMediator.cs&& Mediator.cs

public abstract class BaseMediator{
    public abstract void Start();
    public abstract void Update();
    public abstract void End();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mediator : BaseMediator {
    public ConstructionSystem constructionSystem;
    public CountSystem countSystem;
    public MotionSystem motionSystem;
    public TimingSystem timingststem;
    public GameState gameState;
    public void Init () {
        constructionSystem = new ConstructionSystem (this);

        countSystem = new CountSystem (this);

        motionSystem = new MotionSystem (this);

        timingststem = new TimingSystem (this);
    }
    public override void End () {

        timingststem.OnEnd ();

        countSystem.OnEnd ();

        constructionSystem.OnEnd ();

        motionSystem.OnEnd ();

        this.gameState = GameState.GameEnd;
    }
    public override void Start () {
        constructionSystem.OnStart ();
        countSystem.OnStart ();
        motionSystem.OnStart ();
        timingststem.OnStart ();
        this.gameState = GameState.Gameing;
    }
    public override void Update () {

        timingststem.OnUpdate ();

        countSystem.OnUpdate ();

        constructionSystem.OnUpdate ();

        motionSystem.OnUpdate ();

    }
}

游戏控制类的实现 Game.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum GameState {
	Gameing,
	GamePause,
	GameEnd
}

public class Game : MonoBehaviour {
	public Mediator mediator;
	void Awake () {
		mediator = new Mediator ();

		mediator.Init ();
	}

	void Start () {
		mediator.Start ();
	}
	void Update () {
		if (mediator.gameState == GameState.GameEnd) {
			if (Input.GetKeyDown (KeyCode.Space)) {
				mediator.Start ();
			}
		}
		if (mediator.gameState!=GameState.Gameing)return;
		mediator.Update ();
	}
}

扫描关注->当前文章末尾->获取Demo地址:


在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值