Gamestudio Links
Zorro Links
Newest Posts
Blobsculptor tools and objects download here
by NeoDumont. 03/28/24 03:01
Issue with Multi-Core WFO Training
by aliswee. 03/24/24 20:20
Why Zorro supports up to 72 cores?
by Edgar_Herrera. 03/23/24 21:41
Zorro Trader GPT
by TipmyPip. 03/06/24 09:27
VSCode instead of SED
by 3run. 03/01/24 19:06
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, Imhotep), 567 guests, and 4 spiders.
Key: Admin, Global Mod, Mod
Newest Members
sakolin, rajesh7827, juergen_wue, NITRO_FOREVER, jack0roses
19043 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
wanted to share my working player/camera control action C++ app #474485
10/19/18 04:35
10/19/18 04:35
Joined: Oct 2018
Posts: 1
Ha Noi
H
hoangnganvy1993 Offline OP
Guest
hoangnganvy1993  Offline OP
Guest
H

Joined: Oct 2018
Posts: 1
Ha Noi
I've never seen anyone compile a working example of all the major problem areas faced by beginners such as myself.
Namely, camera control, player control, animation and trigonometry. So now That I've met all my milestones with this little prototype, I'm quite pleased to share my code in its complete form more accurately illustrating(i hope) the ways these things can be successfully implemented.

I wish I'd have had something like this, well.. when I started making this. I hope it demonstrates well enough for some other people like me to overcome some of their theory obstacles.

I wrote this in C++ using the engine SDK (not making a dll).
It spawns a wmb with a terrain entity and a playermodel entity. real simple stuff. it assigns the function playercode to the player entity and tells the engine to hit it every frame (just like an action). Thats where the simple stuff ends.

The player code action/function seizes control of the camera, puts the camera behind the player a bit above it very 3rd person mmo looking. it follows the players position,height, pan,etc... if you click and hold the left mouse button, you get free cam mode orbiting the player with full 360 rotation along the x axis and about 100 degrees up and down tilt. letting go lets the camera drift smoothly back to its default position. holding down the right mouse button lets you control the players pan with mouse_force.x with the camera following along of course, holding both left and right makes the player move forward,play walk animation and still control the pan AND STILL move the cam freely as before. Of course, all that can be changed to fit the particular your application's needs for any variation of those effects.

scrolling the mouse wheel doesnt zoom by changing the camera.arc anymore (basically narrowing and widening the focal width) but rather increments and decrements the camera distance playerskill by small intervals. since the camera distance playerskill value is directly implemented into the orbit/rotation formula it fits beautifully and works perfectly to provide a realistic and smooth zooming effect without altering the focal width but by actually moving the camera along intermittent orbit tracks.
Gravity also works.

oh yea... w,s forward,back a,d turn left,right


ESC = sys_exit

Code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "adll.h" // Include the engine data types, variables, and functions
#include "mtlFX.h"


//Prototypes
var rad2deg(float radians);
float deg2rad(var degrees);
var abz(var val);
//Globals

ENTITY* terrain1;
ENTITY* playermodel;
ENTITY* skycube;
BMAP* mcursor;
TEXT* tDebug;
PANEL* pDebug;




var abz(var val) {
var retval;
if (val >= _VAR(0)) { return val; }
retval = _VAR(0) - val;
return retval;
}


float deg2rad(var degrees) {
float deg2rad = (float)(degrees / 57.29578);
return deg2rad;
}



var rad2deg(float radians) {
var rad2deg = _VAR(radians * 57.29578);
return rad2deg;
}


//Function Definitions

