Maybe. My point is, networked player control doesn't have to use EOIs. No EOIs were used in jestermon's demo, but you say EOIs are needed for networking. I don't see why.
This forum is now archived!
- Welcome to the archive!
News:
The 3DRad community can be found at classdev.net.
- 3D Rad - Free 3D game maker - Forum >
- General Category >
- 3D Rad - User-created Sample Projects, Scripts, Tutorials >
- MouseLook, WASD drive
Author Topic: MouseLook, WASD drive (Read 13078 times)
Then my interpretation of what you said must have tended away from what you meant
Anyways, in any case, both Robert's and Jestermon's scripts combined will eliminate many objects, making room for more stuffs...
What's TOT about? What's it stand for?
Anyways, in any case, both Robert's and Jestermon's scripts combined will eliminate many objects, making room for more stuffs...
What's TOT about? What's it stand for?
TO stands for TargetOne the general name i'v applied to my projects, and Tanks .. i think you get that one.
so we get TOTanks for short, or TargetOne Tanks.
It doesn't work as TO Tanks, so i decided TOTanks was the best option.
so we get TOTanks for short, or TargetOne Tanks.
It doesn't work as TO Tanks, so i decided TOTanks was the best option.
I'm putting the project pieces together.
So i was playing with the Defender tank (converting it into a merge project) and found a couple things.
The Tank is a little "floaty/wobbly", i'm using http://www.3drad.com/forum/index.php?action=dlattach;topic=10131.0;attach=17814 project you supplied. ( i believe the latest version )
Plus the tank targeting gets a little ( some times a lot ) out of alignment. :see attached video.
Also i'm thinking the mouse control should have a on/off option, so the mouse can leave the project window ?, were you expecting this to be a full screen only project ?
.. i was sort of thinking full or windowed mode ?,and i'm not sure how the targeting will work if in windowed mode, thoughts ?.
So i was playing with the Defender tank (converting it into a merge project) and found a couple things.
The Tank is a little "floaty/wobbly", i'm using http://www.3drad.com/forum/index.php?action=dlattach;topic=10131.0;attach=17814 project you supplied. ( i believe the latest version )
Plus the tank targeting gets a little ( some times a lot ) out of alignment. :see attached video.
Also i'm thinking the mouse control should have a on/off option, so the mouse can leave the project window ?, were you expecting this to be a full screen only project ?
.. i was sort of thinking full or windowed mode ?,and i'm not sure how the targeting will work if in windowed mode, thoughts ?.
I've since corrected that targetting problem, but I haven't fixed the wobbly one yet. Link
If re-merging this is a hassle, you might try replacing the script's text with this:
I'm taking a stab at network scripting now. Couldn't open the project in your NBA demo. Wondering if you'd mind my taking a look at it? I'd like to see how your ID remapping works and if it could be integrated into what I'm doing.
If re-merging this is a hassle, you might try replacing the script's text with this:
Code: [Select]
/// objects
int pTest= OBJ_132;
int objTest= OBJ_484;
int objTerrain= OBJ_0;
// skinmesh, and bone IDs
int smTank= OBJ_66;
int bPrimary=1, bTurret= 2, bGun= 3;
int objCar= OBJ_44;
int objCam= OBJ_22;
int objCSprite= OBJ_88;
int objTSprite= OBJ_110;
void setCSpriteRGBA(float a, float r, float g, float b) {OUT_88= a;OUT_89= r;OUT_90= g;OUT_91= b;}
void setTSpriteRGBA(float a, float r, float g, float b) {OUT_110= a;OUT_111= r;OUT_112= g;OUT_113= b;}
int[] testObj= {objTerrain}; // target candidates
int[] gfiObj= {OBJ_264, OBJ_308, OBJ_330}; // impact explosion objects
int objFiringSound= OBJ_176;
int objFiringSmoke= OBJ_198;
int objFiringFlare= OBJ_220;
int objExplosionSound= OBJ_286;
int objPrnDist= OBJ_352;
void prnTargetDistance(float v){OUT_352= v;};
void valPrnTreads(float l, float r){OUT_418= 100*l;OUT_440= 100*r;}
void prnCameraDistance() {OUT_374= cDist;}
void setFov() {OUT_396= OUT_22= fov;}
/// config
int controlMethod= 1; // 1=cam-relative, 2=tank-relative
float revAngle= 45; // go in reverse if abs(car's -z)<revAngle
/// tools
Vector3 vNorm(Vector3 v) {iVectorLengthSet(v,v,1);return v;}
float angleWrap(float a) {while (a<-180) a+=360; while (a> 180) a-=360; return a;}
float sign(float f) {return f<0?-1:f>0?1:0;}
float yAngle(Quaternion q) {return yAngle(vecRot(q, Vector3(0,0,1)));}
float yAngle(Vector3 v) {return 57.295779*atan2(v.x, v.z);}
float fInterpolate(float f1, float f2, float f2p) {return (1-f2p)*f1 + f2p*f2;}
float degFix(float a) {while (a<-180) a+=360; while (a>180) a-=360; return a;}
float RelativeSpeed(int obj) {return iVectorDot(vecRot(objRot(obj), Vector3(0,0,1)), objVelocity(obj));}
float vecLen(Vector3 v) {return iVectorLength(v);}
Vector3 vecLen(Vector3 v, float l) {Vector3 r;iVectorLengthSet(r, v, l);return r;}
Vector3 vecRot(Quaternion q, Vector3 d) {Vector3 r;iVectorRotate(r,d,q);return r;}
Vector3 objVelocity(int obj) {Vector3 SpeedVec;iObjectVelocity(obj, SpeedVec);return SpeedVec;}
Vector3 objPos(int obj) {Vector3 l; iObjectLocation(obj, l); return l;}
Vector3 objPos(int obj, Vector3 l) {iObjectLocationSet(obj, l); return l;}
Quaternion qMul(Quaternion q1, Quaternion q2) {Quaternion qt;iQuaternionMultiply(qt,q1,q2);return qt;} // q1+q2
Quaternion qDelta(Quaternion q1, Quaternion q2) {return qMul(q1, qInv(q2));} // q1-q2
Quaternion qInv(Quaternion q) {return Quaternion(q.x,q.y,q.z,-q.w);} // -q
Quaternion objRot(int obj) {Quaternion q; iObjectOrientation(obj, q); return q;}
Quaternion objRot(int obj, Quaternion q) {iObjectOrientationSet(obj, q); return q;}
Quaternion qAxisAngle(Vector3 vUp, float dy) {Quaternion q; iQuaternionFromAxisAngle(q, vUp, dy); return q;}
Quaternion qEulers(float x, float y, float z) {Quaternion q;iQuaternionFromEulerAngles(q,x,y,z,"xyz");return q;}
Quaternion qInterpolate(Quaternion q1, Quaternion q2, float q1percent) {Quaternion q;iQuaternionInterpolate(q,q1,q2,q1percent);return q;}
Quaternion VectorOrientation(Vector3 v){
Vector3 v1,v2;
iVectorLengthSet(v1,v,1);
iVectorLengthSet(v2,v,2);
return QuatGetLookAt(v2-v1);
}
Quaternion QuatGetLookAt(Vector3 direction){
Vector3 up = Vector3(0,1,0);
Quaternion orientation;
iQuaternionLookAt(orientation,direction,up);
return orientation;
}
float atan2(float value1, float value2) {iDLLArraySet(0,value1); iDLLArraySet(1,value2); iDLLCall(MathDLLHandle,"R_atan2",0); return iDLLArrayGet(0);}
float sin(float value) {iDLLArraySet(0,value); iDLLCall(MathDLLHandle,"R_sin",0); return iDLLArrayGet(0);}
float cos(float value) {iDLLArraySet(0,value); iDLLCall(MathDLLHandle,"R_cos",0); return iDLLArrayGet(0);}
float sqr(float value) {iDLLArraySet(0,value); iDLLCall(MathDLLHandle,"R_sqrt",0); return iDLLArrayGet(0);}
float asin(float value) {iDLLArraySet(0,value); iDLLCall(MathDLLHandle,"R_asin",0); return iDLLArrayGet(0);}
/// treadControl
void treadControl() {
float l,r, n, power=1;
l=r=0;
if (moving) {
l=r=1;
if ((n= iFloatAbs(heading))<90) {
n= cos(degFix(heading*2)/57.295779);
if (heading<0) r= n; else l= n;
} else {
if (heading<0) r= -1; else l= -1;
power=(180-iFloatAbs(heading))/90;
}
if (inReverse) {l*=-1;r*=-1;}
}
valPrnTreads(l, r);
vUp= vecRot(qCar, Vector3(0,1,0));
// determine traction - it's more when compressed to ground
float fAng=0, fLin=0;
float tFL= traction(-1,1.5);
float tFR= traction( 1,1.5);
float tML= traction(-1,0);
float tMR= traction( 1,0);
float tBL= traction(-1,-1.5);
float tBR= traction( 1,-1.5);
float lTraction= (tFL+tML+tBL)/3;
float rTraction= (tFR+tMR+tBR)/3;
l*= lTraction;
r*= rTraction;
float t=(lTraction+rTraction)/2;
if (moving) {
fAng= t*heading; // -spinY(objCar)
fLin= l+r;
}
// if (iFloatAbs(fAng)>45) fAng= sign(fAng)*45;
Vector3 vForce= vecLen(vecRot(qCar, Vector3(0,0,1)),fLin*50);
iObjectAccelerationApply(objCar,vForce);
Vector3 vTorque= vecLen(vecRot(qCar, Vector3(0,-1,0)),fAng*turningForce);
iObjectAngularAccelerationApply(objCar,vTorque);
float d= damp*t;
iObjectDampingApply(objCar, 2*d, d, 2*d, true, true); // damp rotation
iObjectDampingApply(objCar, 2*d, 0, d/2, false, true); // damp moving
}
float sExtended= 0.2, sCompressed= 0.1;
float suspensionForce=25000;
float turningForce= 50000;
float damp= 0.025, force=25000;
float traction(float x, float y) {
Vector3 vPoint,vNorm, carPos= objPos(objCar)+vecRot(objRot(objCar), Vector3(x, 1, y));
Vector3 vScan= vecRot(objRot(objCar), Vector3(0,-1,0));
vScan= vecLen(vScan, 15);
float t;
if (iObjectScan(objTerrain,carPos,vScan,0,vPoint,vNorm)) {
float l= vecLen(vPoint-carPos)-1;
// return l; // determine travel
if (l<sCompressed) t= 1;
else if (l>sExtended) t= 0;
else {
t= 1-(l-sCompressed)/(sExtended-sCompressed);
if (t>1) t=1;
}
} else
t= 0;
// push away from ground
float pressure= t;
Vector3 vForce= vecLen(vecRot(qCar, vUp),pressure*suspensionForce);
iObjectForceApply(objCar,vForce,Vector3(x,1,y));
return t;
}
float spinY(int obj) {Vector3 v=Vector3(0,1,0); iObjectSpin(obj,v);return sign(v.y)*vecLen(v);}
Vector3 vUp;
/// orientCameraToMouse
float mouseX=0, mouseY=0; // for motion smoothing
int cZoom=3;
float iZoom=1, _iZoom=1;
float[] camDist= {8,4,0};
float[] FOV= {90,75,60};
float cDist= camDist[iZoom];
float cDistSteps= 4.0;
bool gunShown= true;
void _updateDist() {
cDist= 0.95*cDist + 0.05*camDist[iZoom];
prnCameraDistance();
if ((cDist<0.75) and (gunShown)) {
// iObjectHide(); // doesn't seem to be working
gunShown= false;
} else if ((cDist>0.75) and (not gunShown)) {
// iObjectShow();
gunShown= true;
}
}
float fov= FOV[iZoom];
void zoom(float mx, float my) {
if (iZoom != _iZoom) {
_iZoom+= sign(iZoom-_iZoom)/16.0;
if (iFloatAbs(iZoom-_iZoom)<(1.0/16.0)) _iZoom= iZoom;
int i= _iZoom; // chop off decimal part
float f= _iZoom-i; // only decimal part
fov= (1-f)*FOV[i] + f*FOV[i+1];
cDist= (1-f)*camDist[i] + f*camDist[i+1];
prnCameraDistance();
setFov();
iMouseLookSpeedSet(2*fov, 5*fov);
iMouseLookSet(mx,my);
}
}
/// relativeWASD
float heading= 0;
bool moving, inReverse; // driving backwards
void relativeWASD(Quaternion qHeading) {
heading= yAngle(qHeading);
float x=0, z=0;
if (iKeyDown(iKeyCode("DIK_W"))) z+=1;
if (iKeyDown(iKeyCode("DIK_S"))) z-=1;
if (iKeyDown(iKeyCode("DIK_D"))) x+=1;
if (iKeyDown(iKeyCode("DIK_A"))) x-=1;
float moveAngle= 0;
moving= (x!=0 or z!=0);
if (moving) moveAngle= 57.295779*atan2(x, z);
float rDir= degFix(moveAngle-heading);
heading= degFix(heading - moveAngle);
if (not (iKeyDown(iKeyCode("DIK_LSHIFT"))))
inReverse= iFloatAbs(rDir)>(180-revAngle);
else
if (!moving) inReverse= false;
if (inReverse) heading= sign(heading)*(180-iFloatAbs(heading));
// OUT_462= inReverse?1:0;
// OUT_484= heading;
}
float scanRange= 2048;
float redDist= 15; // point blank danger
Quaternion qTurret, qGun;
Vector3 viTurret, viGun, viPrimary, vTurret, vGun, vPrimary;
Vector3 targetContactPoint;
Quaternion qTarget;
Vector3 contactPoint, contactNormal;
float contactDist;
/// scanFromObject
bool scanFromObject(int obj) {
return scanFromObject(objPos(obj), vecLen(vecRot(objRot(obj), Vector3(0,0,1)), scanRange));}
bool scanFromObject(Vector3 scanOrigin, Vector3 vScan) {
bool contacts= false;
contactDist= -1;
contactPoint= scanOrigin+vScan;
Vector3 rContactPoint, rContactNormal;
float dist;
int arrayLen= testObj.length(), i, nContacts;
for(i=0;i<arrayLen;i++)
if (iObjectScan(testObj[i], scanOrigin, vScan, 0, rContactPoint, rContactNormal)) {
bool isCloser= contactDist>(dist= iVectorLength(scanOrigin-rContactPoint));
if ((!contacts) or isCloser ) {
contactDist= dist;
contacts= true;
contactPoint= rContactPoint;
contactNormal= rContactNormal;
nContacts+= 1;
}
}
return contacts;
}
void orientCamWithMouse() {
float mx= iMouseLookX();
float my= iMouseLookY();
float mz= iMouseZ(true);
if (mz>1) mz= 1; if (mz<0) mz= -1;
if (mz!=0) if ((iZoom+mz>=0) and (iZoom+mz<cZoom)) iZoom+= mz;
zoom(mx, my);
mouseX= fInterpolate(mx, mouseX, 0.9);
mouseY= fInterpolate(my, mouseY, 0.9);
qCam= qEulers(mouseX, mouseY, 0);
objPos(objCam, vPrimary + cDist*vecRot(qCam, Vector3(0,0.25,-2)));
objRot(objCam, qCam);
}
/// Main
Quaternion qCam, qCar, qWorld;
int MathDLLHandle=0;
void Main() {
if(iInitializing()) {
MathDLLHandle = iDLLLoad(".\\3DRad_res\\objects\\Script\\RadMath2.dll");
if (MathDLLHandle==0)
MathDLLHandle = iDLLLoad(".\\3DRad_res\\objects\\Script\\RadMath.dll");
fireCannon_initImposter();
qWorld= qEulers(0,0,0);
iObjectBoneLocation(smTank,bTurret,viTurret,2);
iObjectBoneLocation(smTank,bGun,viGun,2);
iObjectBoneLocation(smTank,bPrimary,viPrimary,2);
zoom(0, 0);
qCam= objRot(objCam);
qTarget= objRot(objCar);
qTurret= qTarget;
qGun= qTurret;
} else if (iDeinitializing()) {
if (MathDLLHandle != 0) iDLLUnload(MathDLLHandle);
fireCannon_freeImposter();
} else if (MathDLLHandle != 0) {
qCar= objRot(objCar);
vTurret= objPos(objCar)+vecRot(qCar, viTurret);
if (controlMethod==1) // cam-relative WASD
relativeWASD(qDelta(qCar, qCam));
else // car-relative WASD
relativeWASD(qWorld);
treadControl();
if (scanFromObject(objCam)) {
prnTargetDistance(contactDist);
iObjectShow(objPrnDist);
} else
iObjectHide(objPrnDist);
targetContactPoint= contactPoint;
qTarget= VectorOrientation(vNorm(targetContactPoint-vTurret));
objRot(objTest, qTarget); // orient fish
// pose tank skinmesh
Vector3 v= vecRot(qDelta(qTarget,qCar), Vector3(0,0,1));
qTurret= qEulers(0,angleWrap(57.29578231*atan2(v.x, v.z)),0);
iObjectBoneOrientationSet(smTank,bTurret,qTurret,2);
qGun= qEulers(-angleWrap(57.29578231*asin(v.y)),0,0);
iObjectBoneOrientationSet(smTank,bGun,qGun,2);
Quaternion q= qMul(qTurret,qCar);
vGun= vTurret+vecRot(q, viGun);
vPrimary= vGun+vecRot(qMul(qGun, q),viPrimary);
objPos(pTest, vPrimary); // particle position marker
scanFromObject(vPrimary, targetContactPoint-vPrimary);
// sprite To Target
Vector3 vScreenCoords, v1= Vector3(1,1,1);
i3DLocationToScreen(vScreenCoords, contactPoint, objCam);
iObjectLocationSet(objTSprite, vScreenCoords);
float dist= vecLen(vGun-contactPoint);
iObjectScaleSet(objTSprite, vecLen(v1, redDist/iFloatSqrt(redDist+dist)));
float danger;
if (dist<redDist)
danger= 1;
else if (dist<2*redDist)
danger= 1-(dist-redDist)/redDist;
else
danger= 0;
setTSpriteRGBA(1,0.5+0.5*danger,0.5-0.5*danger,0.5-0.5*danger);
checkImpactSchedule();
if (iMouseButtonClick(0)) fireCannon();
orientCamWithMouse();
}
}
void objPosRot(int obj, Vector3 v, Quaternion q) {objPos(obj, v);objRot(obj, q);}
/// fireCannon
int gfiObjs;
Quaternion qGFI;
void fireCannon_initImposter() {
gfiObjs= gfiObj.length();
for(int j=0;j<gfiObjs;j++) {
iObjectImpostersCreate(gfiObj[j],1);
iObjectImposterHide(gfiObj[j],0);
}
iObjectOrientation(gfiObj[1],qGFI);
}
void fireCannon_freeImposter() {for(int j=0;j<gfiObjs;j++) iObjectImpostersDestroy(gfiObj[j]);}
void fireCannon() {
objPosRot(objFiringSmoke,vPrimary,qTarget);
objPosRot(objFiringFlare,vPrimary,qTarget);
iObjectAccelerationApply(objCar,vecLen(vGun-vPrimary,1000)); // firing recoil
iObjectStart(objFiringSmoke);
iObjectStart(objFiringFlare);
iObjectStart(objFiringSound);
scheduleImpact(contactPoint);
}
int now() {return 3600000*iSystemTime(4)+60000*iSystemTime(5)+1000*iSystemTime(6)+iSystemTime(7);}
float projSpeedFactor= 4; // particle speed= 250
void scheduleImpact(Vector3 where) {///
int when= now()+vecLen(contactPoint-vPrimary)*projSpeedFactor;
impactEvent ieThis;
ieThis.where= where;
ieThis.when= when;
@ieThis.next= null;
impactEvent@ iehPrev;
impactEvent@ iehLink;
@iehLink= @iehFirst;
while(iehLink != null) { // find insertion point in linked list
int w= (@iehLink).when;
if (w > when) break;
@iehPrev= @iehLink;
@iehLink= @iehLink.next;
}
if (iehLink != null) @ieThis.next= iehLink;
if (iehPrev != null)
@iehPrev.next= @ieThis;
else {
if (iehFirst != null) ieThis.next= iehFirst;
@iehFirst= ieThis;
}
}
void checkImpactSchedule() {
if (iehFirst != null) {
int w= (@iehFirst).when;
if (w <= now()) {
(@iehFirst).projectileImpact();
@iehFirst= (@iehFirst).next;
}
}
}
impactEvent @iehFirst= null;
class impactEvent {
impactEvent@ next;
Vector3 where;
int when;
void projectileImpact() {
objPos(objExplosionSound, this.where);
iObjectStart(objExplosionSound);
for(int j=0;j<gfiObjs;j++) {
iObjectImposterSet(gfiObj[j],0,qGFI,where);
iObjectImposterShow(gfiObj[j],0);
}
}
}
I'm taking a stab at network scripting now. Couldn't open the project in your NBA demo. Wondering if you'd mind my taking a look at it? I'd like to see how your ID remapping works and if it could be integrated into what I'm doing.
Opps i thought i included the source code originally with the project .
If you want to run the project server press RIGHTSHIFT+H
Once the project is running, LEFTCTRL+LEFTSHIFT+F9 to config your controls cause i have the defaults set to my gamepad.
The "intro script" is the first script that runs and selects client or server mode. near the bottom in the list editor.
The the other two scrips that do the dirty work, that your interested in.
Script - Client
Script - Server
If you want to run the project server press RIGHTSHIFT+H
Once the project is running, LEFTCTRL+LEFTSHIFT+F9 to config your controls cause i have the defaults set to my gamepad.
The "intro script" is the first script that runs and selects client or server mode. near the bottom in the list editor.
The the other two scrips that do the dirty work, that your interested in.
Script - Client
Script - Server