v0.6.2a: reworked key display, new max of 6 keys at once
system is also more flexible, more keys can be added later.
This commit is contained in:
parent
f95adc7452
commit
e9b8bc3490
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 404 B |
|
@ -110,7 +110,6 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndAlchemy;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndAlchemy;
|
||||||
|
@ -1467,7 +1466,7 @@ public class Hero extends Char {
|
||||||
Notes.remove(new SkeletonKey(Dungeon.depth));
|
Notes.remove(new SkeletonKey(Dungeon.depth));
|
||||||
Level.set( doorCell, Terrain.UNLOCKED_EXIT );
|
Level.set( doorCell, Terrain.UNLOCKED_EXIT );
|
||||||
}
|
}
|
||||||
StatusPane.needsKeyUpdate = true;
|
GameScene.updateKeyDisplay();
|
||||||
|
|
||||||
Level.set( doorCell, door == Terrain.LOCKED_DOOR ? Terrain.DOOR : Terrain.UNLOCKED_EXIT );
|
Level.set( doorCell, door == Terrain.LOCKED_DOOR ? Terrain.DOOR : Terrain.UNLOCKED_EXIT );
|
||||||
GameScene.updateMap( doorCell );
|
GameScene.updateMap( doorCell );
|
||||||
|
@ -1482,7 +1481,7 @@ public class Hero extends Char {
|
||||||
} else if (heap.type == Type.CRYSTAL_CHEST){
|
} else if (heap.type == Type.CRYSTAL_CHEST){
|
||||||
Notes.remove(new CrystalKey(Dungeon.depth));
|
Notes.remove(new CrystalKey(Dungeon.depth));
|
||||||
}
|
}
|
||||||
StatusPane.needsKeyUpdate = true;
|
GameScene.updateKeyDisplay();
|
||||||
heap.open( this );
|
heap.open( this );
|
||||||
}
|
}
|
||||||
curAction = null;
|
curAction = null;
|
||||||
|
|
|
@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndJournal;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndJournal;
|
||||||
import com.watabou.noosa.audio.Sample;
|
import com.watabou.noosa.audio.Sample;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
|
@ -54,7 +53,7 @@ public abstract class Key extends Item {
|
||||||
Notes.add(this);
|
Notes.add(this);
|
||||||
Sample.INSTANCE.play( Assets.SND_ITEM );
|
Sample.INSTANCE.play( Assets.SND_ITEM );
|
||||||
hero.spendAndNext( TIME_TO_PICK_UP );
|
hero.spendAndNext( TIME_TO_PICK_UP );
|
||||||
StatusPane.needsKeyUpdate = true;
|
GameScene.updateKeyDisplay();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -746,6 +746,10 @@ public class GameScene extends PixelScene {
|
||||||
public static void flashJournal(){
|
public static void flashJournal(){
|
||||||
if (scene != null) scene.pane.flash();
|
if (scene != null) scene.pane.flash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateKeyDisplay(){
|
||||||
|
if (scene != null) scene.pane.updateKeys();
|
||||||
|
}
|
||||||
|
|
||||||
public static void resetMap() {
|
public static void resetMap() {
|
||||||
if (scene != null) {
|
if (scene != null) {
|
||||||
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
* 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 android.graphics.RectF;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.GoldenKey;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.Key;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
|
import com.watabou.gltextures.SmartTexture;
|
||||||
|
import com.watabou.gltextures.TextureCache;
|
||||||
|
import com.watabou.glwrap.Quad;
|
||||||
|
import com.watabou.glwrap.Vertexbuffer;
|
||||||
|
import com.watabou.noosa.NoosaScript;
|
||||||
|
import com.watabou.noosa.Visual;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class KeyDisplay extends Visual {
|
||||||
|
|
||||||
|
private float[] vertices = new float[16];
|
||||||
|
private FloatBuffer quads;
|
||||||
|
private Vertexbuffer buffer;
|
||||||
|
|
||||||
|
private SmartTexture tx = TextureCache.get(Assets.MENU);
|
||||||
|
|
||||||
|
private boolean dirty = true;
|
||||||
|
private int[] keys;
|
||||||
|
|
||||||
|
//mapping of key types to slots in the array, 0 is reserved for black (missed) keys
|
||||||
|
//this also determines the order these keys will appear (lower first)
|
||||||
|
//and the order they will be truncated if there is no space (higher first, larger counts first)
|
||||||
|
private static final HashMap<Class<? extends Key>, Integer> keyMap = new HashMap<>();
|
||||||
|
static {
|
||||||
|
keyMap.put(SkeletonKey.class, 1);
|
||||||
|
keyMap.put(CrystalKey.class, 2);
|
||||||
|
keyMap.put(GoldenKey.class, 3);
|
||||||
|
keyMap.put(IronKey.class, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int totalKeys = 0;
|
||||||
|
|
||||||
|
public KeyDisplay() {
|
||||||
|
super(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateKeys(){
|
||||||
|
keys = new int[keyMap.size()+1];
|
||||||
|
|
||||||
|
for (Notes.KeyRecord rec : Notes.getRecords(Notes.KeyRecord.class)){
|
||||||
|
if (rec.depth() < Dungeon.depth){
|
||||||
|
//only ever 1 black key
|
||||||
|
keys[0] = 1;
|
||||||
|
} else if (rec.depth() == Dungeon.depth){
|
||||||
|
keys[keyMap.get(rec.type())] += rec.quantity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalKeys = 0;
|
||||||
|
for (int k : keys){
|
||||||
|
totalKeys += k;
|
||||||
|
}
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int keyCount(){
|
||||||
|
return totalKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw() {
|
||||||
|
super.draw();
|
||||||
|
if (dirty){
|
||||||
|
|
||||||
|
updateVertices();
|
||||||
|
|
||||||
|
quads.limit(quads.position());
|
||||||
|
if (buffer == null)
|
||||||
|
buffer = new Vertexbuffer(quads);
|
||||||
|
else
|
||||||
|
buffer.updateVertices(quads);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NoosaScript script = NoosaScript.get();
|
||||||
|
|
||||||
|
tx.bind();
|
||||||
|
|
||||||
|
script.camera( camera() );
|
||||||
|
|
||||||
|
script.uModel.valueM4( matrix );
|
||||||
|
script.lighting(
|
||||||
|
rm, gm, bm, am,
|
||||||
|
ra, ga, ba, aa );
|
||||||
|
script.drawQuadSet( buffer, totalKeys, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateVertices(){
|
||||||
|
//assumes shorter key sprite
|
||||||
|
int maxRows = (int)(height +1) / 5;
|
||||||
|
|
||||||
|
//1 pixel of padding between each key
|
||||||
|
int maxPerRow = (int)(width + 1) / 4;
|
||||||
|
|
||||||
|
int maxKeys = maxPerRow * maxRows;
|
||||||
|
|
||||||
|
|
||||||
|
while (totalKeys > maxKeys){
|
||||||
|
Class<? extends Key> mostType = null;
|
||||||
|
int mostNum = 0;
|
||||||
|
for (Class<?extends Key> k : keyMap.keySet()){
|
||||||
|
if (keys[keyMap.get(k)] >= mostNum){
|
||||||
|
mostType = k;
|
||||||
|
mostNum = keys[keyMap.get(k)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys[keyMap.get(mostType)]--;
|
||||||
|
totalKeys--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rows = (int)Math.ceil(totalKeys / (float)maxPerRow);
|
||||||
|
|
||||||
|
boolean shortKeys = (rows * 8) > height;
|
||||||
|
float left;
|
||||||
|
if (totalKeys > maxPerRow){
|
||||||
|
left = 0;
|
||||||
|
} else {
|
||||||
|
left = (width + 1 - (totalKeys*4))/2;
|
||||||
|
}
|
||||||
|
float top = (height + 1 - (rows * (shortKeys ? 5 : 8)))/2;
|
||||||
|
quads = Quad.createSet(totalKeys);
|
||||||
|
for (int i = 0; i < totalKeys; i++){
|
||||||
|
int keyIdx = 0;
|
||||||
|
|
||||||
|
if (i == 0 && keys[0] > 0){
|
||||||
|
//black key
|
||||||
|
keyIdx = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (int j = 1; j < keys.length; j++){
|
||||||
|
if (keys[j] > 0){
|
||||||
|
keys[j]--;
|
||||||
|
keyIdx = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//texture coordinates
|
||||||
|
RectF r = tx.uvRect(43 + 3*keyIdx, shortKeys ? 8 : 0,
|
||||||
|
46 + 3*keyIdx, shortKeys ? 12 : 7);
|
||||||
|
|
||||||
|
vertices[2] = r.left;
|
||||||
|
vertices[3] = r.top;
|
||||||
|
|
||||||
|
vertices[6] = r.right;
|
||||||
|
vertices[7] = r.top;
|
||||||
|
|
||||||
|
vertices[10] = r.right;
|
||||||
|
vertices[11] = r.bottom;
|
||||||
|
|
||||||
|
vertices[14] = r.left;
|
||||||
|
vertices[15] = r.bottom;
|
||||||
|
|
||||||
|
//screen coordinates
|
||||||
|
vertices[0] = left;
|
||||||
|
vertices[1] = top;
|
||||||
|
|
||||||
|
vertices[4] = left + 3;
|
||||||
|
vertices[5] = top;
|
||||||
|
|
||||||
|
vertices[8] = left + 3;
|
||||||
|
vertices[9] = top + (shortKeys ? 4 : 7);
|
||||||
|
|
||||||
|
vertices[12] = left;
|
||||||
|
vertices[13] = top + (shortKeys ? 4 : 7);
|
||||||
|
|
||||||
|
quads.put(vertices);
|
||||||
|
|
||||||
|
//move to the right for more keys, drop down if the row is done
|
||||||
|
left += 4;
|
||||||
|
if (left + 3 > width){
|
||||||
|
left = 0;
|
||||||
|
top += (shortKeys ? 5 : 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dirty = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,8 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
|
||||||
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.sprites.HeroSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
|
||||||
|
@ -224,21 +222,23 @@ public class StatusPane extends Component {
|
||||||
public void pickup( Item item, int cell) {
|
public void pickup( Item item, int cell) {
|
||||||
pickedUp.reset( item,
|
pickedUp.reset( item,
|
||||||
cell,
|
cell,
|
||||||
btnJournal.icon.x + btnJournal.icon.width()/2f,
|
btnJournal.journalIcon.x + btnJournal.journalIcon.width()/2f,
|
||||||
btnJournal.icon.y + btnJournal.icon.height()/2f);
|
btnJournal.journalIcon.y + btnJournal.journalIcon.height()/2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flash(){
|
public void flash(){
|
||||||
btnJournal.flashing = true;
|
btnJournal.flashing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needsKeyUpdate = false;
|
public void updateKeys(){
|
||||||
|
btnJournal.updateKeyDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
private static class JournalButton extends Button {
|
private static class JournalButton extends Button {
|
||||||
|
|
||||||
private Image bg;
|
private Image bg;
|
||||||
//used to display key state to the player
|
private Image journalIcon;
|
||||||
private Image icon;
|
private KeyDisplay keyIcon;
|
||||||
|
|
||||||
private boolean flashing;
|
private boolean flashing;
|
||||||
|
|
||||||
|
@ -255,10 +255,13 @@ public class StatusPane extends Component {
|
||||||
|
|
||||||
bg = new Image( Assets.MENU, 2, 2, 13, 11 );
|
bg = new Image( Assets.MENU, 2, 2, 13, 11 );
|
||||||
add( bg );
|
add( bg );
|
||||||
|
|
||||||
icon = new Image( Assets.MENU, 31, 0, 11, 7);
|
journalIcon = new Image( Assets.MENU, 31, 0, 11, 7);
|
||||||
add( icon );
|
add( journalIcon );
|
||||||
needsKeyUpdate = true;
|
|
||||||
|
keyIcon = new KeyDisplay();
|
||||||
|
add(keyIcon);
|
||||||
|
updateKeyDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -267,10 +270,16 @@ public class StatusPane extends Component {
|
||||||
|
|
||||||
bg.x = x + 13;
|
bg.x = x + 13;
|
||||||
bg.y = y + 2;
|
bg.y = y + 2;
|
||||||
|
|
||||||
icon.x = bg.x + (bg.width() - icon.width())/2f;
|
journalIcon.x = bg.x + (bg.width() - journalIcon.width())/2f;
|
||||||
icon.y = bg.y + (bg.height() - icon.height())/2f;
|
journalIcon.y = bg.y + (bg.height() - journalIcon.height())/2f;
|
||||||
PixelScene.align(icon);
|
PixelScene.align(journalIcon);
|
||||||
|
|
||||||
|
keyIcon.x = bg.x + 1;
|
||||||
|
keyIcon.y = bg.y + 1;
|
||||||
|
keyIcon.width = bg.width - 2;
|
||||||
|
keyIcon.height = bg.height - 2;
|
||||||
|
PixelScene.align(keyIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float time;
|
private float time;
|
||||||
|
@ -278,11 +287,10 @@ public class StatusPane extends Component {
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
super.update();
|
super.update();
|
||||||
if (needsKeyUpdate)
|
|
||||||
updateKeyDisplay();
|
|
||||||
|
|
||||||
if (flashing){
|
if (flashing){
|
||||||
icon.am = (float)Math.abs(Math.cos( 3 * (time += Game.elapsed) ));
|
journalIcon.am = (float)Math.abs(Math.cos( 3 * (time += Game.elapsed) ));
|
||||||
|
keyIcon.am = journalIcon.am;
|
||||||
if (time >= 0.333f*Math.PI) {
|
if (time >= 0.333f*Math.PI) {
|
||||||
time = 0;
|
time = 0;
|
||||||
}
|
}
|
||||||
|
@ -290,54 +298,29 @@ public class StatusPane extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateKeyDisplay() {
|
public void updateKeyDisplay() {
|
||||||
needsKeyUpdate = false;
|
keyIcon.updateKeys();
|
||||||
|
keyIcon.visible = keyIcon.keyCount() > 0;
|
||||||
boolean blackKey = false;
|
journalIcon.visible = !keyIcon.visible;
|
||||||
boolean specialKey = false;
|
if (keyIcon.keyCount() > 0) {
|
||||||
int ironKeys = 0;
|
bg.brightness(.8f - (Math.min(6, keyIcon.keyCount()) / 20f));
|
||||||
for (Notes.KeyRecord rec : Notes.getRecords(Notes.KeyRecord.class)){
|
|
||||||
if (rec.depth() < Dungeon.depth){
|
|
||||||
blackKey = true;
|
|
||||||
} else if (rec.depth() == Dungeon.depth){
|
|
||||||
if (rec.type().equals(IronKey.class)) {
|
|
||||||
ironKeys += rec.quantity();
|
|
||||||
} else {
|
|
||||||
specialKey = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blackKey || specialKey || ironKeys > 0){
|
|
||||||
int left = 46, top = 0, width = 0, height = 7;
|
|
||||||
if (blackKey){
|
|
||||||
left = 43;
|
|
||||||
width += 3;
|
|
||||||
}
|
|
||||||
if (specialKey){
|
|
||||||
top = 8;
|
|
||||||
width += 3;
|
|
||||||
}
|
|
||||||
width += ironKeys*3;
|
|
||||||
width = Math.min( width, 9);
|
|
||||||
icon.frame(left, top, width, height);
|
|
||||||
} else {
|
} else {
|
||||||
icon.frame(31, 0, 11, 7);
|
bg.resetColor();
|
||||||
}
|
}
|
||||||
layout();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onTouchDown() {
|
protected void onTouchDown() {
|
||||||
bg.brightness( 1.5f );
|
bg.brightness( 1.5f );
|
||||||
icon.brightness( 1.5f );
|
|
||||||
Sample.INSTANCE.play( Assets.SND_CLICK );
|
Sample.INSTANCE.play( Assets.SND_CLICK );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onTouchUp() {
|
protected void onTouchUp() {
|
||||||
bg.resetColor();
|
if (keyIcon.keyCount() > 0) {
|
||||||
icon.resetColor();
|
bg.brightness(.8f - (Math.min(6, keyIcon.keyCount()) / 20f));
|
||||||
|
} else {
|
||||||
|
bg.resetColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue
Block a user