GameMaker [solved] Barrel roll and rotating view.

T

trentallain

Guest
How do I create a barrel roll animation and rotate the view but not the player for this scenario?
In gms 1.x you could do:
Code:
d3d_transform_set_rotation_y(variable);
d3d_transform_add_translation(x,y,0);
draw_sprite(spr_card,variable_two,0,0);
d3d_transform_set_identity();
Which would basically rotate the card along the Y axis with the correct 3D perspective (while not requiring anything else 3D).

Atm I have an x-wing that moves at a constant speed and turns using "A" and "D". And also uses sprite stacking to achieve a 3D look, while staying 2D.
Create:
Code:
image_speed = 0
scale = 4

camera = camera_create_view(0,0,1920,1080,0,-1,-1,-1,0,0)
view_set_camera(0,camera)
scope_length = 200
view_width = camera_get_view_width(camera)
view_height = camera_get_view_height(camera)
view_x = camera_get_view_x(camera)
view_y = camera_get_view_y(camera)
draw_set_font(font0)
angle = 0
Draw:
Code:
for (var i = 0; i < image_number; i += 1)
{
    draw_sprite_ext(sprite_index, i, x, y - i*scale, scale, scale, angle+90, c_white, 1); //The x-wing's sprite is facing up, so I added 90.
}
Step:
Code:
speed = 10
angle += -4*sign(keyboard_check(ord("D")) - keyboard_check(ord("A")))
direction = angle
camera_aim_direction = angle

//Aiming       
view_x = camera_get_view_x(camera)
view_y = camera_get_view_y(camera)
camera_set_view_pos(camera,x + lengthdir_x(scope_length, camera_aim_direction)-view_width/2,y + lengthdir_y(scope_length, camera_aim_direction)-view_height/2)
The barrel roll: Needs to have the correct perspective in all directions. (and will rotate around an axis from its nose to rear in the center.)

The rotating view: The player's ship would not be rotated, so that the ship is always facing up. Any other object that uses sprite stacking (such as other ships) will also need to be at the same perspective as the x-wing (A 3/4 or overhead view - same as the x-wing). I have a feeling transformation matrices would be used here so that they are at the correct positions - I'm probably wrong here and it will have nothing to do with it, but I have no experience with them.

Link to a diagram of what I mean with barrel rolling:
https://drive.google.com/open?id=1Po1odmyVzhMR7tsbWv0W-hAWiVK1lExM

Links to the rotating view effect (as well as stacking sprites for a 3D effect):
https://gfycat.com/ConsciousZanyArmedcrab and https://www.reddit.com/r/gamedev/comments/57x7n3/really_cool_fake_3d_in_gamemaker_by_the_creator/
 
So every ship in the game would simultaneously need to do a barrel roll? Otherwise what you are going to see is all the other ships suddenly turn into a bunch of lines, disappear for a split second, and then reconstitute back to normal. Plus a camera roll will seem odd if everything in your world is contained within a 2d plane. Maybe I'm not understanding what it is you are trying to do.
 
T

trentallain

Guest
So every ship in the game would simultaneously need to do a barrel roll? Otherwise what you are going to see is all the other ships suddenly turn into a bunch of lines, disappear for a split second, and then reconstitute back to normal. Plus a camera roll will seem odd if everything in your world is contained within a 2d plane. Maybe I'm not understanding what it is you are trying to do.
The barrel roll and rotating view are separate. I just thought it would be a bit similar because of perspective etc.
 
Well you can try it and see what happens. So explain exactly how you want the camera to move. Wait, okay. The camera movement doesn't have anything to do with the barrel roll. You just want the ship to face upward on the screen.
 
T

trentallain

Guest
Well you can try it and see what happens. So explain exactly how you want the camera to move. Wait, okay. The camera movement doesn't have anything to do with the barrel roll. You just want the ship to face upward on the screen.
Yeah hahah. Also the ship wouldn't disappear because it would barrel roll pretty fast and skip the two "invisible" angles
 

TheSnidr

Heavy metal viking dentist
GMC Elder
The sliced model technique only works for models seen from above. If you want your model to rotate around other axes than the z axis, you're better off using models. Actually, you're better off using models than that technique at all, since it requires more draw calls and thus is significantly slower.
 
T

trentallain

Guest
The sliced model technique only works for models seen from above. If you want your model to rotate around other axes than the z axis, you're better off using models. Actually, you're better off using models than that technique at all, since it requires more draw calls and thus is significantly slower.
Is there a way to use this code in GMS2 though, I thought it actually works pretty good?
Code:
d3d_transform_set_rotation_y(variable);
d3d_transform_add_translation(x,y,0);
draw_sprite(spr_card,variable_two,0,0);
d3d_transform_set_identity();

Since I only have 2 objects that would potentially be using the stacked sprite method I don't think that would use too much processing power. I could always do 3D, because I did make voxel models and then used the converter but I have no experience with that.
 

TheSnidr

Heavy metal viking dentist
GMC Elder
The d3d functions have been deprecated, so you're left with the matrix functions - which actually gives you more freedom than the old d3d functions did!
If you want to rotate around the y-axis, you can do something like this:
matris_set(matrix_world, matrix_build(x, y, z, 0, variable, 0, 1, 1, 1))

