• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM What's the best wat to use multiple views in a room?

C

Ceymoonie

Guest
*way
I'm trying to use views of different sizes in my room, and smoothly zoom in on them.
Like this, but not instantaneous:
gif

My idea was to use stretched objects to mark the different views, like this:

But I only managed to make it kinda work when the player is moving forward:
gif
Using these codes:
oPlayer step event:
Code:
///Increase view.
var xdir=0,ydir=1,inview=0;

viewincrease=nearest_instance(oViewIncrease,96);

if instance_exists(viewincrease){

if viewincrease.x>view_xview{
xdir=1;}
if viewincrease.x<view_xview{
xdir=-1;}
if viewincrease.y>view_yview{
ydir=1;}
if viewincrease.y<view_yview{
ydir=-1;}


if (x>viewincrease.x && x<viewincrease.x+viewincrease.image_xscale*12 && y>viewincrease.y && y<viewincrease.y+viewincrease.image_yscale*12){
inview=1;}
else{
inview=0;}
if inview or !distance_to_point(viewincrease.x,y)>0{
goalhview+=(viewincrease.image_yscale*12-goalhview)*.1;
view_yview+=(viewincrease.y-view_yview)*.1;}
else if phy_position_x!=phy_position_xprevious or phy_position_y!=phy_position_yprevious{
goalhview+=(viewincrease.image_yscale*12-goalhview)*(1/(distance_to_point(viewincrease.x,y)))*xdir;
view_yview+=(viewincrease.y-view_yview)*(1/(distance_to_point(viewincrease.x,y)))*ydir;}

}

view_xview+=(oPlayer.x-view_xview-(view_wview/2))*.2;
view_hview+=(goalhview-view_hview)*.2;
view_wview=view_hview/0.5625;
Script:
Code:
///nearest_instance(object, max distance)
//returns the instance whose mask is closest to the mask of the object that calls this function, within the given distance
//returns noone if theres no instance within the given distance


var _smallest_distance = argument1;
var _nearest_instance = noone;
with argument0 {
    var _dist = distance_to_object(other);
    if _dist < _smallest_distance {
        _smallest_distance = _dist;
        _nearest_instance = id;
    };
};

return _nearest_instance;
I really have no idea what to do next, can somebody please help me out?
 
Last edited by a moderator:

TehCupcakes

Member
Why are you using multiple views if you are only displaying one at a time? It seems to me that you could circumvent this issue by simply having a single view that adapts its zoom size based on "regions". Each region would have a zoom value for when the player is perfectly centered in the region, then as the player moves towards the edge it would calculate the difference between the region they are in and the other region they are closest to. So for example, if regionA had a zoom of 3 and regionB had a zoom of 5; then when the player is moving from A to B and standing at the border between them it would have a zoom of 4, and gradually increase to 5 as the player continues to move towards the center of regionB.

This might just be semantics, and the math is basically the same... But I think it would be easier to work with objects.

All in all, I think you're pretty close, but it looks your view_yview keeps adding even when you're moving backwards... It should be able to add or subtract relative to the player's x position in the current region. That is, if you are on the far left side it should always be moving in the direction of the previous region, whereas on the right side it moves in the direction of the next region.
 
C

Ceymoonie

Guest
Why are you using multiple views if you are only displaying one at a time?
Thanks, but I'm currently already using only one view (I should've made that more clear). And I'm pretty much doing what you're describing here, but I can't find the right way to calculate the difference between the current view height and the height of the upcoming view object.
 

TehCupcakes

Member
Ok, so assuming both areas are objects and you're able to find which one is the current and which is upcoming...

Code:
height_diff = current_region.sprite_height*image_yscale - next_region.sprite_height*image_yscale;

//Assuming origin is at the upper-left corner of the region object's sprite
region_width = current_region.sprite_width*image_xscale;
height_adjust_percent = 0.5;
//Prevent division by 0
if(current_region.x - player.x != 0)
{
    height_adjust_percent += ((current_region.x - player.x) / (region_width / 2) * 0.5);
}
height_adjust = height_diff * height_adjust_percent;

view_hview[view_current] = current_region.sprite_height*image_yscale + height_adjust;
view_yview[view_current] = player.y - (view_hview[view_current] / 2);
Untested. There are some unnecessary parentheses that I included, but I think it makes it more apparent what pieces of logic are grouped together. Let me explain a little bit...

By grabbing the difference between the current and the "next" region's height, you can determine the range by which the height must adjust. Since the border between two regions is the midpoint where it should be halfway between each region's height, we will always multiply the height difference between the two by at least 0.5. Then, the closer the player is to the center of the region, the higher the percentage, up to 1.0 when the player is at the exact center. (Since we are getting from/to the center, that is why we divide the region_width by 2.) This is basically like a weighted average where the current view is more heavily weighted, ranging between 50% and 100% based on how close they are to the center. Finally, adjust the view's height based on the values we found, and center the view on the player.

Hope this works, or at least helps you get closer to what you wish to achieve. :)
 
C

Ceymoonie

Guest
Ok, so assuming both areas are objects and you're able to find which one is the current and which is upcoming...
Untested. There are some unnecessary parentheses that I included, but I think it makes it more apparent what pieces of logic are grouped together. Let me explain a little bit...

By grabbing the difference between the current and the "next" region's height, you can determine the range by which the height must adjust. Since the border between two regions is the midpoint where it should be halfway between each region's height, we will always multiply the height difference between the two by at least 0.5. Then, the closer the player is to the center of the region, the higher the percentage, up to 1.0 when the player is at the exact center. (Since we are getting from/to the center, that is why we divide the region_width by 2.) This is basically like a weighted average where the current view is more heavily weighted, ranging between 50% and 100% based on how close they are to the center. Finally, adjust the view's height based on the values we found, and center the view on the player.

Hope this works, or at least helps you get closer to what you wish to achieve. :)
Thanks, but I think I'm doing something wrong. This is in the step event of the player:
Code:
///View.
view_xview+=(oPlayer.x-view_xview-(view_wview/2))*.2;

var current_region=place_meeting(x,y,oViewDeactivated);
var next_region=nearest_instance(oView,9999);
var height_diff = current_region.sprite_height - next_region.sprite_height;
var height_adjust_percent = 0.5;
var region_width=view_hview/0.5625;
if(current_region.x - oPlayer.x != 0){
height_adjust_percent += ((current_region.x - oPlayer.x) / (region_width / 2) * 0.5);}
var height_adjust = height_diff * height_adjust_percent;

view_hview[0] = current_region.sprite_height + height_adjust;
view_yview[0] = oPlayer.y - (view_hview[view_current] / 2);
And this is the result:
gif
gmz
 
Top