v0.6.2: all enemies now have health bars if they are injured

removed sad ghost specific health bar
This commit is contained in:
Evan Debenham 2017-09-02 02:37:35 -04:00
parent 1d800853cb
commit 8122e961ee
11 changed files with 120 additions and 59 deletions

View File

@ -62,7 +62,7 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant; import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.TargetHealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
@ -299,7 +299,7 @@ public class CursedWand {
ch.destroy(); ch.destroy();
ch.sprite.killAndErase(); ch.sprite.killAndErase();
Dungeon.level.mobs.remove(ch); Dungeon.level.mobs.remove(ch);
HealthIndicator.instance.target(null); TargetHealthIndicator.instance.target(null);
GameScene.add(sheep); GameScene.add(sheep);
CellEmitter.get(sheep.pos).burst(Speck.factory(Speck.WOOL), 4); CellEmitter.get(sheep.pos).burst(Speck.factory(Speck.WOOL), 4);
} else { } else {

View File

@ -41,7 +41,7 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant; import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual; import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTiledVisual;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.TargetHealthIndicator;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundlable; import com.watabou.utils.Bundlable;
@ -310,7 +310,7 @@ public class PrisonBossLevel extends Level {
Actor.remove(tengu); Actor.remove(tengu);
mobs.remove(tengu); mobs.remove(tengu);
HealthIndicator.instance.target(null); TargetHealthIndicator.instance.target(null);
tengu.sprite.kill(); tengu.sprite.kill();
Room maze = new MazeRoom(); Room maze = new MazeRoom();

View File

@ -70,12 +70,13 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner; import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.CharHealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog; import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane; import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.TargetHealthIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toast; import com.shatteredpixel.shatteredpixeldungeon.ui.Toast;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar; import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
@ -147,6 +148,7 @@ public class GameScene extends PixelScene {
private Group spells; private Group spells;
private Group statuses; private Group statuses;
private Group emoicons; private Group emoicons;
private Group healthIndicators;
private Toolbar toolbar; private Toolbar toolbar;
private Toast prompt; private Toast prompt;
@ -156,9 +158,6 @@ public class GameScene extends PixelScene {
private ActionIndicator action; private ActionIndicator action;
private ResumeIndicator resume; private ResumeIndicator resume;
//temporary, see Ghostsprite
public Group ghostHP;
@Override @Override
public void create() { public void create() {
@ -230,12 +229,11 @@ public class GameScene extends PixelScene {
emitters = new Group(); emitters = new Group();
effects = new Group(); effects = new Group();
emoicons = new Group(); emoicons = new Group();
healthIndicators = new Group();
mobs = new Group(); mobs = new Group();
add( mobs ); add( mobs );
ghostHP = new Group();
for (Mob mob : Dungeon.level.mobs) { for (Mob mob : Dungeon.level.mobs) {
addMobSprite( mob ); addMobSprite( mob );
if (Statistics.amuletObtained) { if (Statistics.amuletObtained) {
@ -284,9 +282,9 @@ public class GameScene extends PixelScene {
hero.updateArmor(); hero.updateArmor();
mobs.add( hero ); mobs.add( hero );
add( new HealthIndicator() ); add( healthIndicators );
//always appears ontop of other health indicators
add( ghostHP ); add( new TargetHealthIndicator() );
add( cellSelector = new CellSelector( tiles ) ); add( cellSelector = new CellSelector( tiles ) );
@ -701,6 +699,10 @@ public class GameScene extends PixelScene {
scene.emoicons.add( icon ); scene.emoicons.add( icon );
} }
public static void add( CharHealthIndicator indicator ){
if (scene != null) scene.healthIndicators.add(indicator);
}
public static void effect( Visual effect ) { public static void effect( Visual effect ) {
scene.effects.add( effect ); scene.effects.add( effect );
} }

View File

@ -39,6 +39,7 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.CharHealthIndicator;
import com.watabou.glwrap.Matrix; import com.watabou.glwrap.Matrix;
import com.watabou.glwrap.Vertexbuffer; import com.watabou.glwrap.Vertexbuffer;
import com.watabou.noosa.Camera; import com.watabou.noosa.Camera;
@ -96,7 +97,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
protected Emitter chilled; protected Emitter chilled;
protected Emitter marked; protected Emitter marked;
protected Emitter levitation; protected Emitter levitation;
protected Emitter health; protected Emitter healing;
protected IceBlock iceBlock; protected IceBlock iceBlock;
protected DarkBlock darkBlock; protected DarkBlock darkBlock;
@ -104,6 +105,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
protected AlphaTweener invisible; protected AlphaTweener invisible;
protected EmoIcon emo; protected EmoIcon emo;
protected CharHealthIndicator health;
private Tweener jumpTweener; private Tweener jumpTweener;
private Callback jumpCallback; private Callback jumpCallback;
@ -130,6 +132,14 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
turnTo( ch.pos, Random.Int( Dungeon.level.length() ) ); turnTo( ch.pos, Random.Int( Dungeon.level.length() ) );
renderShadow = true; renderShadow = true;
if (ch != Dungeon.hero) {
if (health == null) {
health = new CharHealthIndicator(ch);
} else {
health.target(ch);
}
}
ch.updateSpriteState(); ch.updateSpriteState();
} }
@ -238,6 +248,10 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
if (emo != null) { if (emo != null) {
emo.killAndErase(); emo.killAndErase();
} }
if (health != null){
health.killAndErase();
}
} }
public Emitter emitter() { public Emitter emitter() {
@ -324,8 +338,8 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
marked.pour(ShadowParticle.UP, 0.1f); marked.pour(ShadowParticle.UP, 0.1f);
break; break;
case HEALING: case HEALING:
health = emitter(); healing = emitter();
health.pour(Speck.factory(Speck.HEALING), 0.5f); healing.pour(Speck.factory(Speck.HEALING), 0.5f);
} }
} }
@ -384,9 +398,9 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
} }
break; break;
case HEALING: case HEALING:
if (health != null){ if (healing != null){
health.on = false; healing.on = false;
health = null; healing = null;
} }
break; break;
} }
@ -477,6 +491,10 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
if (emo != null) { if (emo != null) {
emo.killAndErase(); emo.killAndErase();
} }
if (health != null){
health.killAndErase();
}
} }
private float[] shadowMatrix = new float[16]; private float[] shadowMatrix = new float[16];

