I am trying to achieve an effect like Google Maps and many other (all?) navigation apps: in navigation mode, the current location is displayed at the bottom of the screen, so that the user can see more of the road in front of them.
I already have the code to update the location and also change the map's orientation based on the bearing. Everything works perfectly if I keep the map centered on the location, so I am moving on to the offset part. Here is what I have:
if (followMe) {
float bearing = [...]; // OK until here
mapView.getController().setCenter(currentLocation); // quickly center on location
mapView.getController().scrollBy(0, -(int)(mapView.getHeight() / 2 * 0.8)); // shift
GeoPoint newCenter = mapView.getProjection().getCurrentCenter(); // get the coordinates of the new center
mapView.getController().animateTo(newCenter, null, (long) 1000, bearing); // center again, this time with a nice animation
}
It does not work as intended and produces weird behaviors: the map is centered elsewhere entirely, updates all of a sudden, etc. I suspect it's because of things like sudden changes in the bearing, or maybe I am just getting it wrong.
Any suggestions?
I've got an app that programmatically moves its window around the user's screen. My problem:
User has two physical monitors
User starts app in primary monitor
App moves window, causing more of it to "overflow" into the secondary monitor than is on the primary monitor
This causes the app's window to entirely jump to that secondary monitor and disappear from the primary monitor.
I would like for the window to stay in the primary monitor unless I want it to go to the secondary monitor, or some defined point (e.g. the center) goes into the secondary monitor, or it would even be ok if the window were split and shown on both. Is there any way to prevent this jump from happening as soon the window intersects more with the secondary monitor?
To reiterate, I'm moving the window programmatically and am using Electron on macOS.
Also, this doesn't appear to happen when I move window manually, but I think this is because it's not using its percentage rule but going on whether or not the point of the mouse has entered the secondary monitor.
Also, I'm open to any kind of solution, including C/C++ or Swift.
EDIT: Here's how I'm currently moving the window:
win.setPosition(x, y);
where win is an instance of Electron's BrowserWindow.
The desired behavior is to move the window anywhere on a display. Currently, if some of the window goes off the edge of the current display enough, it jumps to another display. This is because Apple's default behavior it to automatically move a window to the display with which it overlaps the most and hide it on all other displays. It is worth noting that this is not the behavior when dragging a window manually, but just when moving it programmatically.
I don't know how you are moving this window, or how you want the window to act when it hits the edge, but I will do my best to give you some solutions.
My first thought was for you to create the bounds of the screen when the program starts.
So maybe use GetSystemMetrics(), screen.getPrimaryDisplay(), or perhaps this pseudo-code helps:
var canvas = GetWindowSize()
var canvasWidth = canvas.width
var canvasHeight = canvas.height
if myWindow.x + mywindow.width > canvasWidth
//if you want it to bounce off the edge
then myWindow.direction = oppositeDirection
//if you want it to wrap to the other side of the screen
then myWindow.X -= canvasWidth
You should check out this code of a Bouncing DVD Logo.
Or look at my Asteroids game to see how ship and asteroids move in the screen.
Furthermore, you can use the distance formula to have the window react to the edge when the center gets close. (Although, this would also require you to get the screen bounds x and y.)
Hope that helps!
EDIT:
I think if you were to somehow use the entire screen, (both monitors) your window wouldn't even recognize that there is an edge. That being said, I still don't know what your code actually does.
It's not working when you do win.setPosition(x, y); because of mac OS behaviour.
(I also tried with electron quick start project https://github.com/electron/electron-quick-start, even with the same electron version 6.0.5)
What I did is to programmatically simulate a mouse drag of your app to the right of the screen. To do it you can use robotjs. You will not see the dragging effect, which is pretty close to do a setPosition(x, y)
When you install it you could have an issue when starting you app. Then you have to rebuild rebotJS for your version of electron. https://github.com/octalmage/robotjs/wiki/Electron
So what you will try to do programmatically is
Working code
// get your app bounds and screen bounds
const windowBounds = mainWindow.getBounds()
const displayBounds = electron.screen.getPrimaryDisplay().bounds
setTimeout(() => {
// 1. move mouse upon the top left corner your app
robot.moveMouse(windowBounds.x + 100, windowBounds.y + 5);
// 2. mouse left key, 'down'
robot.mouseToggle("down", "left");
// 3. drag window to (100, 100) from default
robot.dragMouse(displayBounds.width, 0);
// 4. mouse left key toggle 'up'
robot.mouseToggle("up", "left");
}, 100);
Example in main.js: https://playcode.io/electron
I use those version:
"devDependencies": {
"electron": "^6.0.5"
},
"dependencies": {
"robotjs": "^0.6.0"
}
and my versoon of nodejs is v10.20.0
Maybe it's not quite what you asked for, but here's a thought: why not resize the window instead of letting it "overflow" to other screens?
When you predict that window will go out bounds of current display, just reduce its size.
It can be done by something along this lines:
const winWidth = 800;
const winHeight = 600;
const SAFETY_MARGINS = 10;
let mainWindow;
// setPosition //////////////////////////////////////////////////////////////////////////
function setPosition(x, y) {
const displayBounds = screen.getPrimaryDisplay().bounds
const fixedX = Math.min(
displayBounds.x + displayBounds.width,
Math.max(x, displayBounds.x)
);
const fixedY = Math.min(
displayBounds.y + displayBounds.height,
Math.max(y, displayBounds.y)
);
mainWindow.setPosition(fixedX, fixedY);
const fixedWidth = Math.max(SAFETY_MARGINS, Math.min(winWidth, displayBounds.width + displayBounds.x - x, winWidth - displayBounds.x + x));
const fixedHeight = Math.max(SAFETY_MARGINS, Math.min(winHeight, displayBounds.height + displayBounds.y - y, winHeight - displayBounds.y + y));
mainWindow.setSize(fixedWidth, fixedHeight);
}
This version of setPosition will always resize your window so that it won't go beyond display bounds.
You can modify/extend it to allow window to go out of bounds just a bit and to scroll window's content (if needed).
I believe that with some tweaks, for most users, resizing and moving the window just slightly off the screen would look more-or-less like actually moving the window off the screen.
Here's a demo moving the window randomly using this code:
https://github.com/yoava/so-61092503
(I didn't test in with dual screens as I'm only with my laptop now.)
I have a grow / shrink animation sequence. But for some reason the sprite does not scale smoothly. I did change the animation interval and disabled depth test but it did not fix this.
What can be the reason behind this?
Does does have something to do with art asset that is used?
ScaleTo* grow = ScaleTo::create(1, 1.5);
ScaleTo* shrink = ScaleTo::create(1, 1);
Sequence* anim = Sequence::create(grow, shrink , NULL);
RepeatForever *rep = RepeatForever::create(anim);
station_image->runAction(rep);
Solved
I was able to fix this issue by enabling ‘CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL’ in ccConfig.h
I am searching for a way to place a sprite via objective-c in percentage based on the parents dimensions. Is there any way?
try this :
sprite.positionType = CCPositionTypeNormalized;
sprite.position.x = .2f; // 20% of parent's width
sprite.position.y = .45f; // 45% of parent's height
make certain that sprite has a parent i.e. has been added to another node.
obcit. not tested, from memory. With cocos2d 3.x.
I'm pretty new to Cocos 2D-X but have some decent background in C++. I have a sprite _rocket (tied to a Box2D body) that occasionally moves outside the visible view of my screen. I'd like for the view to automatically zoom out as the sprite approaches the edge of the screen, so that the sprite is always in the view. When the sprite returns to the original view frame, the view should scale back to its original size.
I was able to zoom out with the following code in the update function:
Size winSize = Director::getInstance()->getWinSize();
if ((_rocket->getPosition().x - _rocket->getContentSize().width/2 < 10.0) ||
(_rocket->getPosition().x + _rocket->getContentSize().width/2 > winSize.width - 10.0) ||
(_rocket->getPosition().y - _rocket->getContentSize().width/2 < 10.0) ||
(_rocket->getPosition().y + _rocket->getContentSize().width/2 > winSize.height - 10.0))
{
this->setScale(this->getScale()-0.005);
}
However, because winSize isn't updated, this essentially scales forever, until the sprite returns to the original view. I am not sure how to update winSize so that it can be used iteratively to find the screen's edge. There may also be a much easier way of approaching this.
i don't understand why the winSize should change.
if you mean the _rock's contentsize not change
you should use
auto size = _rocket->getBoundingBox().size;
They removed some useful camera functions in cocos2d-x 3.+
The workaround is to scale/move the layer containing the game instead of trying to move the camera.