自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

第一篇:一个防御塔+多个野怪(简易版)第二篇:防御塔随意放置第三篇:防御塔随意放置+多组野怪
1、动态addView防御塔
2、防御塔放置后不可以移动
3、弯曲道路
4、素材替换
第四篇:多波野怪
第五篇:杀死野怪获得金币
第六篇:防御塔可升级,增强攻击力 , 增大射程

自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

文章插图
描述:防御塔可以放置多个,每一个都是独立的,他们的攻击互不影响(防御塔随意拖动在第二篇),这里用到的知识是,自定义view的拖动,防御塔是否可以攻击的计算,防御塔的攻击路径 。
1、放置防御塔
  • 新建类ActivityTower5,主要控制放置塔的回调
  • 新建BattlefieldView5,主要渲染战场
  • 新建TowerView5,主要绘制防御塔 , (其实野怪也需要单独创建view)
1.1ActivityTower5首页该做些什么?这次我们想要做成动态的,由用户自行开启,玩累了还能暂停,而且有钱可以创建多个防御塔(后续加入攻击野怪获得金币),所以创建开启按钮 , 暂停按钮,创建A炮(后续有B炮,C炮...),代码如下
<?xml version="1.0" encoding="utf-8"?><layout><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/layout_relative"......android:gravity="center"......><com.liu.lib_view.tower.tower4.BattlefieldView4android:id="@+id/TowerView"....../><LinearLayoutandroid:id="@+id/bottom"......><Buttonandroid:id="@+id/start"......android:text="开始"/><Buttonandroid:id="@+id/pause"......android:text="暂停"/><Buttonandroid:id="@+id/create"......android:text="创建A炮"/></LinearLayout></RelativeLayout></layout>这次添加一些素材,这些都是在网上随便找的,一个背景图片,一个防御塔,一个野怪 , 这次做成横屏的,我们需要记录一下弯曲道路的xy坐标,封装成一个list(下面有解) 。
自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

文章插图

自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

文章插图

自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

文章插图
1.2、BattlefieldView5渲染战场集成ViewGroup,因为我们要在里面添加其他View , 只有ViewGroup才有addView方法,这里我们声明一些属性 , 妖怪大道、野怪、防御塔画笔这些必不可少 , 我们这次是多个防御塔就要创建towerList来存储我们创建的防御塔,野怪数量也是如此 。
注意:集成ViewGroup这里要写setWillNotDraw方法,不然onDraw()不执行 。
我们设置完背景图片后,开始渲染战?。?首先绘制道路,这次是弯曲的,会用到Path类,
  • ??moveTo(x,y)  移动的起始点
  • ??lineTo(x,y)  从起始点到该点画一条线 。
【自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪】我们按照背景图路线琢磨一下路线坐标(每个手机可能存在差异) , 大概是如下
@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);towerX = w / 2;towerY = h / 2;roadPath = new Path();roadPath.moveTo(0,900);roadPath.lineTo(500,900);roadPath.lineTo(500,200);roadPath.lineTo(800,200);roadPath.lineTo(800,800);roadPath.lineTo(1600,800);roadPath.lineTo(1600,200);roadPath.lineTo(towerX*2,200);}
自定义View6 -塔防小游戏:第三篇防御塔随意放置+多组野怪

文章插图
大体路线已经出来了 , 我们需要获取这条线上的坐标点 , pathMeasure类可以获取path路径上的点数
源码解析
pathMeasure.getLength()获取点数pathMeasure.getPosTan(距离,pos,tan);源码解释:* @param distance The distance along the current contour to sample 沿轮廓到样本的距离* @param pos If not null, returns the sampled position (x==[0], y==[1])* @param tan If not null, returns the sampled tangent (x==[0], y==[1])* @return false if there was no path associated with this measure object*/public boolean getPosTan(float distance, float pos[], float tan[]) {if (pos != null && pos.length < 2 ||tan != null && tan.length < 2) {throw new ArrayIndexOutOfBoundsException();}return native_getPosTan(native_instance, distance, pos, tan);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);......pathMeasure = new PathMeasure();pathMeasure.setPath(roadPath,false);}

推荐阅读