block效果
ActorObject.java
我们在AttackAbleObject和Enemy类之间,新增一个类层次ActorObject;ActorObject类型主要实现sprite被攻击后的阻塞效果(一种后退效果)。
AttackAbleObject类型主要负责hitbox和hurtbox。
有些对象可能没有阻塞效果,比如后面我们会介绍的野狗对象,这样野狗类就可以继承AttackAbleObject;
而像player和enemy这些有阻塞效果的对象,我们就让他们继承ActorObject
另外我们还把一些之前在AttackAbleObject类中实现的方法转移到了ActorObject类中,具体看源码。
阻塞效果主要由blockEffect()方法实现:
总体思想是实现一种后退的效果,后退时我们不想实现成是匀速的,希望开始时少退些,后来多退些,故这里我们使用了正弦函数。
另外在我们判断出当前对象正在遭受攻击时,设置_blocked = true
而在update方法中,如果我们判断blocked为true,我们就调用blockEffect()方法,展示阻塞效果。
public abstract class ActorObject extends AttackAbleObject{ private Animator _animator; private double _flipCord = 1; private float _xBlockOffset = 90f; private double _blockDelay = 700; private double _blockSpeed = 1.5; // private double _blockStrength = 2.0; private double _blockStrength = 0.2; private double _blockDelayTimer = _blockDelay; private int _hp = 0; private int _maxHp = 0; private boolean _blocked = false; private boolean _blockedFromRight = true; public ActorObject(Animator anim, int hp, int strength, int hurt_x, int hurt_y, int hurtscale_x, int hurtscale_y, int hitoffset_x1, int hitoffset_y1, int hitoffset_x2, int hitoffset_y2){ super(anim,strength,hurt_x,hurt_y,hurtscale_x,hurtscale_y,hitoffset_x1,hitoffset_y1,hitoffset_x2,hitoffset_y2); _animator = anim; _hp = hp; } public Animator getAnimator(){ return _animator; } @Override public void move(double x,double y){ super.move(x, y); if(x>0 && _flipCord<0){ _animator.flip(); _flipCord = x; } if(x<0 && _flipCord>0){ _animator.flip(); _flipCord = x; } } public void update(Graphics2D g){ if(!isDead()){ _animator.show(g); if(isBlocked()){ blockEffect(); } setHitting(false); } } abstract void handleAttack(); abstract void attack(); abstract void idle(); public void takeDamage(AttackAbleObject dyn){ setHp(getHp()-dyn.getStrength()); } public boolean isDead(){ return getHp()<=0; } public boolean isHit(AttackAbleObject dyn){ if(!isDead()){ if(!_blocked){ if(dyn.hasHitBoxCollide(this) && dyn.isHitting()){ if(!dyn.getTransform().isFlippedRight()){ _blockedFromRight = false; }else{ _blockedFromRight = true; } _blocked = true; return true; } else{ return false; } } } return false; } public void setBlocked(boolean bl){ _blocked = bl; } public boolean isBlocked(){ return _blocked; } public boolean isBlockedFromRight(){ return _blockedFromRight; } public void setHp(int hp){ _hp = hp; } public int getHp(){ return _hp; } public void setMaxHp(int max){ _maxHp = max; } public int getMaxHp(){ return _maxHp; } void blockEffect(){ _xBlockOffset -= _blockSpeed; double y = Math.toRadians(_xBlockOffset); if(getX()>50 && getX()<555){ if(isBlockedFromRight()){ _animator.translate(Math.sin(y)*_blockStrength, 0); }else{ _animator.translate(-Math.sin(y)*_blockStrength, 0); } } _blockDelayTimer -= Config.TIMER_DIF; if(_blockDelayTimer<=0){ setBlocked(false); _blockDelayTimer = _blockDelay; _xBlockOffset = 100; } } }
同时,在Enemy类的update方法中,我们判断如果对象当前的状态是block,我们就设置block动画。
public class Enemy extends ActorObject{ private Animator _animator; private Player _player; private double _speed = 1.5; @Override public void update(Graphics2D g){ if(!this.isDead()){ _animator.show(g); super.update(g); if(!isDead()){ if(isBlocked()){ getAnimator().setAnimation("block"); } else{ if(!getAnimator().isPlaying("idle") && !getAnimator().isPlaying("block") ){ getAnimator().setAnimation("idle"); } } followPath(); if(this.isHit(_player)){ this.takeDamage(_player); } } } }
如果您迷路了,请参考完整源码: