diff --git a/SPD-classes/src/main/java/com/watabou/noosa/Camera.java b/SPD-classes/src/main/java/com/watabou/noosa/Camera.java index 0b1c0678a..c1cac38d2 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/Camera.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/Camera.java @@ -165,22 +165,47 @@ public class Camera extends Gizmo { //camera moves at a speed such that it will pan to its current target in 1/intensity seconds //keep in mind though that this speed is constantly decreasing, so actual pan time is higher float panIntensity = 0f; + + //what percentage of the screen to ignore when follow panning. + // 0% means always keep in the center, 50% would mean pan until target is within center 50% of screen + float followDeadzone = 0f; @Override public void update() { super.update(); - + + float deadX = 0; + float deadY = 0; if (followTarget != null){ panTarget = followTarget.center().offset(centerOffset); + deadX = width * followDeadzone /2f; + deadY = height * followDeadzone /2f; } if (panIntensity > 0f){ + PointF panMove = new PointF(); panMove.x = panTarget.x - (scroll.x + width/2f); panMove.y = panTarget.y - (scroll.y + height/2f); - + + if (panMove.x > deadX){ + panMove.x -= deadX; + } else if (panMove.x < -deadX){ + panMove.x += deadX; + } else { + panMove.x = 0; + } + + if (panMove.y > deadY){ + panMove.y -= deadY; + } else if (panMove.y < -deadY){ + panMove.y += deadY; + } else { + panMove.y = 0; + } + panMove.scale(Math.min(1f, Game.elapsed * panIntensity)); - + scroll.offset(panMove); } @@ -212,8 +237,10 @@ public class Camera extends Gizmo { public void setCenterOffset( float x, float y ){ scroll.x += x - centerOffset.x; scroll.y += y - centerOffset.y; - panTarget.x += x - centerOffset.x; - panTarget.y += y - centerOffset.y; + if (panTarget != null) { + panTarget.x += x - centerOffset.x; + panTarget.y += y - centerOffset.y; + } centerOffset.set(x, y); } @@ -237,6 +264,10 @@ public class Camera extends Gizmo { followTarget = target; panIntensity = intensity; } + + public void setFollowDeadzone( float deadzone ){ + followDeadzone = deadzone; + } public PointF screenToCamera( int x, int y ) { return new PointF( diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index 13fd8f713..d89990125 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -233,6 +233,8 @@ windows.wndsettings$displaytab.bright=Bright windows.wndsettings$displaytab.visual_grid=Visual Grid windows.wndsettings$displaytab.off=Off windows.wndsettings$displaytab.high=High +windows.wndsettings$displaytab.camera_follow=Camera Follow Intensity +windows.wndsettings$displaytab.low=Low windows.wndsettings$uitab.title=Interface Settings windows.wndsettings$uitab.ui_mode=Interface Mode windows.wndsettings$uitab.scale=Interface Scale diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/SPDSettings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/SPDSettings.java index 605b4ae71..4e2c9c76b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/SPDSettings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/SPDSettings.java @@ -56,6 +56,7 @@ public class SPDSettings extends GameSettings { public static final String KEY_ZOOM = "zoom"; public static final String KEY_BRIGHTNESS = "brightness"; public static final String KEY_GRID = "visual_grid"; + public static final String KEY_CAMERA_FOLLOW= "camera_follow"; public static void fullscreen( boolean value ) { put( KEY_FULLSCREEN, value ); @@ -116,6 +117,15 @@ public class SPDSettings extends GameSettings { public static int visualGrid() { return getInt( KEY_GRID, 0, -1, 2 ); } + + public static void cameraFollow( int value ){ + put( KEY_CAMERA_FOLLOW, value ); + GameScene.updateMap(); + } + + public static int cameraFollow() { + return getInt( KEY_CAMERA_FOLLOW, 4, 1, 4 ); + } //Interface diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index bd23088e1..c4399ee79 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -126,11 +126,9 @@ import com.watabou.noosa.NoosaScript; import com.watabou.noosa.NoosaScriptNoLighting; 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.watabou.noosa.tweeners.Tweener; -import com.watabou.utils.Callback; import com.watabou.utils.DeviceCompat; import com.watabou.utils.GameMath; import com.watabou.utils.Point; @@ -215,6 +213,13 @@ public class GameScene extends PixelScene { Camera.main.zoom( GameMath.gate(minZoom, defaultZoom + SPDSettings.zoom(), maxZoom)); Camera.main.scrollable = true; + switch (SPDSettings.cameraFollow()) { + case 4: default: Camera.main.setFollowDeadzone(0); break; + case 3: Camera.main.setFollowDeadzone(0.2f); break; + case 2: Camera.main.setFollowDeadzone(0.5f); break; + case 1: Camera.main.setFollowDeadzone(0.9f); break; + } + scene = this; terrain = new Group(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/HeroSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/HeroSprite.java index 89abc0bda..19250b58e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/HeroSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/HeroSprite.java @@ -98,7 +98,7 @@ public class HeroSprite extends CharSprite { @Override public void place( int p ) { super.place( p ); - if (Game.scene() instanceof GameScene) Camera.main.panTo(center(), 5f); + if (Game.scene() instanceof GameScene) Camera.main.panFollow(this, 5f); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/OptionSlider.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/OptionSlider.java index 40ea67973..0767a8ad3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/OptionSlider.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/OptionSlider.java @@ -60,11 +60,6 @@ public abstract class OptionSlider extends Component { active = false; } - if (title.length() > 20){ - remove(this.title); - this.title = PixelScene.renderTextBlock(6); - add(this.title); - } this.title.text(title); this.minTxt.text(minTxt); this.maxTxt.text(maxTxt); @@ -74,7 +69,7 @@ public abstract class OptionSlider extends Component { sliderTicks = new ColorBlock[(maxVal - minVal) + 1]; for (int i = 0; i < sliderTicks.length; i++){ - add(sliderTicks[i] = new ColorBlock(1, 11, 0xFF222222)); + add(sliderTicks[i] = new ColorBlock(1, 9, 0xFF222222)); } add(sliderNode); } @@ -87,8 +82,9 @@ public abstract class OptionSlider extends Component { public void setSelectedValue(int val) { this.selectedVal = val; - sliderNode.x = (int)(x + tickDist*(selectedVal-minVal)); + sliderNode.x = (int)(x + tickDist*(selectedVal-minVal)) + 0.5f; sliderNode.y = sliderBG.y-4; + PixelScene.align(sliderNode); } @Override @@ -104,7 +100,7 @@ public abstract class OptionSlider extends Component { add(sliderBG = new ColorBlock(1, 1, 0xFF222222)); sliderNode = Chrome.get(Chrome.Type.RED_BUTTON); - sliderNode.size(5, 9); + sliderNode.size(4, 7); pointerArea = new PointerArea(0, 0, 0, 0){ boolean pressed = false; @@ -126,7 +122,7 @@ public abstract class OptionSlider extends Component { //sets the selected value selectedVal = minVal + Math.round((sliderNode.x - x) / tickDist); - sliderNode.x = x + tickDist * (selectedVal - minVal); + sliderNode.x = x + tickDist * (selectedVal - minVal) + 0.5f; PixelScene.align(sliderNode); onChange(); pressed = false; @@ -147,32 +143,41 @@ public abstract class OptionSlider extends Component { @Override protected void layout() { + + if (title.width() > 0.7f*width){ + String titleText = title.text; + remove(title); + title = PixelScene.renderTextBlock(6); + add(title); + title.text(titleText); + } + title.setPos( x + (width-title.width())/2, y+2 ); PixelScene.align(title); - sliderBG.y = y + height() - 8; + sliderBG.y = y + height() - 7; sliderBG.x = x+2; sliderBG.size(width-5, 1); tickDist = sliderBG.width()/(maxVal - minVal); for (int i = 0; i < sliderTicks.length; i++){ - sliderTicks[i].y = sliderBG.y-5; + sliderTicks[i].y = sliderBG.y-4; sliderTicks[i].x = x + 2 + (tickDist*i); PixelScene.align(sliderTicks[i]); } minTxt.setPos( x+1, - sliderBG.y-6-minTxt.height() + sliderBG.y-5-minTxt.height() ); maxTxt.setPos( x+width()-maxTxt.width()-1, - sliderBG.y-6-minTxt.height() + sliderBG.y-5-minTxt.height() ); - sliderNode.x = x + tickDist*(selectedVal-minVal); - sliderNode.y = sliderBG.y-4; + sliderNode.x = x + tickDist*(selectedVal-minVal) + 0.5f; + sliderNode.y = sliderBG.y-3; PixelScene.align(sliderNode); pointerArea.x = x; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSettings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSettings.java index eb532c62e..6eb005ac0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSettings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSettings.java @@ -58,9 +58,9 @@ public class WndSettings extends WndTabbed { private static final int WIDTH_P = 122; private static final int WIDTH_L = 223; - private static final int SLIDER_HEIGHT = 23; - private static final int BTN_HEIGHT = 17; - private static final float GAP = 2; + private static final int SLIDER_HEIGHT = 21; + private static final int BTN_HEIGHT = 16; + private static final float GAP = 1; private DisplayTab display; private UITab ui; @@ -226,6 +226,7 @@ public class WndSettings extends WndTabbed { ColorBlock sep2; OptionSlider optBrightness; OptionSlider optVisGrid; + OptionSlider optFollowIntensity; @Override protected void createChildren() { @@ -320,6 +321,16 @@ public class WndSettings extends WndTabbed { optVisGrid.setSelectedValue(SPDSettings.visualGrid()); add(optVisGrid); + optFollowIntensity = new OptionSlider(Messages.get(this, "camera_follow"), + Messages.get(this, "low"), Messages.get(this, "high"), 1, 4) { + @Override + protected void onChange() { + SPDSettings.cameraFollow(getSelectedValue()); + } + }; + optFollowIntensity.setSelectedValue(SPDSettings.cameraFollow()); + add(optFollowIntensity); + } @Override @@ -329,7 +340,7 @@ public class WndSettings extends WndTabbed { title.setPos((width - title.width())/2, bottom + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; bottom = sep1.y + 1; @@ -369,7 +380,9 @@ public class WndSettings extends WndTabbed { optVisGrid.setRect(0, optBrightness.bottom() + GAP, width, SLIDER_HEIGHT); } - height = optVisGrid.bottom(); + optFollowIntensity.setRect(0, optVisGrid.bottom() + GAP, width, SLIDER_HEIGHT); + + height = optFollowIntensity.bottom(); } } @@ -385,8 +398,6 @@ public class WndSettings extends WndTabbed { CheckBox chkFlipTags; ColorBlock sep2; CheckBox chkFont; - ColorBlock sep3; - RedButton btnKeyBindings; @Override protected void createChildren() { @@ -610,7 +621,7 @@ public class WndSettings extends WndTabbed { protected void layout() { title.setPos((width - title.width())/2, y + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; height = sep1.y + 1; @@ -639,27 +650,10 @@ public class WndSettings extends WndTabbed { } sep2.size(width, 1); - sep2.y = height + 2; + sep2.y = height + GAP; chkFont.setRect(0, sep2.y + 1 + GAP, width, BTN_HEIGHT); - - if (btnKeyBindings != null){ - if (width > 200){ - chkFont.setSize(width/2-1, BTN_HEIGHT); - sep3.size(1, BTN_HEIGHT + 2*GAP); - sep3.x = chkFont.right() + 0.5f; - sep3.y = sep2.y+1; - PixelScene.align(sep3); - btnKeyBindings.setRect(chkFont.right()+2, chkFont.top(), width/2 - 1, BTN_HEIGHT); - } else { - sep3.size(width, 1); - sep3.y = chkFont.bottom() + 2; - btnKeyBindings.setRect(0, sep3.y + 1 + GAP, width, BTN_HEIGHT); - } - height = btnKeyBindings.bottom(); - } else { - height = chkFont.bottom(); - } + height = chkFont.bottom(); } } @@ -750,7 +744,7 @@ public class WndSettings extends WndTabbed { protected void layout() { title.setPos((width - title.width())/2, y + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; height = sep1.y+1; @@ -858,7 +852,7 @@ public class WndSettings extends WndTabbed { protected void layout() { title.setPos((width - title.width())/2, y + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; float pos; if (width > 200 && chkUpdates != null){ @@ -983,7 +977,7 @@ public class WndSettings extends WndTabbed { protected void layout() { title.setPos((width - title.width())/2, y + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; if (width > 200) { optMusic.setRect(0, sep1.y + 1 + GAP, width/2-1, SLIDER_HEIGHT); @@ -1200,12 +1194,12 @@ public class WndSettings extends WndTabbed { protected void layout() { title.setPos((width - title.width())/2, y + GAP); sep1.size(width, 1); - sep1.y = title.bottom() + 2*GAP; + sep1.y = title.bottom() + 3*GAP; txtLangInfo.setPos(0, sep1.y + 1 + GAP); txtLangInfo.maxWidth((int)width); - y = txtLangInfo.bottom() + GAP; + y = txtLangInfo.bottom() + 2*GAP; int x = 0; sep2.size(width, 1);