• 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!

Rotating screen changes gravity; I want player to move accordingly

M

Manyfans

Guest
Preface:

So I'm making this game where you play as a block/square that rotates around its edges when you press in the respective directions, left or right. Now, I'm adding a mechanic where you can rotate the screen by pressing W, A, or D. W rotates the screen 180 degrees, A rotates the screen 90 degrees counterclockwise, and D rotates it 90 degrees clockwise. For testing purposes, I haven't implemented the screen-rotating function just yet, but I am testing with the gravity feature. I began by creating a variable, global.angleFix, which controls the gravity. It is set to 0 by default and the gravity angle is changed respectively.

Here is a snippet of the code I'm using that controls the player:

Code:
//Left
if(keyboard_check(vk_left) && !fall)   //"fall" is whether the player is falling or not.
{
 if(place_empty(x - lengthdir_x(48, global.angleFix),
  y - lengthdir_y(48, global.angleFix)))   //This checks if a block is in the way in the direction the gravity is.
 {
  a = -1;   //Indicates that the player is moving in a positive direction for use in a later code block.
  rot -= 90;   //This sets the angle that the player will rotate to in another code block.
  ox = x - hw + 48 * ???(global.angleFix);   //X - "ox" is the origin of the x-coordinate of the player. "hw" is half the width of the block.
  oy = y + hh - 48 * ???(global.angleFix);   //Y - "oy" is the origin of the y-coordinate of the player. "hh" is half the height of the block.
  move = true;   //Makes this code unable to loop through again until the player is rested.
 }
}

//Right
else if(keyboard_check(vk_right) && !fall)   //"fall" is whether the player is falling or not.
{
 if(place_empty(x + lengthdir_x(48, global.angleFix),
  y + lengthdir_y(48, global.angleFix)))   //This checks if a block is in the way in the direction the gravity is.
 {
  a = 1;   //Indicates that the player is moving in a positive direction for use in a later code block.
  rot += 90;   //This sets the angle that the player will rotate to in another code block.
  ox = x - hw + 48 * ???(global.angleFix);   //X - "ox" is the origin of the x-coordinate of the player. "hw" is half the width of the block.
  oy = y + hh - 48 * ???(global.angleFix);   //Y - "oy" is the origin of the y-coordinate of the player. "hh" is half the height of the block.
  
  move = true;   //Makes this code unable to loop through again until the player is rested.
 }
}

There are four sets of question marks, ???, that need to either be dsin or dcos. I know where they go for each degree angle, 0, 90, 270, and 360, however there's one problem...


The issue:

I know there has to be some sort of script that can change the sine and cosine functions when the gravity is changed. I'll save you the work of trying to figure out the pattern. Here you go:

0 degrees:
Left = (sin, sin)
Right = (cos, sin)

90 degrees:
Left = (sin, cos)
Right = (sin, sin)

180 degrees:
Left = (-cos, -cos)
Right = (-sin, -cos)

270 degrees:
Left = (-cos, -sin)
Right = (-cos, -cos)

"Left" and "Right" are for the Left and Right sections of the code above, whereas the sin and cos in the parenthesis are set to the X and Y sections in the code in the format (X, Y).

Conclusion:


If anyone can help me figure this out at all, please do so; I've been working on and off with this issue for the past couple of months. Thanks!
 
S

Snail Man

Guest
There's probably a better way, but you could just have a script with a switch function inside. Make the first argument angle, the second LEFT or RIGHT (which would be constants), the third would be X or Y, also constants. Then you could just rig up a switch statement to return the correct values
 
M

Manyfans

Guest
There's probably a better way, but you could just have a script with a switch function inside. Make the first argument angle, the second LEFT or RIGHT (which would be constants), the third would be X or Y, also constants. Then you could just rig up a switch statement to return the correct values
Thanks for the reply, Snail Man! I thought about a similar concept awhile ago, but the problem I kept encountering was: what happens when the degree value for the gravity angle exceeds 360 degrees--or even goes negative? And before someone says to just use the absolute value function, it won't work; 90 degrees is equivalent to -270 degrees just as -90 is to 270. What I need is some sort of way to configure the sine and cosine functions into a repeatable pattern that would work for every positive and negative 360 degrees.
 

wamingo

Member
keep the angles between 0-360?

if (view_angle >=360) view_angle-=360;
if (view_angle < 0) view_angle+=360;
 
M

Manyfans

Guest
keep the angles between 0-360?

if (view_angle >=360) view_angle-=360;
if (view_angle < 0) view_angle+=360;
Thanks for the suggestion, wamingo! There's only one (small) issue with that: when the screen rotates, it should be "smooth", meaning that it will start slow, get faster, then progressively get slower as it reaches the desired angle; basically some mixture of multiplication and division. What happens when you try to reset the screen angle every 360 degrees is that it will have to reach exactly 360 degrees, and that will not happen if it's dividing constantly. Also, if it's rounded off, the screen will "jump" to 360 degrees, which produces an undesirable effect. I only have all this planned out because I made this game (somewhat) before. I had a nice start, however I lost the game file when I switched computers (this was before I started using cloud storage). I still have the game executable, but it's not enough (unless I can extract the code data from the data.win file, but that's a different story). The point is, I've done some of this before. I just can't remember how I did the gravity effect. I also want to make it as efficient as possible.
 
Code:
    var an = -view_angle[0] + 270;  //angle of gravity starts out pointing toward bottom of screen, hence "270"
    var str = 10;  //strength of gravity
    var xg = lengthdir_x(str, an);  //x gravity
    var yg = lengthdir_y(str, an);  //y gravity
 
B

bojack29

Guest
You know to be quite honest. And im assuming your keeping gravity the same regardless of the rotation of the view, id simply make a switch statement that analyzes the current rotation of the view and use that for that. Maybe even make four seperate scripts that handle the different rotation
 
B

bojack29

Guest
Manyfans, if you want that slow fast slow rotation you see with the screen your going to need either cosine or sine (depending on the view angle and where its going)

Say you were going for a view angle that went from 0 to 180. You could use cosine.

Code:
view_angle[0] = 90 - dcos(int_quickFlip) * 90;
if (int_quickFlip < 180){
     int_quickFlip += 10;//Fast/slow
}else{
     int_quickFlip = 180;
}
 
M

Manyfans

Guest
Thanks for all the replies, everyone. I'm pretty sure I can get the screen rotation just fine, and I have already implemented the gravity. It's just that I want to figure out how to make the player move relative to the gravity.

Here's an example of the issue at 90 degrees with the code in the original post:

It produces similar effects at different angles.
 
Top