So, I have this math issue giving me a problem.
My variable "Facing" returns the character's facing direction. (1,2,3,4 is Right,Down,Left,Up respectively)
I need the character to slowly rotate to face that direction in 90 degree angles. This is adequately accomplished using this portion of the code:
If LEFTKEY()=1 AND hold=0 THEN facing=WRAP(facing-1,1,4) : hold=1
If RIGHTKEY()=1 AND hold=0 THEN facing=WRAP(facing+1,1,4) : hold=1
ang=ang_regulate(ang,facing*90,1)
ROTATE OBJECT 1,0,ang,0
IF LEFTKEY()+RIGHTKEY()+UPKEY()=0 THEN hold=0
FUNCTION ang_regulate(a,b,s)
IF (b-a)>180 THEN b=b-360
FOR c=1 TO s
IF (b-a)>0 THEN INC a
IF (b-a)<0 THEN DEC a
NEXT c
ENDFUNCTION a
The problem is, since the object's angle is dependent on facing, the rotation flips the wrong way when it crosses 4, that is to say, it will always rotate correctly except turning from right to up or vice-versa. I thought "IF (b-a)>180 THEN INC b,360" would fix it but it effectively does nothing. That's when I implemented "IF (b-a)>180 THEN b=b-360". Now it can turn TO 4 correctly, but turning from 1 to 4 still messes up, and it returns negative angles (which is perfectly fine, I just don't want to get angle numbers that are too large.)
Here's the rest of the code so you can all test it.
TYPE entity
is_player AS BOOLEAN
is_mobile AS BOOLEAN
entid AS BYTE
curr_x AS INTEGER
curr_y AS INTEGER
loc_x AS INTEGER
loc_y AS INTEGER
grid_x AS INTEGER
grid_y AS INTEGER
ENDTYPE
DIM map(49,49,3)
DIM ent(4) AS entity
IF FILE EXIST("Test.flr")
LOAD ARRAY "Test.flr",map()
ENDIF
create_player(0)
create_floor()
DO
IF UPKEY()=1 AND hold=0
SELECT facing
CASE 1
ent(0).grid_x=ent(0).grid_x+1
ENDCASE
CASE 2
ent(0).grid_y=ent(0).grid_y-1
ENDCASE
CASE 3
ent(0).grid_x=ent(0).grid_x-1
ENDCASE
CASE 4
ent(0).grid_y=ent(0).grid_y+1
ENDCASE
ENDSELECT
hold=1
ENDIF
If LEFTKEY()=1 AND hold=0 THEN facing=WRAP(facing-1,1,4) : hold=1
If RIGHTKEY()=1 AND hold=0 THEN facing=WRAP(facing+1,1,4) : hold=1
ang=ang_regulate(ang,facing*90,1)
ROTATE OBJECT 1,0,ang,0
IF LEFTKEY()+RIGHTKEY()+UPKEY()=0 THEN hold=0
SET CURSOR 0,0
PRINT STR$(facing)
PRINT STR$(ang)
//Object Angle
aY# = Object angle Y(1)
//Get Camera Position
cZ# = NEWZVALUE(ent(0).curr_y,aY#-180,100)
cX# = NEWXVALUE(ent(0).curr_x,aY#-180,100)
//Position Camera And Point At Player
POSITION CAMERA cX#,100,cZ#
POINT CAMERA ent(0).curr_x,50,ent(0).curr_y
POSITION OBJECT 1,ent(0).curr_x,10,ent(0).curr_y
ent(0).curr_x=num_regulate(ent(0).curr_x,ent(0).loc_x,1)
ent(0).curr_y=num_regulate(ent(0).curr_y,ent(0).loc_y,1)
ent(0).loc_x=(ent(0).grid_x*100)+50
ent(0).loc_y=(ent(0).grid_y*100)+50
IF SHIFTKEY()=1 AND SPACEKEY()=1 THEN END
LOOP
END
FUNCTION create_player(x)
ent(x).is_player=1
ent(x).entid=0
ent(x).curr_x=20
ent(x).curr_y=20
ent(x).loc_x=0
ent(x).loc_y=0
ent(x).grid_x=1
ent(x).grid_y=1
MAKE OBJECT SPHERE 1,50
COLOR OBJECT 1,RGB(60,0,0)
ENDFUNCTION
FUNCTION create_floor()
MAKE MATRIX 1,1600,1600,16,16
ENDFUNCTION
FUNCTION num_regulate(a,b,s)
FOR c=1 TO s
IF b>a THEN INC a
IF b<a THEN DEC a
NEXT c
ENDFUNCTION a
FUNCTION ang_regulate(a,b,s)
IF (b-a)>180 THEN b=b-360
FOR c=1 TO s
IF (b-a)>0 THEN INC a
IF (b-a)<0 THEN DEC a
NEXT c
ENDFUNCTION a
FUNCTION num_trim(value,vfloor,vceiling)
IF value>vceiling THEN value=vceiling
IF value<vfloor THEN value=vfloor
ENDFUNCTION value