GameMaker Split screen but one view is rotated.

Coded Games

Member
Ok so I'm trying to do this fairly complicated split screen effect where I have one view on top of another. The view on top needs to be rotated so that the bottom edge of the view forms a diagonal line across the main view (view0). See whiteboard diagram:



Along with that, I want the content of each view to be the proper orientation, so -y is up in both and +x is right. So I need to rotate the camera itself, and rotate the entire view.

The current way I am doing this is by sending the content of view1 to a surface and drawing the surface in the desired position and rotation.

The issue I am running into is I never seem to get the angles right because everything rotates around a different point. Surfaces rotate around the top left corner so I need to compensate for that when I position the surface and then I'm not even sure what the view itself is rotating around. I hope it is the center as I have the view follow an object.

Here is my code so far:

Create event:
Code:
var ww = camera_get_view_width(view_camera[0]);
var hh = camera_get_view_height(view_camera[0]);
view_camera[1] = camera_create_view(x, y, ww, hh, 0, core, -1, -1, ww, hh);
view_set_visible(1, true);

viewSurface = -1;
Step Event:
Code:
var aa = point_direction(obj_player.x, obj_player.y, core.x, core.y);
camera_set_view_angle(view_camera[1], aa);
Draw Event:
Code:
if (view_current == 0) {
    if (!surface_exists(viewSurface)) {
        viewSurface = surface_create(camera_get_view_width(view_camera[1]), camera_get_view_height(view_camera[1]));
        view_surface_id[1] = viewSurface;
    }
  
    if (surface_exists(viewSurface)) {
        var aa = point_direction(obj_player.x, obj_player.y, core.x, core.y);
        var ww = surface_get_width(viewSurface);
        var hh = surface_get_height(viewSurface);
      
        var xx = obj_camera.x + lengthdir_x(ww / 2, -aa + 90) + lengthdir_x(hh, -aa);
        var yy = obj_camera.y + lengthdir_y(ww / 2, -aa + 90) + lengthdir_y(hh, -aa);
        draw_surface_ext(viewSurface, xx, yy, 1, 1, -aa, c_white, 1);
    }
}
The issue obviously lies in the aa variable. I keep trying to flip them, add 90, add 180 but every time I get the position of the view right, the angle of the view itself is incorrect, or the entire view is rotated 180. I feel like I must be doing something wrong here. Any help would be really appreciated.
 
It's not going to look nice, because essentially you'll be interpolating twice. Once when drawing to the view, and another time when drawing the view's surface.

Anyway, this was written in gms1, so appologies, you'll need to substitute with the cooresponding gms2 keywords or functions.

If "center_x" and "center_y" is the world location of the center of your view. And "_angle" is the angle at which you rotate your surface. Then the angle of the view should be "-_angle".

"view_xview[0]", and "view_yview[0]" is the world location of the view. "view_wview[0]" and "view_hview[0]" are the width and height of the view (not the port).

I'm assuming the surface will NOT be scaled, or else further math will be needed.

Code:
view_angle[0] = -angle;
var _c = dcos(angle);
var _s = dsin(angle);
view_xview[0] = center_x + _c*view_wview[0]/2 + _s* view_hview[0]/2 - view_wview[0];
view_yview[0] = center_y - _s*view_wview[0]/2 + _c* view_hview[0]/2 - view_hview[0];
EDIT: Corrected a mistake in code block.

But nice job asking a question I've never seen before.

By the way, you were close to a correct solution, you just mixed up lengthdir_x and lengthdir_y in a certain way.
 
Last edited:

Coded Games

Member
@flyingsaucerinvasion Thanks! I got the position of the surface correct now and scaled properly. As for interpolation I'm not really worried about it, my game uses high resolution assets.

The problem now is that the position of view1 isn't correct. I want it to be centered on an object but when I rotate the view, to match the rotation of the surface, position gets messed up. Unfortunately I can't tell what point the view rotates around (is it top left and why doesn't the manual say this?). Along with that the surface's transparency isn't right, it's transparent in places. I'm pretty sure I've had this problem before and don't remember how to fix it.

Here is what it currently looks like:


The next question also: is there a way to have only certain layers render to a view without having to go to EVERY object's draw event and put this:

Code:
if (view_current == 1) exit;
 
Transparency issues are going to be caused if you are drawing not fully opaque things to your surface. There are two ways to deal with this problem. Probably you intend your surface should remain fully opaque, then you can just disable drawing to the alpha channel while drawing to that surface. Use gpu_set_colorwriteenable(). Look it up before you try to use it.

In gms1, the view definitely rotates around its current center location. I suppose it is possible that the situation is different in gms2, but I doubt it.

If you still aren't getting the view to position correctly, show your code, and we'll try to spot what the current problem is.
 
Wait hold up.... The way I was originally interpreting your question was that you wanted things inside of your view to appear stationary while your view was rotating. Am I mistaken about that?
 
Really sorry for positing three replies in a row. But I want to be sure that you are notified of this message.

There was a mistake in my original response that I would have caught if I had tested it correctly.

Assuming I am interpreting your question accurately, the correct method should be:

Code:
view_xview[0] = center_x + _c*view_wview[0]/2 + _s* view_hview[0]/2 - view_wview[0];
view_yview[0] = center_y - _s*view_wview[0]/2 + _c* view_hview[0]/2 - view_hview[0];
 
Last edited:

Coded Games

Member
Ok I'm stuck once again. I tried you code but can't seem to get it to work. Here is what I got, all that is left is that I want centerX and centerY to be in the center of my rotated view:

Code:
var aa = point_direction(obj_player.x, obj_player.y, core.x, core.y);
var ww = max(core.sprite_width * 3, 64);
var hh = max(core.sprite_height * 3, 64);
camera_set_view_size(view_camera[1], ww, hh);

var viewAngle = -aa + 90;
var centerX = core.x;
var centerY = core.y;

var xx = centerX + lengthdir_x(ww / 2, viewAngle) + lengthdir_x(hh / 2, viewAngle - 90); 
var yy = centerY + lengthdir_y(ww / 2, viewAngle) + lengthdir_y(hh / 2, viewAngle - 90);

camera_set_view_angle(view_camera[1], viewAngle); 
camera_set_view_pos(view_camera[1], xx, yy);
 
Top