飞碟游戏改进

改进飞碟游戏

  • 游戏内容要求:
    • adapter模式 设计图修改飞碟游戏
    • 使它同时支持物理运动与运动学(变换)运动

要求是使用adapter模式修改飞碟游戏,但是我的代码并不适合这样修改。

适合使用adapter模式有三种情况:

  • 系统需要使用现有的类,而此类的接口不符合系统的需要。
  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。
  • 通过接口转换,将一个类插入另一个类系中。

对于放飞飞碟,我是用一个moveable类赋予飞碟运动的能力,这个moveable类并没有上层接口,其本身是一种能力。飞碟通过拥有一个moveable的实例获得了运动学运动的能力。其中moveable的代码如下:

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

public class Moveable: MonoBehaviour {
	int move_speed = 1;
	
	// change frequently
	int moving_status;	// 0->not moving, 1->moving to middle, 2->moving to dest
	Vector3 dest;
	Vector3 middle;

	void Update() {
		
		if (moving_status == 1) {
			// Debug.Log(transform.position);
			moveTo(transform.position, dest, move_speed * Time.deltaTime);
			// ufoAction.moveTo(this.gameObject,transform.position, dest, move_speed * Time.deltaTime);
			// transform.position = Vector3.MoveTowards (transform.position, dest, move_speed * Time.deltaTime);
			if (transform.position == dest) {
				moving_status = 0;
			}
		}
	}
	

	
	void moveTo(Vector3 pos, Vector3 des, float speed){
		this.transform.position = Vector3.MoveTowards (pos, des, speed);
	}
	public void setDestination(Vector3 _dest,int speed) {
		move_speed = speed;
		dest = _dest;
		moving_status = 1;
	}

	public void reset() {
		moving_status = 0;
	}
}

使用moveable的示例如下:

public class UFO {      
	public GameObject ufo;
	public Moveable ms;
	void start(){
		ufo = Object.Instantiate (Resources.Load ("Prefabs/disk1", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
		ms = ufo.AddComponent(typeof(Moveable)) as Moveable;
		ms.setDestination(new Vector3(0,0,0),10);
	}
}

这种情况下要满足题目第二个条件并不适合用适配器模式,因为Moveable本身不依赖于任何一个GameObject,也没有上层接口。

不过,要让游戏同时支持物理运动与运动学(变换)运动在我的代码中非常容易实现,这也是我不想强行使用适配器模式的原因之一。为了满足要求,我们只需要增添一个physicMoveable类即可,飞碟类同时拥有moveable的一个实例和physicMoveable的一个实例,也就是说,飞碟类同时拥有了物理运动和变换运动的能力。只需要在Fly函数中决定使用哪一种运动能力即可。

因此,整份代码需要修改的地方只有两处。

  1. 增加一个physicMoveable类,采用物理运动的方式
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class physicMoveable : MonoBehaviour
{
	public float r_speed;
	public float u_speed;
	void start(){
		r_speed = 0.0f;
		u_speed = 0.0f;
	}
	
	void setSpeed(float R_speed,float U_speed){
		this.r_speed = R_speed;
		this.u_speed = U_speed;
	}
	
	public void moveTo(Vector3 pos, Vector3 des, float speed){
		float disX = des.x -pos.x;
		float disY = Mathf.Abs( pos.y -des.y);
		float disF =  disX * disX + disY * disY;
		float dis = Mathf.Sqrt(disF);
		float speedX = speed * (disX / dis / 2);
		float speedY = speed * (disY / dis / 2);
		setSpeed(speedX,speedY);
	}

	void FixedUpdate(){
		if(!this.gameObject.GetComponent<Rigidbody>()){
            this.gameObject.AddComponent<Rigidbody>();
        }
		Rigidbody rigid = this.gameObject.GetComponent<Rigidbody>();
		if(rigid){
			rigid.useGravity = false;
			rigid.AddForce(Vector3.right * r_speed);
			rigid.AddForce(Vector3.up * u_speed);
		}else{
			Debug.Log("no rigid");
		}
	}
}

  1. 在UFO类中增加一个physicMoveable的实例,只需要增加几行代码即可,具体增加代码的位置请看注释。
public class UFO {
		public GameObject ufo;
		public int type;
		public int speed;
		public int score = 1;                   
		public Moveable ms;
		
		// 增加physicMoveable实例pt
		public physicMoveable pt;
		
		public UFO(int ufo_type){
			
			type = ufo_type;
			Debug.Log("right here UFO 1");
			if (type == 1) {
				speed = 5;
				ufo = Object.Instantiate (Resources.Load ("Prefabs/disk1", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            } else if (type == 2)  {
				speed = 8;
				score = 2;
                ufo = Object.Instantiate (Resources.Load ("Prefabs/disk2", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            } else {
				speed = 10;
				score = 3;
                ufo = Object.Instantiate (Resources.Load ("Prefabs/disk3", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            }
			ms = ufo.AddComponent(typeof(Moveable)) as Moveable;
			
			// 添加physicMoveable组件
			pt = ufo.AddComponent(typeof(physicMoveable)) as physicMoveable;
		}
		
		public void Fly(){
			int fy0 = Random.Range(-10,10);
			ufo.transform.position = new Vector3(0,fy0,0);
			int fy = Random.Range(-10,10);
			Vector3 des = new Vector3(20,fy,0);
			Vector3 start = ufo.transform.position;
			
			// 选择哪个就取消哪个的注释
			pt.moveTo(start,des,speed);
			// ms.setDestination(des,speed);
		}
	}

这样实现的好处有以下几点:

  • 代码复用率高,因此工作量小。上个版本所有的代码都可以复用,只需要增加一个类以及修改一个类即可

  • 更改运动模式方便。只需要注释一行代码以及取消一行注释就可以实现(以下代码选自BaseCode.cs中的UFO类):

    			// 选择哪个就取消哪个的注释
    			pt.moveTo(start,des,speed);
    			// ms.setDestination(des,speed);
    

github传送门

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值