Gamemaker Zooming and Dragging - object

I am currently using gamemaker to create a floorplan system. I am able to zoom into a room, drag and zoom out but how can i limit how much i can zoom in and out? The size of the room is 1024 by 768 px. I want to be able to zoom out to the way it originally looks when you first enter the room.
This is my code currently which i have placed in the script:
X=view_xview[0];
Y=view_yview[0];
if mouse_check_button(mb_left){
global.DRAG=true;
window_set_cursor(cr_drag);
view_xview-=vmx;
view_yview-=vmy;
}
/*else{
if !keyboard_check(vk_space){
global.DRAG=false
}
window_set_cursor(cr_default);
}
*/
vmx=(mouse_x-X)-omx;
omx=(mouse_x-X);
vmy=(mouse_y-Y)-omy;
omy=(mouse_y-Y);
if mouse_wheel_up(){
center_of_space_x=view_xview+view_wview/2;
center_of_space_y=view_yview+view_hview/2;
view_wview-=view_wview*0.15;
view_hview-=view_hview*0.15;
view_xview=center_of_space_x-view_wview/2;
view_yview=center_of_space_y-view_hview/2;
}
if mouse_wheel_down(){
center_of_space_x=view_xview+view_wview/2;
center_of_space_y=view_yview+view_hview/2;
view_wview+=view_wview*0.15;
view_hview+=view_hview*0.15;
view_xview=center_of_space_x-view_wview/2;
view_yview=center_of_space_y-view_hview/2;
}

To do this is fairly simple, using the clamp function. A modified version of your code would look like this:
view_wview = clamp(view_wview * 0.15, min_size, 1024)
view_hview = clamp(view_hview * 0.15, min_size, 768)

simply use the clamp function to limit the view_wview and view_hview
var maxZoomIn = 0.2; //500% zoom in limit
var maxZoomOut = 1; //100% zoom out limit
if mouse_wheel_up(){
center_of_space_x=view_xview+view_wview/2;
center_of_space_y=view_yview+view_hview/2;
view_wview = clamp(view_wview - view_wview * 0.15, maxZoomIn*room_width, maxZoomOut*room_width)
view_hview = clamp(view_hview - view_hview * 0.15, maxZoomIn*room_height, maxZoomOut*room_height)
view_xview=center_of_space_x-view_wview/2;
view_yview=center_of_space_y-view_hview/2;
}
and similar for mouse_wheel_down.

Related

Why don't these lines have the same thickness? PIXI.JS

Let me ask you a question about PIXI.js. In Chrome, these lines looks like not the same thickness, but its the same Graphics API (lineTo, moveTo). Why is that?
let boxW = 46.5;
this.leftBox
.lineStyle(1, 0x000,1)
.beginFill(0xffffff)
.moveTo(0, 0)
.lineTo(465, 0)
.lineTo(465, 465)
.lineTo(0, 465)
.lineTo(0, 0)
.endFill();
for (let i = 1; i <= 9; i++) {
this.leftBox.moveTo(boxW * i, 0).lineTo(boxW * i, 465);
}
PAEz is right, it is likely anti aliasing.
When you create you Application anti-aliasing is turned off by default.
Try the below and see if it helps:
const app = new PIXI.Application({
'antialias': true,
'resolution': 2 // This may help too
});
// Add the view to the DOM
document.body.appendChild(app.view);
// ... your line code
The documentation for the Application class and its options can be found here:
https://pixijs.download/dev/docs/PIXI.Application.html
As a side note, PIXI is very fast but as your application scales anti-aliasing and resolution may have performance implications.
Finally to answer your question about what anti-aliasing is, in short, its a way to smooth out jagged edges on non-rectangular shapes, though you have a series lines it could help with your situation too. Here is an article that can tell you more: https://www.gamingscan.com/what-is-anti-aliasing/

Bitmap Image: cropping with portrait orientation