void player_code() {
ENTITY *my;
my =(ENTITY *)ev->me;
ev->player = my; // I'm the player
VECTOR* move_vec =_vec(0,0,0);
VECTOR* temp_vec =_vec(0,0,0);
var distance_to_ground;

//Calculate Movement
move_vec->x = (v(key_w) - v(key_s))* 0.015 * v(time_step); // move player on x axis
move_vec->y = 0;//(v(key_a) - v(key_d)) * 0.025 *v(time_step); // move player on y axis
my->pan-= (v(key_d) - v(key_a)) * 0.02 * v(time_step);

//Read Forces
if (v(mouse_left)) {
my->skill[0] += (v(mouse_force).x * 0.02 * v(time_step));
my->skill[6] += (v(mouse_force).y * 0.02 * v(time_step));
if ( my->skill[0] < _VAR(-360) ) { my->skill[0] += _VAR(360); }
if ( my->skill[0] > _VAR(360) ) { my->skill[0] -= _VAR(360); }
if ( my->skill[6] <= _VAR(-89) ) { my->skill[6] = _VAR(-90); }
if ( my->skill[6] >= _VAR(9) ) { my->skill[6] = _VAR(10); }
} else {
if (my->skill[0] < _VAR(0)) { my->skill[0]+= 3 * v(time_step); }
if (my->skill[0] > _VAR(0)) { my->skill[0]-= 3 * v(time_step); }
if (my->skill[0] > _VAR(-1) && my->skill[0] < _VAR(1) ) { my->skill[0]=0; }
if (my->skill[6] < _VAR(-61)) { my->skill[6]+= 3 * v(time_step); }
if (my->skill[6] > _VAR(-59)) { my->skill[6]-= 3 * v(time_step); }
if (my->skill[6] < _VAR(-61) && my->skill[6] > _VAR(-59) ) { my->skill[6]=-60; }
}
if (v(mouse_right)) {
my->pan-= v(mouse_force).x * 0.02 * v(time_step);
if( v(mouse_left) ){
move_vec->x = _VAR(2) * 0.015 * v(time_step); // move player on x axis
}
}
my->skill[3] -=v(mickey).z*0.0001; //Calc Zoom Distance

//Calculate Z Axis Gravity And Move Player
vec_set(temp_vec,(VECTOR*)&my->x);
temp_vec->z -= _VAR(5000); //Set to 5000 below player
distance_to_ground = c_trace((VECTOR*)&my->x,temp_vec, _VAR(IGNORE_ME | USE_BOX));
if (distance_to_ground != 0) {
move_vec->z = -(distance_to_ground - _VAR(25));
move_vec->z = maxv(_VAR(-35) * v(time_step),move_vec->z);
}
c_move(me,move_vec,_vec(0,0,0),GLIDE); // function to actually move player, with GLIDE collision

//Animate As Needed
if (v(key_w) == OFF && v(key_s) == OFF) {
if(v(mouse_left) && v(mouse_right)){
ent_animate(my, "Walka", my->skill[5], ANM_CYCLE);
} else {
ent_animate(my, "Standa", my->skill[5], ANM_CYCLE);
}
} else {
ent_animate(my, "Walka", my->skill[5], ANM_CYCLE);
}
my->skill[5] += 6 * v(time_step);
my->skill[5] = my->skill[5]%_VAR(100);

//Move The Camera
if (abz(my->skill[0]) >= _VAR(0) && abz(my->skill[0]) < _VAR(90)) {
vec_set((VECTOR*)&v(camera).x,vector(my->x -(my->skill[3] * cosv(my->pan + my->skill[0])),my->y -(my->skill[3] * sinv(my->pan + my->skill[0])),my->z+_VAR(my->skill[4])));
} else if (abz(my->skill[0]) > _VAR(90) && abz(my->skill[0]) < _VAR(180)) {
vec_set((VECTOR*)&v(camera).x,vector(my->x -(my->skill[3] * -cosv(_VAR(180)-(my->pan + my->skill[0]))),my->y -(my->skill[3] * sinv(_VAR(180)-(my->pan + my->skill[0]))),my->z+_VAR(my->skill[4])));
} else if (abz(my->skill[0]) > _VAR(180) && abz(my->skill[0]) < _VAR(270)) {
vec_set((VECTOR*)&v(camera).x,vector(my->x -(my->skill[3] * -cosv(_VAR(180)-(my->pan + my->skill[0]))),my->y -(my->skill[3] * sinv(_VAR(180)-(my->pan + my->skill[0]))),my->z+_VAR(my->skill[4])));
} else if (abz(my->skill[0]) > _VAR(270) && abz(my->skill[0]) < _VAR(360)) {
vec_set((VECTOR*)&v(camera).x,vector(my->x -(my->skill[3] * cosv(my->pan + my->skill[0])),my->y -(my->skill[3] * sinv(my->pan + my->skill[0])),my->z+_VAR(my->skill[4])));
}

if (my->skill[6] < _VAR(0) && my->skill[6] > _VAR(-90)) {
v(camera).z=my->z - my->skill[4] * sinv(my->tilt + my->skill[6]);
} else if (my->skill[6] > _VAR(0) && my->skill[6] < _VAR(90)) {
v(camera).z=my->z - my->skill[4] * sinv(_VAR(180)-(my->tilt + my->skill[6]));
}
//Keep Eye On Player After Moving
vec_set(temp_vec,(VECTOR*)&my->x);
vec_sub(temp_vec,(VECTOR*)&v(camera).x);
temp_vec->z+=40;
vec_to_angle((ANGLE*)&v(camera).pan,temp_vec);

}

