v1.4.0: added a setting to adjust camera follow intensity
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user