Adding camera functionality to my app is killing me! Started with the basic UWP camera sample, but I have to add zooming capability which added a ScrollViewer around the preview control and complicated my life. Found the cropping code in a different sample. Everything works in landscape, but when you rotate the tablet to portrait the cropped image (even without any actual cropping) is rotated 90.
The cropping logic takes originX/Y, ScrollViewer.ViewportWidth/Height & ScrollViewer.ExtentWidth/Height. I don't understand how these values change with the rotation! In Landscape I use topLeft for the X/Y. What would I do for Portrait? I'm setting the width to 400 and in both views it's STILL 400 so I don't believe width/height should be flipped.
Here's the cropping code. Can anyone comment on what should be different for the 2 (actually 4) orientations?
async public static Task<WriteableBitmap> GetCroppedBitmapAsync(StorageFile originalImageFile,
Point startPoint, Size cropSize, Size previewSize)
{
using (IRandomAccessStream stream = await originalImageFile.OpenReadAsync())
{
// Create a decoder from the stream. With the decoder, we can get the properties of the image.
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
// Adjust the start x/y to the stream size
uint scaledStartPointX = (uint)Math.Round((decoder.PixelWidth * (startPoint.X / previewSize.Width)));
uint scaledStartPointY = (uint)Math.Round((decoder.PixelHeight * (startPoint.Y / previewSize.Height)));
// Now get the scaled size of the viewport (ie the cropped area)
uint selectedAreaWidth = (uint)Math.Round(decoder.PixelWidth * (cropSize.Width / previewSize.Width));
uint selectedAreaHeight = (uint)Math.Round(decoder.PixelHeight * (cropSize.Height / previewSize.Height));
// Get the cropped pixels.
byte[] pixels = await GetPixelData(decoder, scaledStartPointX, scaledStartPointY, selectedAreaWidth, selectedAreaHeight,
decoder.PixelWidth, decoder.PixelHeight);
// Stream the bytes into a WriteableBitmap
WriteableBitmap cropBmp = new WriteableBitmap((int)selectedAreaWidth, (int)selectedAreaHeight);
Stream pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, (int)(selectedAreaWidth * selectedAreaHeight * 4));
return cropBmp;
}
}

How do I get a Plymouth sprite to rotate?

I'm working on a custom Plymouth splash for Kubuntu. I'm attempting to make an image rotate as the system is loading. I have tested it using both reboots and the X11 plugin and have been unsuccessful in both. Here's the .script file:
spiral_image = Image("Splash.png");
spiral_sprite = Sprite(spiral_image);
spiral_sprite.SetX(window.GetWidth() /2 - spiral_image.GetWidth() /2);
spiral_sprite.SetY(window.GetHeight() /2 - spiral_image.GetHeight() /2);
fun refresh_callback ()
{
time++;
theta = time / 100;
spiral_sprite.Rotate(theta);
}
Plymouth.SetRefreshFunction (refresh_callback);
You need to rotate the image, not the sprite:
fun refresh_callback () {
time++;
theta = time / 100;
spiral_sprite.SetImage( spiral_image.Rotate(theta) );
}
As per official documentation, in case anyone finds this question before they manage to find Plymouth documentation.
(Extra notes, slightly off-topic: Documentation says that default text colour is white. Don't count on that too much, it's black.)

three.js get double clicked 3d object

Ciao, I am trying to accomplish this: I would be able to know wich 3d object is double clicked in my scene, and animate camera position to bring the object in the center of the screen.
I tried without success to adapt the interactive cubes example that uses raycaster and projector...
http://www.gioblu.com/GiO/web/solarsystem/index_backup
As you can see you can navigate in space and change camera position with right and left mouse button. I would be able to come back to initial camera position (earth in the center of the screen) with a double click on the planet.
Why didn't you had success by adapting the example? What errors are occuring? Did you mean this example?
Because raycaster and projector is the way you are looking for.
First of all you need an eventListener for the ondblclick Event on your container. In the event function you can copy&paste from the linked example:
1) Saving mouse coordinates
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
2) Project coordinates to world system via the camera and create a ray
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
3) Check if the double clicked element is your planet
var intersects = raycaster.intersectObject( "your_planet" );
if ( intersects.length > 0 ) {
reset your camera
}
Hope this helps!

Best method of scaling text to fill an HTML5 canvas

I need to 'scale' text to fill an antire HTML5 canvas. It appears that the scale() method does not affect text. I've seen approximation methods with iterative loops on the measureText() method but this doesn't get me exactly what I need. Ideally I'd like to fill both horizontally and vertically without conserving the aspect ratio. Would SVG possibly be able to help with this?
My bad - Scale DOES apply to text. I've come up with a solution:
context.font = "20px 'Segoe UI'";
var metrics = context.measureText("Testing!");
var textWidth = metrics.width;
var scalex = (canvas.width / textWidth);
var scaley = (canvas.height / 23);
var ypos = (canvas.height / (scaley * 1.25));
context.scale(scalex, scaley);
context.fillText("Testing!", 0, ypos);
Scale does affect text. Try this:
var can = document.getElementById('test');
var ctx = can.getContext('2d');
ctx.fillText("test", 10, 10); // not scaled text
ctx.scale(3,3);
ctx.fillText("test", 10, 10); // scaled text
See it in action here:
http://jsfiddle.net/3zeBk/8/

Resources