//WINMAIN!!!OMFGZ!!!
// application instance handle, // always zero // application command line // window flags
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) {
ev = engine_open(NULL);
if (!ev) return 1; // acknex.dll not found

//Add Content Folders Paths
add_folder("terrains");
add_folder("images");
add_folder("models");
add_folder("code");
level_load("dh.wmb");
engine_frame();

//Initialize The Graphics Environment
video_set(_VAR(1280),_VAR(1024),_VAR(32),_VAR(0));

//Setup The Worldscape
terrain1 = ent_for_name("terrain0x0");
playermodel = ent_for_name("playermodel"); //These two are placed in the level by wed. This will change. Maybe. I hate wed.

//Ready The Player
playermodel->x=0;
playermodel->y=0;
playermodel->z=_VAR(550);
//Init player skills
playermodel->skill[0] = 0; //thetax
playermodel->skill[1] = 0; //tempforcex
playermodel->skill[2] = 0; //tempforcey
playermodel->skill[3] = 180; //Camera Distance
playermodel->skill[4] = 70; //Camera Height
playermodel->skill[5] = 0; //Player Animation Percent
playermodel->skill[6] = -60; //thetay
playermodel->event=(EVENT)player_code;
playermodel->emask |= DYNAMIC;
playermodel->emask |= ENABLE_FRAME;

//Wait for the player to materialize
while(ev->player == NULL) { engine_frame(); }

//Move Camera to Player And Look at the fucker
vec_set((VECTOR*)&v(camera).x,_vec(-180,0,70));
vec_rotate((VECTOR*)&v(camera).x,(ANGLE*)&v(player).pan);
vec_add((VECTOR*)&v(camera).x,(VECTOR*)&v(player).x);
v(camera).pan = v(player).pan;

//Stall For A Frame (add more if ur compy sux0rz)
engine_frame();

//Make a Pretty Sky
skycube = (ENTITY *)ent_createlayer("skycube+6.tga", _VAR(SKY | CUBE | VISIBLE), _VAR(0));

//Bring Up The Mouse
mcursor = bmap_create("brokenarrow.pcx");
ev->mouse_map = mcursor;
v(mouse_mode)=2;

//GUI time
tDebug = txt_create(_VAR(5),_VAR(1));
tDebug->pos_x = _VAR(200);
tDebug->pos_y = _VAR(200);
tDebug->flags |= VISIBLE;
pDebug = pan_create("digits(0,10,"TEMPFORCEX: ",*,0,NULL);
digits(70,10,4,*,1,player.skill2);
digits(0,20,"TEMPFORCEY: ",*,0,NULL);
digits(70,20,4,*,1,player.skill3);
digits(140,10,"THETA X: ",*,0,NULL);
digits(230,10,4,*,1,player.skill1);
digits(310,10,"THETA Y: ",*,0,NULL);
digits(410,10,4,*,1,player.skill7);
digits(140,20,"Camera Distance: ",*,0,NULL);
digits(230,20,4,*,1,player.skill4);
digits(140,30,"Camera Height: ",*,0,NULL);
digits(230,30,4,*,1,player.skill5);
digits(0,40,"PLAYER X: ",*,0,NULL);
digits(70,40,4,*,1,player.x);
digits(0,50,"PLAYER Y: ",*,0,NULL);
digits(70,50,4,*,1,player.y);
digits(0,60,"PLAYER Z: ",*,0,NULL);
digits(70,60,4,*,1,player.z);
digits(140,40,"Camera X: ",*,0,NULL);
digits(230,40,4,*,1,camera.x);
digits(140,50,"Camera Y: ",*,0,NULL);
digits(230,50,4,*,1,camera.y);
digits(140,60,"Camera Z: ",*,0,NULL);
digits(230,60,4,*,1,camera.z);
digits(140,120,"AnimPercent: ",*,0,NULL);
digits(230,120,4,*,1,player.skill6);
digits(0,90,"MOUSELEFT: ",*,0,NULL);
digits(70,90,4,*,1,mouse_left);
digits(0,100,"MOUSERIGHT: ",*,0,NULL);
digits(70,100,4,*,1,mouse_right);",_VAR(1));
pDebug->flags |= VISIBLE;
pDebug->pos_x = _VAR(600);
pDebug->pos_y = _VAR(200);

//Main Loop
while (engine_frame()) {
//Main Loop
v(mouse_pos).x = v(mouse_cursor).x;
v(mouse_pos).y = v(mouse_cursor).y;
if (v(key_esc)) { sys_exit(""); }
}//Main Loop
engine_close();
return 0;
}


Hope It Helps Someone, Wish I'd Have Had It,
hoangnganvy1993

Re: wanted to share my working player/camera control action C++ app [Re: hoangnganvy1993] #474490
10/19/18 12:37
10/19/18 12:37
Joined: Jul 2008
Posts: 2,107
Germany
rayp Offline

X
rayp  Offline

X

Joined: Jul 2008
Posts: 2,107
Germany
Thanks.

There are a lot of examples doing basic player and stuff.

You know AUM for example?

Greets

Last edited by rayp; 10/19/18 12:38.

Acknex umgibt uns...zwischen Dir, mir, dem Stein dort...
"Hey Griswold ... where u gonna put a tree that big ?"
1998 i married my loved wife ... Sheeva from Mortal Kombat, not Evil-Lyn as might have been expected
rayp.flags |= UNTOUCHABLE;

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1