Update DEV Beta21-P3
|
@ -38,48 +38,48 @@ import java.nio.FloatBuffer;
|
|||
import java.util.HashMap;
|
||||
|
||||
public class RenderedText extends Image {
|
||||
|
||||
|
||||
private BitmapFont font = null;
|
||||
private int size;
|
||||
private String text;
|
||||
|
||||
|
||||
public RenderedText( ) {
|
||||
text = null;
|
||||
}
|
||||
|
||||
|
||||
public RenderedText( int size ){
|
||||
text = null;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
||||
public RenderedText(String text, int size){
|
||||
this.text = text;
|
||||
this.size = size;
|
||||
|
||||
|
||||
measure();
|
||||
}
|
||||
|
||||
|
||||
public void text( String text ){
|
||||
this.text = text;
|
||||
|
||||
|
||||
measure();
|
||||
}
|
||||
|
||||
|
||||
public String text(){
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
public void size( int size ){
|
||||
this.size = size;
|
||||
measure();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void measure(){
|
||||
|
||||
if (Thread.currentThread().getName().equals("SHPD Actor Thread")){
|
||||
|
||||
if (Thread.currentThread().getName().equals("CAPD Actor Thread")){
|
||||
throw new RuntimeException("Text measured from the actor thread!");
|
||||
}
|
||||
|
||||
|
||||
if ( text == null || text.equals("") ) {
|
||||
text = "";
|
||||
width=height=0;
|
||||
|
@ -88,23 +88,31 @@ public class RenderedText extends Image {
|
|||
} else {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
font = Game.platform.getFont(size, text, true, true);
|
||||
|
||||
|
||||
font = Game.platform.getFont(size, text, true, true, false);
|
||||
|
||||
if (font != null){
|
||||
GlyphLayout glyphs = new GlyphLayout( font, text);
|
||||
|
||||
|
||||
for (char c : text.toCharArray()) {
|
||||
BitmapFont.Glyph g = font.getData().getGlyph(c);
|
||||
if (g == null || (g.id != c)){
|
||||
String toException = text;
|
||||
if (toException.length() > 30){
|
||||
toException = toException.substring(0, 30) + "...";
|
||||
font = Game.platform.getFont(size, text, true, true, true);
|
||||
for (char c1 : text.toCharArray()) {
|
||||
BitmapFont.Glyph g1 = font.getData().getGlyph(c1);
|
||||
if (g1 == null || (g1.id != c1)){
|
||||
String toException = text;
|
||||
if (toException.length() > 30){
|
||||
toException = toException.substring(0, 30) + "...";
|
||||
}
|
||||
font = Game.platform.getFont(size, text, true, true, false);
|
||||
Game.reportException(new Throwable("font file " + font.toString() + " could not render " + c + " from string: " + toException));
|
||||
}
|
||||
}
|
||||
Game.reportException(new Throwable("font file " + font.toString() + " could not render " + c + " from string: " + toException));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//We use the xadvance of the last glyph in some cases to fix issues
|
||||
// with fullwidth punctuation marks in some asian scripts
|
||||
BitmapFont.Glyph lastGlyph = font.getData().getGlyph(text.charAt(text.length()-1));
|
||||
|
@ -113,15 +121,15 @@ public class RenderedText extends Image {
|
|||
} else {
|
||||
width = glyphs.width;
|
||||
}
|
||||
|
||||
|
||||
//this is identical to l.height in most cases, but we force this for consistency.
|
||||
height = Math.round(size*0.75f);
|
||||
renderedHeight = glyphs.height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private float renderedHeight = 0;
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateMatrix() {
|
||||
super.updateMatrix();
|
||||
|
@ -130,9 +138,9 @@ public class RenderedText extends Image {
|
|||
Matrix.translate(matrix, 0, Math.round(height - renderedHeight));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static TextRenderBatch textRenderer = new TextRenderBatch();
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void draw() {
|
||||
if (font != null) {
|
||||
|
@ -146,7 +154,7 @@ public class RenderedText extends Image {
|
|||
//can interface with the freetype font generator
|
||||
//some copypasta from BitmapText here
|
||||
private static class TextRenderBatch implements Batch {
|
||||
|
||||
|
||||
//this isn't as good as only updating once, like with BitmapText
|
||||
// but it skips almost all allocations, which is almost as good
|
||||
private static RenderedText textBeingRendered = null;
|
||||
|
@ -156,7 +164,7 @@ public class RenderedText extends Image {
|
|||
@Override
|
||||
public void draw(Texture texture, float[] spriteVertices, int offset, int count) {
|
||||
Visual v = textBeingRendered;
|
||||
|
||||
|
||||
FloatBuffer toOpenGL;
|
||||
if (buffers.containsKey(count/20)){
|
||||
toOpenGL = buffers.get(count/20);
|
||||
|
@ -165,54 +173,54 @@ public class RenderedText extends Image {
|
|||
toOpenGL = Quad.createSet(count / 20);
|
||||
buffers.put(count/20, toOpenGL);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < count; i += 20){
|
||||
|
||||
|
||||
vertices[0] = spriteVertices[i+0];
|
||||
vertices[1] = spriteVertices[i+1];
|
||||
|
||||
|
||||
vertices[2] = spriteVertices[i+3];
|
||||
vertices[3] = spriteVertices[i+4];
|
||||
|
||||
|
||||
vertices[4] = spriteVertices[i+5];
|
||||
vertices[5] = spriteVertices[i+6];
|
||||
|
||||
|
||||
vertices[6] = spriteVertices[i+8];
|
||||
vertices[7] = spriteVertices[i+9];
|
||||
|
||||
|
||||
vertices[8] = spriteVertices[i+10];
|
||||
vertices[9] = spriteVertices[i+11];
|
||||
|
||||
|
||||
vertices[10] = spriteVertices[i+13];
|
||||
vertices[11] = spriteVertices[i+14];
|
||||
|
||||
|
||||
vertices[12] = spriteVertices[i+15];
|
||||
vertices[13] = spriteVertices[i+16];
|
||||
|
||||
|
||||
vertices[14] = spriteVertices[i+18];
|
||||
vertices[15] = spriteVertices[i+19];
|
||||
|
||||
|
||||
toOpenGL.put(vertices);
|
||||
|
||||
|
||||
}
|
||||
|
||||
((Buffer)toOpenGL).position(0);
|
||||
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
|
||||
texture.bind();
|
||||
com.watabou.glwrap.Texture.clear();
|
||||
|
||||
|
||||
script.camera( v.camera() );
|
||||
|
||||
|
||||
script.uModel.valueM4( v.matrix );
|
||||
script.lighting(
|
||||
v.rm, v.gm, v.bm, v.am,
|
||||
v.ra, v.ga, v.ba, v.aa );
|
||||
|
||||
|
||||
script.drawQuadSet( toOpenGL, count/20 );
|
||||
}
|
||||
|
||||
|
||||
//none of these functions are needed, so they are stubbed
|
||||
@Override
|
||||
public void begin() { }
|
||||
|
@ -252,4 +260,4 @@ public class RenderedText extends Image {
|
|||
public boolean isDrawing() { return false; }
|
||||
public void dispose() { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextArea;
|
|||
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import com.watabou.glscripts.Script;
|
||||
import com.watabou.glwrap.Blending;
|
||||
|
@ -74,7 +73,7 @@ public class TextInput extends Component {
|
|||
skin = new Skin(FileUtils.getFileHandle(Files.FileType.Internal, "gdx/textfield.json"));
|
||||
|
||||
TextField.TextFieldStyle style = skin.get(TextField.TextFieldStyle.class);
|
||||
style.font = Game.platform.getFont(size, "", false, false);
|
||||
style.font = Game.platform.getFont(size, "", false, false,false);
|
||||
style.background = null;
|
||||
textField = multiline ? new TextArea("", style) : new TextField("", style);
|
||||
textField.setProgrammaticChangeEvents(true);
|
||||
|
@ -84,7 +83,7 @@ public class TextInput extends Component {
|
|||
textField.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
BitmapFont f = Game.platform.getFont(size, textField.getText(), false, false);
|
||||
BitmapFont f = Game.platform.getFont(size, textField.getText(), false, false,false);
|
||||
TextField.TextFieldStyle style = textField.getStyle();
|
||||
if (f != style.font){
|
||||
style.font = f;
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
package com.watabou.utils;
|
||||
|
||||
import static com.watabou.utils.DeviceCompat.isDebug;
|
||||
|
||||
import com.badlogic.gdx.Application;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.PixmapPacker;
|
||||
|
@ -31,13 +31,12 @@ import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
|||
import com.watabou.noosa.Game;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class PlatformSupport {
|
||||
|
||||
|
||||
public abstract void updateDisplaySize();
|
||||
public void logd( String message ) {
|
||||
if (isDebug()) Gdx.app.log("DEBUG", message);
|
||||
}
|
||||
|
||||
public abstract void updateSystemUI();
|
||||
|
||||
public abstract boolean connectedToUnmeteredNetwork();
|
||||
|
@ -47,26 +46,48 @@ public abstract class PlatformSupport {
|
|||
Gdx.input.vibrate( millis );
|
||||
}
|
||||
|
||||
public void setHonorSilentSwitch( boolean value ){
|
||||
//does nothing by default
|
||||
}
|
||||
|
||||
public boolean openURI( String uri ){
|
||||
return Gdx.net.openURI( uri );
|
||||
}
|
||||
|
||||
//TODO should consider spinning this into its own class, rather than platform support getting ever bigger
|
||||
protected static HashMap<FreeTypeFontGenerator, HashMap<Integer, BitmapFont>> fonts;
|
||||
|
||||
protected static FreeTypeFontGenerator fallbackFontGenerator;
|
||||
|
||||
//splits on newlines, underscores, and chinese/japaneses characters
|
||||
protected static Pattern regularsplitter = Pattern.compile(
|
||||
"(?<=\n)|(?=\n)|(?<=_)|(?=_)|(?<=\\\\)|(?=\\\\)|" +
|
||||
"(?<=[^\\x00-\\xff])|(?=[^\\x00-\\xff])|" +
|
||||
"(?<=\\p{InHiragana})|(?=\\p{InHiragana})|" +
|
||||
"(?<=\\p{InKatakana})|(?=\\p{InKatakana})|" +
|
||||
"(?<=\\p{InHangul_Syllables})|(?=!\\p{InHangul_Syllables})|" +
|
||||
"(?<=\\p{InCJK_Unified_Ideographs})|(?=\\p{InCJK_Unified_Ideographs})|" +
|
||||
"(?<=\\p{InCJK_Symbols_and_Punctuation})|(?=\\p{InCJK_Symbols_and_Punctuation})" +
|
||||
"(?<=\\p{InHalfwidth_and_Fullwidth_Forms})|(?=\\p{InHalfwidth_and_Fullwidth_Forms})");
|
||||
|
||||
//additionally splits on words, so that each word can be arranged individually
|
||||
protected static Pattern regularsplitterMultiline = Pattern.compile(
|
||||
"(?<= )|(?= )|(?<=\n)|(?=\n)|(?<=_)|(?=_)|(?<=\\\\)|(?=\\\\)|" +
|
||||
"(?<=[^\\x00-\\xff])|(?=[^\\x00-\\xff])|" +
|
||||
"(?<=\\p{InHiragana})|(?=\\p{InHiragana})|" +
|
||||
"(?<=\\p{InKatakana})|(?=\\p{InKatakana})|" +
|
||||
"(?<=\\p{InHangul_Syllables})|(?=!\\p{InHangul_Syllables})|" +
|
||||
"(?<=\\p{InCJK_Unified_Ideographs})|(?=\\p{InCJK_Unified_Ideographs})|" +
|
||||
"(?<=\\p{InCJK_Symbols_and_Punctuation})|(?=\\p{InCJK_Symbols_and_Punctuation})" +
|
||||
"(?<=\\p{InHalfwidth_and_Fullwidth_Forms})|(?=\\p{InHalfwidth_and_Fullwidth_Forms})");
|
||||
|
||||
protected int pageSize;
|
||||
protected PixmapPacker packer;
|
||||
protected boolean systemfont;
|
||||
|
||||
|
||||
public abstract void setupFontGenerators(int pageSize, boolean systemFont );
|
||||
|
||||
protected abstract FreeTypeFontGenerator getGeneratorForString( String input );
|
||||
|
||||
public abstract String[] splitforTextBlock( String text, boolean multiline );
|
||||
public String[] splitforTextBlock(String text, boolean multiline) {
|
||||
if (multiline) {
|
||||
return regularsplitterMultiline.split(text);
|
||||
} else {
|
||||
return regularsplitter.split(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetGenerators(){
|
||||
resetGenerators( true );
|
||||
|
@ -113,8 +134,8 @@ public abstract class PlatformSupport {
|
|||
|
||||
//flipped is needed because Shattered's graphics are y-down, while GDX graphics are y-up.
|
||||
//this is very confusing, I know.
|
||||
public BitmapFont getFont(int size, String text, boolean flipped, boolean border) {
|
||||
FreeTypeFontGenerator generator = getGeneratorForString(text);
|
||||
public BitmapFont getFont(int size, String text, boolean flipped, boolean border, boolean fallback) {
|
||||
FreeTypeFontGenerator generator = fallback ? fallbackFontGenerator : getGeneratorForString(text);
|
||||
|
||||
if (generator == null){
|
||||
return null;
|
||||
|
@ -145,7 +166,7 @@ public abstract class PlatformSupport {
|
|||
BitmapFont font = generator.generateFont(parameters);
|
||||
font.getData().missingGlyph = font.getData().getGlyph('<27>');
|
||||
fonts.get(generator).put(key, font);
|
||||
} catch ( Exception e ){
|
||||
} catch ( Exception e ) {
|
||||
Game.reportException(e);
|
||||
return null;
|
||||
}
|
||||
|
@ -154,4 +175,70 @@ public abstract class PlatformSupport {
|
|||
return fonts.get(generator).get(key);
|
||||
}
|
||||
|
||||
}
|
||||
public void setHonorSilentSwitch( boolean value ){
|
||||
//does nothing by default
|
||||
}
|
||||
|
||||
public boolean supportsFullScreen(){
|
||||
switch (Gdx.app.getType()){
|
||||
case Android:
|
||||
//Android 4.4+ supports hiding UI via immersive mode
|
||||
return Gdx.app.getVersion() >= 19;
|
||||
case iOS:
|
||||
//iOS supports hiding UI via drawing into the gesture safe area
|
||||
return Gdx.graphics.getSafeInsetBottom() != 0;
|
||||
default:
|
||||
//TODO implement functionality for other platforms here
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAndroid() {
|
||||
return Gdx.app.getType() == Application.ApplicationType.Android;
|
||||
}
|
||||
|
||||
public boolean isiOS() {
|
||||
return Gdx.app.getType() == Application.ApplicationType.iOS;
|
||||
}
|
||||
|
||||
public boolean isDesktop() {
|
||||
return Gdx.app.getType() == Application.ApplicationType.Desktop;
|
||||
}
|
||||
|
||||
public boolean hasHardKeyboard() {
|
||||
return Gdx.input.isPeripheralAvailable(Input.Peripheral.HardwareKeyboard);
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return Game.version.contains("INDEV");
|
||||
}
|
||||
|
||||
public boolean isSnapshot() {
|
||||
return Game.version.contains("SNAPSHOT");
|
||||
}
|
||||
|
||||
public boolean openURI( String URI ) {
|
||||
return Gdx.net.openURI(URI);
|
||||
}
|
||||
|
||||
public void log( String tag, String message ){
|
||||
Gdx.app.log( tag, message );
|
||||
}
|
||||
|
||||
public void debug( String message ) {
|
||||
if (isDebug()) Gdx.app.log("DEBUG", message);
|
||||
}
|
||||
|
||||
public void setClipboardContents( String str ) {
|
||||
Gdx.app.getClipboard().setContents( str );
|
||||
}
|
||||
|
||||
public String getClipboardContents() {
|
||||
return Gdx.app.getClipboard().getContents();
|
||||
}
|
||||
|
||||
public boolean isClipboardEmpty() {
|
||||
return !Gdx.app.getClipboard().hasContents();
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
public class AndroidPlatformSupport extends PlatformSupport {
|
||||
|
||||
|
||||
public void updateDisplaySize(){
|
||||
if (SPDSettings.landscape() != null) {
|
||||
AndroidGame.instance.setRequestedOrientation( SPDSettings.landscape() ?
|
||||
|
@ -55,10 +55,10 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
}
|
||||
|
||||
GLSurfaceView view = (GLSurfaceView) ((AndroidGraphics)Gdx.graphics).getView();
|
||||
|
||||
|
||||
if (view.getMeasuredWidth() == 0 || view.getMeasuredHeight() == 0)
|
||||
return;
|
||||
|
||||
|
||||
Game.dispWidth = view.getMeasuredWidth();
|
||||
Game.dispHeight = view.getMeasuredHeight();
|
||||
|
||||
|
@ -71,40 +71,40 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
Game.dispWidth = Game.dispHeight;
|
||||
Game.dispHeight = tmp;
|
||||
}
|
||||
|
||||
|
||||
float dispRatio = Game.dispWidth / (float)Game.dispHeight;
|
||||
|
||||
|
||||
float renderWidth = dispRatio > 1 ? PixelScene.MIN_WIDTH_L : PixelScene.MIN_WIDTH_P;
|
||||
float renderHeight = dispRatio > 1 ? PixelScene.MIN_HEIGHT_L : PixelScene.MIN_HEIGHT_P;
|
||||
|
||||
|
||||
//force power saver in this case as all devices must run at at least 2x scale.
|
||||
if (Game.dispWidth < renderWidth*2 || Game.dispHeight < renderHeight*2)
|
||||
SPDSettings.put( SPDSettings.KEY_POWER_SAVER, true );
|
||||
|
||||
|
||||
if (SPDSettings.powerSaver() && fullscreen){
|
||||
|
||||
|
||||
int maxZoom = (int)Math.min(Game.dispWidth/renderWidth, Game.dispHeight/renderHeight);
|
||||
|
||||
|
||||
renderWidth *= Math.max( 2, Math.round(1f + maxZoom*0.4f));
|
||||
renderHeight *= Math.max( 2, Math.round(1f + maxZoom*0.4f));
|
||||
|
||||
|
||||
if (dispRatio > renderWidth / renderHeight){
|
||||
renderWidth = renderHeight * dispRatio;
|
||||
} else {
|
||||
renderHeight = renderWidth / dispRatio;
|
||||
}
|
||||
|
||||
|
||||
final int finalW = Math.round(renderWidth);
|
||||
final int finalH = Math.round(renderHeight);
|
||||
if (finalW != Game.width || finalH != Game.height){
|
||||
|
||||
|
||||
AndroidGame.instance.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.getHolder().setFixedSize(finalW, finalH);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
AndroidGame.instance.runOnUiThread(new Runnable() {
|
||||
|
@ -115,16 +115,16 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateSystemUI() {
|
||||
|
||||
|
||||
AndroidGame.instance.runOnUiThread(new Runnable() {
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void run() {
|
||||
boolean fullscreen = Build.VERSION.SDK_INT < Build.VERSION_CODES.N
|
||||
|| !AndroidGame.instance.isInMultiWindowMode();
|
||||
|
||||
|
||||
if (fullscreen){
|
||||
AndroidGame.instance.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
|
@ -132,23 +132,21 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
AndroidGame.instance.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
|
||||
if (SPDSettings.fullscreen()) {
|
||||
AndroidGame.instance.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
|
||||
} else {
|
||||
AndroidGame.instance.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
|
||||
}
|
||||
|
||||
if (SPDSettings.fullscreen()) {
|
||||
AndroidGame.instance.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
|
||||
} else {
|
||||
AndroidGame.instance.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean connectedToUnmeteredNetwork() {
|
||||
|
@ -160,26 +158,28 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return activeNetwork != null && activeNetwork.isConnectedOrConnecting() &&
|
||||
(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_WIMAX
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_BLUETOOTH
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_ETHERNET);
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_WIMAX
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_BLUETOOTH
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_ETHERNET);
|
||||
}
|
||||
}
|
||||
|
||||
/* FONT SUPPORT */
|
||||
|
||||
|
||||
//droid sans / roboto, or a custom pixel font, for use with Latin and Cyrillic languages
|
||||
private static FreeTypeFontGenerator basicFontGenerator;
|
||||
//droid sans / nanum gothic / noto sans, for use with Korean
|
||||
private static FreeTypeFontGenerator KRFontGenerator;
|
||||
//droid sans / noto sans, for use with Simplified Chinese
|
||||
private static FreeTypeFontGenerator SCFontGenerator;
|
||||
//droid sans / noto sans, for use with Traditional Chinese
|
||||
private static FreeTypeFontGenerator TCFontGenerator;
|
||||
//droid sans / noto sans, for use with Japanese
|
||||
private static FreeTypeFontGenerator JPFontGenerator;
|
||||
|
||||
|
||||
//special logic for handling korean android 6.0 font oddities
|
||||
private static boolean koreanAndroid6OTF = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void setupFontGenerators(int pageSize, boolean systemfont) {
|
||||
//don't bother doing anything if nothing has changed
|
||||
|
@ -191,16 +191,23 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
|
||||
resetGenerators(false);
|
||||
fonts = new HashMap<>();
|
||||
basicFontGenerator = KRFontGenerator = SCFontGenerator = JPFontGenerator = null;
|
||||
|
||||
if (systemfont && Gdx.files.absolute("/system/fonts/Roboto-Regular.ttf").exists()) {
|
||||
basicFontGenerator = KRFontGenerator = SCFontGenerator = TCFontGenerator = JPFontGenerator = fallbackFontGenerator = null;
|
||||
|
||||
if (Gdx.files.absolute("/system/fonts/Roboto-Regular.ttf").exists()) {
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/Roboto-Regular.ttf"));
|
||||
} else if (systemfont && Gdx.files.absolute("/system/fonts/DroidSans.ttf").exists()){
|
||||
} else if (Gdx.files.absolute("/system/fonts/DroidSans.ttf").exists()){
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/DroidSans.ttf"));
|
||||
} else {
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel_font.ttf"));
|
||||
}
|
||||
|
||||
if (!systemfont) {
|
||||
if (basicFontGenerator == null) {
|
||||
basicFontGenerator = fallbackFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel_font.ttf"));
|
||||
}
|
||||
else {
|
||||
fallbackFontGenerator = basicFontGenerator;
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel_font.ttf"));
|
||||
}
|
||||
}
|
||||
|
||||
//android 7.0+. all asian fonts are nicely contained in one spot
|
||||
if (Gdx.files.absolute("/system/fonts/NotoSansCJK-Regular.ttc").exists()) {
|
||||
//typefaces are 0-JP, 1-KR, 2-SC, 3-TC.
|
||||
|
@ -209,15 +216,19 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
case JAPANESE:
|
||||
typeFace = 0;
|
||||
break;
|
||||
// case KOREAN:
|
||||
// typeFace = 1;
|
||||
// break;
|
||||
case HARDCHINESE:
|
||||
case CHINESE:
|
||||
default:
|
||||
typeFace = 2;
|
||||
}
|
||||
KRFontGenerator = SCFontGenerator = JPFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansCJK-Regular.ttc"), typeFace);
|
||||
|
||||
//otherwise we have to go over a few possibilities.
|
||||
KRFontGenerator = SCFontGenerator = TCFontGenerator = JPFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansCJK-Regular.ttc"), typeFace);
|
||||
|
||||
//otherwise we have to go over a few possibilities.
|
||||
} else {
|
||||
|
||||
|
||||
//Korean font generators
|
||||
if (Gdx.files.absolute("/system/fonts/NanumGothic.ttf").exists()){
|
||||
KRFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NanumGothic.ttf"));
|
||||
|
@ -225,19 +236,26 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
KRFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansKR-Regular.otf"));
|
||||
koreanAndroid6OTF = true;
|
||||
}
|
||||
|
||||
//Chinese font generators
|
||||
|
||||
//Simplified Chinese font generators
|
||||
if (Gdx.files.absolute("/system/fonts/NotoSansSC-Regular.otf").exists()){
|
||||
SCFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansSC-Regular.otf"));
|
||||
} else if (Gdx.files.absolute("/system/fonts/NotoSansHans-Regular.otf").exists()){
|
||||
SCFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansHans-Regular.otf"));
|
||||
}
|
||||
|
||||
|
||||
//Traditional Chinese font generators
|
||||
if (Gdx.files.absolute("/system/fonts/NotoSansTC-Regular.otf").exists()){
|
||||
TCFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansTC-Regular.otf"));
|
||||
} else if (Gdx.files.absolute("/system/fonts/NotoSansHant-Regular.otf").exists()){
|
||||
TCFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansHant-Regular.otf"));
|
||||
}
|
||||
|
||||
//Japaneses font generators
|
||||
if (Gdx.files.absolute("/system/fonts/NotoSansJP-Regular.otf").exists()){
|
||||
JPFontGenerator = new FreeTypeFontGenerator(Gdx.files.absolute("/system/fonts/NotoSansJP-Regular.otf"));
|
||||
}
|
||||
|
||||
|
||||
//set up a fallback generator for any remaining fonts
|
||||
FreeTypeFontGenerator fallbackGenerator;
|
||||
if (Gdx.files.absolute("/system/fonts/DroidSansFallback.ttf").exists()){
|
||||
|
@ -246,62 +264,67 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
//no fallback font, just set to null =/
|
||||
fallbackGenerator = null;
|
||||
}
|
||||
|
||||
|
||||
if (KRFontGenerator == null) KRFontGenerator = fallbackGenerator;
|
||||
if (SCFontGenerator == null) SCFontGenerator = fallbackGenerator;
|
||||
if (TCFontGenerator == null) TCFontGenerator = fallbackGenerator;
|
||||
if (JPFontGenerator == null) JPFontGenerator = fallbackGenerator;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!systemfont) {
|
||||
switch (SPDSettings.language()) {
|
||||
case CHINESE:
|
||||
fallbackFontGenerator = SCFontGenerator;
|
||||
break;
|
||||
case HARDCHINESE:
|
||||
fallbackFontGenerator = TCFontGenerator;
|
||||
break;
|
||||
case JAPANESE:
|
||||
fallbackFontGenerator = JPFontGenerator;
|
||||
break;
|
||||
}
|
||||
KRFontGenerator = SCFontGenerator = TCFontGenerator = JPFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/fusion_pixel.ttf"));
|
||||
}
|
||||
|
||||
if (basicFontGenerator != null) fonts.put(basicFontGenerator, new HashMap<>());
|
||||
if (KRFontGenerator != null) fonts.put(KRFontGenerator, new HashMap<>());
|
||||
if (SCFontGenerator != null) fonts.put(SCFontGenerator, new HashMap<>());
|
||||
if (TCFontGenerator != null) fonts.put(TCFontGenerator, new HashMap<>());
|
||||
if (JPFontGenerator != null) fonts.put(JPFontGenerator, new HashMap<>());
|
||||
|
||||
if (fallbackFontGenerator != null) fonts.put(fallbackFontGenerator, new HashMap<>());
|
||||
|
||||
//would be nice to use RGBA4444 to save memory, but this causes problems on some gpus =S
|
||||
packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false);
|
||||
}
|
||||
|
||||
private static Matcher KRMatcher = Pattern.compile("\\p{InHangul_Syllables}").matcher("");
|
||||
private static Matcher SCMatcher = Pattern.compile("\\p{InCJK_Unified_Ideographs}|\\p{InCJK_Symbols_and_Punctuation}|\\p{InHalfwidth_and_Fullwidth_Forms}").matcher("");
|
||||
private static Matcher CNMatcher = Pattern.compile("\\p{InCJK_Unified_Ideographs}|\\p{InCJK_Symbols_and_Punctuation}|\\p{InHalfwidth_and_Fullwidth_Forms}").matcher("");
|
||||
private static Matcher JPMatcher = Pattern.compile("\\p{InHiragana}|\\p{InKatakana}").matcher("");
|
||||
|
||||
@Override
|
||||
protected FreeTypeFontGenerator getGeneratorForString( String input ){
|
||||
if (KRMatcher.reset(input).find()){
|
||||
return KRFontGenerator;
|
||||
} else if (SCMatcher.reset(input).find()){
|
||||
return SCFontGenerator;
|
||||
} else if (CNMatcher.reset(input).find()){
|
||||
switch (SPDSettings.language()) {
|
||||
case CHINESE:
|
||||
default:
|
||||
return SCFontGenerator;
|
||||
case HARDCHINESE:
|
||||
return TCFontGenerator;
|
||||
}
|
||||
} else if (JPMatcher.reset(input).find()){
|
||||
return JPFontGenerator;
|
||||
} else {
|
||||
return basicFontGenerator;
|
||||
}
|
||||
}
|
||||
|
||||
//splits on newlines, underscores, and chinese/japaneses characters
|
||||
private Pattern regularsplitter = Pattern.compile(
|
||||
"(?<=\n)|(?=\n)|(?<=_)|(?=_)|" +
|
||||
"(?<=\\p{InHiragana})|(?=\\p{InHiragana})|" +
|
||||
"(?<=\\p{InKatakana})|(?=\\p{InKatakana})|" +
|
||||
"(?<=\\p{InCJK_Unified_Ideographs})|(?=\\p{InCJK_Unified_Ideographs})|" +
|
||||
"(?<=\\p{InCJK_Symbols_and_Punctuation})|(?=\\p{InCJK_Symbols_and_Punctuation})|" +
|
||||
"(?<=\\p{InHalfwidth_and_Fullwidth_Forms})|(?=\\p{InHalfwidth_and_Fullwidth_Forms})");
|
||||
|
||||
//additionally splits on words, so that each word can be arranged individually
|
||||
private Pattern regularsplitterMultiline = Pattern.compile(
|
||||
"(?<= )|(?= )|(?<=\n)|(?=\n)|(?<=_)|(?=_)|" +
|
||||
"(?<=\\p{InHiragana})|(?=\\p{InHiragana})|" +
|
||||
"(?<=\\p{InKatakana})|(?=\\p{InKatakana})|" +
|
||||
"(?<=\\p{InCJK_Unified_Ideographs})|(?=\\p{InCJK_Unified_Ideographs})|" +
|
||||
"(?<=\\p{InCJK_Symbols_and_Punctuation})|(?=\\p{InCJK_Symbols_and_Punctuation})|" +
|
||||
"(?<=\\p{InHalfwidth_and_Fullwidth_Forms})|(?=\\p{InHalfwidth_and_Fullwidth_Forms})");
|
||||
|
||||
|
||||
//splits on each non-hangul character. Needed for weird android 6.0 font files
|
||||
private Pattern android6KRSplitter = Pattern.compile(
|
||||
"(?<= )|(?= )|(?<=\n)|(?=\n)|(?<=_)|(?=_)|" +
|
||||
private static Pattern android6KRSplitter = Pattern.compile(
|
||||
"(?<= )|(?= )|(?<=\n)|(?=\n)|(?<=_)|(?=_)|(?<=\\\\)|(?=\\\\)|" +
|
||||
"(?!\\p{InHangul_Syllables})|(?<!\\p{InHangul_Syllables})");
|
||||
|
||||
|
||||
@Override
|
||||
public String[] splitforTextBlock(String text, boolean multiline) {
|
||||
if (koreanAndroid6OTF && getGeneratorForString(text) == KRFontGenerator){
|
||||
|
@ -312,5 +335,20 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
return regularsplitter.split(text);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAndroid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isiOS() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDesktop() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
BIN
core/src/main/assets/fonts/fusion_pixel.ttf
Normal file
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 797 B |
BIN
core/src/main/assets/interfaces/2years.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
core/src/main/assets/interfaces/go-surface.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 18 KiB |
BIN
core/src/main/assets/interfaces/menutitle.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
|
@ -1253,10 +1253,10 @@ actors.hero.heroclass.warrior_desc_item=蕾零安洁初始携带一枚可以贴
|
|||
actors.hero.heroclass.warrior_desc_loadout=蕾零安洁初始携带一把_破损的短剑。_这把武器的直接近战伤害是所有初始武器中最高的。\n\n蕾零安洁初始携带_三块石子。_石子可以扔出攻击远处,造成一定的少量伤害。\n\n蕾零安洁初始携带一个可以收纳各种药水并保护药水瓶不被冻碎的_药水架。_
|
||||
actors.hero.heroclass.warrior_desc_misc=蕾零安洁每次食用食物时都能恢复少量生命值。\n\n蕾零安洁开局鉴定的物品有:\n- 鉴定卷轴\n- 治疗药水\n- 盛怒卷轴
|
||||
actors.hero.heroclass.warrior_desc_subclasses=在击杀第二个Boss后可以选择一种专精。蕾零安洁可以在两种专精中二选一:
|
||||
actors.hero.heroclass.warrior_story=剧情故事待补充
|
||||
actors.hero.heroclass.huntress_story=剧情故事待补充
|
||||
actors.hero.heroclass.rogue_story=剧情故事待补充
|
||||
actors.hero.heroclass.mage_story=剧情故事待补充
|
||||
actors.hero.heroclass.warrior_story=剧情故事待补充-123
|
||||
actors.hero.heroclass.huntress_story=剧情故事待补充-456
|
||||
actors.hero.heroclass.rogue_story=剧情故事待补充-789
|
||||
actors.hero.heroclass.mage_story=剧情故事待补充-101112
|
||||
|
||||
actors.hero.heroclass.mage=茉莉伊洛
|
||||
actors.hero.heroclass.mage_unlock=茉莉伊洛精通各类法杖,并在开局时持有一根_独特的魔杖_。\n\n_在一局游戏中使用两张升级卷轴_以解锁茉莉伊洛。
|
||||
|
|
|
@ -257,7 +257,7 @@ scenes.guidescene.page_9=当你完成了一些特殊挑战后,0层的四个基
|
|||
scenes.guidescene.title_10=未完待续
|
||||
scenes.guidescene.page_10=感谢你阅读这篇指南,它可能并不完善。但应该能帮助你。\n\n同时,这只是上半段的结束。请期待下半段的更新。
|
||||
|
||||
scenes.thanksscene.code=编码致谢:\n-REN(夜临2作者)\n-Alexstrasza(注解作者)\n-SmuJB(诅咒作者)\n-Tianscar(碳化作者)\n-TrashBoxbodylev(经验作者)
|
||||
scenes.thanksscene.code=编码致谢:\n-REN(夜临2作者)\n-Alexstrasza(注解作者)\n-SmuJB(诅咒作者)\n-Tianscar(碳素作者)\n-TrashBoxbodylev(经验作者)
|
||||
scenes.thanksscene.test=\n\n测试致谢:\n-CodenameE\n-熊猫头\n-迷茫\n-小狐狸\n-摘希\n-ZIOM-ObSir\n-坏猫猫\n-不是史神\n-月鸾\n-口水猫
|
||||
scenes.thanksscene.music=\n\n音乐致谢:\n-Prohonor\n-泰拉瑞亚
|
||||
scenes.thanksscene.art=\n\n美术致谢:\n-被子\n-冷群怪\n-REN\n-Daniel Clan\n-奈亚子-\nTianScar\n-ObSir\n-Nxhy
|
||||
|
|
BIN
core/src/main/assets/music/newtheme.ogg
Normal file
|
@ -100,6 +100,9 @@ public class Assets {
|
|||
|
||||
public static final String BANNERS = "interfaces/banners.png";
|
||||
|
||||
public static final String MENUTITLE = "interfaces/menutitle.png";
|
||||
public static final String TWOYEARS = "interfaces/2years.png";
|
||||
|
||||
//圣诞节
|
||||
public static final String BANNERSSD = "interfaces/banners_sd.png";
|
||||
|
||||
|
@ -122,6 +125,8 @@ public class Assets {
|
|||
|
||||
public static final String SURFACE = "interfaces/surface.png";
|
||||
|
||||
public static final String NEW_MENU = "interfaces/go-surface.png";
|
||||
|
||||
public static final String LOADING_GOLD = "interfaces/loading_gold.png";
|
||||
public static final String LOADING_SEWERS = "interfaces/loading_sewers.png";
|
||||
public static final String LOADING_PRISON = "interfaces/loading_prison.png";
|
||||
|
@ -155,7 +160,7 @@ public class Assets {
|
|||
public static final String THEME = "music/theme.ogg";
|
||||
public static final String GO = "music/Open.ogg";
|
||||
public static final String SHOP = "music/shop.ogg";
|
||||
public static final String THEME_1 = "music/theme.ogg";
|
||||
public static final String THEME_1 = "music/newtheme.ogg";
|
||||
public static final String THEME_2 = "music/theme.ogg";
|
||||
|
||||
public static final String SEWERS_1 = "music/Level1.ogg";
|
||||
|
|
|
@ -152,9 +152,6 @@ public class RedDragon extends NPC {
|
|||
@Override
|
||||
public void call() {
|
||||
switch (Quest.type) {
|
||||
//豺狼炼药长老
|
||||
//豺狼萨满长老
|
||||
//FLAME-C02
|
||||
case 1:
|
||||
default:
|
||||
GameScene.show(new WndQuest(RedDragon.this, Messages.get(RedDragon.this,
|
||||
|
@ -174,13 +171,9 @@ public class RedDragon extends NPC {
|
|||
|
||||
int newPos = -1;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int Click = 1;
|
||||
if (3 == 3) {
|
||||
Click = 1 + 10;
|
||||
AlarmTrap Waring = new AlarmTrap();
|
||||
Waring.pos = super.pos;
|
||||
Waring.activate();
|
||||
}
|
||||
AlarmTrap Waring = new AlarmTrap();
|
||||
Waring.pos = super.pos;
|
||||
Waring.activate();
|
||||
newPos = Dungeon.level.randomRespawnCell( this );
|
||||
if (newPos != -1) {
|
||||
break;
|
||||
|
|
|
@ -59,6 +59,7 @@ public class WarHammer extends MeleeWeapon {
|
|||
Buff.prolong(defender, Vertigo.class, 12f+level);
|
||||
Buff.prolong(defender, Terror.class, 12f+level);
|
||||
Buff.affect(defender, Burning.class).reignite(defender,5f+level);
|
||||
//Over Level 3,Not Debuff
|
||||
if(Random.Float()<0.65f && level <3) {
|
||||
Buff.affect(attacker, Vulnerable.class, 6f);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ import com.watabou.noosa.Group;
|
|||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.PointerArea;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
|
||||
public class AboutScene extends PixelScene {
|
||||
|
||||
|
|
|
@ -21,94 +21,207 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.ui.Icons.RENAME_OFF;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Rankings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDAction;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Journal;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PinkLingSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Fireball;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.ExitButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StyledButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndChallenges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndHeroInfo;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStartGame;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTextInput;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.glwrap.Quad;
|
||||
import com.watabou.input.GameAction;
|
||||
import com.watabou.input.PointerEvent;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.ColorBlock;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NoosaScript;
|
||||
import com.watabou.noosa.PointerArea;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class HeroSelectScene extends PixelScene {
|
||||
|
||||
private Image background;
|
||||
private RenderedTextBlock prompt;
|
||||
private static HeroClass[] heroClasses = new HeroClass[] {
|
||||
HeroClass.WARRIOR,
|
||||
HeroClass.MAGE,
|
||||
HeroClass.ROGUE,
|
||||
HeroClass.HUNTRESS
|
||||
};
|
||||
private static int heroClassIndex = 0;
|
||||
private static void addHeroClassIndex(int add) {
|
||||
heroClassIndex = heroClassIndex + add;
|
||||
if (heroClassIndex >= heroClasses.length) heroClassIndex -= heroClasses.length;
|
||||
else if (heroClassIndex < 0) heroClassIndex += heroClasses.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static HeroClass heroClass() {
|
||||
return heroClasses[heroClassIndex];
|
||||
}
|
||||
|
||||
private static final int FRAME_WIDTH = 88;
|
||||
private static final int FRAME_HEIGHT = 125;
|
||||
|
||||
private static final int FRAME_MARGIN_TOP = 9;
|
||||
private static final int FRAME_MARGIN_X = 4;
|
||||
|
||||
private static final int BUTTON_HEIGHT = 20;
|
||||
|
||||
private static final int SKY_WIDTH = 80;
|
||||
private static final int SKY_HEIGHT = 112;
|
||||
|
||||
private static final int NSTARS = 100;
|
||||
private static final int NCLOUDS = 5;
|
||||
|
||||
private Camera viewport;
|
||||
|
||||
private Avatar a;
|
||||
private RedButton startBtn;
|
||||
private Image frame;
|
||||
|
||||
//fading UI elements
|
||||
private ArrayList<StyledButton> heroBtns = new ArrayList<>();
|
||||
private StyledButton startBtn;
|
||||
private IconButton infoButton;
|
||||
private IconButton challengeButton;
|
||||
private IconButton btnExit;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Dungeon.hero = null;
|
||||
|
||||
Badges.loadGlobal();
|
||||
Journal.loadGlobal();
|
||||
|
||||
background = new Image(HeroClass.WARRIOR.splashArt()){
|
||||
@Override
|
||||
public void update() {
|
||||
if (rm > 1f){
|
||||
rm -= Game.elapsed;
|
||||
gm = bm = rm;
|
||||
} else {
|
||||
rm = gm = bm = 1;
|
||||
}
|
||||
// Music.INSTANCE.playTracks(
|
||||
// new String[]{Assets.Music.THEME},
|
||||
// new float[]{1},
|
||||
// false);
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
float vx = align((w - SKY_WIDTH) / 2f);
|
||||
float vy = align((h - SKY_HEIGHT - BUTTON_HEIGHT) / 2f);
|
||||
|
||||
Point s = Camera.main.cameraToScreen( vx, vy );
|
||||
viewport = new Camera( s.x, s.y, SKY_WIDTH, SKY_HEIGHT, defaultZoom );
|
||||
Camera.add( viewport );
|
||||
|
||||
Group window = new Group();
|
||||
window.camera = viewport;
|
||||
add( window );
|
||||
|
||||
boolean dayTime =
|
||||
Calendar.getInstance().get(Calendar.HOUR_OF_DAY) < 18 && Calendar.getInstance().get(Calendar.HOUR_OF_DAY) > 7;
|
||||
|
||||
Sky sky = new Sky( Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) ;
|
||||
sky.scale.set( SKY_WIDTH, SKY_HEIGHT );
|
||||
window.add( sky );
|
||||
|
||||
if (!dayTime) {
|
||||
for (int i=0; i < NSTARS; i++) {
|
||||
float size = Random.Float();
|
||||
ColorBlock star = new ColorBlock( size, size, 0xFFFFFFFF );
|
||||
star.x = Random.Float( SKY_WIDTH ) - size / 2;
|
||||
star.y = Random.Float( SKY_HEIGHT ) - size / 2;
|
||||
star.am = size * (1 - star.y / SKY_HEIGHT);
|
||||
window.add( star );
|
||||
}
|
||||
};
|
||||
background.scale.set(Camera.main.height/background.height);
|
||||
|
||||
background.x = (Camera.main.width - background.width())/2f;
|
||||
background.y = (Camera.main.height - background.height())/2f;
|
||||
background.visible = false;
|
||||
PixelScene.align(background);
|
||||
add(background);
|
||||
|
||||
if (background.x > 0){
|
||||
Image fadeLeft = new Image(TextureCache.createGradient(0xFF000000, 0x00000000));
|
||||
fadeLeft.x = background.x-2;
|
||||
fadeLeft.scale.set(4, background.height());
|
||||
add(fadeLeft);
|
||||
|
||||
Image fadeRight = new Image(fadeLeft);
|
||||
fadeRight.x = background.x + background.width() + 2;
|
||||
fadeRight.y = background.y + background.height();
|
||||
fadeRight.angle = 180;
|
||||
add(fadeRight);
|
||||
}
|
||||
|
||||
startBtn = new StyledButton(Chrome.Type.GREY_BUTTON_TR, ""){
|
||||
float range = SKY_HEIGHT * 2 / 3;
|
||||
for (int i=0; i < NCLOUDS; i++) {
|
||||
Cloud cloud = new Cloud( (NCLOUDS - 1 - i) * (range / NCLOUDS) + Random.Float( range / NCLOUDS ), dayTime );
|
||||
window.add( cloud );
|
||||
}
|
||||
|
||||
int nPatches = (int)(sky.width() / GrassPatch.WIDTH + 1);
|
||||
|
||||
for (int i=0; i < nPatches * 4; i++) {
|
||||
GrassPatch patch = new GrassPatch( (i - 0.75f) * GrassPatch.WIDTH / 4, SKY_HEIGHT + 1, dayTime );
|
||||
patch.brightness( dayTime ? 0.7f : 0.4f );
|
||||
window.add( patch );
|
||||
}
|
||||
|
||||
a = new Avatar( heroClass() );
|
||||
// Removing semitransparent contour
|
||||
a.am = 2; a.aa = -1;
|
||||
a.x = (SKY_WIDTH - a.width) / 2;
|
||||
a.y = SKY_HEIGHT - a.height;
|
||||
align(a);
|
||||
|
||||
window.add( a );
|
||||
|
||||
window.add( new PointerArea( a ) {
|
||||
protected void onClick( PointerEvent event ) {
|
||||
if (GamesInProgress.selectedClass == null) return;
|
||||
HeroClass cl = GamesInProgress.selectedClass;
|
||||
if( cl.isUnlocked() ) ShatteredPixelDungeon.scene().addToFront(new WndHeroInfo(cl));
|
||||
else ShatteredPixelDungeon.scene().addToFront( new WndMessage(cl.unlockMsg()));
|
||||
}
|
||||
} );
|
||||
|
||||
for (int i=0; i < nPatches; i++) {
|
||||
GrassPatch patch = new GrassPatch( (i - 0.5f) * GrassPatch.WIDTH, SKY_HEIGHT, dayTime );
|
||||
patch.brightness( dayTime ? 1.0f : 0.8f );
|
||||
window.add( patch );
|
||||
}
|
||||
|
||||
frame = new Image( Assets.Interfaces.NEW_MENU );
|
||||
|
||||
frame.frame( FRAME_WIDTH + GrassPatch.WIDTH*4, 0, FRAME_WIDTH, FRAME_HEIGHT );
|
||||
frame.x = vx - FRAME_MARGIN_X;
|
||||
frame.y = vy - FRAME_MARGIN_TOP;
|
||||
add( frame );
|
||||
|
||||
if (dayTime) {
|
||||
a.brightness( 1.2f );
|
||||
} else {
|
||||
frame.hardlight( 0xDDEEFF );
|
||||
}
|
||||
|
||||
startBtn = new RedButton( "" ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
|
@ -126,18 +239,28 @@ public class HeroSelectScene extends PixelScene {
|
|||
Game.switchScene( InterlevelScene.class );
|
||||
}
|
||||
}
|
||||
public void enable( boolean value ) {
|
||||
active = value;
|
||||
text.alpha( value ? 1.0f : 0.3f );
|
||||
icon.alpha( value ? 1.0f : 0.3f );
|
||||
}
|
||||
};
|
||||
startBtn.icon(Icons.get(Icons.ENTER));
|
||||
startBtn.setSize(80, 21);
|
||||
startBtn.setPos((Camera.main.width - startBtn.width())/2f, (Camera.main.height - HeroBtn.HEIGHT + 2 - startBtn.height()));
|
||||
add(startBtn);
|
||||
startBtn.visible = false;
|
||||
add( startBtn );
|
||||
|
||||
infoButton = new IconButton(Icons.get(Icons.INFO)){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndHeroInfo(GamesInProgress.selectedClass));
|
||||
if (GamesInProgress.selectedClass == null) return;
|
||||
HeroClass cl = GamesInProgress.selectedClass;
|
||||
if( cl.isUnlocked() ) ShatteredPixelDungeon.scene().addToFront(new WndHeroInfo(cl));
|
||||
else ShatteredPixelDungeon.scene().addToFront( new WndMessage(cl.unlockMsg()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameAction keyAction() {
|
||||
return SPDAction.HERO_INFO;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -145,38 +268,22 @@ public class HeroSelectScene extends PixelScene {
|
|||
return Messages.titleCase(Messages.get(WndKeyBindings.class, "hero_info"));
|
||||
}
|
||||
};
|
||||
infoButton.visible = false;
|
||||
infoButton.setSize(21, 21);
|
||||
add(infoButton);
|
||||
|
||||
HeroClass[] classes = HeroClass.values();
|
||||
|
||||
int btnWidth = HeroBtn.MIN_WIDTH;
|
||||
int curX = (Camera.main.width - btnWidth * classes.length)/2;
|
||||
if (curX > 0){
|
||||
btnWidth += Math.min(curX/(classes.length/2), 15);
|
||||
curX = (Camera.main.width - btnWidth * classes.length)/2;
|
||||
}
|
||||
|
||||
int heroBtnleft = curX;
|
||||
for (HeroClass cl : classes){
|
||||
HeroBtn button = new HeroBtn(cl);
|
||||
button.setRect(curX, Camera.main.height-HeroBtn.HEIGHT+3, btnWidth, HeroBtn.HEIGHT);
|
||||
curX += btnWidth;
|
||||
add(button);
|
||||
heroBtns.add(button);
|
||||
}
|
||||
|
||||
challengeButton = new IconButton(
|
||||
Icons.get( SPDSettings.challenges() > 0 ? Icons.CHALLENGE_ON :Icons.CHALLENGE_OFF)){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndChallenges(SPDSettings.challenges(), true) {
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
icon(Icons.get(SPDSettings.challenges() > 0 ? Icons.CHALLENGE_ON : Icons.CHALLENGE_OFF));
|
||||
}
|
||||
} );
|
||||
if (DeviceCompat.isDebug() || Badges.isUnlocked(Badges.Badge.VICTORY)) {
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndChallenges(SPDSettings.challenges(), true) {
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
icon(Icons.get(SPDSettings.challenges() > 0 ? Icons.CHALLENGE_ON : Icons.CHALLENGE_OFF));
|
||||
}
|
||||
} );
|
||||
}
|
||||
else ShatteredPixelDungeon.scene().addToFront( new WndMessage( Messages.get(HeroSelectScene.class, "challenges_unlock") ));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,148 +299,414 @@ public class HeroSelectScene extends PixelScene {
|
|||
return Messages.titleCase(Messages.get(WndChallenges.class, "title"));
|
||||
}
|
||||
};
|
||||
challengeButton.setRect(heroBtnleft + 16, Camera.main.height-HeroBtn.HEIGHT-16, 21, 21);
|
||||
challengeButton.visible = false;
|
||||
challengeButton.setRect(startBtn.left() + 16, Camera.main.height- BUTTON_HEIGHT-16, 21, 21);
|
||||
|
||||
if (DeviceCompat.isDebug() || Badges.isUnlocked(Badges.Badge.VICTORY)){
|
||||
add(challengeButton);
|
||||
} else {
|
||||
add(challengeButton);
|
||||
if (!(DeviceCompat.isDebug() || Badges.isUnlocked(Badges.Badge.VICTORY))){
|
||||
Dungeon.challenges = 0;
|
||||
SPDSettings.challenges(0);
|
||||
}
|
||||
|
||||
setSelectedHero();
|
||||
|
||||
IconButton prevBtn = new IconButton( Icons.get(Icons.LEFTBUTTON) ) {
|
||||
{
|
||||
width = 20;
|
||||
height = 20;
|
||||
}
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
|
||||
addHeroClassIndex(-1);
|
||||
setSelectedHero();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String hoverText() {
|
||||
return Messages.titleCase(Messages.get(WndKeyBindings.class, "prev"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameAction keyAction() {
|
||||
return GameAction.NONE;
|
||||
}
|
||||
};
|
||||
prevBtn.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
prevBtn.setPos( frame.x - BUTTON_HEIGHT - FRAME_MARGIN_X, frame.y + frame.height / 2 - BUTTON_HEIGHT / 2f);
|
||||
PixelScene.align(prevBtn);
|
||||
add( prevBtn );
|
||||
|
||||
IconButton nextBtn = new IconButton( Icons.get(Icons.RIGHTBUTTON) ) {
|
||||
{
|
||||
width = 20;
|
||||
height = 20;
|
||||
}
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
|
||||
addHeroClassIndex(1);
|
||||
setSelectedHero();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String hoverText() {
|
||||
return Messages.titleCase(Messages.get(WndKeyBindings.class, "next"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameAction keyAction() {
|
||||
return GameAction.NONE;
|
||||
}
|
||||
};
|
||||
nextBtn.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
nextBtn.setPos( frame.x + frame.width + FRAME_MARGIN_X, frame.y + frame.height / 2 - BUTTON_HEIGHT / 2f);
|
||||
PixelScene.align(nextBtn);
|
||||
add( nextBtn );
|
||||
|
||||
IconButton Telnetsc = new IconButton(new ItemSprite(ItemSpriteSheet.ARTIFACT_SPELLBOOK, null)){
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
HeroClass cl = heroClass();
|
||||
GamesInProgress.selectedClass = cl;
|
||||
a.heroClass(cl);
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndMessage(Messages.get(cl, cl.name() + "_story")));
|
||||
}
|
||||
};
|
||||
Telnetsc.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
Telnetsc.setPos( frame.x + frame.width + FRAME_MARGIN_X, frame.y + frame.height - BUTTON_HEIGHT);
|
||||
add(Telnetsc);
|
||||
|
||||
IconButton DevMode = new IconButton(Icons.get(Icons.WARNING)){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
//
|
||||
}
|
||||
};
|
||||
DevMode.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
DevMode.setPos( frame.x + frame.width + FRAME_MARGIN_X, frame.y-14+ frame.height-14 - BUTTON_HEIGHT);
|
||||
add(DevMode);
|
||||
|
||||
IconButton Rename = new IconButton(Icons.get(Icons.RENAME_OFF)){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if(!Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_1)){
|
||||
Game.runOnRenderThread(() -> ShatteredPixelDungeon.scene().add(new WndTextInput(Messages.get(WndStartGame.class,"custom_name"),
|
||||
Messages.get(WndStartGame.class, "custom_name_desc")+SPDSettings.heroName(),
|
||||
SPDSettings.heroName(), 20,
|
||||
false, Messages.get(WndStartGame.class,"custom_name_set"),
|
||||
Messages.get(WndStartGame.class,"custom_name_clear")){
|
||||
@Override
|
||||
public void onSelect(boolean name, String str) {
|
||||
if (name) {
|
||||
SPDSettings.heroName(str);
|
||||
} else {
|
||||
SPDSettings.heroName("");
|
||||
}
|
||||
icon(Icons.get(SPDSettings.heroName().equals("") ? RENAME_OFF : Icons.RENAME_ON));
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndMessage("击败圣境密林_任意Boss后_解锁重命名功能"));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
Rename.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
Rename.setPos( frame.x + frame.width + FRAME_MARGIN_X, frame.y-38+ frame.height-38- BUTTON_HEIGHT);
|
||||
add(Rename);
|
||||
|
||||
IconButton EverDayGo = new IconButton(new Image(new PinkLingSprite())) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if(!Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_1)){
|
||||
Game.runOnRenderThread(() -> ShatteredPixelDungeon.scene().add(new WndTextInput(Messages.get(WndStartGame.class,"custom_name"),
|
||||
Messages.get(WndStartGame.class, "custom_name_desc")+SPDSettings.heroName(),
|
||||
SPDSettings.heroName(), 20,
|
||||
false, Messages.get(WndStartGame.class,"custom_name_set"),
|
||||
Messages.get(WndStartGame.class,"custom_name_clear")){
|
||||
@Override
|
||||
public void onSelect(boolean name, String str) {
|
||||
if (name) {
|
||||
SPDSettings.heroName(str);
|
||||
} else {
|
||||
SPDSettings.heroName("");
|
||||
}
|
||||
icon(Icons.get(SPDSettings.heroName().equals("") ? RENAME_OFF : Icons.RENAME_ON));
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
ShatteredPixelDungeon.scene().addToFront(new WndMessage("获得_衪人之遇_徽章后解锁每日挑战。"));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
EverDayGo.setSize( BUTTON_HEIGHT, BUTTON_HEIGHT );
|
||||
EverDayGo.setPos( frame.x + frame.width + FRAME_MARGIN_X, frame.y-51+ frame.height-51- BUTTON_HEIGHT);
|
||||
add(EverDayGo);
|
||||
|
||||
|
||||
btnExit = new ExitButton();
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
add( btnExit );
|
||||
btnExit.visible = !SPDSettings.intro() || Rankings.INSTANCE.totalNumber > 0;
|
||||
if (landscape()) {
|
||||
|
||||
prompt = PixelScene.renderTextBlock(Messages.get(this, "title"), 12);
|
||||
prompt.hardlight(Window.TITLE_COLOR);
|
||||
prompt.setPos( (Camera.main.width - prompt.width())/2f, (Camera.main.height - HeroBtn.HEIGHT - prompt.height() - 4));
|
||||
PixelScene.align(prompt);
|
||||
add(prompt);
|
||||
} else {
|
||||
Image title = new Image(Assets.Interfaces.MENUTITLE, 0, 0, 126, 34);
|
||||
|
||||
PointerArea fadeResetter = new PointerArea(0, 0, Camera.main.width, Camera.main.height){
|
||||
@Override
|
||||
public boolean onSignal(PointerEvent event) {
|
||||
resetFade();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
add(fadeResetter);
|
||||
resetFade();
|
||||
//float topRegion = Math.max(title.height/2, 20f);
|
||||
|
||||
if (GamesInProgress.selectedClass != null){
|
||||
setSelectedHero(GamesInProgress.selectedClass);
|
||||
|
||||
title.setPos(frame.x - frame.width / 5f + FRAME_MARGIN_X / 5f, frame.y + frame.height / 8 - BUTTON_HEIGHT - 45);
|
||||
placeTorch(title.x - 8, title.y + 42);
|
||||
placeTorch(title.x + 132, title.y + 42);
|
||||
add(title);
|
||||
|
||||
Image twotitle = new Image(Assets.Interfaces.TWOYEARS, 0, 0, 126, 34);
|
||||
|
||||
//float topRegion = Math.max(title.height/2, 20f);
|
||||
|
||||
twotitle.setPos(frame.x - frame.width / 5f + FRAME_MARGIN_X / 5f, frame.y + frame.height / 4 - BUTTON_HEIGHT - 40);
|
||||
add(twotitle);
|
||||
}
|
||||
|
||||
fadeIn();
|
||||
|
||||
}
|
||||
|
||||
private void setSelectedHero(HeroClass cl){
|
||||
private void placeTorch( float x, float y ) {
|
||||
Fireball fb2 = new Fireball();
|
||||
fb2.setPos( x, y );
|
||||
add( fb2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Camera.remove( viewport );
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
private void setSelectedHero() {
|
||||
HeroClass cl = heroClass();
|
||||
GamesInProgress.selectedClass = cl;
|
||||
a.heroClass(cl);
|
||||
|
||||
background.texture( cl.splashArt() );
|
||||
background.visible = true;
|
||||
background.hardlight(1.5f,1.5f,1.5f);
|
||||
|
||||
prompt.visible = false;
|
||||
startBtn.visible = true;
|
||||
startBtn.text(Messages.titleCase(cl.title()));
|
||||
startBtn.textColor(Window.TITLE_COLOR);
|
||||
startBtn.setSize(startBtn.reqWidth() + 8, 21);
|
||||
startBtn.setPos((Camera.main.width - startBtn.width())/2f, startBtn.top());
|
||||
startBtn.textColor(Window.WHITE);
|
||||
startBtn.setSize(Math.max(startBtn.reqWidth() + 8, SKY_WIDTH - FRAME_MARGIN_X * 2), BUTTON_HEIGHT);
|
||||
startBtn.setPos( (Camera.main.width - startBtn.width())/2f, frame.y + frame.height + FRAME_MARGIN_X );
|
||||
PixelScene.align(startBtn);
|
||||
startBtn.enable( cl.isUnlocked() );
|
||||
|
||||
infoButton.visible = true;
|
||||
infoButton.setPos(startBtn.right(), startBtn.top());
|
||||
|
||||
challengeButton.visible = true;
|
||||
challengeButton.setPos(startBtn.left()-challengeButton.width(), startBtn.top());
|
||||
}
|
||||
|
||||
private float uiAlpha;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
btnExit.visible = !SPDSettings.intro() || Rankings.INSTANCE.totalNumber > 0;
|
||||
//do not fade when a window is open
|
||||
for (Object v : members){
|
||||
if (v instanceof Window) resetFade();
|
||||
public void onBackPressed() {
|
||||
ShatteredPixelDungeon.switchScene(TitleScene.class);
|
||||
}
|
||||
|
||||
private static class Sky extends Visual {
|
||||
|
||||
private static final int[] day = {0xFF4488FF, 0xFFCCEEFF};
|
||||
private static final int[] night = {0xFF001155, 0xFF335980};
|
||||
private static final int[][] gradients = new int[][] {
|
||||
{ 0xff012459, 0xff001322 },
|
||||
{ 0xff003972, 0xff001322 },
|
||||
{ 0xff003972, 0xff001322 },
|
||||
{ 0xff004372, 0xff00182b },
|
||||
{ 0xff004372, 0xff011d34 },
|
||||
{ 0xff016792, 0xff00182b },
|
||||
{ 0xff07729f, 0xff042c47 },
|
||||
{ 0xff12a1c0, 0xff07506e },
|
||||
{ 0xff74d4cc, 0xff1386a6 },
|
||||
{ 0xffefeebc, 0xff61d0cf },
|
||||
{ 0xfffee154, 0xffa3dec6 },
|
||||
{ 0xfffdc352, 0xffe8ed92 },
|
||||
{ 0xffffac6f, 0xffffe467 },
|
||||
{ 0xfffda65a, 0xffffe467 },
|
||||
{ 0xfffd9e58, 0xffffe467 },
|
||||
{ 0xfff18448, 0xffffd364 },
|
||||
{ 0xfff06b7e, 0xfff9a856 },
|
||||
{ 0xffca5a92, 0xfff4896b },
|
||||
{ 0xff5b2c83, 0xffd1628b },
|
||||
{ 0xff371a79, 0xff713684 },
|
||||
{ 0xff28166b, 0xff45217c },
|
||||
{ 0xff192861, 0xff372074 },
|
||||
{ 0xff040b3c, 0xff233072 },
|
||||
{ 0xff040b3c, 0xff012459 },
|
||||
};
|
||||
|
||||
private SmartTexture texture;
|
||||
private FloatBuffer verticesBuffer;
|
||||
|
||||
public Sky( int hour ) {
|
||||
super( 0, 0, 1, 1 );
|
||||
|
||||
texture = TextureCache.createGradient( gradients[hour] );
|
||||
|
||||
float[] vertices = new float[16];
|
||||
verticesBuffer = Quad.create();
|
||||
|
||||
vertices[2] = 0.25f;
|
||||
vertices[6] = 0.25f;
|
||||
vertices[10] = 0.75f;
|
||||
vertices[14] = 0.75f;
|
||||
|
||||
vertices[3] = 0;
|
||||
vertices[7] = 1;
|
||||
vertices[11] = 1;
|
||||
vertices[15] = 0;
|
||||
|
||||
|
||||
vertices[0] = 0;
|
||||
vertices[1] = 0;
|
||||
|
||||
vertices[4] = 1;
|
||||
vertices[5] = 0;
|
||||
|
||||
vertices[8] = 1;
|
||||
vertices[9] = 1;
|
||||
|
||||
vertices[12] = 0;
|
||||
vertices[13] = 1;
|
||||
|
||||
((Buffer)verticesBuffer).position( 0 );
|
||||
verticesBuffer.put( vertices );
|
||||
}
|
||||
if (GamesInProgress.selectedClass != null) {
|
||||
if (uiAlpha > 0f){
|
||||
uiAlpha -= Game.elapsed/4f;
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
texture.bind();
|
||||
|
||||
script.camera( camera() );
|
||||
|
||||
script.uModel.valueM4( matrix );
|
||||
script.lighting(
|
||||
rm, gm, bm, am,
|
||||
ra, ga, ba, aa );
|
||||
|
||||
script.drawQuad( verticesBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
private static class Cloud extends Image {
|
||||
|
||||
private static int lastIndex = -1;
|
||||
|
||||
public Cloud( float y, boolean dayTime ) {
|
||||
super( Assets.Interfaces.SURFACE );
|
||||
|
||||
int index;
|
||||
do {
|
||||
index = Random.Int( 3 );
|
||||
} while (index == lastIndex);
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
frame( 88, 0, 49, 20 );
|
||||
break;
|
||||
case 1:
|
||||
frame( 88, 20, 49, 22 );
|
||||
break;
|
||||
case 2:
|
||||
frame( 88, 42, 50, 18 );
|
||||
break;
|
||||
}
|
||||
float alpha = GameMath.gate(0f, uiAlpha, 1f);
|
||||
for (StyledButton b : heroBtns){
|
||||
b.alpha(alpha);
|
||||
|
||||
lastIndex = index;
|
||||
|
||||
this.y = y;
|
||||
|
||||
scale.set( 1 - y / SKY_HEIGHT );
|
||||
x = Random.Float( SKY_WIDTH + width() ) - width();
|
||||
speed.x = scale.x * (dayTime ? +8 : -8);
|
||||
|
||||
if (dayTime) {
|
||||
tint( 0xCCEEFF, 1 - scale.y );
|
||||
} else {
|
||||
rm = gm = bm = +3.0f;
|
||||
ra = ga = ba = -2.1f;
|
||||
}
|
||||
startBtn.alpha(alpha);
|
||||
btnExit.icon().alpha(alpha);
|
||||
challengeButton.icon().alpha(alpha);
|
||||
infoButton.icon().alpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetFade(){
|
||||
//starts fading after 4 seconds, fades over 4 seconds.
|
||||
uiAlpha = 2f;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
if (btnExit.visible){
|
||||
ShatteredPixelDungeon.switchScene(TitleScene.class);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private class HeroBtn extends StyledButton {
|
||||
|
||||
private HeroClass cl;
|
||||
|
||||
private static final int MIN_WIDTH = 20;
|
||||
private static final int HEIGHT = 24;
|
||||
|
||||
HeroBtn ( HeroClass cl ){
|
||||
super(Chrome.Type.GREY_BUTTON_TR, "");
|
||||
|
||||
this.cl = cl;
|
||||
|
||||
icon(new Image(cl.spritesheet(), 0, 90, 12, 15));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (cl != GamesInProgress.selectedClass){
|
||||
if (!cl.isUnlocked()){
|
||||
icon.brightness(0.1f);
|
||||
} else {
|
||||
icon.brightness(0.6f);
|
||||
}
|
||||
} else {
|
||||
icon.brightness(1f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
|
||||
if( !cl.isUnlocked() ){
|
||||
ShatteredPixelDungeon.scene().addToFront( new WndMessage(cl.unlockMsg()));
|
||||
} else if (GamesInProgress.selectedClass == cl) {
|
||||
ShatteredPixelDungeon.scene().add(new WndHeroInfo(cl));
|
||||
} else {
|
||||
setSelectedHero(cl);
|
||||
if (speed.x > 0 && x > SKY_WIDTH) {
|
||||
x = -width();
|
||||
} else if (speed.x < 0 && x < -width()) {
|
||||
x = SKY_WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private static class Avatar extends Image {
|
||||
|
||||
private static final int WIDTH = 24;
|
||||
private static final int HEIGHT = 32;
|
||||
|
||||
public Avatar( HeroClass cl ) {
|
||||
super( Assets.Sprites.AVATARS );
|
||||
frame( new TextureFilm( texture, WIDTH, HEIGHT ).get( cl.ordinal() ) );
|
||||
}
|
||||
|
||||
public void heroClass( HeroClass cl ) {
|
||||
frame( new TextureFilm( texture, WIDTH, HEIGHT ).get( cl.ordinal() ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class GrassPatch extends Image {
|
||||
|
||||
public static final int WIDTH = 16;
|
||||
public static final int HEIGHT = 14;
|
||||
|
||||
private float tx;
|
||||
private float ty;
|
||||
|
||||
private double a = Random.Float( 5 );
|
||||
private double angle;
|
||||
|
||||
private boolean forward;
|
||||
|
||||
public GrassPatch( float tx, float ty, boolean forward ) {
|
||||
|
||||
super( Assets.Interfaces.SURFACE );
|
||||
|
||||
frame( 88 + Random.Int( 4 ) * WIDTH, 60, WIDTH, HEIGHT );
|
||||
|
||||
this.tx = tx;
|
||||
this.ty = ty;
|
||||
|
||||
this.forward = forward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
a += Random.Float( Game.elapsed * 5 );
|
||||
angle = (2 + Math.cos( a )) * (forward ? +0.2 : -0.2);
|
||||
|
||||
scale.y = (float)Math.cos( angle );
|
||||
|
||||
x = tx + (float)Math.tan( angle ) * width;
|
||||
y = ty - scale.y * height;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMatrix() {
|
||||
super.updateMatrix();
|
||||
Matrix.skewX( matrix, (float)(angle / Matrix.G2RAD) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndGameInProgress;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStartGame;
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Image;
|
||||
|
@ -266,9 +265,18 @@ public class StartScene extends PixelScene {
|
|||
|
||||
@Override
|
||||
//old select scene like good,I don't like new select scene.
|
||||
// protected void onClick() {
|
||||
// if (newGame) {
|
||||
// ShatteredPixelDungeon.scene().add( new WndStartGame(slot));
|
||||
// } else {
|
||||
// ShatteredPixelDungeon.scene().add( new WndGameInProgress(slot));
|
||||
// }
|
||||
// }
|
||||
protected void onClick() {
|
||||
if (newGame) {
|
||||
ShatteredPixelDungeon.scene().add( new WndStartGame(slot));
|
||||
GamesInProgress.selectedClass = null;
|
||||
GamesInProgress.curSlot = slot;
|
||||
ShatteredPixelDungeon.switchScene(HeroSelectScene.class);
|
||||
} else {
|
||||
ShatteredPixelDungeon.scene().add( new WndGameInProgress(slot));
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import com.watabou.noosa.Camera;
|
|||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
|
||||
public class SupporterScene extends PixelScene {
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ import com.watabou.noosa.Game;
|
|||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NoosaScript;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.PointerArea;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.Point;
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.watabou.utils.ColorMath;
|
|||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -37,11 +38,10 @@ public class TitleScene extends PixelScene {
|
|||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
|
||||
super.create();
|
||||
|
||||
Music.INSTANCE.play( Assets.Music.THEME, true );
|
||||
Music.INSTANCE.play(Random.Float() < 0.6f ? Assets.Music.THEME : Assets.Music.THEME_1, true);
|
||||
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ public enum Icons {
|
|||
MAGE,
|
||||
ROGUE,
|
||||
HUNTRESS,
|
||||
LEFTBUTTON,
|
||||
RIGHTBUTTON,
|
||||
|
||||
//grey icons, mainly used for buttons, spacing for 16x16
|
||||
EXIT,
|
||||
|
@ -160,6 +162,12 @@ public enum Icons {
|
|||
case HUNTRESS:
|
||||
icon.frame( icon.texture.uvRectBySize( 64, 16, 16, 16 ) );
|
||||
break;
|
||||
case LEFTBUTTON:
|
||||
icon.frame( icon.texture.uvRectBySize( 80, 16, 9, 9 ) );
|
||||
break;
|
||||
case RIGHTBUTTON:
|
||||
icon.frame( icon.texture.uvRectBySize( 97, 16, 9, 9 ) );
|
||||
break;
|
||||
|
||||
case EXIT:
|
||||
icon.frame( icon.texture.uvRectBySize( 0, 32, 15, 11 ) );
|
||||
|
|
|
@ -124,15 +124,17 @@ public class DesktopPlatformSupport extends PlatformSupport {
|
|||
fonts = new HashMap<>();
|
||||
|
||||
if (systemfont) {
|
||||
basicFontGenerator = asianFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf"));
|
||||
basicFontGenerator = asianFontGenerator = fallbackFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf"));
|
||||
} else {
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel_font.ttf"));
|
||||
asianFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf"));
|
||||
asianFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/fusion_pixel.ttf"));
|
||||
fallbackFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf"));
|
||||
}
|
||||
|
||||
|
||||
fonts.put(basicFontGenerator, new HashMap<>());
|
||||
fonts.put(asianFontGenerator, new HashMap<>());
|
||||
|
||||
fonts.put(fallbackFontGenerator, new HashMap<>());
|
||||
|
||||
packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false);
|
||||
}
|
||||
|
||||
|
|