v1.4.0: added a setting to adjust camera follow intensity

This commit is contained in:
Evan Debenham
2022-09-13 15:42:34 -04:00
parent 39fa4adbe1
commit 41ea6aad60
7 changed files with 102 additions and 55 deletions

View File

@@ -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 //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 //keep in mind though that this speed is constantly decreasing, so actual pan time is higher
float panIntensity = 0f; 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 @Override
public void update() { public void update() {
super.update(); super.update();
float deadX = 0;
float deadY = 0;
if (followTarget != null){ if (followTarget != null){
panTarget = followTarget.center().offset(centerOffset); panTarget = followTarget.center().offset(centerOffset);
deadX = width * followDeadzone /2f;
deadY = height * followDeadzone /2f;
} }
if (panIntensity > 0f){ if (panIntensity > 0f){
PointF panMove = new PointF(); PointF panMove = new PointF();
panMove.x = panTarget.x - (scroll.x + width/2f); panMove.x = panTarget.x - (scroll.x + width/2f);
panMove.y = panTarget.y - (scroll.y + height/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)); panMove.scale(Math.min(1f, Game.elapsed * panIntensity));
scroll.offset(panMove); scroll.offset(panMove);
} }
@@ -212,8 +237,10 @@ public class Camera extends Gizmo {
public void setCenterOffset( float x, float y ){ public void setCenterOffset( float x, float y ){
scroll.x += x - centerOffset.x; scroll.x += x - centerOffset.x;
scroll.y += y - centerOffset.y; scroll.y += y - centerOffset.y;
panTarget.x += x - centerOffset.x; if (panTarget != null) {
panTarget.y += y - centerOffset.y; panTarget.x += x - centerOffset.x;
panTarget.y += y - centerOffset.y;
}
centerOffset.set(x, y); centerOffset.set(x, y);
} }
@@ -237,6 +264,10 @@ public class Camera extends Gizmo {
followTarget = target; followTarget = target;
panIntensity = intensity; panIntensity = intensity;
} }
public void setFollowDeadzone( float deadzone ){
followDeadzone = deadzone;
}
public PointF screenToCamera( int x, int y ) { public PointF screenToCamera( int x, int y ) {
return new PointF( return new PointF(

View File

@@ -233,6 +233,8 @@ windows.wndsettings$displaytab.bright=Bright
windows.wndsettings$displaytab.visual_grid=Visual Grid windows.wndsettings$displaytab.visual_grid=Visual Grid
windows.wndsettings$displaytab.off=Off windows.wndsettings$displaytab.off=Off
windows.wndsettings$displaytab.high=High 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.title=Interface Settings
windows.wndsettings$uitab.ui_mode=Interface Mode windows.wndsettings$uitab.ui_mode=Interface Mode
windows.wndsettings$uitab.scale=Interface Scale windows.wndsettings$uitab.scale=Interface Scale

View File

@@ -56,6 +56,7 @@ public class SPDSettings extends GameSettings {
public static final String KEY_ZOOM = "zoom"; public static final String KEY_ZOOM = "zoom";
public static final String KEY_BRIGHTNESS = "brightness"; public static final String KEY_BRIGHTNESS = "brightness";
public static final String KEY_GRID = "visual_grid"; public static final String KEY_GRID = "visual_grid";
public static final String KEY_CAMERA_FOLLOW= "camera_follow";
public static void fullscreen( boolean value ) { public static void fullscreen( boolean value ) {
put( KEY_FULLSCREEN, value ); put( KEY_FULLSCREEN, value );
@@ -116,6 +117,15 @@ public class SPDSettings extends GameSettings {
public static int visualGrid() { public static int visualGrid() {
return getInt( KEY_GRID, 0, -1, 2 ); 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 //Interface

View File

@@ -126,11 +126,9 @@ import com.watabou.noosa.NoosaScript;
import com.watabou.noosa.NoosaScriptNoLighting; import com.watabou.noosa.NoosaScriptNoLighting;
import com.watabou.noosa.SkinnedBlock; import com.watabou.noosa.SkinnedBlock;
import com.watabou.noosa.Visual; import com.watabou.noosa.Visual;
import com.watabou.noosa.audio.Music;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.Emitter;
import com.watabou.noosa.tweeners.Tweener; import com.watabou.noosa.tweeners.Tweener;
import com.watabou.utils.Callback;
import com.watabou.utils.DeviceCompat; import com.watabou.utils.DeviceCompat;
import com.watabou.utils.GameMath; import com.watabou.utils.GameMath;
import com.watabou.utils.Point; 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.zoom( GameMath.gate(minZoom, defaultZoom + SPDSettings.zoom(), maxZoom));
Camera.main.scrollable = true; 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; scene = this;
terrain = new Group(); terrain = new Group();

View File

@@ -98,7 +98,7 @@ public class HeroSprite extends CharSprite {
@Override @Override
public void place( int p ) { public void place( int p ) {
super.place( 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 @Override

View File

@@ -60,11 +60,6 @@ public abstract class OptionSlider extends Component {
active = false; active = false;
} }
if (title.length() > 20){
remove(this.title);
this.title = PixelScene.renderTextBlock(6);
add(this.title);
}
this.title.text(title); this.title.text(title);
this.minTxt.text(minTxt); this.minTxt.text(minTxt);
this.maxTxt.text(maxTxt); this.maxTxt.text(maxTxt);
@@ -74,7 +69,7 @@ public abstract class OptionSlider extends Component {
sliderTicks = new ColorBlock[(maxVal - minVal) + 1]; sliderTicks = new ColorBlock[(maxVal - minVal) + 1];
for (int i = 0; i < sliderTicks.length; i++){ 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); add(sliderNode);
} }
@@ -87,8 +82,9 @@ public abstract class OptionSlider extends Component {
public void setSelectedValue(int val) { public void setSelectedValue(int val) {
this.selectedVal = 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; sliderNode.y = sliderBG.y-4;
PixelScene.align(sliderNode);
} }
@Override @Override
@@ -104,7 +100,7 @@ public abstract class OptionSlider extends Component {
add(sliderBG = new ColorBlock(1, 1, 0xFF222222)); add(sliderBG = new ColorBlock(1, 1, 0xFF222222));
sliderNode = Chrome.get(Chrome.Type.RED_BUTTON); sliderNode = Chrome.get(Chrome.Type.RED_BUTTON);
sliderNode.size(5, 9); sliderNode.size(4, 7);
pointerArea = new PointerArea(0, 0, 0, 0){ pointerArea = new PointerArea(0, 0, 0, 0){
boolean pressed = false; boolean pressed = false;
@@ -126,7 +122,7 @@ public abstract class OptionSlider extends Component {
//sets the selected value //sets the selected value
selectedVal = minVal + Math.round((sliderNode.x - x) / tickDist); 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); PixelScene.align(sliderNode);
onChange(); onChange();
pressed = false; pressed = false;
@@ -147,32 +143,41 @@ public abstract class OptionSlider extends Component {
@Override @Override
protected void layout() { 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( title.setPos(
x + (width-title.width())/2, x + (width-title.width())/2,
y+2 y+2
); );
PixelScene.align(title); PixelScene.align(title);
sliderBG.y = y + height() - 8; sliderBG.y = y + height() - 7;
sliderBG.x = x+2; sliderBG.x = x+2;
sliderBG.size(width-5, 1); sliderBG.size(width-5, 1);
tickDist = sliderBG.width()/(maxVal - minVal); tickDist = sliderBG.width()/(maxVal - minVal);
for (int i = 0; i < sliderTicks.length; i++){ 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); sliderTicks[i].x = x + 2 + (tickDist*i);
PixelScene.align(sliderTicks[i]); PixelScene.align(sliderTicks[i]);
} }
minTxt.setPos( minTxt.setPos(
x+1, x+1,
sliderBG.y-6-minTxt.height() sliderBG.y-5-minTxt.height()
); );
maxTxt.setPos( maxTxt.setPos(
x+width()-maxTxt.width()-1, x+width()-maxTxt.width()-1,
sliderBG.y-6-minTxt.height() sliderBG.y-5-minTxt.height()
); );
sliderNode.x = x + tickDist*(selectedVal-minVal); sliderNode.x = x + tickDist*(selectedVal-minVal) + 0.5f;
sliderNode.y = sliderBG.y-4; sliderNode.y = sliderBG.y-3;
PixelScene.align(sliderNode); PixelScene.align(sliderNode);
pointerArea.x = x; pointerArea.x = x;

View File

@@ -58,9 +58,9 @@ public class WndSettings extends WndTabbed {
private static final int WIDTH_P = 122; private static final int WIDTH_P = 122;
private static final int WIDTH_L = 223; private static final int WIDTH_L = 223;
private static final int SLIDER_HEIGHT = 23; private static final int SLIDER_HEIGHT = 21;
private static final int BTN_HEIGHT = 17; private static final int BTN_HEIGHT = 16;
private static final float GAP = 2; private static final float GAP = 1;
private DisplayTab display; private DisplayTab display;
private UITab ui; private UITab ui;
@@ -226,6 +226,7 @@ public class WndSettings extends WndTabbed {
ColorBlock sep2; ColorBlock sep2;
OptionSlider optBrightness; OptionSlider optBrightness;
OptionSlider optVisGrid; OptionSlider optVisGrid;
OptionSlider optFollowIntensity;
@Override @Override
protected void createChildren() { protected void createChildren() {
@@ -320,6 +321,16 @@ public class WndSettings extends WndTabbed {
optVisGrid.setSelectedValue(SPDSettings.visualGrid()); optVisGrid.setSelectedValue(SPDSettings.visualGrid());
add(optVisGrid); 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 @Override
@@ -329,7 +340,7 @@ public class WndSettings extends WndTabbed {
title.setPos((width - title.width())/2, bottom + GAP); title.setPos((width - title.width())/2, bottom + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
bottom = sep1.y + 1; bottom = sep1.y + 1;
@@ -369,7 +380,9 @@ public class WndSettings extends WndTabbed {
optVisGrid.setRect(0, optBrightness.bottom() + GAP, width, SLIDER_HEIGHT); 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; CheckBox chkFlipTags;
ColorBlock sep2; ColorBlock sep2;
CheckBox chkFont; CheckBox chkFont;
ColorBlock sep3;
RedButton btnKeyBindings;
@Override @Override
protected void createChildren() { protected void createChildren() {
@@ -610,7 +621,7 @@ public class WndSettings extends WndTabbed {
protected void layout() { protected void layout() {
title.setPos((width - title.width())/2, y + GAP); title.setPos((width - title.width())/2, y + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
height = sep1.y + 1; height = sep1.y + 1;
@@ -639,27 +650,10 @@ public class WndSettings extends WndTabbed {
} }
sep2.size(width, 1); sep2.size(width, 1);
sep2.y = height + 2; sep2.y = height + GAP;
chkFont.setRect(0, sep2.y + 1 + GAP, width, BTN_HEIGHT); chkFont.setRect(0, sep2.y + 1 + GAP, width, BTN_HEIGHT);
height = chkFont.bottom();
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();
}
} }
} }
@@ -750,7 +744,7 @@ public class WndSettings extends WndTabbed {
protected void layout() { protected void layout() {
title.setPos((width - title.width())/2, y + GAP); title.setPos((width - title.width())/2, y + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
height = sep1.y+1; height = sep1.y+1;
@@ -858,7 +852,7 @@ public class WndSettings extends WndTabbed {
protected void layout() { protected void layout() {
title.setPos((width - title.width())/2, y + GAP); title.setPos((width - title.width())/2, y + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
float pos; float pos;
if (width > 200 && chkUpdates != null){ if (width > 200 && chkUpdates != null){
@@ -983,7 +977,7 @@ public class WndSettings extends WndTabbed {
protected void layout() { protected void layout() {
title.setPos((width - title.width())/2, y + GAP); title.setPos((width - title.width())/2, y + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
if (width > 200) { if (width > 200) {
optMusic.setRect(0, sep1.y + 1 + GAP, width/2-1, SLIDER_HEIGHT); optMusic.setRect(0, sep1.y + 1 + GAP, width/2-1, SLIDER_HEIGHT);
@@ -1200,12 +1194,12 @@ public class WndSettings extends WndTabbed {
protected void layout() { protected void layout() {
title.setPos((width - title.width())/2, y + GAP); title.setPos((width - title.width())/2, y + GAP);
sep1.size(width, 1); sep1.size(width, 1);
sep1.y = title.bottom() + 2*GAP; sep1.y = title.bottom() + 3*GAP;
txtLangInfo.setPos(0, sep1.y + 1 + GAP); txtLangInfo.setPos(0, sep1.y + 1 + GAP);
txtLangInfo.maxWidth((int)width); txtLangInfo.maxWidth((int)width);
y = txtLangInfo.bottom() + GAP; y = txtLangInfo.bottom() + 2*GAP;
int x = 0; int x = 0;
sep2.size(width, 1); sep2.size(width, 1);