场景中的动态物件

场景中除了像1002.json这样的地图配置文件,直接配置某些物件的具体位置等,还会有些能在游戏中和玩家交互,如被吃、被敲碎、定时刷新等等这样的动态物件。

方便统一术语,这里把动态物件统一称为球。

本项目中有6种:

类型 说明
食物(食物球) 食物可以被吃、定时刷新
动态障碍物(蘑菇球) 动态障碍物可以被敲碎、定时刷新
炸弹[食物](食物球) 炸弹(食物),可以被吃、定时刷新,并让玩家可以丢一次炸弹
锤子[食物](食物球) 锤子(食物),可以被吃、定时刷新,并让玩家可以丢一次锤子
玩家(玩家球) 玩家,本质上来说也是一种场景中的动态物件。

mope\server\config\xml\food.xml

该配置文件中,定义了各种动态物件,按大类分主要有3类:

  1. 食物 (主要定义,大小、刷新时间、总数量)
  2. 动态障碍物(主要定义,大小、刷新时间、总数量)
  3. 技能球(主要定义,大小)

项目食物生成代码分析 - Scene.go

在 Scene::Init() -> this.reset() -> this.CreateAllBirthPoint(this) 开始执行食物生成

// 生成食物 、 动态障碍物
func (this *SceneBirthPointHelper) CreateAllBirthPoint(scene *Scene) {
    var xlist, ylist []float64
    items := conf.ConfigMgr_GetMe().GetXmlFoodItems(scene.SceneID())
    for _, item := range items.Items {
        ftype := item.FoodType
        fid := item.FoodId
        birthTime := item.BirthTime
        foodnum := conf.ConfigMgr_GetMe().GetFoodMapNum(scene.SceneID(), fid)
        size := float64(conf.ConfigMgr_GetMe().GetFoodSize(scene.SceneID(), fid))
        if foodnum > 0 {
            for i := 0; i < int(foodnum); i++ {
                x, y, op := scene.GetPos()
                if op {
                    point := NewBirthPoint(scene.NewBallId(), float32(x), float32(y), float32(size), float32(size), fid, ftype, birthTime, 1, scene)
                    this.AddBirthPoint(point)
                }
                if ftype == uint16(usercmd.BallType_FoodNormal) {
                    xlist = append(xlist, x)
                    ylist = append(ylist, y)
                }
            }
        }
    }
    for i := 0; i < len(xlist); i++ {
        scene.ReturnPos(xlist[i], ylist[i])
    }
}
  • 读取配置food.xml( items := conf.ConfigMgr_GetMe().GetXmlFoodItems(scene.SceneID()) )
  • 创建食物、动态障碍物 生成器对象( point := NewBirthPoint(...) )

项目食物生成器代码分析 - BirthPoint.go

  • 创建食物、动态障碍物

    func (this *BirthPoint) CreateUnit() interfaces.IBall {
      this.childrenCount++
      scene := this.scene
      var ball interfaces.IBall
      ballType := interfaces.BallTypeToKind(usercmd.BallType(this.ballType))
      switch ballType {
      case interfaces.BallKind_Food:
          posNew := BallFood_InitPos(&this.pos, usercmd.BallType(this.ballType), this.birthRadiusMin, this.birthRadiusMax)
          ball = bll.NewBallFood(this.id, this.ballTypeId, float64(posNew.X), float64(posNew.Y), scene)
      case interfaces.BallKind_Feed:
          x := math.Floor(float64(this.pos.X)) + 0.25
          y := math.Floor(float64(this.pos.Y)) + 0.25
          ball = bll.NewBallFeed(scene, this.ballTypeId, this.id, x, y)
      default:
          glog.Error("CreateUnit unknow ballType:", ballType, "  typeid:", this.ballTypeId)
      }
    
      ball.SetBirthPoint(this)
      return ball
    }
    

    创建食物 ( ball = bll.NewBallFood(...) )

    创建动态障碍物 ( ball = bll.NewBallFeed(scene, this.ballTypeId, this.id, x, y) )

  • 定时刷新

    func (this *BirthPoint) Refresh(perTime float64, scene *Scene) {
      if this.childrenCount >= this.birthMax {
          return
      }
      if this.birthTimer >= this.birthTime {
          this.birthTimer = 0
          this.CreateUnit()
      } else {
          this.birthTimer += perTime
      }
    }
    

    当食物、动态障碍物少于指定数量时,调用 this.CreateUnit()

项目食物类代码分析 - BallFood.go

食物球是所有其他球基类。

比较简单,代码分析略

results matching ""

    No results matching ""