Edit: Just remember to reset the world matrix afterwards by building an identity matrix ;)
 
T

trentallain

Guest
The d3d functions have been deprecated, so you're left with the matrix functions - which actually gives you more freedom than the old d3d functions did!
If you want to rotate around the y-axis, you can do something like this:
matris_set(matrix_world, matrix_build(x, y, z, 0, variable, 0, 1, 1, 1))

Edit: Just remember to reset the world matrix afterwards by building an identity matrix ;)
Okay cool, thanks lots. I'll try both
 
T

trentallain

Guest
The d3d functions have been deprecated, so you're left with the matrix functions - which actually gives you more freedom than the old d3d functions did!
If you want to rotate around the y-axis, you can do something like this:
matris_set(matrix_world, matrix_build(x, y, z, 0, variable, 0, 1, 1, 1))

Edit: Just remember to reset the world matrix afterwards by building an identity matrix ;)
Would I use the matrix functions or view_angle for rotating the camera in my second question?
 
T

trentallain

Guest
The d3d functions have been deprecated, so you're left with the matrix functions - which actually gives you more freedom than the old d3d functions did!
If you want to rotate around the y-axis, you can do something like this:
matris_set(matrix_world, matrix_build(x, y, z, 0, variable, 0, 1, 1, 1))

Edit: Just remember to reset the world matrix afterwards by building an identity matrix ;)
So to reset it would I do matrix_set(matrix_world,matrix_build(x,y,z,0,0,0,1,1,1))
 
T

trentallain

Guest
Almost! The coordinates should all be 0 as well. Alternatively you could use matrix_build_identity()
matrix_set(matrix_world, matrix_build(x, y, 0, 0, rotation, 0, 1, 1, 1))
for (var i = 0; i < image_number; i += 1)
{
draw_sprite_ext(sprite_index, i, x, y - i*scale, scale, scale, angle+90, c_white, 1);
}
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1))
I have no idea what I'm doing...
 
T

trentallain

Guest
That looks correct, this code does the same as the one you posted earlier from 1.4 ;)
But it doesn't work? Nothing is being displayed (nothing else is being drawn currently so its not a depth issue)
 
Last edited:

TheSnidr

Heavy metal viking dentist
GMC Elder
Oh, you're adding coordinates twice. Remove the coordinates from either the matrix build function or the draw function
 
T

trentallain

Guest
Oh, you're adding coordinates twice. Remove the coordinates from either the matrix build function or the draw function
Okay that worked kind of. Its not rotating around its center though.
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, rotation, 0, 1, 1, 1))
for (var i = 0; i < image_number; i += 1)
{
draw_sprite_ext(sprite_index, i, x, y - i*scale, scale, scale, angle+90, c_white, 1);
}
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1))
 

TheSnidr

Heavy metal viking dentist
GMC Elder
Then you should rather keep the coordinates in the matrix build function than in the draw function! The coordinates in the matrix build are added after rotation, whereas the coordinates in the draw functions are added after - so the position is also rotated!
 
T

trentallain

Guest
Then you should rather keep the coordinates in the matrix build function than in the draw function! The coordinates in the matrix build are added after rotation, whereas the coordinates in the draw functions are added after - so the position is also rotated!
Could you please show me what you mean? I tried this:

matrix_set(matrix_world, matrix_build(x, y, 0, 0, rotation, 0, 1, 1, 1))
for (var i = 0; i < image_number; i += 1)
{
draw_sprite_ext(sprite_index, i, 0, 0 - i*scale, scale, scale, angle+90, c_white, 1);
}
matrix_set(matrix_world, matrix_build(x, y, 0, 0, 0, 0, 1, 1, 1))

But that didn't draw anything (at least where I could see it)
 
T

trentallain

Guest
Then you should rather keep the coordinates in the matrix build function than in the draw function! The coordinates in the matrix build are added after rotation, whereas the coordinates in the draw functions are added after - so the position is also rotated!
An example would be great btw haha
 
T

trentallain

Guest
Then you should rather keep the coordinates in the matrix build function than in the draw function! The coordinates in the matrix build are added after rotation, whereas the coordinates in the draw functions are added after - so the position is also rotated!
I got it working by doing:
Code:
matrix_set(matrix_world, matrix_build(x, y, 0, 0, rotation, 0, 1, 1, 1))
if rotation < 90 || rotation > 270
{
    for (var i = 0; i < image_number; i += 1)
    {
        draw_sprite_ext(sprite_index, i, 0, 0 - i*scale, scale, scale, angle+90, c_white, 1);
    }
}
else
{
    for (var i = image_number; i > 0; i -= 1)
    {
        draw_sprite_ext(sprite_index, i, 0, 0 - i*scale, scale, scale, angle+90, c_white, 1);
    }
}
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1))

draw_set_colour(c_white)
draw_text(x,y,rotation)
Yeah it doesn't really look that great. How would I draw a 3D model instead (so it would look like what it was before with the perspective, just actually 3D)? Btw, its a .obj with .mtl and .png file for its colours.
 
Last edited:
T

trentallain

Guest
I found a way to do the barrel roll:
What I did was instead of getting the layer sprites from the ship from the normal position, I put it on its end to get the layers, so the rotation occurs along the correct axis.
 
Top