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

到这里,我们就可以拿到路径了,我们还需要把妖怪大道path集合存入到每个野怪属性里,让野怪沿着这条路线走,
public class BlameBean {private int blameId;public int x;public int y;public int speed;//行走速度public int HP;//血量public boolean isAttacks;//是否可以被攻击public boolean wounded;//受伤效果public int position=0;public List<RoadXY> roadXYList = new ArrayList<>();position是走到第几步 , roadXYList就是路线,动态添加6个野怪 , 路线别忘记添加了,3000可以理解为整条路线野怪需要走3000步才能到终点 。
1.3、动态添加野怪/** * 添加一个野怪 */private void addBlame() {if (countDownTimer != null) {return;}countDownTimer = new CountDownTimer(12000, 2000) {@Overridepublic void onTick(long millisUntilFinished) {if (blameList.size() >= 6) {return;}BlameBean blameBean = new BlameBean();blameBean.setHP(100);blameBean.setSpeed(1);blameBean.setX(towerX + 200);blameBean.setY(0);List<BlameBean.RoadXY> roadXYList = blameBean.getRoadXYList();for (int i = 0; i < 3000; i++) {pathMeasure.getPosTan(i/3000f * pathMeasure.getLength(),pos,tan);BlameBean.RoadXY roadXY = new BlameBean.RoadXY();roadXY.setRoadX((int) pos[0]);roadXY.setRoadY((int) pos[1]);roadXYList.add(roadXY);}blameBean.setRoadXYList(roadXYList);blameList.add(blameBean);}@Overridepublic void onFinish() {}};}1.4、添加防御塔,动态创建A炮

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

文章插图
Activity中mBinding.create.setOnClickListener(v ->{TowerView5 towerView = new TowerView5(activity);RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);lp.width = 700;lp.height = 700;towerView.setLayoutParams(lp);//一旦放置成功后调用towerView.setTowerListener(() -> {int raduis = 350;towerView.setMove(false);mBinding.TowerView.addTower((int)towerView.getX()+raduis,(int)towerView.getY()+raduis,raduis);});mBinding.layoutRelative.addView(towerView);listTower.add(towerView);});View中/*** 添加一个防御塔*/public void addTower(int x, int y, int raduis) {TowerBean towerBean = new TowerBean();towerBean.setTowerId(towerList.size());towerBean.setAttacksSpeed(500);towerBean.setHarm(5);towerBean.setX(x);towerBean.setY(y);towerBean.setRaduis(raduis);towerList.add(towerBean);}我们添加完成需要在ondraw方法中绘制出来
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//野怪路线canvas.drawPath(roadPath,roadPaint);//皇帝for (int i = 0; i < blameList.size(); i++) {if (blameList.get(i).getX() > (towerX * 2 - 100) && blameList.get(i).getHP() > 0) {kingHP -= blameList.get(i).getHP();}}if (kingHP <= 0) {kingHP = 0;canvas.drawText("失败", towerX, towerY, tp);valueAnimator.cancel();}canvas.drawText("皇帝" + kingHP, towerX * 2 - 100, 200, tp);//野怪移动for (int i = 0; i < blameList.size(); i++) {BlameBean blameBean = blameList.get(i);if (blameBean.getHP() > 0) {canvas.drawRect(blameBean.getX() - 40, blameBean.getY()-15, blameBean.getX() + 60, blameBean.getY()-5, towerPaint);canvas.drawRect(blameBean.getX() - 39, blameBean.getY() - 10, blameBean.getX() + 58 - (100 - blameBean.getHP()), blameBean.getY() - 10, hpPaint);bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.yeguai2);canvas.drawBitmap(bitmap, blameBean.getX() - 20, blameBean.getY() , tp);}}}写到这里还没有写刷新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));}}}}

推荐阅读