View File

@ -24,24 +24,14 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import android.opengl.GLES20; import android.opengl.GLES20;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShaftParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShaftParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthBar;
import com.watabou.noosa.TextureFilm; import com.watabou.noosa.TextureFilm;
import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL10;
//FIXME the healthbar added here is a quick fix.
// The game should have a much more flexible health bar system which works for any character
// However I want a ghost HP bar to get into 0.6.1, so this will have to do for now.
public class GhostSprite extends MobSprite { public class GhostSprite extends MobSprite {
private HealthBar hpBar;
public GhostSprite() { public GhostSprite() {
super(); super();
@ -64,24 +54,6 @@ public class GhostSprite extends MobSprite {
play( idle ); play( idle );
} }
@Override
public void link(Char ch) {
super.link(ch);
if (ch instanceof DriedRose.GhostHero){
final Char finalCH = ch;
hpBar = new HealthBar(){
@Override
public synchronized void update() {
super.update();
hpBar.setRect(finalCH.sprite.x, finalCH.sprite.y-3, finalCH.sprite.width, hpBar.height());
hpBar.level( finalCH );
visible = finalCH.sprite.visible;
}
};
((GameScene)ShatteredPixelDungeon.scene()).ghostHP.add(hpBar);
}
}
@Override @Override
public void draw() { public void draw() {
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE ); GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE );
@ -92,7 +64,6 @@ public class GhostSprite extends MobSprite {
@Override @Override
public void die() { public void die() {
super.die(); super.die();
if (hpBar != null) hpBar.killAndErase();
emitter().start( ShaftParticle.FACTORY, 0.3f, 4 ); emitter().start( ShaftParticle.FACTORY, 0.3f, 4 );
emitter().start( Speck.factory( Speck.LIGHT ), 0.2f, 3 ); emitter().start( Speck.factory( Speck.LIGHT ), 0.2f, 3 );
} }

View File

@ -178,7 +178,7 @@ public class AttackIndicator extends Tag {
lastTarget = (Mob)target; lastTarget = (Mob)target;
instance.updateImage(); instance.updateImage();
HealthIndicator.instance.target( target ); TargetHealthIndicator.instance.target( target );
} }
public static void updateState() { public static void updateState() {

View File

@ -0,0 +1,72 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2017 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
public class CharHealthIndicator extends HealthBar {
private static final int HEIGHT = 1;
private Char target;
public CharHealthIndicator( Char c ){
target = c;
GameScene.add(this);
}
@Override
protected void createChildren() {
super.createChildren();
height = HEIGHT;
}
@Override
public void update() {
super.update();
if (target != null && target.isAlive() && target.sprite.visible) {
CharSprite sprite = target.sprite;
width = sprite.width()*(4/6f);
x = sprite.x + sprite.width()/6f;
y = sprite.y - 2;
level( target );
visible = target.HP < target.HT;
} else {
visible = false;
}
}
public void target( Char ch ) {
if (ch != null && ch.isAlive()) {
target = ch;
} else {
target = null;
}
}
public Char target() {
return target;
}
}

View File

@ -102,7 +102,7 @@ public class DangerIndicator extends Tag {
Mob target = Dungeon.hero.visibleEnemy(enemyIndex++); Mob target = Dungeon.hero.visibleEnemy(enemyIndex++);
HealthIndicator.instance.target(target == HealthIndicator.instance.target() ? null : target); TargetHealthIndicator.instance.target(target == TargetHealthIndicator.instance.target() ? null : target);
if (Dungeon.hero.curAction == null) { if (Dungeon.hero.curAction == null) {
Camera.main.target = null; Camera.main.target = null;

View File

@ -60,15 +60,13 @@ public class HealthBar extends Component {
Bg.x = Shld.x = Hp.x = x; Bg.x = Shld.x = Hp.x = x;
Bg.y = Shld.y = Hp.y = y; Bg.y = Shld.y = Hp.y = y;
Bg.size( width, HEIGHT ); Bg.size( width, height );
//logic here rounds up to the nearest pixel //logic here rounds up to the nearest pixel
float pixelWidth = width; float pixelWidth = width;
if (camera() != null) pixelWidth *= camera().zoom; if (camera() != null) pixelWidth *= camera().zoom;
Shld.size( width * (float)Math.ceil(shield * pixelWidth)/pixelWidth, HEIGHT ); Shld.size( width * (float)Math.ceil(shield * pixelWidth)/pixelWidth, height );
Hp.size( width * (float)Math.ceil(health * pixelWidth)/pixelWidth, HEIGHT ); Hp.size( width * (float)Math.ceil(health * pixelWidth)/pixelWidth, height );
height = HEIGHT;
} }
public void level( float value ) { public void level( float value ) {

View File

@ -230,7 +230,7 @@ public class QuickSlotButton extends Button implements WndBag.Listener {
if (target != Dungeon.hero) { if (target != Dungeon.hero) {
lastTarget = target; lastTarget = target;
HealthIndicator.instance.target( target ); TargetHealthIndicator.instance.target( target );
} }
} }

View File

@ -24,13 +24,13 @@ package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
public class HealthIndicator extends HealthBar { public class TargetHealthIndicator extends HealthBar {
public static HealthIndicator instance; public static TargetHealthIndicator instance;
private Char target; private Char target;
public HealthIndicator() { public TargetHealthIndicator() {
super(); super();
instance = this; instance = this;