How do I make a scroll-able map. For example, my preferred back buffer is 800x600 and the map is 2400x1800 (approximately 3x3). Also, how do I handle the keyboard state to scroll and do walking. I know most games keep the player centered and scroll the world. The problem with this approach is the corners. There would be a large unmoveable area.
To make scrollable map you can use simple Rectangle or ViewPort (named camera):
' Initialize camera with size of game viewport
Dim viewport As Viewport = spriteBatch.GraphicsDevice.Viewport
Dim camera As New Rectangle(viewport.X, viewport.Y, viewport.Width, viewport.Height)
' Draw method code
spriteBatch.Begin()
spriteBatch.Draw(image,
New Rectangle(0, 0, viewport.Width, viewport.Height), // Destination rectangle
camera, // Source rectangle
Color.White)
spriteBatch.End()
By changing camera.X and camera.Y values you can adjust origin from where your image is drawn thus moving camera around. For example following code would move your camera to the right:
Dim keyboardState As KeyboardState = Keyboard.GetState()
If keyboardState.IsKeyDown(Keys.Right) Then
camera.X += 1
End If
Walking can be done very similarly, by increasing character position X and Y coordinates when according buttons are pressed.
Keeping player in the center of the screen is a bit trickier. Basically you want to keep character in the center of the screen at all times except when distance between it and edge of world is less then half the screen. In this case stop moving camera and start moving character off of center to the desired side.
Related
Problem : I have an image with zoom and pan attached. I need to draw rectangles over it.
What I have done : I created a Canvas as an overlay over the image and made rectangle the children of canvas. Everything works well with zoom and pan etc but if the user resizes my the window then the added rectangles starts moving from their places because the rectangle position is set with respect to top and left of canvas.
I am thinking of drawing rectangles over the image and overriding the render. Any suggestions how can I achieve it easily?
I have a rectangle sprite that animates when a score is reached. Starts offscreen and then move onscreen before moving off-screen again. Works fine. Problem is when I change the resolution for different devices the sprite resizes and doesn't display as intended. The text fields inside the rectangle move outside on some of the resolutions. How can i keep the sprite at the original size regardless of resolution. I have tried Preserve Aspect, Set Native Size, moving anchors but it still resizes. I also tried using a panel.Any Ideas?
I am trying to scale my application to work similar on various aspect ratios.
I read about viewport and camera. And came to a conclusion that I should use FitViewport for my game stage so that no asset is being stretched. And I will use some background image to fill the black bars caused by fitviewport. But the problem is, whenever I use any other viewport than FitViewport for background image, the whole stage (both background and main stage) are being stretched, is there a way we can get away from black/white bar of FitViewport? I tried all the viewports for background namely StretchViewport, ScreenViewport, FillViewport.
Am I missing something very trivial? or is setting up multiple different viewport on same screen possible.
ps I was able to setup two same viewports with different size on same screen.
Here is the screen, I am getting after fitviewport. Notice the white bars on top and bottom which I am trying to eliminate.
this answer worked for me. Just for reference
You would need a second viewport, probably ExtendViewport with the
same virtual dimensions as your FitViewport.
//create:
fitViewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
extendViewport = new ExtendViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
//resize:
fitViewport.update(width, height);
extendViewport.update(width, height);
//render:
fitViewport.apply();
batch.setProjectionMatrix(fitViewport.getCamera().combined);
batch.begin();
//draw game
batch.end();
extendViewport.apply();
batch.setProjectionMatrix(extendViewport.getCamera().combined);
batch.begin();
//draw stuff in border
batch.end();
If you want to be sure the border stuff doesn't overlap your game, you
could swap the draw order above.
Or you could just use ExtendViewport to begin with for everything.
I'm trying to move the location of a Mac cursor using Objective-C along a path outside of any UI element (not just on some window, but around the entire screen irrelevant of what the mouse is hovering over). I don't want to directly warp the mouse to a position, but rather progressively move it there (i.e. iterate through a loop, and in each iteration move the cursor 1 pixel to the right).
The problem is that the cursor constantly jumps back and forth over the horizontal center line of the screen (if I start the cursor at y=289, it jumps to y=511, and then back to y=289, and so forth, as my screen is 800 pixels high) even if I don't actually move it anywhere.
NSPoint mPoint = [NSEvent mouseLocation];
NSPoint mouseWarpLocation = NSMakePoint(mPoint.x, mPoint.y);
CGWarpMouseCursorPosition(mouseWarpLocation);
The code above effectively warps the mouse to its current position, but for some reason the cursor jumps back and forth over the horizontal center line. Any thoughts as to why or what I can do to fix it?
The problem is that AppKit (which provides the NSEvent class) and Quartz Display Services (which provides CGWarpMouseCursorPosition) use different coordinate systems for the screen.
In Quartz, the origin of the screen coordinate system is at the top-left corner of the “main” screen, which is the screen that contains the menu bar, and Y coordinates increase as you move down the screen.
In AppKit, the origin of the screen coordinate system is at the bottom-left corner of the main screen, and Y coordinates increase as you move up the screen.
So if you ask AppKit for the mouse location (in screen coordinates), you need to convert the Y coordinate to the Quartz coordinate system before passing it to a Quartz function.
To transform the Y coordinate, subtract it from the height of the main screen:
NSPoint point = [NSEvent mouseLocation];
point.y = [NSScreen mainScreen].frame.size.height - point.y;
CGWarpMouseCursorPosition(point);
I'm animating a button's position, rotating it around a circle. This creates a UISwitch-like behavior, except it is a lot more fancy. The button rotates, but it ends up off the desired position by about 0.25 radians. I'm trying to figure out where to put the anchor point to make the button rotate in a perfect circle around its origin.
Here's the code that I use to make the button "orbit" with a 120 pixel radius from the original location.
float offsetX=120;
float offsetY=0;
enableDisableButton.layer.anchorPoint =
CGPointMake(offsetX/enableDisableButton.frame.size.width,
offsetY/enableDisableButton.frame.size.height);
I use the following method to do the calculations. Passing an argument of 90 for degrees, I expect to see the button start at a 180˚ position and move to 90˚, still 120 pixels away from its origin
-(CGAffineTransform)calculateLabelPositionFromFixedPointWithOffsetClockwiseInDegrees:(float)degrees
{
float rotation = degrees*(2*M_PI/360);
CGAffineTransform transform24 = CGAffineTransformMakeRotation(rotation);
NSLog(#"rotation: %f", rotation);
return transform24;
}
This little 0.25 radian or so offset means that I need to visually confirm the location of each button and cannot easily adjust its location programmatically. Any help in determining the correct way to rotate the button is appreciated.
I tried other ways to rotate objects. For example, I have an arrow
<--------x, and I would like to rotate this arrow in a circle around x . What is the correct anchor point placement for this operation? Is it [1, 0.5]?
An easier way to do this kind of rotations is to put an object within a symmetric UIView, center it at the desired point of rotation and assign a rotation transform. This works, but requires the view to be twice as big:
Y----x----Y < this rotates Y around center point X without any anchor point adjustments. this is a very useful method to rotate arrows within analog gauges and such.
"An easier way to do this kind of rotations is to put an object within a symmetric UIView, center it at the desired point of rotation and assign a rotation transform." this way is fine.
The anchor point of your enableDisableButton in the example would be
CGPointMake(offsetX/enableDisableButton.frame.size.width, 0)
i.e. not vertically centered in your button. Rotating around the anchor point would result in the button being offset to the top or bottom of the desired position. The transform looks alright, so I think it is just the anchor point. It should be:
CGPointMake(offsetX/enableDisableButton.frame.size.width, 0.5f)