V0.1.0 Partial Commit
changed package and application names to differentiate from main PD release
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.watabou.input.Touchscreen.Touch;
|
||||
import com.watabou.noosa.BitmapTextMultiline;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.TouchArea;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
|
||||
public class AboutScene extends PixelScene {
|
||||
|
||||
private static final String TXT =
|
||||
"Code & graphics: Watabou\n" +
|
||||
"Music: Cube_Code\n\n" +
|
||||
"This game is inspired by Brian Walker's Brogue. " +
|
||||
"Try it on Windows, Mac OS or Linux - it's awesome! ;)\n\n" +
|
||||
"Please visit official website for additional info:";
|
||||
|
||||
private static final String LNK = "shatteredpixeldungeon.watabou.ru";
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
BitmapTextMultiline text = createMultiline( TXT, 8 );
|
||||
text.maxWidth = Math.min( Camera.main.width, 120 );
|
||||
text.measure();
|
||||
add( text );
|
||||
|
||||
text.x = align( (Camera.main.width - text.width()) / 2 );
|
||||
text.y = align( (Camera.main.height - text.height()) / 2 );
|
||||
|
||||
BitmapTextMultiline link = createMultiline( LNK, 8 );
|
||||
link.maxWidth = Math.min( Camera.main.width, 120 );
|
||||
link.measure();
|
||||
link.hardlight( Window.TITLE_COLOR );
|
||||
add( link );
|
||||
|
||||
link.x = text.x;
|
||||
link.y = text.y + text.height();
|
||||
|
||||
TouchArea hotArea = new TouchArea( link ) {
|
||||
@Override
|
||||
protected void onClick( Touch touch ) {
|
||||
Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse( "http://" + LNK ) );
|
||||
Game.instance.startActivity( intent );
|
||||
}
|
||||
};
|
||||
add( hotArea );
|
||||
|
||||
Image wata = Icons.WATA.get();
|
||||
wata.x = align( text.x + (text.width() - wata.width) / 2 );
|
||||
wata.y = text.y - wata.height - 8;
|
||||
add( wata );
|
||||
|
||||
new Flare( 7, 64 ).color( 0x112233, true ).show( wata, 0 ).angularSpeed = +20;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( Camera.main.width, Camera.main.height );
|
||||
addToBack( archs );
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
Game.switchScene( TitleScene.class );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.watabou.noosa.BitmapTextMultiline;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class AmuletScene extends PixelScene {
|
||||
|
||||
private static final String TXT_EXIT = "Let's call it a day";
|
||||
private static final String TXT_STAY = "I'm not done yet";
|
||||
|
||||
private static final int WIDTH = 120;
|
||||
private static final int BTN_HEIGHT = 18;
|
||||
private static final float SMALL_GAP = 2;
|
||||
private static final float LARGE_GAP = 8;
|
||||
|
||||
private static final String TXT =
|
||||
"You finally hold it in your hands, the Amulet of Yendor. Using its power " +
|
||||
"you can take over the world or bring peace and prosperity to people or whatever. " +
|
||||
"Anyway, your life will change forever and this game will end here. " +
|
||||
"Or you can stay a mere mortal a little longer.";
|
||||
|
||||
public static boolean noText = false;
|
||||
|
||||
private Image amulet;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
BitmapTextMultiline text = null;
|
||||
if (!noText) {
|
||||
text = createMultiline( TXT, 8 );
|
||||
text.maxWidth = WIDTH;
|
||||
text.measure();
|
||||
add( text );
|
||||
}
|
||||
|
||||
amulet = new Image( Assets.AMULET );
|
||||
add( amulet );
|
||||
|
||||
RedButton btnExit = new RedButton( TXT_EXIT ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Dungeon.deleteGame( Dungeon.hero.heroClass, true );
|
||||
Game.switchScene( noText ? TitleScene.class : RankingsScene.class );
|
||||
}
|
||||
};
|
||||
btnExit.setSize( WIDTH, BTN_HEIGHT );
|
||||
add( btnExit );
|
||||
|
||||
RedButton btnStay = new RedButton( TXT_STAY ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
onBackPressed();
|
||||
}
|
||||
};
|
||||
btnStay.setSize( WIDTH, BTN_HEIGHT );
|
||||
add( btnStay );
|
||||
|
||||
float height;
|
||||
if (noText) {
|
||||
height = amulet.height + LARGE_GAP + btnExit.height() + SMALL_GAP + btnStay.height();
|
||||
|
||||
amulet.x = align( (Camera.main.width - amulet.width) / 2 );
|
||||
amulet.y = align( (Camera.main.height - height) / 2 );
|
||||
|
||||
btnExit.setPos( (Camera.main.width - btnExit.width()) / 2, amulet.y + amulet.height + LARGE_GAP );
|
||||
btnStay.setPos( btnExit.left(), btnExit.bottom() + SMALL_GAP );
|
||||
|
||||
} else {
|
||||
height = amulet.height + LARGE_GAP + text.height() + LARGE_GAP + btnExit.height() + SMALL_GAP + btnStay.height();
|
||||
|
||||
amulet.x = align( (Camera.main.width - amulet.width) / 2 );
|
||||
amulet.y = align( (Camera.main.height - height) / 2 );
|
||||
|
||||
text.x = align( (Camera.main.width - text.width()) / 2 );
|
||||
text.y = amulet.y + amulet.height + LARGE_GAP;
|
||||
|
||||
btnExit.setPos( (Camera.main.width - btnExit.width()) / 2, text.y + text.height() + LARGE_GAP );
|
||||
btnStay.setPos( btnExit.left(), btnExit.bottom() + SMALL_GAP );
|
||||
}
|
||||
|
||||
new Flare( 8, 48 ).color( 0xFFDDBB, true ).show( amulet, 0 ).angularSpeed = +30;
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
InterlevelScene.mode = InterlevelScene.Mode.CONTINUE;
|
||||
Game.switchScene( InterlevelScene.class );
|
||||
}
|
||||
|
||||
private float timer = 0;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
if ((timer -= Game.elapsed) < 0) {
|
||||
timer = Random.Float( 0.5f, 5f );
|
||||
|
||||
Speck star = (Speck)recycle( Speck.class );
|
||||
star.reset( 0, amulet.x + 10.5f, amulet.y + 5.5f, Speck.DISCOVER );
|
||||
add( star );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BadgesList;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.ScrollPane;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
|
||||
public class BadgesScene extends PixelScene {
|
||||
|
||||
private static final String TXT_TITLE = "Your Badges";
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Music.INSTANCE.play( Assets.THEME, true );
|
||||
Music.INSTANCE.volume( 1f );
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
int pw = Math.min( 160, w - 10 );
|
||||
int ph = h - 24;
|
||||
|
||||
NinePatch panel = Chrome.get( Chrome.Type.WINDOW );
|
||||
panel.size( pw, ph );
|
||||
panel.x = (w - pw) / 2;
|
||||
panel.y = (h - ph) / 2;
|
||||
add( panel );
|
||||
|
||||
BitmapText title = PixelScene.createText( TXT_TITLE, 9 );
|
||||
title.hardlight( Window.TITLE_COLOR );
|
||||
title.measure();
|
||||
title.x = align( (w - title.width()) / 2 );
|
||||
title.y = align( (panel.y - title.baseLine()) / 2 );
|
||||
add( title );
|
||||
|
||||
Badges.loadGlobal();
|
||||
|
||||
ScrollPane list = new BadgesList( true );
|
||||
add( list );
|
||||
|
||||
list.setRect(
|
||||
panel.x + panel.marginLeft(),
|
||||
panel.y + panel.marginTop(),
|
||||
panel.innerWidth(),
|
||||
panel.innerHeight() );
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
Game.switchScene( TitleScene.class );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.watabou.input.Touchscreen.Touch;
|
||||
import com.watabou.noosa.TouchArea;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class CellSelector extends TouchArea {
|
||||
|
||||
public Listener listener = null;
|
||||
|
||||
public boolean enabled;
|
||||
|
||||
private float dragThreshold;
|
||||
|
||||
public CellSelector( DungeonTilemap map ) {
|
||||
super( map );
|
||||
camera = map.camera();
|
||||
|
||||
dragThreshold = PixelScene.defaultZoom * DungeonTilemap.SIZE / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick( Touch touch ) {
|
||||
if (dragging) {
|
||||
|
||||
dragging = false;
|
||||
|
||||
} else {
|
||||
|
||||
select( ((DungeonTilemap)target).screenToTile(
|
||||
(int)touch.current.x,
|
||||
(int)touch.current.y ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void select( int cell ) {
|
||||
if (enabled && listener != null && cell != -1) {
|
||||
|
||||
listener.onSelect( cell );
|
||||
GameScene.ready();
|
||||
|
||||
} else {
|
||||
|
||||
GameScene.cancel();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean pinching = false;
|
||||
private Touch another;
|
||||
private float startZoom;
|
||||
private float startSpan;
|
||||
|
||||
@Override
|
||||
protected void onTouchDown( Touch t ) {
|
||||
|
||||
if (t != touch && another == null) {
|
||||
|
||||
if (!touch.down) {
|
||||
touch = t;
|
||||
onTouchDown( t );
|
||||
return;
|
||||
}
|
||||
|
||||
pinching = true;
|
||||
|
||||
another = t;
|
||||
startSpan = PointF.distance( touch.current, another.current );
|
||||
startZoom = camera.zoom;
|
||||
|
||||
dragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTouchUp( Touch t ) {
|
||||
if (pinching && (t == touch || t == another)) {
|
||||
|
||||
pinching = false;
|
||||
|
||||
int zoom = Math.round( camera.zoom );
|
||||
camera.zoom( zoom );
|
||||
ShatteredPixelDungeon.zoom((int) (zoom - PixelScene.defaultZoom));
|
||||
|
||||
dragging = true;
|
||||
if (t == touch) {
|
||||
touch = another;
|
||||
}
|
||||
another = null;
|
||||
lastPos.set( touch.current );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean dragging = false;
|
||||
private PointF lastPos = new PointF();
|
||||
|
||||
@Override
|
||||
protected void onDrag( Touch t ) {
|
||||
|
||||
camera.target = null;
|
||||
|
||||
if (pinching) {
|
||||
|
||||
float curSpan = PointF.distance( touch.current, another.current );
|
||||
camera.zoom( GameMath.gate(
|
||||
PixelScene.minZoom,
|
||||
startZoom * curSpan / startSpan,
|
||||
PixelScene.maxZoom ) );
|
||||
|
||||
} else {
|
||||
|
||||
if (!dragging && PointF.distance( t.current, t.start ) > dragThreshold) {
|
||||
|
||||
dragging = true;
|
||||
lastPos.set( t.current );
|
||||
|
||||
} else if (dragging) {
|
||||
camera.scroll.offset( PointF.diff( lastPos, t.current ).invScale( camera.zoom ) );
|
||||
lastPos.set( t.current );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
|
||||
if (listener != null) {
|
||||
listener.onSelect( null );
|
||||
}
|
||||
|
||||
GameScene.ready();
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onSelect( Integer cell );
|
||||
String prompt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,613 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.*;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.SkinnedBlock;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.EmoIcon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Ripple;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.SpellSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlink;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.DiscardedItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.PlantSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Banner;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BusyIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.HealthIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlot;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Toast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag.Mode;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndGame;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStory;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class GameScene extends PixelScene {
|
||||
|
||||
private static final String TXT_WELCOME = "Welcome to the level %d of Pixel Dungeon!";
|
||||
private static final String TXT_WELCOME_BACK = "Welcome back to the level %d of Pixel Dungeon!";
|
||||
private static final String TXT_NIGHT_MODE = "Be cautious, since the dungeon is even more dangerous at night!";
|
||||
|
||||
private static final String TXT_CHASM = "Your steps echo across the dungeon.";
|
||||
private static final String TXT_WATER = "You hear the water splashing around you.";
|
||||
private static final String TXT_GRASS = "The smell of vegetation is thick in the air.";
|
||||
private static final String TXT_SECRETS = "The atmosphere hints that this floor hides many secrets.";
|
||||
|
||||
static GameScene scene;
|
||||
|
||||
private SkinnedBlock water;
|
||||
private DungeonTilemap tiles;
|
||||
private FogOfWar fog;
|
||||
private HeroSprite hero;
|
||||
|
||||
private GameLog log;
|
||||
|
||||
private BusyIndicator busy;
|
||||
|
||||
private static CellSelector cellSelector;
|
||||
|
||||
private Group terrain;
|
||||
private Group ripples;
|
||||
private Group plants;
|
||||
private Group heaps;
|
||||
private Group mobs;
|
||||
private Group emitters;
|
||||
private Group effects;
|
||||
private Group gases;
|
||||
private Group spells;
|
||||
private Group statuses;
|
||||
private Group emoicons;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private Toast prompt;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
Music.INSTANCE.play( Assets.TUNE, true );
|
||||
Music.INSTANCE.volume( 1f );
|
||||
|
||||
ShatteredPixelDungeon.lastClass(Dungeon.hero.heroClass.ordinal());
|
||||
|
||||
super.create();
|
||||
Camera.main.zoom( defaultZoom + ShatteredPixelDungeon.zoom() );
|
||||
|
||||
scene = this;
|
||||
|
||||
terrain = new Group();
|
||||
add( terrain );
|
||||
|
||||
water = new SkinnedBlock(
|
||||
Level.WIDTH * DungeonTilemap.SIZE,
|
||||
Level.HEIGHT * DungeonTilemap.SIZE,
|
||||
Dungeon.level.waterTex() );
|
||||
terrain.add( water );
|
||||
|
||||
ripples = new Group();
|
||||
terrain.add( ripples );
|
||||
|
||||
tiles = new DungeonTilemap();
|
||||
terrain.add( tiles );
|
||||
|
||||
Dungeon.level.addVisuals( this );
|
||||
|
||||
plants = new Group();
|
||||
add( plants );
|
||||
|
||||
int size = Dungeon.level.plants.size();
|
||||
for (int i=0; i < size; i++) {
|
||||
addPlantSprite( Dungeon.level.plants.valueAt( i ) );
|
||||
}
|
||||
|
||||
heaps = new Group();
|
||||
add( heaps );
|
||||
|
||||
size = Dungeon.level.heaps.size();
|
||||
for (int i=0; i < size; i++) {
|
||||
addHeapSprite( Dungeon.level.heaps.valueAt( i ) );
|
||||
}
|
||||
|
||||
emitters = new Group();
|
||||
effects = new Group();
|
||||
emoicons = new Group();
|
||||
|
||||
mobs = new Group();
|
||||
add( mobs );
|
||||
|
||||
for (Mob mob : Dungeon.level.mobs) {
|
||||
addMobSprite( mob );
|
||||
if (Statistics.amuletObtained) {
|
||||
mob.beckon( Dungeon.hero.pos );
|
||||
}
|
||||
}
|
||||
|
||||
add( emitters );
|
||||
add( effects );
|
||||
|
||||
gases = new Group();
|
||||
add( gases );
|
||||
|
||||
for (Blob blob : Dungeon.level.blobs.values()) {
|
||||
blob.emitter = null;
|
||||
addBlobSprite( blob );
|
||||
}
|
||||
|
||||
fog = new FogOfWar( Level.WIDTH, Level.HEIGHT );
|
||||
fog.updateVisibility( Dungeon.visible, Dungeon.level.visited, Dungeon.level.mapped );
|
||||
add( fog );
|
||||
|
||||
brightness( ShatteredPixelDungeon.brightness() );
|
||||
|
||||
spells = new Group();
|
||||
add( spells );
|
||||
|
||||
statuses = new Group();
|
||||
add( statuses );
|
||||
|
||||
add( emoicons );
|
||||
|
||||
hero = new HeroSprite();
|
||||
hero.place( Dungeon.hero.pos );
|
||||
hero.updateArmor();
|
||||
mobs.add( hero );
|
||||
|
||||
|
||||
add( new HealthIndicator() );
|
||||
|
||||
add( cellSelector = new CellSelector( tiles ) );
|
||||
|
||||
StatusPane sb = new StatusPane();
|
||||
sb.camera = uiCamera;
|
||||
sb.setSize( uiCamera.width, 0 );
|
||||
add( sb );
|
||||
|
||||
toolbar = new Toolbar();
|
||||
toolbar.camera = uiCamera;
|
||||
toolbar.setRect( 0,uiCamera.height - toolbar.height(), uiCamera.width, toolbar.height() );
|
||||
add( toolbar );
|
||||
|
||||
AttackIndicator attack = new AttackIndicator();
|
||||
attack.camera = uiCamera;
|
||||
attack.setPos(
|
||||
uiCamera.width - attack.width(),
|
||||
toolbar.top() - attack.height() );
|
||||
add( attack );
|
||||
|
||||
log = new GameLog();
|
||||
log.camera = uiCamera;
|
||||
log.setRect( 0, toolbar.top(), attack.left(), 0 );
|
||||
add( log );
|
||||
|
||||
if (Dungeon.depth < Statistics.deepestFloor) {
|
||||
GLog.i( TXT_WELCOME_BACK, Dungeon.depth );
|
||||
} else {
|
||||
GLog.i( TXT_WELCOME, Dungeon.depth );
|
||||
Sample.INSTANCE.play( Assets.SND_DESCEND );
|
||||
}
|
||||
switch (Dungeon.level.feeling) {
|
||||
case CHASM:
|
||||
GLog.w( TXT_CHASM );
|
||||
break;
|
||||
case WATER:
|
||||
GLog.w( TXT_WATER );
|
||||
break;
|
||||
case GRASS:
|
||||
GLog.w( TXT_GRASS );
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (Dungeon.level instanceof RegularLevel &&
|
||||
((RegularLevel)Dungeon.level).secretDoors > Random.IntRange( 3, 4 )) {
|
||||
GLog.w( TXT_SECRETS );
|
||||
}
|
||||
if (Dungeon.nightMode && !Dungeon.bossLevel()) {
|
||||
GLog.w( TXT_NIGHT_MODE );
|
||||
}
|
||||
|
||||
busy = new BusyIndicator();
|
||||
busy.camera = uiCamera;
|
||||
busy.x = 1;
|
||||
busy.y = sb.bottom() + 1;
|
||||
add( busy );
|
||||
|
||||
switch (InterlevelScene.mode) {
|
||||
case RESURRECT:
|
||||
WandOfBlink.appear( Dungeon.hero, Dungeon.level.entrance );
|
||||
new Flare( 8, 32 ).color( 0xFFFF66, true ).show( hero, 2f ) ;
|
||||
break;
|
||||
case RETURN:
|
||||
WandOfBlink.appear( Dungeon.hero, Dungeon.hero.pos );
|
||||
break;
|
||||
case FALL:
|
||||
Chasm.heroLand();
|
||||
break;
|
||||
case DESCEND:
|
||||
switch (Dungeon.depth) {
|
||||
case 1:
|
||||
WndStory.showChapter( WndStory.ID_SEWERS );
|
||||
break;
|
||||
case 6:
|
||||
WndStory.showChapter( WndStory.ID_PRISON );
|
||||
break;
|
||||
case 11:
|
||||
WndStory.showChapter( WndStory.ID_CAVES );
|
||||
break;
|
||||
case 16:
|
||||
WndStory.showChapter( WndStory.ID_METROPOLIS );
|
||||
break;
|
||||
case 22:
|
||||
WndStory.showChapter( WndStory.ID_HALLS );
|
||||
break;
|
||||
}
|
||||
if (Dungeon.hero.isAlive() && Dungeon.depth != 22) {
|
||||
Badges.validateNoKilling();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
Camera.main.target = hero;
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
scene = null;
|
||||
Badges.saveGlobal();
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void pause() {
|
||||
try {
|
||||
Dungeon.saveAll();
|
||||
Badges.saveGlobal();
|
||||
} catch (IOException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
if (Dungeon.hero == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.update();
|
||||
|
||||
water.offset( 0, -5 * Game.elapsed );
|
||||
|
||||
Actor.process();
|
||||
|
||||
if (Dungeon.hero.ready && !Dungeon.hero.paralysed) {
|
||||
log.newLine();
|
||||
}
|
||||
|
||||
cellSelector.enabled = Dungeon.hero.ready;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
if (!cancel()) {
|
||||
add( new WndGame() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMenuPressed() {
|
||||
if (Dungeon.hero.ready) {
|
||||
selectItem( null, WndBag.Mode.ALL, null );
|
||||
}
|
||||
}
|
||||
|
||||
public void brightness( boolean value ) {
|
||||
water.rm = water.gm = water.bm =
|
||||
tiles.rm = tiles.gm = tiles.bm =
|
||||
value ? 1.5f : 1.0f;
|
||||
if (value) {
|
||||
fog.am = +2f;
|
||||
fog.aa = -1f;
|
||||
} else {
|
||||
fog.am = +1f;
|
||||
fog.aa = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void addHeapSprite( Heap heap ) {
|
||||
ItemSprite sprite = heap.sprite = (ItemSprite)heaps.recycle( ItemSprite.class );
|
||||
sprite.revive();
|
||||
sprite.link( heap );
|
||||
heaps.add( sprite );
|
||||
}
|
||||
|
||||
private void addDiscardedSprite( Heap heap ) {
|
||||
heap.sprite = (DiscardedItemSprite)heaps.recycle( DiscardedItemSprite.class );
|
||||
heap.sprite.revive();
|
||||
heap.sprite.link( heap );
|
||||
heaps.add( heap.sprite );
|
||||
}
|
||||
|
||||
private void addPlantSprite( Plant plant ) {
|
||||
(plant.sprite = (PlantSprite)plants.recycle( PlantSprite.class )).reset( plant );
|
||||
}
|
||||
|
||||
private void addBlobSprite( final Blob gas ) {
|
||||
if (gas.emitter == null) {
|
||||
gases.add( new BlobEmitter( gas ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void addMobSprite( Mob mob ) {
|
||||
CharSprite sprite = mob.sprite();
|
||||
sprite.visible = Dungeon.visible[mob.pos];
|
||||
mobs.add( sprite );
|
||||
sprite.link( mob );
|
||||
}
|
||||
|
||||
private void prompt( String text ) {
|
||||
|
||||
if (prompt != null) {
|
||||
prompt.killAndErase();
|
||||
prompt = null;
|
||||
}
|
||||
|
||||
if (text != null) {
|
||||
prompt = new Toast( text ) {
|
||||
@Override
|
||||
protected void onClose() {
|
||||
cancel();
|
||||
}
|
||||
};
|
||||
prompt.camera = uiCamera;
|
||||
prompt.setPos( (uiCamera.width - prompt.width()) / 2, uiCamera.height - 60 );
|
||||
add( prompt );
|
||||
}
|
||||
}
|
||||
|
||||
private void showBanner( Banner banner ) {
|
||||
banner.camera = uiCamera;
|
||||
banner.x = align( uiCamera, (uiCamera.width - banner.width) / 2 );
|
||||
banner.y = align( uiCamera, (uiCamera.height - banner.height) / 3 );
|
||||
add( banner );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
|
||||
public static void add( Plant plant ) {
|
||||
if (scene != null) {
|
||||
scene.addPlantSprite( plant );
|
||||
}
|
||||
}
|
||||
|
||||
public static void add( Blob gas ) {
|
||||
Actor.add( gas );
|
||||
if (scene != null) {
|
||||
scene.addBlobSprite( gas );
|
||||
}
|
||||
}
|
||||
|
||||
public static void add( Heap heap ) {
|
||||
if (scene != null) {
|
||||
scene.addHeapSprite( heap );
|
||||
}
|
||||
}
|
||||
|
||||
public static void discard( Heap heap ) {
|
||||
if (scene != null) {
|
||||
scene.addDiscardedSprite( heap );
|
||||
}
|
||||
}
|
||||
|
||||
public static void add( Mob mob ) {
|
||||
Dungeon.level.mobs.add( mob );
|
||||
Actor.add( mob );
|
||||
Actor.occupyCell( mob );
|
||||
scene.addMobSprite( mob );
|
||||
}
|
||||
|
||||
public static void add( Mob mob, float delay ) {
|
||||
Dungeon.level.mobs.add( mob );
|
||||
Actor.addDelayed( mob, delay );
|
||||
Actor.occupyCell( mob );
|
||||
scene.addMobSprite( mob );
|
||||
}
|
||||
|
||||
public static void add( EmoIcon icon ) {
|
||||
scene.emoicons.add( icon );
|
||||
}
|
||||
|
||||
public static void effect( Visual effect ) {
|
||||
scene.effects.add( effect );
|
||||
}
|
||||
|
||||
public static Ripple ripple( int pos ) {
|
||||
Ripple ripple = (Ripple)scene.ripples.recycle( Ripple.class );
|
||||
ripple.reset( pos );
|
||||
return ripple;
|
||||
}
|
||||
|
||||
public static SpellSprite spellSprite() {
|
||||
return (SpellSprite)scene.spells.recycle( SpellSprite.class );
|
||||
}
|
||||
|
||||
public static Emitter emitter() {
|
||||
if (scene != null) {
|
||||
Emitter emitter = (Emitter)scene.emitters.recycle( Emitter.class );
|
||||
emitter.revive();
|
||||
return emitter;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FloatingText status() {
|
||||
return scene != null ? (FloatingText)scene.statuses.recycle( FloatingText.class ) : null;
|
||||
}
|
||||
|
||||
public static void pickUp( Item item ) {
|
||||
scene.toolbar.pickup( item );
|
||||
}
|
||||
|
||||
public static void updateMap() {
|
||||
if (scene != null) {
|
||||
scene.tiles.updated.set( 0, 0, Level.WIDTH, Level.HEIGHT );
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateMap( int cell ) {
|
||||
if (scene != null) {
|
||||
scene.tiles.updated.union( cell % Level.WIDTH, cell / Level.WIDTH );
|
||||
}
|
||||
}
|
||||
|
||||
public static void discoverTile( int pos, int oldValue ) {
|
||||
if (scene != null) {
|
||||
scene.tiles.discover( pos, oldValue );
|
||||
}
|
||||
}
|
||||
|
||||
public static void show( Window wnd ) {
|
||||
cancelCellSelector();
|
||||
scene.add( wnd );
|
||||
}
|
||||
|
||||
public static void afterObserve() {
|
||||
if (scene != null) {
|
||||
scene.fog.updateVisibility( Dungeon.visible, Dungeon.level.visited, Dungeon.level.mapped );
|
||||
|
||||
for (Mob mob : Dungeon.level.mobs) {
|
||||
mob.sprite.visible = Dungeon.visible[mob.pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void flash( int color ) {
|
||||
scene.fadeIn( 0xFF000000 | color, true );
|
||||
}
|
||||
|
||||
public static void gameOver() {
|
||||
Banner gameOver = new Banner( BannerSprites.get( BannerSprites.Type.GAME_OVER ) );
|
||||
gameOver.show( 0x000000, 1f );
|
||||
scene.showBanner( gameOver );
|
||||
|
||||
Sample.INSTANCE.play( Assets.SND_DEATH );
|
||||
}
|
||||
|
||||
public static void bossSlain() {
|
||||
if (Dungeon.hero.isAlive()) {
|
||||
Banner bossSlain = new Banner( BannerSprites.get( BannerSprites.Type.BOSS_SLAIN ) );
|
||||
bossSlain.show( 0xFFFFFF, 0.3f, 5f );
|
||||
scene.showBanner( bossSlain );
|
||||
|
||||
Sample.INSTANCE.play( Assets.SND_BOSS );
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleCell( int cell ) {
|
||||
cellSelector.select( cell );
|
||||
}
|
||||
|
||||
public static void selectCell( CellSelector.Listener listener ) {
|
||||
cellSelector.listener = listener;
|
||||
scene.prompt( listener.prompt() );
|
||||
}
|
||||
|
||||
private static boolean cancelCellSelector() {
|
||||
if (cellSelector.listener != null && cellSelector.listener != defaultCellListener) {
|
||||
cellSelector.cancel();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static WndBag selectItem( WndBag.Listener listener, WndBag.Mode mode, String title ) {
|
||||
cancelCellSelector();
|
||||
|
||||
WndBag wnd = mode == Mode.SEED ?
|
||||
WndBag.seedPouch( listener, mode, title ) :
|
||||
WndBag.lastBag( listener, mode, title );
|
||||
scene.add( wnd );
|
||||
|
||||
return wnd;
|
||||
}
|
||||
|
||||
static boolean cancel() {
|
||||
if (Dungeon.hero.curAction != null || Dungeon.hero.restoreHealth) {
|
||||
|
||||
Dungeon.hero.curAction = null;
|
||||
Dungeon.hero.restoreHealth = false;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return cancelCellSelector();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void ready() {
|
||||
selectCell( defaultCellListener );
|
||||
QuickSlot.cancel();
|
||||
}
|
||||
|
||||
private static final CellSelector.Listener defaultCellListener = new CellSelector.Listener() {
|
||||
@Override
|
||||
public void onSelect( Integer cell ) {
|
||||
if (cell != -1) {
|
||||
Dungeon.hero.handle( cell );
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String prompt() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndError;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStory;
|
||||
|
||||
public class InterlevelScene extends PixelScene {
|
||||
|
||||
private static final float TIME_TO_FADE = 0.3f;
|
||||
|
||||
private static final String TXT_DESCENDING = "Descending...";
|
||||
private static final String TXT_ASCENDING = "Ascending...";
|
||||
private static final String TXT_LOADING = "Loading...";
|
||||
private static final String TXT_RESURRECTING= "Resurrecting...";
|
||||
private static final String TXT_RETURNING = "Returning...";
|
||||
private static final String TXT_FALLING = "Falling...";
|
||||
|
||||
private static final String ERR_FILE_NOT_FOUND = "File not found. For some reason.";
|
||||
private static final String ERR_GENERIC = "Something went wrong..." ;
|
||||
|
||||
public static enum Mode {
|
||||
DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL
|
||||
};
|
||||
public static Mode mode;
|
||||
|
||||
public static int returnDepth;
|
||||
public static int returnPos;
|
||||
|
||||
public static boolean noStory = false;
|
||||
|
||||
public static boolean fallIntoPit;
|
||||
|
||||
private enum Phase {
|
||||
FADE_IN, STATIC, FADE_OUT
|
||||
};
|
||||
private Phase phase;
|
||||
private float timeLeft;
|
||||
|
||||
private BitmapText message;
|
||||
|
||||
private Thread thread;
|
||||
private String error = null;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
String text = "";
|
||||
switch (mode) {
|
||||
case DESCEND:
|
||||
text = TXT_DESCENDING;
|
||||
break;
|
||||
case ASCEND:
|
||||
text = TXT_ASCENDING;
|
||||
break;
|
||||
case CONTINUE:
|
||||
text = TXT_LOADING;
|
||||
break;
|
||||
case RESURRECT:
|
||||
text = TXT_RESURRECTING;
|
||||
break;
|
||||
case RETURN:
|
||||
text = TXT_RETURNING;
|
||||
break;
|
||||
case FALL:
|
||||
text = TXT_FALLING;
|
||||
break;
|
||||
}
|
||||
|
||||
message = PixelScene.createText( text, 9 );
|
||||
message.measure();
|
||||
message.x = (Camera.main.width - message.width()) / 2;
|
||||
message.y = (Camera.main.height - message.height()) / 2;
|
||||
add( message );
|
||||
|
||||
phase = Phase.FADE_IN;
|
||||
timeLeft = TIME_TO_FADE;
|
||||
|
||||
thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
Generator.reset();
|
||||
|
||||
Sample.INSTANCE.load(
|
||||
Assets.SND_OPEN,
|
||||
Assets.SND_UNLOCK,
|
||||
Assets.SND_ITEM,
|
||||
Assets.SND_DEWDROP,
|
||||
Assets.SND_HIT,
|
||||
Assets.SND_MISS,
|
||||
Assets.SND_STEP,
|
||||
Assets.SND_WATER,
|
||||
Assets.SND_DESCEND,
|
||||
Assets.SND_EAT,
|
||||
Assets.SND_READ,
|
||||
Assets.SND_LULLABY,
|
||||
Assets.SND_DRINK,
|
||||
Assets.SND_SHATTER,
|
||||
Assets.SND_ZAP,
|
||||
Assets.SND_LIGHTNING,
|
||||
Assets.SND_LEVELUP,
|
||||
Assets.SND_DEATH,
|
||||
Assets.SND_CHALLENGE,
|
||||
Assets.SND_CURSED,
|
||||
Assets.SND_EVOKE,
|
||||
Assets.SND_TRAP,
|
||||
Assets.SND_TOMB,
|
||||
Assets.SND_ALERT,
|
||||
Assets.SND_MELD,
|
||||
Assets.SND_BOSS,
|
||||
Assets.SND_BLAST,
|
||||
Assets.SND_PLANT,
|
||||
Assets.SND_RAY,
|
||||
Assets.SND_BEACON,
|
||||
Assets.SND_TELEPORT,
|
||||
Assets.SND_CHARMS,
|
||||
Assets.SND_MASTERY,
|
||||
Assets.SND_PUFF,
|
||||
Assets.SND_ROCKS,
|
||||
Assets.SND_BURNING,
|
||||
Assets.SND_FALLING,
|
||||
Assets.SND_GHOST,
|
||||
Assets.SND_SECRET,
|
||||
Assets.SND_BONES );
|
||||
|
||||
switch (mode) {
|
||||
case DESCEND:
|
||||
descend();
|
||||
break;
|
||||
case ASCEND:
|
||||
ascend();
|
||||
break;
|
||||
case CONTINUE:
|
||||
restore();
|
||||
break;
|
||||
case RESURRECT:
|
||||
resurrect();
|
||||
break;
|
||||
case RETURN:
|
||||
returnTo();
|
||||
break;
|
||||
case FALL:
|
||||
fall();
|
||||
break;
|
||||
}
|
||||
|
||||
if ((Dungeon.depth % 5) == 0) {
|
||||
Sample.INSTANCE.load( Assets.SND_BOSS );
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
|
||||
error = ERR_FILE_NOT_FOUND;
|
||||
|
||||
} catch (Exception e ) {
|
||||
|
||||
error = ERR_GENERIC;
|
||||
|
||||
}
|
||||
|
||||
if (phase == Phase.STATIC && error == null) {
|
||||
phase = Phase.FADE_OUT;
|
||||
timeLeft = TIME_TO_FADE;
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
float p = timeLeft / TIME_TO_FADE;
|
||||
|
||||
switch (phase) {
|
||||
|
||||
case FADE_IN:
|
||||
message.alpha( 1 - p );
|
||||
if ((timeLeft -= Game.elapsed) <= 0) {
|
||||
if (!thread.isAlive() && error == null) {
|
||||
phase = Phase.FADE_OUT;
|
||||
timeLeft = TIME_TO_FADE;
|
||||
} else {
|
||||
phase = Phase.STATIC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FADE_OUT:
|
||||
message.alpha( p );
|
||||
|
||||
if (mode == Mode.CONTINUE || (mode == Mode.DESCEND && Dungeon.depth == 1)) {
|
||||
Music.INSTANCE.volume( p );
|
||||
}
|
||||
if ((timeLeft -= Game.elapsed) <= 0) {
|
||||
Game.switchScene( GameScene.class );
|
||||
}
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
if (error != null) {
|
||||
add( new WndError( error ) {
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
Game.switchScene( StartScene.class );
|
||||
};
|
||||
} );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void descend() throws Exception {
|
||||
|
||||
Actor.fixTime();
|
||||
if (Dungeon.hero == null) {
|
||||
Dungeon.init();
|
||||
if (noStory) {
|
||||
Dungeon.chapters.add( WndStory.ID_SEWERS );
|
||||
noStory = false;
|
||||
}
|
||||
} else {
|
||||
Dungeon.saveLevel();
|
||||
}
|
||||
|
||||
Level level;
|
||||
if (Dungeon.depth >= Statistics.deepestFloor) {
|
||||
level = Dungeon.newLevel();
|
||||
} else {
|
||||
Dungeon.depth++;
|
||||
level = Dungeon.loadLevel( Dungeon.hero.heroClass );
|
||||
}
|
||||
Dungeon.switchLevel( level, level.entrance );
|
||||
}
|
||||
|
||||
private void fall() throws Exception {
|
||||
|
||||
Actor.fixTime();
|
||||
Dungeon.saveLevel();
|
||||
|
||||
Level level;
|
||||
if (Dungeon.depth >= Statistics.deepestFloor) {
|
||||
level = Dungeon.newLevel();
|
||||
} else {
|
||||
Dungeon.depth++;
|
||||
level = Dungeon.loadLevel( Dungeon.hero.heroClass );
|
||||
}
|
||||
Dungeon.switchLevel( level, fallIntoPit ? level.pitCell() : level.randomRespawnCell() );
|
||||
}
|
||||
|
||||
private void ascend() throws Exception {
|
||||
Actor.fixTime();
|
||||
|
||||
Dungeon.saveLevel();
|
||||
Dungeon.depth--;
|
||||
Level level = Dungeon.loadLevel( Dungeon.hero.heroClass );
|
||||
Dungeon.switchLevel( level, level.exit );
|
||||
}
|
||||
|
||||
private void returnTo() throws Exception {
|
||||
|
||||
Actor.fixTime();
|
||||
|
||||
Dungeon.saveLevel();
|
||||
Dungeon.depth = returnDepth;
|
||||
Level level = Dungeon.loadLevel( Dungeon.hero.heroClass );
|
||||
Dungeon.switchLevel( level, Level.resizingNeeded ? level.adjustPos( returnPos ) : returnPos );
|
||||
}
|
||||
|
||||
private void restore() throws Exception {
|
||||
|
||||
Actor.fixTime();
|
||||
|
||||
Dungeon.loadGame( StartScene.curClass );
|
||||
if (Dungeon.depth == -1) {
|
||||
Dungeon.depth = Statistics.deepestFloor;
|
||||
Dungeon.switchLevel( Dungeon.loadLevel( StartScene.curClass ), -1 );
|
||||
} else {
|
||||
Level level = Dungeon.loadLevel( StartScene.curClass );
|
||||
Dungeon.switchLevel( level, Level.resizingNeeded ? level.adjustPos( Dungeon.hero.pos ) : Dungeon.hero.pos );
|
||||
}
|
||||
}
|
||||
|
||||
private void resurrect() throws Exception {
|
||||
|
||||
Actor.fixTime();
|
||||
|
||||
if (Dungeon.bossLevel()) {
|
||||
Dungeon.hero.resurrect( Dungeon.depth );
|
||||
Dungeon.depth--;
|
||||
Level level = Dungeon.newLevel(/* true */);
|
||||
Dungeon.switchLevel( level, level.entrance );
|
||||
} else {
|
||||
Dungeon.hero.resurrect( -1 );
|
||||
Dungeon.resetLevel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStory;
|
||||
|
||||
public class IntroScene extends PixelScene {
|
||||
|
||||
private static final String TEXT =
|
||||
"Many heroes of all kinds ventured into the Dungeon before you. Some of them have returned with treasures and magical " +
|
||||
"artifacts, most have never been heard of since. But none have succeeded in retrieving the Amulet of Yendor, " +
|
||||
"which is told to be hidden in the depths of the Dungeon.\n\n" +
|
||||
"" +
|
||||
"You consider yourself ready for the challenge, but most importantly, you feel that fortune smiles on you. " +
|
||||
"It's time to start your own adventure!";
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
add( new WndStory( TEXT ) {
|
||||
@Override
|
||||
public void hide() {
|
||||
super.hide();
|
||||
Game.switchScene( InterlevelScene.class );
|
||||
}
|
||||
} );
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.watabou.input.Touchscreen;
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.BitmapText.Font;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.BitmapTextMultiline;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.ColorBlock;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Scene;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BadgeBanner;
|
||||
import com.watabou.utils.BitmapCache;
|
||||
|
||||
public class PixelScene extends Scene {
|
||||
|
||||
public static final float MIN_WIDTH = 128;
|
||||
public static final float MIN_HEIGHT = 224;
|
||||
|
||||
public static float defaultZoom = 0;
|
||||
public static float minZoom;
|
||||
public static float maxZoom;
|
||||
|
||||
public static boolean landscapeAvailable;
|
||||
|
||||
public static Camera uiCamera;
|
||||
|
||||
public static BitmapText.Font font1x;
|
||||
public static BitmapText.Font font15x;
|
||||
public static BitmapText.Font font2x;
|
||||
public static BitmapText.Font font25x;
|
||||
public static BitmapText.Font font3x;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
GameScene.scene = null;
|
||||
|
||||
defaultZoom = (int)Math.ceil( Game.density * 2.5 );
|
||||
while ((
|
||||
Game.width / defaultZoom < MIN_WIDTH ||
|
||||
Game.height / defaultZoom < MIN_HEIGHT
|
||||
) && defaultZoom > 1) {
|
||||
|
||||
defaultZoom--;
|
||||
}
|
||||
|
||||
landscapeAvailable =
|
||||
Game.height / defaultZoom >= MIN_WIDTH &&
|
||||
Game.width / defaultZoom >= MIN_HEIGHT;
|
||||
|
||||
if (ShatteredPixelDungeon.scaleUp()) {
|
||||
while ((Game.width / (defaultZoom + 1) >= MIN_WIDTH && Game.height / (defaultZoom + 1) >= MIN_HEIGHT)) {
|
||||
defaultZoom++;
|
||||
}
|
||||
}
|
||||
minZoom = 1;
|
||||
maxZoom = defaultZoom * 2;
|
||||
|
||||
|
||||
Camera.reset( new PixelCamera( defaultZoom ) );
|
||||
|
||||
float uiZoom = defaultZoom;
|
||||
uiCamera = Camera.createFullscreen( uiZoom );
|
||||
Camera.add( uiCamera );
|
||||
|
||||
if (font1x == null) {
|
||||
|
||||
// 3x5 (6)
|
||||
font1x = Font.colorMarked(
|
||||
BitmapCache.get( Assets.FONTS1X ), 0x00000000, BitmapText.Font.LATIN_FULL );
|
||||
font1x.baseLine = 6;
|
||||
font1x.tracking = -1;
|
||||
|
||||
// 5x8 (10)
|
||||
font15x = Font.colorMarked(
|
||||
BitmapCache.get( Assets.FONTS15X ), 12, 0x00000000, BitmapText.Font.LATIN_FULL );
|
||||
font15x.baseLine = 9;
|
||||
font15x.tracking = -1;
|
||||
|
||||
// 6x10 (12)
|
||||
font2x = Font.colorMarked(
|
||||
BitmapCache.get( Assets.FONTS2X ), 14, 0x00000000, BitmapText.Font.LATIN_FULL );
|
||||
font2x.baseLine = 11;
|
||||
font2x.tracking = -1;
|
||||
|
||||
// 7x12 (15)
|
||||
font25x = Font.colorMarked(
|
||||
BitmapCache.get( Assets.FONTS25X ), 17, 0x00000000, BitmapText.Font.LATIN_FULL );
|
||||
font25x.baseLine = 13;
|
||||
font25x.tracking = -1;
|
||||
|
||||
// 9x15 (18)
|
||||
font3x = Font.colorMarked(
|
||||
BitmapCache.get( Assets.FONTS3X ), 22, 0x00000000, BitmapText.Font.LATIN_FULL );
|
||||
font3x.baseLine = 17;
|
||||
font3x.tracking = -2;
|
||||
}
|
||||
|
||||
Sample.INSTANCE.load(
|
||||
Assets.SND_CLICK,
|
||||
Assets.SND_BADGE,
|
||||
Assets.SND_GOLD );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
Touchscreen.event.removeAll();
|
||||
}
|
||||
|
||||
public static BitmapText.Font font;
|
||||
public static float scale;
|
||||
|
||||
public static void chooseFont( float size ) {
|
||||
|
||||
float pt = size * defaultZoom;
|
||||
|
||||
if (pt >= 19) {
|
||||
|
||||
scale = pt / 19;
|
||||
if (1.5 <= scale && scale < 2) {
|
||||
font = font25x;
|
||||
scale = (int)(pt / 14);
|
||||
} else {
|
||||
font = font3x;
|
||||
scale = (int)scale;
|
||||
}
|
||||
|
||||
} else if (pt >= 14) {
|
||||
|
||||
scale = pt / 14;
|
||||
if (1.8 <= scale && scale < 2) {
|
||||
font = font2x;
|
||||
scale = (int)(pt / 12);
|
||||
} else {
|
||||
font = font25x;
|
||||
scale = (int)scale;
|
||||
}
|
||||
|
||||
} else if (pt >= 12) {
|
||||
|
||||
scale = pt / 12;
|
||||
if (1.7 <= scale && scale < 2) {
|
||||
font = font15x;
|
||||
scale = (int)(pt / 10);
|
||||
} else {
|
||||
font = font2x;
|
||||
scale = (int)scale;
|
||||
}
|
||||
|
||||
} else if (pt >= 10) {
|
||||
|
||||
scale = pt / 10;
|
||||
if (1.4 <= scale && scale < 2) {
|
||||
font = font1x;
|
||||
scale = (int)(pt / 7);
|
||||
} else {
|
||||
font = font15x;
|
||||
scale = (int)scale;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
font = font1x;
|
||||
scale = Math.max( 1, (int)(pt / 7) );
|
||||
|
||||
}
|
||||
|
||||
scale /= defaultZoom;
|
||||
}
|
||||
|
||||
public static BitmapText createText( float size ) {
|
||||
return createText( null, size );
|
||||
}
|
||||
|
||||
public static BitmapText createText( String text, float size ) {
|
||||
|
||||
chooseFont( size );
|
||||
|
||||
BitmapText result = new BitmapText( text, font );
|
||||
result.scale.set( scale );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BitmapTextMultiline createMultiline( float size ) {
|
||||
return createMultiline( null, size );
|
||||
}
|
||||
|
||||
public static BitmapTextMultiline createMultiline( String text, float size ) {
|
||||
|
||||
chooseFont( size );
|
||||
|
||||
BitmapTextMultiline result = new BitmapTextMultiline( text, font );
|
||||
result.scale.set( scale );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float align( Camera camera, float pos ) {
|
||||
return ((int)(pos * camera.zoom)) / camera.zoom;
|
||||
}
|
||||
|
||||
public static float align( float pos ) {
|
||||
return ((int)(pos * defaultZoom)) / defaultZoom;
|
||||
}
|
||||
|
||||
public static void align( Visual v ) {
|
||||
Camera c = v.camera();
|
||||
v.x = align( c, v.x );
|
||||
v.y = align( c, v.y );
|
||||
}
|
||||
|
||||
protected void fadeIn() {
|
||||
fadeIn( 0xFF000000, false );
|
||||
}
|
||||
|
||||
protected void fadeIn( int color, boolean light ) {
|
||||
add( new Fader( color, light ) );
|
||||
}
|
||||
|
||||
public static void showBadge( Badges.Badge badge ) {
|
||||
BadgeBanner banner = BadgeBanner.show( badge.image );
|
||||
banner.camera = uiCamera;
|
||||
banner.x = align( banner.camera, (banner.camera.width - banner.width) / 2 );
|
||||
banner.y = align( banner.camera, (banner.camera.height - banner.height) / 3 );
|
||||
Game.scene().add( banner );
|
||||
}
|
||||
|
||||
protected static class Fader extends ColorBlock {
|
||||
|
||||
private static float FADE_TIME = 1f;
|
||||
|
||||
private boolean light;
|
||||
|
||||
private float time;
|
||||
|
||||
public Fader( int color, boolean light ) {
|
||||
super( uiCamera.width, uiCamera.height, color );
|
||||
|
||||
this.light = light;
|
||||
|
||||
camera = uiCamera;
|
||||
|
||||
alpha( 1f );
|
||||
time = FADE_TIME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
super.update();
|
||||
|
||||
if ((time -= Game.elapsed) <= 0) {
|
||||
alpha( 0f );
|
||||
parent.remove( this );
|
||||
} else {
|
||||
alpha( time / FADE_TIME );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (light) {
|
||||
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE );
|
||||
super.draw();
|
||||
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
|
||||
} else {
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class PixelCamera extends Camera {
|
||||
|
||||
public PixelCamera( float zoom ) {
|
||||
super(
|
||||
(int)(Game.width - Math.ceil( Game.width / zoom ) * zoom) / 2,
|
||||
(int)(Game.height - Math.ceil( Game.height / zoom ) * zoom) / 2,
|
||||
(int)Math.ceil( Game.width / zoom ),
|
||||
(int)Math.ceil( Game.height / zoom ), zoom );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMatrix() {
|
||||
float sx = align( this, scroll.x + shakeX );
|
||||
float sy = align( this, scroll.y + shakeY );
|
||||
|
||||
matrix[0] = +zoom * invW2;
|
||||
matrix[5] = -zoom * invH2;
|
||||
|
||||
matrix[12] = -1 + x * invW2 - sx * matrix[0];
|
||||
matrix[13] = +1 - y * invH2 - sy * matrix[5];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.BitmapTextMultiline;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.ui.Button;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Rankings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndError;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndRanking;
|
||||
|
||||
public class RankingsScene extends PixelScene {
|
||||
|
||||
private static final String TXT_TITLE = "Top Rankings";
|
||||
private static final String TXT_TOTAL = "Total games played: %d";
|
||||
private static final String TXT_NO_GAMES = "No games have been played yet.";
|
||||
|
||||
private static final String TXT_NO_INFO = "No additional information";
|
||||
|
||||
private static final float ROW_HEIGHT = 30;
|
||||
private static final float GAP = 4;
|
||||
|
||||
private Archs archs;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Music.INSTANCE.play( Assets.THEME, true );
|
||||
Music.INSTANCE.volume( 1f );
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
Rankings.INSTANCE.load();
|
||||
|
||||
if (Rankings.INSTANCE.records.size() > 0) {
|
||||
|
||||
float left = (w - Math.min( 160, w )) / 2 + GAP;
|
||||
float top = align( (h - ROW_HEIGHT * Rankings.INSTANCE.records.size()) / 2 );
|
||||
|
||||
BitmapText title = PixelScene.createText( TXT_TITLE, 9 );
|
||||
title.hardlight( Window.TITLE_COLOR );
|
||||
title.measure();
|
||||
title.x = align( (w - title.width()) / 2 );
|
||||
title.y = align( top - title.height() - GAP );
|
||||
add( title );
|
||||
|
||||
int pos = 0;
|
||||
|
||||
for (Rankings.Record rec : Rankings.INSTANCE.records) {
|
||||
Record row = new Record( pos, pos == Rankings.INSTANCE.lastRecord, rec );
|
||||
row.setRect( left, top + pos * ROW_HEIGHT, w - left * 2, ROW_HEIGHT );
|
||||
add( row );
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (Rankings.INSTANCE.totalNumber >= Rankings.TABLE_SIZE) {
|
||||
BitmapText total = PixelScene.createText( Utils.format( TXT_TOTAL, Rankings.INSTANCE.totalNumber ), 8 );
|
||||
total.hardlight( Window.TITLE_COLOR );
|
||||
total.measure();
|
||||
total.x = align( (w - total.width()) / 2 );
|
||||
total.y = align( top + pos * ROW_HEIGHT + GAP );
|
||||
add( total );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
BitmapText title = PixelScene.createText( TXT_NO_GAMES, 8 );
|
||||
title.hardlight( Window.TITLE_COLOR );
|
||||
title.measure();
|
||||
title.x = align( (w - title.width()) / 2 );
|
||||
title.y = align( (h - title.height()) / 2 );
|
||||
add( title );
|
||||
|
||||
}
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
Game.switchScene( TitleScene.class );
|
||||
}
|
||||
|
||||
public static class Record extends Button {
|
||||
|
||||
private static final float GAP = 4;
|
||||
|
||||
private static final int TEXT_WIN = 0xFFFF88;
|
||||
private static final int TEXT_LOSE = 0xCCCCCC;
|
||||
private static final int FLARE_WIN = 0x888866;
|
||||
private static final int FLARE_LOSE = 0x666666;
|
||||
|
||||
private Rankings.Record rec;
|
||||
|
||||
private ItemSprite shield;
|
||||
private Flare flare;
|
||||
private BitmapText position;
|
||||
private BitmapTextMultiline desc;
|
||||
private Image classIcon;
|
||||
|
||||
public Record( int pos, boolean latest, Rankings.Record rec ) {
|
||||
super();
|
||||
|
||||
this.rec = rec;
|
||||
|
||||
if (latest) {
|
||||
flare = new Flare( 6, 24 );
|
||||
flare.angularSpeed = 90;
|
||||
flare.color( rec.win ? FLARE_WIN : FLARE_LOSE );
|
||||
addToBack( flare );
|
||||
}
|
||||
|
||||
position.text( Integer.toString( pos+1 ) );
|
||||
position.measure();
|
||||
|
||||
desc.text( rec.info );
|
||||
desc.measure();
|
||||
|
||||
if (rec.win) {
|
||||
shield.view( ItemSpriteSheet.AMULET, null );
|
||||
position.hardlight( TEXT_WIN );
|
||||
desc.hardlight( TEXT_WIN );
|
||||
} else {
|
||||
position.hardlight( TEXT_LOSE );
|
||||
desc.hardlight( TEXT_LOSE );
|
||||
}
|
||||
|
||||
classIcon.copy( Icons.get( rec.heroClass ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
|
||||
super.createChildren();
|
||||
|
||||
shield = new ItemSprite( ItemSpriteSheet.TOMB, null );
|
||||
add( shield );
|
||||
|
||||
position = new BitmapText( PixelScene.font1x );
|
||||
add( position );
|
||||
|
||||
desc = createMultiline( 9 );
|
||||
add( desc );
|
||||
|
||||
classIcon = new Image();
|
||||
add( classIcon );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
|
||||
super.layout();
|
||||
|
||||
shield.x = x;
|
||||
shield.y = y + (height - shield.height) / 2;
|
||||
|
||||
position.x = align( shield.x + (shield.width - position.width()) / 2 );
|
||||
position.y = align( shield.y + (shield.height - position.height()) / 2 + 1 );
|
||||
|
||||
if (flare != null) {
|
||||
flare.point( shield.center() );
|
||||
}
|
||||
|
||||
classIcon.x = align( x + width - classIcon.width );
|
||||
classIcon.y = shield.y;
|
||||
|
||||
desc.x = shield.x + shield.width + GAP;
|
||||
desc.maxWidth = (int)(classIcon.x - desc.x);
|
||||
desc.measure();
|
||||
desc.y = position.y + position.baseLine() - desc.baseLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if (rec.gameFile.length() > 0) {
|
||||
parent.add( new WndRanking( rec.gameFile ) );
|
||||
} else {
|
||||
parent.add( new WndError( TXT_NO_INFO ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.*;
|
||||
import com.watabou.input.Touchscreen;
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.BitmapTextMultiline;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.TouchArea;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.noosa.ui.Button;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.SimpleButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndList;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTitledMessage;
|
||||
|
||||
public class StartScene extends PixelScene {
|
||||
|
||||
private static final float BUTTON_HEIGHT = 24;
|
||||
private static final float GAP = 2;
|
||||
|
||||
private static final String TXT_TITLE = "Select Your Hero";
|
||||
|
||||
private static final String TXT_LOAD = "Load Game";
|
||||
private static final String TXT_NEW = "New Game";
|
||||
|
||||
private static final String TXT_ERASE = "Erase current game";
|
||||
private static final String TXT_DPTH_LVL = "Depth: %d, level: %d";
|
||||
|
||||
private static final String TXT_REALLY = "Do you really want to start new game?";
|
||||
private static final String TXT_WARNING = "Your current game progress will be erased.";
|
||||
private static final String TXT_YES = "Yes, start new game";
|
||||
private static final String TXT_NO = "No, return to main menu";
|
||||
|
||||
private static final String TXT_UNLOCK = "To unlock this character class, slay the 3rd boss with any other class";
|
||||
|
||||
private float width;
|
||||
private float height;
|
||||
private float top;
|
||||
private float left;
|
||||
|
||||
private static HashMap<HeroClass, GemButton> gems = new HashMap<HeroClass, StartScene.GemButton>();
|
||||
|
||||
private Avatar avatar;
|
||||
private NinePatch frame;
|
||||
private BitmapText className;
|
||||
|
||||
private SimpleButton btnMastery;
|
||||
|
||||
private GameButton btnLoad;
|
||||
private GameButton btnNewGame;
|
||||
|
||||
private boolean huntressUnlocked;
|
||||
private Group unlock;
|
||||
|
||||
public static HeroClass curClass;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Badges.loadGlobal();
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
width = 128;
|
||||
height = 220;
|
||||
left = (w - width) / 2;
|
||||
top = (h - height) / 2;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
BitmapText title = PixelScene.createText( TXT_TITLE, 9 );
|
||||
title.hardlight( Window.TITLE_COLOR );
|
||||
title.measure();
|
||||
title.x = align( (w - title.width()) / 2 );
|
||||
title.y = align( top );
|
||||
add( title );
|
||||
|
||||
float pos = title.y + title.height() + GAP;
|
||||
|
||||
GemButton btns[] = {
|
||||
new GemButton( HeroClass.WARRIOR ),
|
||||
new GemButton( HeroClass.MAGE ),
|
||||
new GemButton( HeroClass.ROGUE ),
|
||||
new GemButton( HeroClass.HUNTRESS ) };
|
||||
|
||||
float space = width;
|
||||
for (GemButton btn : btns) {
|
||||
space -= btn.width();
|
||||
}
|
||||
|
||||
float p = 0;
|
||||
for (GemButton btn : btns) {
|
||||
add( btn );
|
||||
btn.setPos( align( left + p ), align( pos ) );
|
||||
p += btn.width() + space / 3;
|
||||
}
|
||||
|
||||
|
||||
frame = Chrome.get( Chrome.Type.TOAST_TR );
|
||||
add( frame );
|
||||
|
||||
btnNewGame = new GameButton( TXT_NEW ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if (GamesInProgress.check( curClass ) != null) {
|
||||
StartScene.this.add( new WndOptions( TXT_REALLY, TXT_WARNING, TXT_YES, TXT_NO ) {
|
||||
@Override
|
||||
protected void onSelect( int index ) {
|
||||
if (index == 0) {
|
||||
startNewGame();
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
} else {
|
||||
startNewGame();
|
||||
}
|
||||
}
|
||||
};
|
||||
add( btnNewGame );
|
||||
|
||||
btnLoad = new GameButton( TXT_LOAD ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
InterlevelScene.mode = InterlevelScene.Mode.CONTINUE;
|
||||
Game.switchScene( InterlevelScene.class );
|
||||
}
|
||||
};
|
||||
add( btnLoad );
|
||||
|
||||
frame.size( width, BUTTON_HEIGHT + frame.marginVer() );
|
||||
frame.x = align( left );
|
||||
frame.y = align( h - top - frame.height() );
|
||||
|
||||
avatar = new Avatar();
|
||||
|
||||
NinePatch avFrame = Chrome.get( Chrome.Type.TOAST_TR );
|
||||
avFrame.size( avatar.width() * 1.6f, avatar.height() * 1.6f );
|
||||
avFrame.x = align( (w - avFrame.width()) / 2 );
|
||||
avFrame.y = align( (frame.y + btns[0].bottom() - avFrame.height()) / 2 );
|
||||
add( avFrame );
|
||||
|
||||
className = PixelScene.createText( "Placeholder", 9 );
|
||||
className.measure();
|
||||
className.y = align( avFrame.y + avFrame.innerBottom() - className.height() );
|
||||
add( className );
|
||||
|
||||
avatar.point( avFrame.center() );
|
||||
avatar.camera = Camera.main;
|
||||
align( avatar );
|
||||
add( avatar );
|
||||
|
||||
Image iconInfo = Icons.INFO.get();
|
||||
iconInfo.x = avFrame.x + avFrame.innerRight() - iconInfo.width();
|
||||
iconInfo.y = avFrame.y + avFrame.marginTop();
|
||||
add( iconInfo );
|
||||
|
||||
add( new TouchArea( avFrame ) {
|
||||
@Override
|
||||
protected void onClick( Touchscreen.Touch touch ) {
|
||||
add( new WndList( curClass.perks() ) );
|
||||
}
|
||||
} );
|
||||
|
||||
btnMastery = new SimpleButton( Icons.MASTERY.get() ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
String text = null;
|
||||
switch (curClass) {
|
||||
case WARRIOR:
|
||||
text = HeroSubClass.GLADIATOR.desc() + "\n\n" + HeroSubClass.BERSERKER.desc();
|
||||
break;
|
||||
case MAGE:
|
||||
text = HeroSubClass.BATTLEMAGE.desc() + "\n\n" + HeroSubClass.WARLOCK.desc();
|
||||
break;
|
||||
case ROGUE:
|
||||
text = HeroSubClass.FREERUNNER.desc() + "\n\n" + HeroSubClass.ASSASSIN.desc();
|
||||
break;
|
||||
case HUNTRESS:
|
||||
text = HeroSubClass.SNIPER.desc() + "\n\n" + HeroSubClass.WARDEN.desc();
|
||||
break;
|
||||
}
|
||||
StartScene.this.add( new WndTitledMessage( Icons.MASTERY.get(), "Mastery", text ) );
|
||||
}
|
||||
};
|
||||
btnMastery.setPos(
|
||||
avFrame.x + avFrame.innerRight() - btnMastery.width(),
|
||||
avFrame.y + avFrame.innerBottom() - btnMastery.height() );
|
||||
add( btnMastery );
|
||||
|
||||
unlock = new Group();
|
||||
add( unlock );
|
||||
|
||||
if (!(huntressUnlocked = Badges.isUnlocked( Badges.Badge.BOSS_SLAIN_3 ))) {
|
||||
|
||||
BitmapTextMultiline text = PixelScene.createMultiline( TXT_UNLOCK, 5 );
|
||||
text.maxWidth = (int)frame.innerWidth();
|
||||
text.measure();
|
||||
|
||||
pos = frame.center().y - text.height() / 2;
|
||||
for (BitmapText line : text.new LineSplitter().split()) {
|
||||
line.measure();
|
||||
line.hardlight( 0xFFFF00 );
|
||||
line.x = PixelScene.align( frame.center().x - line.width() / 2 );
|
||||
line.y = PixelScene.align( pos );
|
||||
unlock.add( line );
|
||||
|
||||
pos += line.height();
|
||||
}
|
||||
}
|
||||
|
||||
curClass = null;
|
||||
updateClass( HeroClass.values()[ShatteredPixelDungeon.lastClass()] );
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
private void updateClass( HeroClass cl ) {
|
||||
|
||||
if (curClass == cl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (curClass != null) {
|
||||
gems.get( curClass ).highlight( false );
|
||||
}
|
||||
|
||||
gems.get( curClass = cl ).highlight( true );
|
||||
|
||||
className.text( Utils.capitalize( cl.title() ) );
|
||||
className.measure();
|
||||
className.x = align( frame.center().x - className.width() / 2 );
|
||||
|
||||
if (cl != HeroClass.HUNTRESS || huntressUnlocked) {
|
||||
|
||||
unlock.visible = false;
|
||||
|
||||
float buttonPos = frame.y + frame.innerBottom() - BUTTON_HEIGHT;
|
||||
|
||||
GamesInProgress.Info info = GamesInProgress.check( curClass );
|
||||
if (info != null) {
|
||||
|
||||
btnLoad.visible = true;
|
||||
btnLoad.secondary( Utils.format( TXT_DPTH_LVL, info.depth, info.level ) );
|
||||
btnNewGame.visible = true;
|
||||
btnNewGame.secondary( TXT_ERASE );
|
||||
|
||||
float w = (frame.innerWidth() - GAP) / 2;
|
||||
|
||||
btnLoad.setRect(
|
||||
frame.x + frame.marginLeft(), buttonPos, w, BUTTON_HEIGHT );
|
||||
btnNewGame.setRect(
|
||||
btnLoad.right() + GAP, buttonPos, w, BUTTON_HEIGHT );
|
||||
|
||||
} else {
|
||||
btnLoad.visible = false;
|
||||
|
||||
btnNewGame.visible = true;
|
||||
btnNewGame.secondary( null );
|
||||
btnNewGame.setRect(
|
||||
frame.x + frame.marginLeft(), buttonPos, frame.innerWidth(), BUTTON_HEIGHT );
|
||||
}
|
||||
|
||||
Badges.Badge badgeToCheck = null;
|
||||
switch (curClass) {
|
||||
case WARRIOR:
|
||||
badgeToCheck = Badges.Badge.MASTERY_WARRIOR;
|
||||
break;
|
||||
case MAGE:
|
||||
badgeToCheck = Badges.Badge.MASTERY_MAGE;
|
||||
break;
|
||||
case ROGUE:
|
||||
badgeToCheck = Badges.Badge.MASTERY_ROGUE;
|
||||
break;
|
||||
case HUNTRESS:
|
||||
badgeToCheck = Badges.Badge.MASTERY_HUNTRESS;
|
||||
break;
|
||||
}
|
||||
btnMastery.active =
|
||||
btnMastery.visible =
|
||||
Badges.isUnlocked( badgeToCheck );
|
||||
|
||||
} else {
|
||||
|
||||
unlock.visible = true;
|
||||
btnLoad.visible = false;
|
||||
btnNewGame.visible = false;
|
||||
btnMastery.active = btnMastery.visible = false;
|
||||
|
||||
}
|
||||
|
||||
avatar.selectClass( curClass );
|
||||
}
|
||||
|
||||
private void startNewGame() {
|
||||
|
||||
Dungeon.hero = null;
|
||||
InterlevelScene.mode = InterlevelScene.Mode.DESCEND;
|
||||
|
||||
if (ShatteredPixelDungeon.intro()) {
|
||||
ShatteredPixelDungeon.intro(false);
|
||||
Game.switchScene( IntroScene.class );
|
||||
} else {
|
||||
Game.switchScene( InterlevelScene.class );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
Game.switchScene( TitleScene.class );
|
||||
}
|
||||
|
||||
private static class Avatar extends Image {
|
||||
|
||||
private static final int WIDTH = 24;
|
||||
private static final int HEIGHT = 32;
|
||||
private static final int SCALE = 2;
|
||||
|
||||
private TextureFilm frames;
|
||||
|
||||
private float brightness = 0;
|
||||
|
||||
public Avatar() {
|
||||
super( Assets.AVATARS );
|
||||
|
||||
frames = new TextureFilm( texture, WIDTH, HEIGHT );
|
||||
selectClass( HeroClass.WARRIOR );
|
||||
scale.set( SCALE );
|
||||
|
||||
origin.set( width() / 2, height() / 2 );
|
||||
}
|
||||
|
||||
public void selectClass( HeroClass cl ) {
|
||||
frame( frames.get( cl.ordinal() ) );
|
||||
}
|
||||
|
||||
public void flash() {
|
||||
brightness = 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
if (brightness > 0) {
|
||||
ra = ga = ba = brightness;
|
||||
brightness -= Game.elapsed * 4;
|
||||
if (brightness < 0) {
|
||||
resetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class GemButton extends Button {
|
||||
|
||||
private NinePatch bg;
|
||||
private Image icon;
|
||||
|
||||
private HeroClass cl;
|
||||
|
||||
public GemButton( HeroClass cl ) {
|
||||
super();
|
||||
|
||||
this.cl = cl;
|
||||
gems.put( cl, this );
|
||||
|
||||
icon.copy( Icons.get( cl ) );
|
||||
setSize( 32, 32 );
|
||||
|
||||
highlight( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
super.createChildren();
|
||||
|
||||
bg = Chrome.get( Chrome.Type.GEM );
|
||||
add( bg );
|
||||
|
||||
icon = new Image();
|
||||
add( icon );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
super.layout();
|
||||
|
||||
bg.x = x;
|
||||
bg.y = y;
|
||||
bg.size( width, height );
|
||||
|
||||
icon.x = x + (width - icon.width) / 2;
|
||||
icon.y = y + (height - icon.height) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTouchDown() {
|
||||
Emitter emitter = (Emitter)recycle( Emitter.class );
|
||||
emitter.revive();
|
||||
emitter.pos( bg );
|
||||
emitter.burst( Speck.factory( Speck.LIGHT ), 3 );
|
||||
|
||||
updateClass( cl );
|
||||
avatar.flash();
|
||||
|
||||
Sample.INSTANCE.play( Assets.SND_CLICK, 1, 1, 1.2f );
|
||||
}
|
||||
|
||||
public void highlight( boolean value ) {
|
||||
if (value) {
|
||||
bg.rm = 1.2f;
|
||||
bg.gm = 1.2f;
|
||||
bg.bm = 1.1f;
|
||||
bg.am = 0.8f;
|
||||
} else {
|
||||
bg.rm = 1.0f;
|
||||
bg.gm = 1.0f;
|
||||
bg.bm = 1.0f;
|
||||
bg.am = 0.6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class GameButton extends RedButton {
|
||||
|
||||
private static final int SECONDARY_COLOR = 0xCACFC2;
|
||||
|
||||
private BitmapText secondary;
|
||||
|
||||
public GameButton( String primary ) {
|
||||
super( primary );
|
||||
|
||||
this.secondary.text( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
super.createChildren();
|
||||
|
||||
secondary = createText( 6 );
|
||||
secondary.hardlight( SECONDARY_COLOR );
|
||||
add( secondary );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
super.layout();
|
||||
|
||||
if (secondary.text().length() > 0) {
|
||||
text.y = y + (height - text.height() - secondary.baseLine()) / 2;
|
||||
|
||||
secondary.x = align( x + (width - secondary.width()) / 2 );
|
||||
secondary.y = align( text.y + text.height() );
|
||||
} else {
|
||||
text.y = y + (height - text.baseLine()) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
public void secondary( String text ) {
|
||||
secondary.text( text );
|
||||
secondary.measure();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import com.watabou.gltextures.Gradient;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.glwrap.Quad;
|
||||
import com.watabou.input.Touchscreen.Touch;
|
||||
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.TextureFilm;
|
||||
import com.watabou.noosa.TouchArea;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.RatSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class SurfaceScene extends PixelScene {
|
||||
|
||||
private static final int WIDTH = 80;
|
||||
private static final int HEIGHT = 112;
|
||||
|
||||
private static final int NSTARS = 100;
|
||||
private static final int NCLOUDS = 5;
|
||||
|
||||
private Camera viewport;
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Music.INSTANCE.play( Assets.HAPPY, true );
|
||||
Music.INSTANCE.volume( 1f );
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.reversed = true;
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
float vx = align( (w - WIDTH) / 2 );
|
||||
float vy = align( (h - HEIGHT) / 2 );
|
||||
|
||||
Point s = Camera.main.cameraToScreen( vx, vy );
|
||||
viewport = new Camera( s.x, s.y, WIDTH, HEIGHT, defaultZoom );
|
||||
Camera.add( viewport );
|
||||
|
||||
Group window = new Group();
|
||||
window.camera = viewport;
|
||||
add( window );
|
||||
|
||||
boolean dayTime = !Dungeon.nightMode;
|
||||
|
||||
Sky sky = new Sky( dayTime );
|
||||
sky.scale.set( WIDTH, 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( WIDTH ) - size / 2;
|
||||
star.y = Random.Float( HEIGHT ) - size / 2;
|
||||
star.am = size * (1 - star.y / HEIGHT);
|
||||
window.add( star );
|
||||
}
|
||||
}
|
||||
|
||||
float range = 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, HEIGHT + 1, dayTime );
|
||||
patch.brightness( dayTime ? 0.7f : 0.4f );
|
||||
window.add( patch );
|
||||
}
|
||||
|
||||
Avatar a = new Avatar( Dungeon.hero.heroClass );
|
||||
// Removing semitransparent contour
|
||||
a.am = 2; a.aa = -1;
|
||||
a.x = PixelScene.align( (WIDTH - a.width) / 2 );
|
||||
a.y = HEIGHT - a.height + 1;
|
||||
window.add( a );
|
||||
|
||||
final Pet pet = new Pet();
|
||||
pet.rm = pet.gm = pet.bm = 1.2f;
|
||||
pet.x = WIDTH / 2 + 2;
|
||||
pet.y = HEIGHT - pet.height;
|
||||
window.add( pet );
|
||||
|
||||
if (dayTime) {
|
||||
a.brightness( 1.2f );
|
||||
pet.brightness( 1.2f );
|
||||
}
|
||||
|
||||
window.add( new TouchArea( sky ) {
|
||||
protected void onClick( Touch touch ) {
|
||||
pet.jump();
|
||||
};
|
||||
} );
|
||||
|
||||
for (int i=0; i < nPatches; i++) {
|
||||
GrassPatch patch = new GrassPatch( (i - 0.5f) * GrassPatch.WIDTH, HEIGHT, dayTime );
|
||||
patch.brightness( dayTime ? 1.0f : 0.8f );
|
||||
window.add( patch );
|
||||
}
|
||||
|
||||
Image frame = new Image( Assets.SURFACE );
|
||||
if (!dayTime) {
|
||||
frame.hardlight( 0xDDEEFF );
|
||||
}
|
||||
frame.frame( 0, 0, 88, 125 );
|
||||
frame.x = vx - 4;
|
||||
frame.y = vy - 9;
|
||||
add( frame );
|
||||
|
||||
RedButton gameOver = new RedButton( "Game Over" ) {
|
||||
protected void onClick() {
|
||||
Game.switchScene( TitleScene.class );
|
||||
}
|
||||
};
|
||||
gameOver.setSize( WIDTH - 10, 20 );
|
||||
gameOver.setPos( 5 + frame.x + 4, frame.y + frame.height + 4 );
|
||||
add( gameOver );
|
||||
|
||||
Badges.validateHappyEnd();
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Badges.saveGlobal();
|
||||
|
||||
Camera.remove( viewport );
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackPressed() {
|
||||
}
|
||||
|
||||
private static class Sky extends Visual {
|
||||
|
||||
private static final int[] day = {0xFF4488FF, 0xFFCCEEFF};
|
||||
private static final int[] night = {0xFF001155, 0xFF335980};
|
||||
|
||||
private SmartTexture texture;
|
||||
private FloatBuffer verticesBuffer;
|
||||
|
||||
public Sky( boolean dayTime ) {
|
||||
super( 0, 0, 1, 1 );
|
||||
|
||||
texture = new Gradient( dayTime ? day : night );
|
||||
|
||||
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;
|
||||
|
||||
verticesBuffer.position( 0 );
|
||||
verticesBuffer.put( vertices );
|
||||
}
|
||||
|
||||
@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.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;
|
||||
}
|
||||
|
||||
lastIndex = index;
|
||||
|
||||
this.y = y;
|
||||
|
||||
scale.set( 1 - y / HEIGHT );
|
||||
x = Random.Float( 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (speed.x > 0 && x > WIDTH) {
|
||||
x = -width();
|
||||
} else if (speed.x < 0 && x < -width()) {
|
||||
x = 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.AVATARS );
|
||||
frame( new TextureFilm( texture, WIDTH, HEIGHT ).get( cl.ordinal() ) );
|
||||
}
|
||||
}
|
||||
|
||||
private static class Pet extends RatSprite {
|
||||
|
||||
public void jump() {
|
||||
play( run );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete( Animation anim ) {
|
||||
if (anim == run) {
|
||||
idle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.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) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.ui.Button;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Fireball;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.PrefsButton;
|
||||
|
||||
public class TitleScene extends PixelScene {
|
||||
|
||||
private static final String TXT_PLAY = "Play";
|
||||
private static final String TXT_HIGHSCORES = "Rankings";
|
||||
private static final String TXT_BADGES = "Badges";
|
||||
private static final String TXT_ABOUT = "About";
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
super.create();
|
||||
|
||||
Music.INSTANCE.play( Assets.THEME, true );
|
||||
Music.INSTANCE.volume( 1f );
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
float height = 180;
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
Image title = BannerSprites.get( BannerSprites.Type.PIXEL_DUNGEON );
|
||||
add( title );
|
||||
|
||||
title.x = (w - title.width()) / 2;
|
||||
title.y = (h - height) / 2;
|
||||
|
||||
placeTorch( title.x + 18, title.y + 20 );
|
||||
placeTorch( title.x + title.width - 18, title.y + 20 );
|
||||
|
||||
DashboardItem btnBadges = new DashboardItem( TXT_BADGES, 3 ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Game.switchScene( BadgesScene.class );
|
||||
}
|
||||
};
|
||||
btnBadges.setPos( w / 2 - btnBadges.width(), (h + height) / 2 - DashboardItem.SIZE );
|
||||
add( btnBadges );
|
||||
|
||||
DashboardItem btnAbout = new DashboardItem( TXT_ABOUT, 1 ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Game.switchScene( AboutScene.class );
|
||||
}
|
||||
};
|
||||
btnAbout.setPos( w / 2, (h + height) / 2 - DashboardItem.SIZE );
|
||||
add( btnAbout );
|
||||
|
||||
DashboardItem btnPlay = new DashboardItem( TXT_PLAY, 0 ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Game.switchScene( StartScene.class );
|
||||
}
|
||||
};
|
||||
btnPlay.setPos( w / 2 - btnPlay.width(), btnAbout.top() - DashboardItem.SIZE );
|
||||
add( btnPlay );
|
||||
|
||||
DashboardItem btnHighscores = new DashboardItem( TXT_HIGHSCORES, 2 ) {
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Game.switchScene( RankingsScene.class );
|
||||
}
|
||||
};
|
||||
btnHighscores.setPos( w / 2, btnPlay.top() );
|
||||
add( btnHighscores );
|
||||
|
||||
BitmapText version = new BitmapText( "v " + Game.version, font1x );
|
||||
version.measure();
|
||||
version.hardlight( 0x888888 );
|
||||
version.x = w - version.width();
|
||||
version.y = h - version.height();
|
||||
add( version );
|
||||
|
||||
PrefsButton btnPrefs = new PrefsButton();
|
||||
btnPrefs.setPos( w - btnPrefs.width() - 1, 1 );
|
||||
add( btnPrefs );
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
private void placeTorch( float x, float y ) {
|
||||
Fireball fb = new Fireball();
|
||||
fb.setPos( x, y );
|
||||
add( fb );
|
||||
}
|
||||
|
||||
private static class DashboardItem extends Button {
|
||||
|
||||
public static final float SIZE = 48;
|
||||
|
||||
private static final int IMAGE_SIZE = 32;
|
||||
|
||||
private Image image;
|
||||
private BitmapText label;
|
||||
|
||||
public DashboardItem( String text, int index ) {
|
||||
super();
|
||||
|
||||
image.frame( image.texture.uvRect( index * IMAGE_SIZE, 0, (index + 1) * IMAGE_SIZE, IMAGE_SIZE ) );
|
||||
this.label.text( text );
|
||||
this.label.measure();
|
||||
|
||||
setSize( SIZE, SIZE );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
super.createChildren();
|
||||
|
||||
image = new Image( Assets.DASHBOARD );
|
||||
add( image );
|
||||
|
||||
label = createText( 9 );
|
||||
add( label );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
super.layout();
|
||||
|
||||
image.x = align( x + (width - image.width()) / 2 );
|
||||
image.y = align( y );
|
||||
|
||||
label.x = align( x + (width - label.width()) / 2 );
|
||||
label.y = align( image.y + image.height() +2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTouchDown() {
|
||||
image.brightness( 1.5f );
|
||||
Sample.INSTANCE.play( Assets.SND_CLICK, 1, 1, 0.8f );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTouchUp() {
|
||||
image.resetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user