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
//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(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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