v0.8.1: overhauled the game's about scene
This commit is contained in:
parent
a1e35263d3
commit
0b57fefa62
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 12 KiB |
|
@ -23,129 +23,196 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.ExitButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.ScrollPane;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.watabou.input.PointerEvent;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.ColorBlock;
|
||||
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 {
|
||||
|
||||
private static final String TTL_SHPX = "Shattered Pixel Dungeon";
|
||||
|
||||
private static final String TXT_SHPX =
|
||||
"Design, Code, & Graphics: Evan";
|
||||
|
||||
private static final String LNK_SHPX = "ShatteredPixel.com";
|
||||
|
||||
private static final String TTL_WATA = "Pixel Dungeon";
|
||||
|
||||
private static final String TXT_WATA =
|
||||
"Code & Graphics: Watabou\n" +
|
||||
"Music: Cube_Code";
|
||||
|
||||
private static final String LNK_WATA = "pixeldungeon.watabou.ru";
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
final float colWidth = Camera.main.width / (landscape() ? 2 : 1);
|
||||
final float colTop = (Camera.main.height / 2) - (landscape() ? 30 : 90);
|
||||
final float wataOffset = landscape() ? colWidth : 0;
|
||||
final float colWidth = 120;
|
||||
final float fullWidth = colWidth * (landscape() ? 2 : 1);
|
||||
|
||||
Image shpx = Icons.SHPX.get();
|
||||
shpx.x = (colWidth - shpx.width()) / 2;
|
||||
shpx.y = colTop;
|
||||
align(shpx);
|
||||
add( shpx );
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
new Flare( 7, 64 ).color( 0x225511, true ).show( shpx, 0 ).angularSpeed = +20;
|
||||
ScrollPane list = new ScrollPane( new Component() );
|
||||
add( list );
|
||||
|
||||
RenderedTextBlock shpxtitle = renderTextBlock( TTL_SHPX, 8 );
|
||||
shpxtitle.hardlight( Window.SHPX_COLOR );
|
||||
add( shpxtitle );
|
||||
Component content = list.content();
|
||||
content.clear();
|
||||
|
||||
shpxtitle.setPos(
|
||||
(colWidth - shpxtitle.width()) / 2,
|
||||
shpx.y + shpx.height + 5
|
||||
);
|
||||
align(shpxtitle);
|
||||
//*** Shattered Pixel Dungeon Credits ***
|
||||
|
||||
RenderedTextBlock shpxtext = renderTextBlock( TXT_SHPX, 8 );
|
||||
shpxtext.maxWidth((int)Math.min(colWidth, 120));
|
||||
add( shpxtext );
|
||||
CreditsBlock shpx = new CreditsBlock(true, Window.SHPX_COLOR,
|
||||
"Shattered Pixel Dungeon",
|
||||
Icons.SHPX.get(),
|
||||
"Developed by: _Evan Debenham_\nBased on Pixel Dungeon's open source",
|
||||
"ShatteredPixel.com",
|
||||
"https://ShatteredPixel.com");
|
||||
shpx.setRect((w - fullWidth)/2f, 6, 120, 0);
|
||||
content.add(shpx);
|
||||
|
||||
shpxtext.setPos((colWidth - shpxtext.width()) / 2, shpxtitle.bottom() + 12);
|
||||
align(shpxtext);
|
||||
CreditsBlock alex = new CreditsBlock(false, Window.SHPX_COLOR,
|
||||
"Hero Art & Design:",
|
||||
Icons.ALEKS.get(),
|
||||
"Aleksandar Komitov",
|
||||
"alekskomitov.com",
|
||||
"https://www.alekskomitov.com");
|
||||
alex.setSize(colWidth/2f, 0);
|
||||
if (landscape()){
|
||||
alex.setPos(shpx.right(), shpx.top() + (shpx.height() - alex.height())/2f);
|
||||
} else {
|
||||
alex.setPos(w/2f - colWidth/2f, shpx.bottom()+5);
|
||||
}
|
||||
content.add(alex);
|
||||
|
||||
RenderedTextBlock shpxlink = renderTextBlock( LNK_SHPX, 8 );
|
||||
shpxlink.maxWidth(shpxtext.maxWidth());
|
||||
shpxlink.hardlight( Window.SHPX_COLOR );
|
||||
add( shpxlink );
|
||||
CreditsBlock charlie = new CreditsBlock(false, Window.SHPX_COLOR,
|
||||
"Sound Effects:",
|
||||
Icons.CHARLIE.get(),
|
||||
"Charlie",
|
||||
"s9menine.itch.io",
|
||||
"https://s9menine.itch.io");
|
||||
charlie.setRect(alex.right(), alex.top(), colWidth/2f, 0);
|
||||
content.add(charlie);
|
||||
|
||||
shpxlink.setPos((colWidth - shpxlink.width()) / 2, shpxtext.bottom() + 6);
|
||||
align(shpxlink);
|
||||
//*** Pixel Dungeon Credits ***
|
||||
|
||||
PointerArea shpxhotArea = new PointerArea( shpxlink.left(), shpxlink.top(), shpxlink.width(), shpxlink.height() ) {
|
||||
@Override
|
||||
protected void onClick( PointerEvent event ) {
|
||||
DeviceCompat.openURI( "https://" + LNK_SHPX );
|
||||
}
|
||||
};
|
||||
add( shpxhotArea );
|
||||
final int WATA_COLOR = 0x55AAFF;
|
||||
CreditsBlock wata = new CreditsBlock(true, WATA_COLOR,
|
||||
"Pixel Dungeon",
|
||||
Icons.WATA.get(),
|
||||
"Developed by: _Watabou_\nInspired by Brian Walker's Brogue",
|
||||
"pixeldungeon.watabou.ru",
|
||||
"http://pixeldungeon.watabou.ru");
|
||||
if (landscape()){
|
||||
wata.setRect(shpx.left(), shpx.bottom() + 8, colWidth, 0);
|
||||
} else {
|
||||
wata.setRect(shpx.left(), alex.bottom() + 8, colWidth, 0);
|
||||
}
|
||||
content.add(wata);
|
||||
|
||||
Image wata = Icons.WATA.get();
|
||||
wata.x = wataOffset + (colWidth - wata.width()) / 2;
|
||||
wata.y = landscape() ? colTop: shpxlink.top() + wata.height + 20;
|
||||
align(wata);
|
||||
add( wata );
|
||||
addLine(wata.top() - 4, content);
|
||||
|
||||
new Flare( 7, 64 ).color( 0x112233, true ).show( wata, 0 ).angularSpeed = +20;
|
||||
CreditsBlock cube = new CreditsBlock(false, WATA_COLOR,
|
||||
"Music:",
|
||||
Icons.CUBE_CODE.get(),
|
||||
"Cube Code",
|
||||
null,
|
||||
null);
|
||||
cube.setSize(colWidth/2f, 0);
|
||||
if (landscape()){
|
||||
cube.setPos(wata.right(), wata.top() + (wata.height() - cube.height())/2f);
|
||||
} else {
|
||||
cube.setPos(alex.left(), wata.bottom()+5);
|
||||
}
|
||||
content.add(cube);
|
||||
|
||||
RenderedTextBlock wataTitle = renderTextBlock( TTL_WATA, 8 );
|
||||
wataTitle.hardlight(Window.TITLE_COLOR);
|
||||
add( wataTitle );
|
||||
//*** LibGDX Credits ***
|
||||
|
||||
wataTitle.setPos(
|
||||
wataOffset + (colWidth - wataTitle.width()) / 2,
|
||||
wata.y + wata.height + 11
|
||||
);
|
||||
align(wataTitle);
|
||||
final int GDX_COLOR = 0xE44D3C;
|
||||
CreditsBlock gdx = new CreditsBlock(true,
|
||||
GDX_COLOR,
|
||||
null,
|
||||
Icons.LIBGDX.get(),
|
||||
"ShatteredPD is powered by _LibGDX_!",
|
||||
"libgdx.badlogicgames.com",
|
||||
"http://libgdx.badlogicgames.com");
|
||||
if (landscape()){
|
||||
gdx.setRect(wata.left(), wata.bottom() + 8, colWidth, 0);
|
||||
} else {
|
||||
gdx.setRect(wata.left(), cube.bottom() + 8, colWidth, 0);
|
||||
}
|
||||
content.add(gdx);
|
||||
|
||||
RenderedTextBlock wataText = renderTextBlock( TXT_WATA, 8 );
|
||||
wataText.maxWidth((int)Math.min(colWidth, 120));
|
||||
wataText.setHightlighting(false); //underscore in cube_code
|
||||
add( wataText );
|
||||
addLine(gdx.top() - 4, content);
|
||||
|
||||
wataText.setPos(wataOffset + (colWidth - wataText.width()) / 2, wataTitle.bottom() + 12);
|
||||
align(wataText);
|
||||
|
||||
RenderedTextBlock wataLink = renderTextBlock( LNK_WATA, 8 );
|
||||
wataLink.maxWidth((int)Math.min(colWidth, 120));
|
||||
wataLink.hardlight(Window.TITLE_COLOR);
|
||||
add(wataLink);
|
||||
|
||||
wataLink.setPos(wataOffset + (colWidth - wataLink.width()) / 2 , wataText.bottom() + 6);
|
||||
align(wataLink);
|
||||
|
||||
PointerArea hotArea = new PointerArea( wataLink.left(), wataLink.top(), wataLink.width(), wataLink.height() ) {
|
||||
@Override
|
||||
protected void onClick( PointerEvent event ) {
|
||||
DeviceCompat.openURI( "http://" + LNK_WATA );
|
||||
}
|
||||
};
|
||||
add( hotArea );
|
||||
//blocks the rays from the LibGDX icon going above the line
|
||||
ColorBlock blocker = new ColorBlock(w, 8, 0xFF000000);
|
||||
blocker.y = gdx.top() - 12;
|
||||
content.addToBack(blocker);
|
||||
content.sendToBack(gdx);
|
||||
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( Camera.main.width, Camera.main.height );
|
||||
addToBack( archs );
|
||||
CreditsBlock arcnor = new CreditsBlock(false, GDX_COLOR,
|
||||
"Pixel Dungeon GDX:",
|
||||
Icons.ARCNOR.get(),
|
||||
"Edu García",
|
||||
"twitter.com/arcnor",
|
||||
"https://twitter.com/arcnor");
|
||||
arcnor.setSize(colWidth/2f, 0);
|
||||
if (landscape()){
|
||||
arcnor.setPos(gdx.right(), gdx.top() + (gdx.height() - arcnor.height())/2f);
|
||||
} else {
|
||||
arcnor.setPos(alex.left(), gdx.bottom()+5);
|
||||
}
|
||||
content.add(arcnor);
|
||||
|
||||
CreditsBlock purigro = new CreditsBlock(false, GDX_COLOR,
|
||||
"Shattered GDX Help:",
|
||||
Icons.PURIGRO.get(),
|
||||
"Kevin MacMartin",
|
||||
"github.com/prurigro",
|
||||
"https://github.com/prurigro/");
|
||||
purigro.setRect(arcnor.right()+2, arcnor.top(), colWidth/2f, 0);
|
||||
content.add(purigro);
|
||||
|
||||
//*** Transifex Credits ***
|
||||
|
||||
CreditsBlock transifex = new CreditsBlock(true,
|
||||
Window.TITLE_COLOR,
|
||||
null,
|
||||
null,
|
||||
"ShatteredPD is community-translated via _Transifex_! Thank you so much to all of Shattered's volunteer translators!",
|
||||
"www.transifex.com/shattered-pixel/",
|
||||
"https://www.transifex.com/shattered-pixel/shattered-pixel-dungeon/");
|
||||
transifex.setRect((Camera.main.width - colWidth)/2f, purigro.bottom() + 8, colWidth, 0);
|
||||
content.add(transifex);
|
||||
|
||||
addLine(transifex.top() - 4, content);
|
||||
|
||||
addLine(transifex.bottom() + 4, content);
|
||||
|
||||
//*** Freesound Credits ***
|
||||
|
||||
CreditsBlock freesound = new CreditsBlock(true,
|
||||
Window.TITLE_COLOR,
|
||||
null,
|
||||
null,
|
||||
"Shattered Pixel Dungeon uses the following sound samples from _freesound.org_:\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD\n" +
|
||||
"_-_ TBD by TBD",
|
||||
null,
|
||||
null);
|
||||
freesound.setRect(transifex.left(), transifex.bottom() + 8, colWidth, 0);
|
||||
content.add(freesound);
|
||||
|
||||
content.setSize( fullWidth, freesound.bottom() );
|
||||
|
||||
list.setRect( 0, 0, w, h );
|
||||
list.scrollTo(0, 0);
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
|
@ -156,6 +223,150 @@ public class AboutScene extends PixelScene {
|
|||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
ShatteredPixelDungeon.switchNoFade(TitleScene.class);
|
||||
ShatteredPixelDungeon.switchScene(TitleScene.class);
|
||||
}
|
||||
|
||||
private void addLine( float y, Group content ){
|
||||
ColorBlock line = new ColorBlock(Camera.main.width, 1, 0xFF333333);
|
||||
line.y = y;
|
||||
content.add(line);
|
||||
}
|
||||
|
||||
private static class CreditsBlock extends Component {
|
||||
|
||||
boolean large;
|
||||
RenderedTextBlock title;
|
||||
Image avatar;
|
||||
Flare flare;
|
||||
RenderedTextBlock body;
|
||||
|
||||
RenderedTextBlock link;
|
||||
ColorBlock linkUnderline;
|
||||
PointerArea linkButton;
|
||||
|
||||
//many elements can be null, but body is assumed to have content.
|
||||
private CreditsBlock(boolean large, int highlight, String title, Image avatar, String body, String linkText, String linkUrl){
|
||||
super();
|
||||
|
||||
this.large = large;
|
||||
|
||||
if (title != null) {
|
||||
this.title = PixelScene.renderTextBlock(title, large ? 8 : 6);
|
||||
if (highlight != -1) this.title.hardlight(highlight);
|
||||
add(this.title);
|
||||
}
|
||||
|
||||
if (avatar != null){
|
||||
this.avatar = avatar;
|
||||
add(this.avatar);
|
||||
}
|
||||
|
||||
if (large && highlight != -1 && this.avatar != null){
|
||||
this.flare = new Flare( 7, 24 ).color( highlight, true ).show(this.avatar, 0);
|
||||
this.flare.angularSpeed = 20;
|
||||
}
|
||||
|
||||
this.body = PixelScene.renderTextBlock(body, 6);
|
||||
if (highlight != -1) this.body.setHightlighting(true, highlight);
|
||||
if (large) this.body.align(RenderedTextBlock.CENTER_ALIGN);
|
||||
add(this.body);
|
||||
|
||||
if (linkText != null && linkUrl != null){
|
||||
|
||||
int color = 0xFFFFFFFF;
|
||||
if (highlight != -1) color = 0xFF000000 | highlight;
|
||||
this.linkUnderline = new ColorBlock(1, 1, color);
|
||||
add(this.linkUnderline);
|
||||
|
||||
this.link = PixelScene.renderTextBlock(linkText, 6);
|
||||
if (highlight != -1) this.link.hardlight(highlight);
|
||||
add(this.link);
|
||||
|
||||
linkButton = new PointerArea(0, 0, 0, 0){
|
||||
@Override
|
||||
protected void onClick( PointerEvent event ) {
|
||||
DeviceCompat.openURI( linkUrl );
|
||||
}
|
||||
};
|
||||
add(linkButton);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
super.layout();
|
||||
|
||||
float topY = top();
|
||||
|
||||
if (title != null){
|
||||
title.maxWidth((int)width());
|
||||
title.setPos( x + (width() - title.width())/2f, topY);
|
||||
topY += title.height() + (large ? 2 : 1);
|
||||
}
|
||||
|
||||
if (large){
|
||||
|
||||
if (avatar != null){
|
||||
avatar.x = x + (width()-avatar.width())/2f;
|
||||
avatar.y = topY;
|
||||
PixelScene.align(avatar);
|
||||
if (flare != null){
|
||||
flare.point(avatar.center());
|
||||
}
|
||||
topY = avatar.y + avatar.height() + 2;
|
||||
}
|
||||
|
||||
body.maxWidth((int)width());
|
||||
body.setPos( x + (width() - body.width())/2f, topY);
|
||||
topY += body.height() + 2;
|
||||
|
||||
} else {
|
||||
|
||||
if (avatar != null){
|
||||
avatar.x = x;
|
||||
body.maxWidth((int)(width() - avatar.width - 1));
|
||||
|
||||
if (avatar.height() > body.height()){
|
||||
avatar.y = topY;
|
||||
body.setPos( avatar.x + avatar.width() + 1, topY + (avatar.height() - body.height())/2f);
|
||||
topY += avatar.height() + 1;
|
||||
} else {
|
||||
avatar.y = topY + (body.height() - avatar.height())/2f;
|
||||
PixelScene.align(avatar);
|
||||
body.setPos( avatar.x + avatar.width() + 1, topY);
|
||||
topY += body.height() + 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
topY += 1;
|
||||
body.maxWidth((int)width());
|
||||
body.setPos( x, topY);
|
||||
topY += body.height()+2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (link != null){
|
||||
if (large) topY += 1;
|
||||
link.maxWidth((int)width());
|
||||
link.setPos( x + (width() - link.width())/2f, topY);
|
||||
topY += link.height() + 2;
|
||||
|
||||
linkButton.x = link.left()-1;
|
||||
linkButton.y = link.top()-1;
|
||||
linkButton.width = link.width()+2;
|
||||
linkButton.height = link.height()+2;
|
||||
|
||||
linkUnderline.size(link.width(), PixelScene.align(0.49f));
|
||||
linkUnderline.x = link.left();
|
||||
linkUnderline.y = link.bottom()+1;
|
||||
|
||||
}
|
||||
|
||||
topY -= 2;
|
||||
|
||||
height = Math.max(height, topY - top());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ public class TitleScene extends PixelScene {
|
|||
TitleButton btnAbout = new TitleButton(Messages.get(this, "about")){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
ShatteredPixelDungeon.switchNoFade( AboutScene.class );
|
||||
ShatteredPixelDungeon.switchScene( AboutScene.class );
|
||||
}
|
||||
};
|
||||
btnAbout.icon(Icons.get(Icons.SHPX));
|
||||
|
|
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||
import com.watabou.noosa.Image;
|
||||
|
||||
public enum Icons {
|
||||
|
@ -71,7 +72,14 @@ public enum Icons {
|
|||
//misc icons
|
||||
LIBGDX,
|
||||
WATA,
|
||||
WARNING;
|
||||
WARNING,
|
||||
|
||||
//32x32 icons for credits
|
||||
CUBE_CODE,
|
||||
PURIGRO,
|
||||
ARCNOR,
|
||||
ALEKS,
|
||||
CHARLIE;
|
||||
|
||||
public Image get() {
|
||||
return get( this );
|
||||
|
@ -192,6 +200,29 @@ public enum Icons {
|
|||
case WARNING:
|
||||
icon.frame( icon.texture.uvRect( 34, 81, 48, 95 ) );
|
||||
break;
|
||||
|
||||
//32*32 icons are scaled down to match game's size
|
||||
case ALEKS:
|
||||
icon.frame( icon.texture.uvRect( 0, 96, 32, 128 ) );
|
||||
icon.scale.set(PixelScene.align(0.49f));
|
||||
break;
|
||||
case CHARLIE:
|
||||
icon.frame( icon.texture.uvRect( 32, 96, 64, 128 ) );
|
||||
icon.scale.set(PixelScene.align(0.49f));
|
||||
break;
|
||||
case ARCNOR:
|
||||
icon.frame( icon.texture.uvRect( 64, 96, 96, 128 ) );
|
||||
icon.scale.set(PixelScene.align(0.49f));
|
||||
break;
|
||||
case PURIGRO:
|
||||
icon.frame( icon.texture.uvRect( 96, 96, 128, 128 ) );
|
||||
icon.scale.set(PixelScene.align(0.49f));
|
||||
break;
|
||||
case CUBE_CODE:
|
||||
icon.frame( icon.texture.uvRect( 101, 39, 128, 69 ) );
|
||||
icon.scale.set(PixelScene.align(0.49f));
|
||||
break;
|
||||
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ public class RenderedTextBlock extends Component {
|
|||
} else {
|
||||
if (word.height() > height) height = word.height();
|
||||
|
||||
if ((x - this.x) + word.width() > maxWidth){
|
||||
if ((x - this.x) + word.width() > maxWidth && !curLine.isEmpty()){
|
||||
y += height+2f;
|
||||
x = this.x;
|
||||
nLines++;
|
||||
|
|
Loading…
Reference in New Issue
Block a user