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

写到这里还没有写刷新view的代码 , 带着疑问 , 如何刷新数据 , 如何更新野怪行走的数据 , 如何判断是否在开炮射程内 。
public BattlefieldView5(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//ViewGroup不跳过onDraw()方法 , 默认是跳过setWillNotDraw(false);......valueAnimator = ValueAnimator.ofInt(0, 10);valueAnimator.setDuration(5000);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.setRepeatCount(-1);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {updateParticle();invalidate();}});}解释:我们开启一个动画 , 让其不断的重绘 。updateParticle方法最关键 , 记录了野怪移动数据 , 开炮动画等
private void updateParticle() {//野怪移动for (int i = 0; i < blameList.size(); i++) {BlameBean blameBean = blameList.get(i);if(blameBean.getPosition()>=3000){break;}int roadX = blameBean.getRoadXYList().get(blameBean.position).getRoadX();int roadY = blameBean.getRoadXYList().get(blameBean.position).getRoadY();blameBean.setPosition(blameBean.getPosition()+1);blameBean.setX(roadX);blameBean.setY(roadY);//野怪进入防御塔范围isAttacks(i);//开炮动画if (blameList.get(i) != null && blameList.get(i).getMapAttacksTower().size() > 0) {Map<Integer, Integer> listAttacksTower = blameList.get(i).getMapAttacksTower();for (Integer j : listAttacksTower.keySet()) {shotMove(towerList.get(listAttacksTower.get(j)).getX(), towerList.get(listAttacksTower.get(j)).getY(), blameBean.getX(), blameBean.getY(), i, listAttacksTower.get(j));}}}}是否进入防御塔范围 , 这里我们使用map来存int raduis = (int) Math.hypot(Math.abs(x), Math.abs(y));常用于勾股定理 , 如果在防御塔范围内 , 野怪就记录一下id , 如果在两个防御塔内 , 就把两个防御塔的id记录一下 , map的特性 , 不会有key重复 。也就是不会有防御塔重复攻击 。
public class BlameBean {/***使用map的好处是唯一* 被哪些防御塔攻击* */public Map<Integer,Integer> mapAttacksTower=new HashMap<>();private void isAttacks(int position) {for (int j = 0; j < towerList.size(); j++) {int x = blameList.get(position).getX() - towerList.get(j).getX();int y = blameList.get(position).getY() - towerList.get(j).getY();int raduis = (int) Math.hypot(Math.abs(x), Math.abs(y));Map<Integer, Integer> mapAttacksTower = blameList.get(position).getMapAttacksTower();if (raduis < towerList.get(j).getRaduis() && blameList.get(position).getHP() > 0) {mapAttacksTower.put(towerList.get(j).getTowerId(), towerList.get(j).getTowerId());blameList.get(position).setMapAttacksTower(mapAttacksTower);} else {//移除防御塔//攻击到该野怪塔的集合for (Integer key : mapAttacksTower.keySet()) {if (mapAttacksTower.get(key) == towerList.get(j).getTowerId()) {mapAttacksTower.remove(key);blameList.get(position).setMapAttacksTower(mapAttacksTower);break;}}}}}开炮动画 , 遍历野怪可被攻击的集合即可
//开炮动画if (blameList.get(i) != null && blameList.get(i).getMapAttacksTower().size() > 0) {Map<Integer, Integer> listAttacksTower = blameList.get(i).getMapAttacksTower();for (Integer j : listAttacksTower.keySet()) {shotMove(towerList.get(listAttacksTower.get(j)).getX(), towerList.get(listAttacksTower.get(j)).getY(), blameBean.getX(), blameBean.getY(), i, listAttacksTower.get(j));}}1.5、炮弹动画判断如果可以攻击了 , 就开启一个从xy(防御塔) , 移动到x2y2 (野怪)的动画  , 动画结束后掉血 。动画开始时不可能再次开启 , 要符合防御塔一次只能攻击一个野怪的效果 , 这里开炮动画有点问题 , 就是视觉上老是打偏 , 有的时候炮弹慢的话 , 就会打在野怪身后 , 也没有好的解决方式 。博友有想法请留言 。

经验总结扩展阅读