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.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);
RenderedTextBlock shpxlink = renderTextBlock( LNK_SHPX, 8 );
shpxlink.maxWidth(shpxtext.maxWidth());
shpxlink.hardlight( Window.SHPX_COLOR );
add( shpxlink );
shpxlink.setPos((colWidth - shpxlink.width()) / 2, shpxtext.bottom() + 6);
align(shpxlink);
PointerArea shpxhotArea = new PointerArea( shpxlink.left(), shpxlink.top(), shpxlink.width(), shpxlink.height() ) {
@Override
protected void onClick( PointerEvent event ) {
DeviceCompat.openURI( "https://" + LNK_SHPX );
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);
}
};
add( shpxhotArea );
content.add(alex);
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 );
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);
new Flare( 7, 64 ).color( 0x112233, true ).show( wata, 0 ).angularSpeed = +20;
//*** Pixel Dungeon Credits ***
RenderedTextBlock wataTitle = renderTextBlock( TTL_WATA, 8 );
wataTitle.hardlight(Window.TITLE_COLOR);
add( wataTitle );
wataTitle.setPos(
wataOffset + (colWidth - wataTitle.width()) / 2,
wata.y + wata.height + 11
);
align(wataTitle);
RenderedTextBlock wataText = renderTextBlock( TXT_WATA, 8 );
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);
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 );
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);
}
};
add( hotArea );
content.add(wata);
addLine(wata.top() - 4, content);
Archs archs = new Archs();
archs.setSize( Camera.main.width, Camera.main.height );
addToBack( archs );
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);
//*** LibGDX Credits ***
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);
addLine(gdx.top() - 4, content);
//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);
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());
}
}
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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++;