v0.8.1: overhauled the game's about scene

This commit is contained in:
Evan Debenham 2020-05-22 22:33:50 -04:00
parent a1e35263d3
commit 0b57fefa62
5 changed files with 337 additions and 95 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -23,129 +23,196 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
import com.shatteredpixel.shatteredpixeldungeon.ui.ExitButton; import com.shatteredpixel.shatteredpixeldungeon.ui.ExitButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock; import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.ScrollPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.input.PointerEvent; import com.watabou.input.PointerEvent;
import com.watabou.noosa.Camera; import com.watabou.noosa.Camera;
import com.watabou.noosa.ColorBlock;
import com.watabou.noosa.Group;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
import com.watabou.noosa.PointerArea; import com.watabou.noosa.PointerArea;
import com.watabou.noosa.ui.Component;
import com.watabou.utils.DeviceCompat; import com.watabou.utils.DeviceCompat;
public class AboutScene extends PixelScene { 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 @Override
public void create() { public void create() {
super.create(); super.create();
final float colWidth = Camera.main.width / (landscape() ? 2 : 1); final float colWidth = 120;
final float colTop = (Camera.main.height / 2) - (landscape() ? 30 : 90); final float fullWidth = colWidth * (landscape() ? 2 : 1);
final float wataOffset = landscape() ? colWidth : 0;
Image shpx = Icons.SHPX.get(); int w = Camera.main.width;
shpx.x = (colWidth - shpx.width()) / 2; int h = Camera.main.height;
shpx.y = colTop;
align(shpx);
add( shpx );
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 ); Component content = list.content();
shpxtitle.hardlight( Window.SHPX_COLOR ); content.clear();
add( shpxtitle );
shpxtitle.setPos( //*** Shattered Pixel Dungeon Credits ***
(colWidth - shpxtitle.width()) / 2,
shpx.y + shpx.height + 5
);
align(shpxtitle);
RenderedTextBlock shpxtext = renderTextBlock( TXT_SHPX, 8 ); CreditsBlock shpx = new CreditsBlock(true, Window.SHPX_COLOR,
shpxtext.maxWidth((int)Math.min(colWidth, 120)); "Shattered Pixel Dungeon",
add( shpxtext ); 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); CreditsBlock alex = new CreditsBlock(false, Window.SHPX_COLOR,
align(shpxtext); "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 ); CreditsBlock charlie = new CreditsBlock(false, Window.SHPX_COLOR,
shpxlink.maxWidth(shpxtext.maxWidth()); "Sound Effects:",
shpxlink.hardlight( Window.SHPX_COLOR ); Icons.CHARLIE.get(),
add( shpxlink ); "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); //*** Pixel Dungeon Credits ***
align(shpxlink);
PointerArea shpxhotArea = new PointerArea( shpxlink.left(), shpxlink.top(), shpxlink.width(), shpxlink.height() ) { final int WATA_COLOR = 0x55AAFF;
@Override CreditsBlock wata = new CreditsBlock(true, WATA_COLOR,
protected void onClick( PointerEvent event ) { "Pixel Dungeon",
DeviceCompat.openURI( "https://" + LNK_SHPX ); Icons.WATA.get(),
} "Developed by: _Watabou_\nInspired by Brian Walker's Brogue",
}; "pixeldungeon.watabou.ru",
add( shpxhotArea ); "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(); addLine(wata.top() - 4, content);
wata.x = wataOffset + (colWidth - wata.width()) / 2;
wata.y = landscape() ? colTop: shpxlink.top() + wata.height + 20;
align(wata);
add( wata );
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 ); //*** LibGDX Credits ***
wataTitle.hardlight(Window.TITLE_COLOR);
add( wataTitle );
wataTitle.setPos( final int GDX_COLOR = 0xE44D3C;
wataOffset + (colWidth - wataTitle.width()) / 2, CreditsBlock gdx = new CreditsBlock(true,
wata.y + wata.height + 11 GDX_COLOR,
); null,
align(wataTitle); 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 ); addLine(gdx.top() - 4, content);
wataText.maxWidth((int)Math.min(colWidth, 120));
wataText.setHightlighting(false); //underscore in cube_code
add( wataText );
wataText.setPos(wataOffset + (colWidth - wataText.width()) / 2, wataTitle.bottom() + 12); //blocks the rays from the LibGDX icon going above the line
align(wataText); ColorBlock blocker = new ColorBlock(w, 8, 0xFF000000);
blocker.y = gdx.top() - 12;
content.addToBack(blocker);
content.sendToBack(gdx);
RenderedTextBlock wataLink = renderTextBlock( LNK_WATA, 8 ); CreditsBlock arcnor = new CreditsBlock(false, GDX_COLOR,
wataLink.maxWidth((int)Math.min(colWidth, 120)); "Pixel Dungeon GDX:",
wataLink.hardlight(Window.TITLE_COLOR); Icons.ARCNOR.get(),
add(wataLink); "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);
wataLink.setPos(wataOffset + (colWidth - wataLink.width()) / 2 , wataText.bottom() + 6); CreditsBlock purigro = new CreditsBlock(false, GDX_COLOR,
align(wataLink); "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);
PointerArea hotArea = new PointerArea( wataLink.left(), wataLink.top(), wataLink.width(), wataLink.height() ) { //*** Transifex Credits ***
@Override
protected void onClick( PointerEvent event ) {
DeviceCompat.openURI( "http://" + LNK_WATA );
}
};
add( hotArea );
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);
Archs archs = new Archs(); addLine(transifex.top() - 4, content);
archs.setSize( Camera.main.width, Camera.main.height );
addToBack( archs ); 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(); ExitButton btnExit = new ExitButton();
btnExit.setPos( Camera.main.width - btnExit.width(), 0 ); btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
@ -156,6 +223,150 @@ public class AboutScene extends PixelScene {
@Override @Override
protected void onBackPressed() { 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());
}
} }
} }

View File

@ -174,7 +174,7 @@ public class TitleScene extends PixelScene {
TitleButton btnAbout = new TitleButton(Messages.get(this, "about")){ TitleButton btnAbout = new TitleButton(Messages.get(this, "about")){
@Override @Override
protected void onClick() { protected void onClick() {
ShatteredPixelDungeon.switchNoFade( AboutScene.class ); ShatteredPixelDungeon.switchScene( AboutScene.class );
} }
}; };
btnAbout.icon(Icons.get(Icons.SHPX)); btnAbout.icon(Icons.get(Icons.SHPX));

View File

@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
public enum Icons { public enum Icons {
@ -71,7 +72,14 @@ public enum Icons {
//misc icons //misc icons
LIBGDX, LIBGDX,
WATA, WATA,
WARNING; WARNING,
//32x32 icons for credits
CUBE_CODE,
PURIGRO,
ARCNOR,
ALEKS,
CHARLIE;
public Image get() { public Image get() {
return get( this ); return get( this );
@ -192,6 +200,29 @@ public enum Icons {
case WARNING: case WARNING:
icon.frame( icon.texture.uvRect( 34, 81, 48, 95 ) ); icon.frame( icon.texture.uvRect( 34, 81, 48, 95 ) );
break; 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; return icon;
} }

View File

@ -211,7 +211,7 @@ public class RenderedTextBlock extends Component {
} else { } else {
if (word.height() > height) height = word.height(); 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; y += height+2f;
x = this.x; x = this.x;
nLines++; nLines++;