svētdiena, 2022. gada 4. decembris

JURMALA STREETS 3D PSEUDO CODE MULTIPLAYER TWEENING ISSUES

code and documentation can still can be found on github page, master repository, https://github.com/lv88h/JurmalaStreets3dPSEUDO6

first of all, every mysql table that get's loaded with ajax from .php files need to have auto incrementation and right table rows (if something really does not match it, the code fails)

second of all, here, the biggest issue, is launching tween.start() only if other player coordinates get updated, and second issue is having a proper tween that includes jumping and player speed rotation updates to character that get's tweened. 

tween.js works like this - https://enable3d.io/examples/use-tweenjs.html but this is not proper example, cause it does not include character that rotates, jumps or moves. 

third of all problems is still, no climbing animation or physics variations meeting different loaded .glb objects besides map (book6.glb)

fourth and not least, chat bubbles need to be updated correctly and should be reversed and dissapear moments after that.

this code contains all commentaries I could give - You can check how it acts on my server 

skatetube (dot) sytes (dot)    /jurmalastreets3d/gamenew.php

as a demo.






<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>3D ONLINE GAME 2</title>
<link rel="stylesheet" href="css/examples.css?ver=1.0.0" />
<script src="js/examples.js?ver=1.1.1"></script>
<script src="lib/phaser.min.js?ver=3.52.0"></script>
<script src="lib/enable3d/enable3d.phaserExtension.0.25.0.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<script src="lib/tween.umd.js"></script>


</head>

<!-- header really has everything included in projects zip file css, jquery, phaser, enable3d and tween -->














<body>
<!--- <div id="info-text">Use WASD, SPACE and your Mouse.<br />Try to play it on your mobile device :)</div> -->
<center>
<h1>
<?php
include_once '/db.php';

$sessionid = $_SESSION['user_id'];

echo $user_data['username'];

if(empty($sessionid)){
// header('Location: index.php');

//echo $sessionid;

} else {
?>
<script>
///LOADS ONLINE TABLE
window.setInterval(function () {

$.ajax({
type: "GET",
async: false,
url: 'loadonline.php',
data: {},
success: function (data) {
}
});
}, 2000);

//REMOVES OLD ONLINE TABLE ROWS MUST TO IN LONGER INTERVAL LIKE ONCE IN HALF MINS
window.setInterval(function () {

$.ajax({
type: "GET",
async: false,
url: 'removeonline.php',
data: {},
success: function (data) {
}
});
}, 4000);

</script>
<?php

}

//skripts kurš pie katras čaraktera kustību apstājas updeito tabulas sadaļu *location*
//skripts kurš katru lietotāju kura datetime sakrīt ar intervālu pēdējās 15 min, zīmē ekrānā

?>








</h1> <a href="logout.php">Logout.</a>http://mytechservinginternetmeals.blogspot.com/2022/02/video-game-development-4.html
<br>
<b>Things need to be implemented: 1)physics between two 3d objects besides map object 2)shadered and textured maps 3)animations for special objects 4)multiplayer and quests
Mainly, physics work, no such thing as stairs climbing animation or physics.
shaders are based on idea that, there is no reflection, or texture on a .glb .fbx object
only animations are jumping, idle and walking, could be changing weather and different ways of interaction with "nature"
multiplayer is based on idea, that AJAX retrieves coordinates, and as they change, tween functionality would run on the selected character,
which differs from main player (which is You), adding animations with the whole tweening too, for example
if player jumps while coordinates move, tween should do a jumping animation on the character object

</b>
</center>








<script>
//this const contains most usability
const {
enable3d,
Scene3D,
Canvas,
ThirdDimension,
THREE,
JoyStick,
ExtendedObject3D,
ThirdPersonControls,
PointerLock,
PointerDrag
} = ENABLE3D

/**
* Is touch device?
*/
const isTouchDevice = 'ontouchstart' in window

//main class is the whole progran
class MainScene extends Scene3D {
constructor() {
super({
key: 'MainScene'
})
}

//init runs and adds 3d spherem defines settings
init() {
this.accessThirdDimension({
maxSubSteps: 10,
fixedTimeStep: 1 / 120
})
this.third.renderer.outputEncoding = THREE.LinearEncoding
this.canJump = true
this.move = false

this.moveTop = 0
this.moveRight = 0
}

//this is function that loads asynchronously, it waits on update() function to run, in the function it creates 1)map 2)characters 3)extra objects on map
async create() {
//this constants define lights and visibility in creation
const {
lights
} = await this.third.warpSpeed('-ground', '-orbitControls')

const {
hemisphereLight,
ambientLight,
directionalLight
} = lights
const intensity = 0.65
hemisphereLight.intensity = intensity
ambientLight.intensity = intensity
directionalLight.intensity = intensity




var updeitot; /// this defines if game needs to be updated




/** KARTE / MAP - THIS IS OBJECT THAT DEFINES THE WHOLE GAME MAP (BUILDINGS AND STATIC ELEMENTS SUCH AS HILLS, ROCKS, GRASS ETC)
*
* Medieval Fantasy Book by Pixel (https://sketchfab.com/stefan.lengyel1)
* https://sketchfab.com/3d-models/medieval-fantasy-book-06d5a80a04fc4c5ab552759e9a97d91a
* Attribution 4.0 International (CC BY 4.0)
E4E717
*/
this.third.load.gltf('/jurmalastreets3d/assets/glb/book6.glb').then(object => {
const scene = object.scenes[0]

const book = new ExtendedObject3D()
book.name = 'scene'
book.add(scene)
this.third.add.existing(book)

// add animations
// sadly only the flags animations works
object.animations.forEach((anim, i) => {
book.mixer = this.third.animationMixers.create(book)
// overwrite the action to be an array of actions
book.action = []
book.action[i] = book.mixer.clipAction(anim)
book.action[i].play()
})

book.traverse(child => {
if (child.isMesh) {
child.castShadow = child.receiveShadow = false
child.material.metalness = 0
child.material.roughness = 1
//THIS GIVES PHYSICAL FACTOR TO THE MAP, MAKING IT HAVE COLLISIONS AND PHYSICS.
if (/mesh/i.test(child.name)) {
this.third.physics.add.existing(child, {
shape: 'concave',
mass: 0,
collisionFlags: 1,
autoCenter: false
})
child.body.setAngularFactor(0, 0, 0)
child.body.setLinearFactor(0, 0, 0)
}
}
})
})







/** ELEMENTS MĀJA ELEMENT HOUSE - AN EXTRA ELEMENT, THE APPEARS ON THE MAP (SO FAR APPEARED IN FIRST VERSION OF GAME, MIGHT NOT APPEAR NOW)
* box_man.glb by Jan Bláha
* https://github.com/swift502/Sketchbook
* CC-0 license 2018
*/
this.third.load.gltf('/jurmalastreets3d/assets/glb/house.glb').then(object => {
const house = object.scene.children[0]


this.house = new ExtendedObject3D()
this.house.name = 'house'
this.house.rotateY(Math.PI + 0.1) // a hack
this.house.add(house)
this.house.rotation.set(0, Math.PI * 1.5, 0)

var obj;
$.ajax({
type: "GET",
async: false,
url: 'getlocation.php',
data: {},
success: function (html) {
obj = JSON.parse(html);
console.log("noliek", obj);
}

});

this.house.position.set(804.2014, 10, -205.63472)




// add shadow
this.house.traverse(child => {
if (child.isMesh) {
child.castShadow = child.receiveShadow = true
// https://discourse.threejs.org/t/cant-export-material-from-blender-gltf/12258
child.material.roughness = 1
child.material.metalness = 0
}
})

/**
* Animations
*/
this.third.animationMixers.add(this.house.animation.mixer)
object.animations.forEach(animation => {
if (animation.name) {
this.house.animation.add(animation.name, animation)
}
})
this.house.animation.play('idle')

/**
* Add the player /house to the scene with a body
*/
this.third.add.existing(this.house)
this.third.physics.add.existing(this.house, {
shape: 'sphere',
radius: 0.25,
width: 0.5,
offset: {
y: -0.25
}
})
this.house.body.setFriction(0.8)
this.house.body.setAngularFactor(0, 0, 0)

// https://docs.panda3d.org/1.10/python/programming/physics/bullet/ccd
this.house.body.setCcdMotionThreshold(1e-7)
this.house.body.setCcdSweptSphereRadius(0.25)

/**
* Add 3rd Person Controls
*/
this.controls = new ThirdPersonControls(this.third.camera, this.house, {
offset: new THREE.Vector3(0, 1, 0),
targetRadius: 3
})
// set initial view to 90 deg theta
this.controls.theta = 90

/**
* Add Pointer Lock and Pointer Drag
*/
if (!isTouchDevice) {
let pl = new PointerLock(this.game.canvas)
let pd = new PointerDrag(this.game.canvas)
pd.onMove(delta => {
if (pl.isLocked()) {
this.moveTop = -delta.y
this.moveRight = delta.x
}
})
}
})



/**
*
* IELĀDĒT PLAYER LOKĀCIJAS KURA VAR NOTIKT TIKAI UZ MAINĪGĀ BĀZES
*
*/

//creates an array to store coordinates for player characters
window.objx = [];
window.objy = [];
window.objz = [];
//let counter = 0;
//let objxl = objx.length;
Array.prototype.clear = function () {
this.splice(0, this.length);
};

//creates an interval that should generate player coordinates (refresh them)

window.setInterval(function () {
if (updeitot = 1) {


//$.ajax({
//type: "GET",
//async: false,
//url: 'getlocation.php',
//data: {},
//success: function (data) {
//var nameArr = data.split(',');

//console.log("idioti");
//for(let i=0; i<nameArr.length; i++){
//console.log("pushes skins");

//if(nameArr[i]){
//skins.push(nameArr[i]);
//}
//}



//}
//});
objx.clear();
objy.clear();
objz.clear();


//satur lokācijas
$.ajax({
type: "GET",
async: false,
url: 'getlocation.php',
data: {},
success: function (data) {
var data2 = data.split("*");
//objx = data2.x
////objy = data2.y
console.log("garums", data2.length);
for (var i = 0; i < data2.length - 1; i++) {
var data3 = JSON.parse(data2[i]);
console.log("dati no datubazes", i, data3);

//pushes coordinates to array inside create function
objx.push(data3.x);
objy.push(data3.y);
objz.push(data3.z);

}

////objz = data2.z

//console.log("lokacijas x", data2.x);
//console.log("lokacijas y", data2.y);
//console.log("lokacijas z", data2.z);
// console.log("notiek dahuja");


//ja visi masīva pēdējie pievienotie elementi nesakrīt jau ar esošajiem pievienot masīvam citus

// koordinātēm jābūt vienādai kārtībai ar čaraktera user id



// counter++;




}
});
}
}, 400);



window.objx2 = [];
window.objy2 = [];
window.objz2 = [];


//creates an second interval that should generate player coordinates (later)

window.setInterval(function () {
if (updeitot = 1) {


//$.ajax({
//type: "GET",
//async: false,
//url: 'getlocation.php',
//data: {},
//success: function (data) {
//var nameArr = data.split(',');

//console.log("idioti");
//for(let i=0; i<nameArr.length; i++){
//console.log("pushes skins");

//if(nameArr[i]){
//skins.push(nameArr[i]);
//}
//}



//}
//});
objx2.clear();
objy2.clear();
objz2.clear();


//satur lokācijas
$.ajax({
type: "GET",
async: false,
url: 'getlocation.php',
data: {},
success: function (data) {
var data2 = data.split("*");
//objx = data2.x
////objy = data2.y
console.log("garums", data2.length);
for (var i = 0; i < data2.length - 1; i++) {
var data3 = JSON.parse(data2[i]);
console.log("dati no datubazes velak", i, data3);


objx2.push(data3.x);
objy2.push(data3.y);
objz2.push(data3.z);
console.log("pirms tween x", data3.x);

}

////objz = data2.z

//console.log("lokacijas x", data2.x);
//console.log("lokacijas y", data2.y);
//console.log("lokacijas z", data2.z);
// console.log("notiek dahuja");


//ja visi masīva pēdējie pievienotie elementi nesakrīt jau ar esošajiem pievienot masīvam citus

// koordinātēm jābūt vienādai kārtībai ar čaraktera user id



// counter++;




}
});
}
}, 800);




//after both refresh we check what's the coordinate

console.log("kas ir iekš x ", objx);

// uzskaita pareizu skaitu hujņu



//if(counter > objxl.length){
//counter = objxl.length;
//}



//console.log("tryx", objx); // hz kāpēc masīvs tukšss





//this creates loop that loads chat database into array
var getchat = [];
window.setInterval(function () {


if (updeitot = 1) {

$.ajax({
type: "GET",
async: false,
url: 'getchat.php',
data: {},
success: function (data) {
getchat = data.split("*").map(String);

}

});
}
}, 600);













//these are constants that have information from chat and locations loaded into them (arrays)
var uu;
var location2;
var location3;
var location4;
window.setInterval(function () {
uu = getchat[0]
location2 = parseInt(objx[0]);
location3 = location2 + 185;
location4 = location3.toString();
console.log("uu", location4);
}, 600);

//this adds a chat bubbles on display in correct coordinate if they were loaded in the array
const foo = () => {
//chatbubbles.php
//
this.add.text(location4, 328, uu, {
fontSize: '24px'
});
}
//executes loading chat bubble function
window.setInterval(function () {
foo();
}, 610);






/**
*
* IELĀDĒT SKINUS FUNKCIJA KURA VAR NOTIKT TIKAI UZ MAINĪGĀ BĀZES
*
*/





//creates skins arrays that will contain .glb file locations for every character

var skins = [];
var skins2 = [];
var userskin = [];
var userid = [];
let skin;
let skin2;



$.ajax({
type: "GET",
async: false,
url: 'loadskins.php',
data: {},
success: function (data) {
var nameArr = data.split(',');

// console.log("idioti");
for (let i = 0; i < nameArr.length; i++) {
console.log("pushes skins");

if (nameArr[i]) {
skins.push(nameArr[i]);

}
}



}
});




//does it second time (user skins)
$.ajax({
type: "GET",
async: false,
url: 'loadskins2.php',
data: {},
success: function (data) {
var nameArr2 = data.split(',');

// console.log("idioti");
for (let i = 0; i < nameArr2.length; i++) {
console.log("pushes skins2");
if (nameArr2[i]) {
skins2.push(nameArr2[i]);
}
}



}
});




//loads user skins
$.ajax({
type: "GET",
async: false,
url: 'loaduserskin.php',
data: {},
success: function (data) {
var nameArr = data.split(',');

//console.log("idioti");
for (let i = 0; i < nameArr.length; i++) {
console.log("pushes skins");

if (nameArr[i]) {
userskin.push(nameArr[i]);
}
}



}
});

//loads user id
$.ajax({
type: "GET",
async: false,
url: 'loaduserid.php',
data: {},
success: function (data) {
var nameArr = data.split(',');

//console.log("idioti");
for (let i = 0; i < nameArr.length; i++) {
console.log("pushes skins");

if (nameArr[i]) {
userid.push(nameArr[i]);
}
}



}
});






/**
*
* IELĀDĒ CHARAKTERUS NO IEGUTAS INFORMACIJAS
*
*
*
* IEČĒKOT TABULAS online SATURU UN attiecīgās lokācijas skinus un ja tie eksistē un ir tādi paši kā tabulā users, tad tos ievietot spēlē updeitojot
*
*/
//let object;



//setInterval(function (third) {
//console.log("saturs", skins);


//skinsIZR = skinsZ[0].split(",").map(String);
//console.log("IZR", skinsIZR[0]);

console.log("speletaju skaits", skins.length);

//creates coordinates array, which get loaded with stuff
var cooords = [];

//for every users skin (loads a character, and sets position to 804.2014, 10, -205.63472 --instead should be using data from objx, objy, objz array)
for (let step = 0; step < skins.length; step++) {


//const object = this.third.load.gltf(skins[step])

//console.log("trust", object.scene);


var object = await this.third.load.gltf(skins[step])

///this.third.load.gltf('/assets/glb/box_man.glb').then(object => {
const scene2 = object.scene.children[0]


//this.third.load.gltf(skins[step]).then(object => {
//const scene2 = object.scenes[0]

const man = object.scene.children[0]

///this.third.load.gltf('/assets/glb/box_man.glb').then(object => {

console.log("zb", man);



this.man = new ExtendedObject3D()
this.man.name = 'man'
this.man.rotateY(Math.PI + 0.1) // a hack
this.man.add(man)
this.man.rotation.set(0, Math.PI * 1.5, 0)


let that = this.man;



this.man.position.set(804.2014, 10, -205.63472)

let coords2 = this.man.position.clone()
cooords.push(coords2);


////}
////}
var vertibasx = objx;
var vertibasy = objy;
var vertibasz = objz;

console.log("xxxx", vertibasx);
console.log("yyyy", vertibasy);
console.log("zzzz", vertibasz);

//let verx = vertibasx[step];
//let very = 3;
//let verz = vertibasz[step];
console.log("this.tweens", tweens);



//this adds tweens to tween array (that runs when tween.start() would happen - remember, it should only happen if user id does not match Yours)
this.tweens.add({
targets: man.position.clone(),
duration: 100000,
delay: 1,
x: '+=10',
z: '+=1',
onUpdate: () => {
console.log("noteik tween");

//this.man.position.set(vertibasx.x, vertibasy.y, vertibasz.z)
}
})






//console.log("iteracija", i);
//if(vertibasx !== null && vertibasy !== null && vertibasz !== null){



//const coords2 = this.man.position.clone();

//these are effects characters all get like, shadow animations etc

// add shadow
this.man.traverse(child => {
if (child.isMesh) {
child.castShadow = child.receiveShadow = true
// https://discourse.threejs.org/t/cant-export-material-from-blender-gltf/12258
child.material.roughness = 1
child.material.metalness = 0
}
})

/**
* Animations
*/
this.third.animationMixers.add(this.man.animation.mixer)
object.animations.forEach(animation => {
if (animation.name) {
this.man.animation.add(animation.name, animation)
}
})
this.man.animation.play('idle')

/**
* Add the player to the scene with a body
*/
this.third.add.existing(this.man)
this.third.physics.add.existing(this.man, {
shape: 'sphere',
radius: 0.25,
width: 0.5,
offset: {
y: -0.25
}
})
this.man.body.setFriction(0.8)
this.man.body.setAngularFactor(0, 0, 0)

// https://docs.panda3d.org/1.10/python/programming/physics/bullet/ccd
this.man.body.setCcdMotionThreshold(1e-7)
this.man.body.setCcdSweptSphereRadius(0.25)





//}, 500);










//makes sure Your character gets a controls
/**
* Add 3rd Person Controls
*/
this.controls = new ThirdPersonControls(this.third.camera, this.man, {
offset: new THREE.Vector3(0, 1, 0),
targetRadius: 3
})
// set initial view to 90 deg theta
this.controls.theta = 90

/**
* Add Pointer Lock and Pointer Drag
*/
if (!isTouchDevice) {
let pl = new PointerLock(this.game.canvas)
let pd = new PointerDrag(this.game.canvas)
pd.onMove(delta => {
if (pl.isLocked()) {
this.moveTop = -delta.y
this.moveRight = delta.x
}
})
}
// })










/**
* Add Keys
*/




/**
* Add joystick
*/
if (isTouchDevice) {
const joystick = new JoyStick()
const axis = joystick.add.axis({
styles: {
left: 35,
bottom: 35,
size: 100
}
})
axis.onMove(event => {
/**
* Update Camera
*/
const {
top,
right
} = event
this.moveTop = top * 3
this.moveRight = right * 3
})
const buttonA = joystick.add.button({
letter: 'A',
styles: {
right: 35,
bottom: 110,
size: 80
}
})
buttonA.onClick(() => this.jump())
const buttonB = joystick.add.button({
letter: 'B',
styles: {
right: 110,
bottom: 35,
size: 80
}
})
buttonB.onClick(() => (this.move = true))
buttonB.onRelease(() => (this.move = false))
}









//console.log("uzstada", vertibasx, vertibasy, vertibasx);









};







//setInterval(greet, 8000);




////// ideja ka nepieciešams priekļūt this.man.position iekš intervāla, lai izmainītu vertibas xyz kuras passtāvīgi tiek updeitotas no datubāzes ar intervālu pirms tam.
//////setInterval(function (man) {
//////if(vertibasx != vertibasxPIRMSTAM){
//function greet(){
////console.log("man inside");

//////if (updeitot = 1) {
//////refreshoja charakteru
////if (window.localStorage.getItem('x') && window.localStorage.getItem('y') && window.localStorage.getItem('z')) {
//console.log("man inside2");
//console.log("changes?", that.position);

//that.position.set(window.localStorage.getItem('x'), window.localStorage.getItem('y'), window.localStorage.getItem('z'))
////} else {
////this.man.position.set(754.2014, 10, -205.63472)
//}

//for (let stepe = 0; stepe < cooords.length; stepe++) {



//let insidecoords = cooords[stepe];

//console.log("inside", insidecoords);
//setInterval(function () {
//console.log("izsauc tween");


//}, 2000);




//}
}









//tween(man, moveTo, time = 1000, delay = 0) {

//console.log("middle");
//const coords = this.man.position.clone()
//console.log("coords", this.man.position);
//console.log("coords2", coords);
//console.log("moveTo", moveTo);
//console.log("moveTox", moveTo.x);
//const tween = new TWEEN.Tween(coords)
//.to({ x: moveTo.x, y: moveTo.y, z: moveTo.z }, time)
//.easing(TWEEN.Easing.Quadratic.Out)
//.onUpdate(() => {
//console.log("notiek tweens");


//this.man.position.set(coords.x, coords.y, coords.z)
//if (this.man.body) this.man.body.needUpdate = true
//})


//this.man.position.set(coords.x, coords.y, coords.z)

//console.log(this.man.position);
//console.log("tweeen", tween);
//console.log("end");

////}
//function tween(man)
////xc = "804.201";
////yc = "10";
////zc = "-205.63472";
////console.log("notiek tweeens");
////console.log("inside2", insidecoords);



////const tween2 = new TWEEN.Tween(insidecoords)
////.to({ x: moveTo.xc, y: moveTo.yc, z: moveTo.zc }, time)
////.easing(TWEEN.Easing.Quadratic.Out)
////.onUpdate(() => {
////console.log("notiek tweens2");


////this.man.position.set(insidecoords.x, insidecoords.y, insidecoords.z)
////if (this.man.body) this.man.body.needUpdate = true
////})
////}
//}




// THIS IS TWEEN FUNCTION THAT HAPPENS OUTSIDE CREATE() AND BEFORE JUMP() OR UPDATE, IT SHOULD HAPPEN ONLY WHEN OTHERS PLAYERS UPDATE COORDINATES
// AND SHOULD ADD ANIMATION THAT HAPPEN WHILE TWEENING (THUS PLAYER ACTIONS SUCH AS JUMP SHOULD BE UPDATED FROM DATABASE)


tween(man, moveTo, time = 1000, delay = 0) {
const coords = man.position.clone()

const tween = new TWEEN.Tween(coords)
.to({
x: moveTo.vertibasx,
y: moveTo.vertibasy,
z: moveTo.vertibasz
}, time)
.easing(TWEEN.Easing.Quadratic.Out)
.onUpdate(() => {
man.position.set(coords.vertibasx, coords.vertibasy, coords.vertibasz)
if (man.body) man.body.needUpdate = true
})

if (delay === 0) tween.start()
else setTimeout(() => tween.start(), delay)
}





/// iegūst no datubāzes vai leciens ir animācija
// EXECUTE JUMP, SHOULD UPDATE TO DATABASE THAT IT HAPPENED SO IT COULD BE USED IN TWEEN
jump() {
if (!this.man || !this.canJump) return
this.canJump = false
this.man.animation.play('jump_running', 500, false)
this.time.addEvent({
delay: 650,
callback: () => {
this.canJump = true
this.man.animation.play('idle')
}
})
this.man.body.applyForceY(6)
}
//ja tas notiek updeito datubāzi ar to ka palecās




// FUNCTION THAT HAPPENS ALL THE TIME, GIVING KEYS, TEXTUAL WINDOWS FOR WRITING CHATS
// ALSO, CHECKS IF USER PRESSES THEM TO POST NEWLY GIVEN COORDINATES TO DATABASE
update(time, delta) {



this.keys = {

a: this.input.keyboard.addKey('a'),
w: this.input.keyboard.addKey('w'),
d: this.input.keyboard.addKey('d'),
s: this.input.keyboard.addKey('s'),
space: this.input.keyboard.addKey(32)
}
var choicef = 1;


if (choicef === 1) {


this.keys = {

a: this.input.keyboard.addKey('a'),
w: this.input.keyboard.addKey('w'),
d: this.input.keyboard.addKey('d'),
s: this.input.keyboard.addKey('s'),
space: this.input.keyboard.addKey(32)
}
}

if (choicef === 2) {
this.input.keyboard.removeCapture('W,S,A,D');
this.input.keyboard.removeCapture([32]);

}


var area = document.getElementById('textarea');



//CHECKS IF USER CLICKED ON TEXTUAL INPUT WINDOWS (HTML)
area.addEventListener('click', (e) => {
//alert("uzlieku pa virsu");
choicef = 2;
});



var elem = document.getElementById('enable3d-phaser-canvas');
elem.addEventListener('click', (e) => {
console.log("uzlieku pa virsu");
choicef = 1;
});


//IF CHECK HAPPENS, DISABLES 3D CONTROLS

area.addEventListener('keyup', (e) => {
if (e.keyCode === 13) {
// Cancel the default action, if needed
e.preventDefault();
// Trigger the button element with a click
var textarea = document.getElementById('textarea').value;
//avar groupidTRIM = document.getElementById("groupchatID").innerHTML;
//var groupid = "grupa";
//alert(111);

//alert(111);

var username;

$.ajax({
type: "GET",
async: false,
url: 'getusername.php',
data: {},
success: function (data) {
username = data;
//alert(username)
}

});

var kopadata = username + " " + textarea;

console.log("uzpeld", kopadata);



if (textarea) {

console.log("suta zinju", textarea);


$.ajax({
type: "post",
url: "groupchatfunction.php",
data: {
textarea: textarea
},
cache: false,
success: function (html) {
console.log("aizsutija");

//izmēģinam ievietot kastīti ja aizsūtas ziņa
// this.third.physics.add.box({ y: 10, x: 754.2014 }, { lambert: { color: 'red' } })


/// tekstu ieposto datubāzē , izmaina globālo masīvu ar tekstu un tā īpašnieku
/// vēlāk globālo masīvu zīmē gluži kā čarakteru iekš update funkcijas, iekļauj sarakstā visas ziņas
// un uzzīmē thought buble virs čaraktera galvas ar iedomāto tekstu
var kopadata2 = kopadata;

var doit = textbubble.push(kopadata2);
var messageelements = '<div class="msg_a"><span data-tooltip="now" data-tooltip-position="bottom">' + textarea + '</span></div><br>';


$("#outputmessages").append(messageelements);


//window.setTimeout(function(){
//var elem = document.getElementById('msg_body');
//elem.scrollTop = elem.scrollHeight;
//}, 1200);


}



});
}

document.getElementById('textarea').value = '';


}
});



// THIS DEALS WITH CHARACTERS LOCATION, ROTATION AND SPEED (ROTATION AND SPEED SHOULD ALSO BE UPDATED TO DATABASE)

if (this.man && this.man.body) {
/**
* Update Controls
*/
this.controls.update(this.moveRight * 2, -this.moveTop * 2)
if (!isTouchDevice) this.moveRight = this.moveTop = 0
/**
* Player Turn
*/
const speed = 4
const v3 = new THREE.Vector3()

const rotation = this.third.camera.getWorldDirection(v3)
const theta = Math.atan2(rotation.x, rotation.z)
const rotationMan = this.man.getWorldDirection(v3)
const thetaMan = Math.atan2(rotationMan.x, rotationMan.z)
this.man.body.setAngularVelocityY(0)

const l = Math.abs(theta - thetaMan)
let rotationSpeed = isTouchDevice ? 2 : 4
let d = Math.PI / 24

if (l > d) {
if (l > Math.PI - d) rotationSpeed *= -1
if (theta < thetaMan) rotationSpeed *= -1
this.man.body.setAngularVelocityY(rotationSpeed)
}

/**
* Player Move
*/
if (this.keys.w.isDown || this.move) {
//chatbubbles.php


/// vajadzētu atcelt funkciju kas veic lokāciju pārlādi
var updeitot = 0;


if (this.man.animation.current === 'idle' && this.canJump) this.man.animation.play('run')

const x = Math.sin(theta) * speed,
y = this.man.body.velocity.y,
z = Math.cos(theta) * speed


var sutit = {
"x": x,
"y": y,
"z": 10
};
console.log("sutit", sutit);


//THIS POSTS LOCATION, NEED TO POST SPEED, AND ROTATION TOO
$.ajax({
type: "POST",
async: false,
url: 'postlocation.php',
data: {
sutit: sutit
},
success: function (data) {
console.log("nomainija datubazi");
//var data2 = JSON.parse(data);
//objx = data2.x
//objy = data2.y
//objz = data2.z
//console.log("lokacijas x", data2.x);
//console.log("lokacijas y", data2.y);
//console.log("lokacijas z", data2.z);

}
});



this.man.body.setVelocity(x, y, z)
this.man.position.set(804.2014, 10, -205.63472)
} else {
var updeitot = 1;
if (this.man.animation.current === 'run' && this.canJump) this.man.animation.play('idle')
}

/**
* Player Jump
*/
if (this.keys.space.isDown && this.canJump) {
this.jump()
//THIS SHOULD ALSO BE UPDATED
}
}
}

}





//THIS IS PHASER 3D CONFIGURATION THAT INITIALIZES SCALE OF SCREEN, USING OF WEBGL library
const config = {
type: Phaser.WEBGL,
transparent: true,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
width: window.innerWidth * Math.max(1, window.devicePixelRatio / 2),
height: window.innerHeight * Math.max(1, window.devicePixelRatio / 2)
},
scene: [MainScene],
...Canvas({
antialias: false
})
}

//this loads enable3d physics module called kripken
window.addEventListener('load', () => {
enable3d(() => new Phaser.Game(config)).withPhysics('lib/ammo/kripken')
})
</script>
</body>
</html>




© 2022 GitHub, Inc.
Terms
Privacy
Security
Status
Docs
Contact GitHub
Pricing
API
Training
Blog
About
s


trešdiena, 2022. gada 23. novembris

tweening problems with enable3d.io

THIS IS 3D BROWSER GAME CODE that looks almost perfect, it does load the game, load characters in coordinates from database . and it should USE TWEENING functionality for other players besides main player, updating it every second from database, but for some reason function is broken? - originally it works right here - ([https://github.com/.../master/src/examples/use-tweenjs.html](https://github.com/enable3d/enable3d-website/blob/master/src/examples/use-tweenjs.html?fbclid=IwAR2r7ljoNSvbQjQCtwxRG8JIm-2fym4U5UQJOmu9N2L8MZTBKMM_IVGvUvk))

In my code  console.log("notiek tweeens"); and  console.log("inside2", insidecoords);

both get logged and contain needed coordinates for the tween function to work, for some reason it does not affect selected object (this.man). #javascript #enable3d 

gamenew.php - https://pastebin.pl/view/36b614c1

the whole project on github - https://github.com/lv88h/JurmalaStreets3dPSEUDO6



MORALE AND TECHNICAL DIFFICULTIES EXPLAINED:

so these two "methods" I found that should do tweening, first one does not log onUpdate thus does not position.set , nor does tween

const coords = man.position.clone()

const tween = new TWEEN.Tween(coords)
.to({ x: vertibasx, y: vertibasy, z: vertibasz }, 1000)
.easing(TWEEN.Easing.Quadratic.Out)
.onUpdate(() => {
console.log("notiek tween");
man.position.set(coords.x, coords.y, coords.z)
if (man.body) man.body.needUpdate = true
})
TWEEN.update(1000 * 1000)

second one sets position but breaks the game, also logs inside of onUpdate, and if we comment out setting position, nothing tweens 
this.tweens.add({
targets: man.position.clone(),
duration: 100000,
delay: 100,
x: '+=400',
z: '+=400',
onUpdate: () => {
console.log("noteik tween");
this.man.position.set(vertibasx.x, vertibasy.y, vertibasz.z)
}
})

trešdiena, 2022. gada 5. oktobris

Colorise/texturise Dzintari park in THUG 2 map and get a new skill ...

how to - https://mytechservinginternetmeals.blogspot.com/2022/08/thps-and-thug-2-game-modifying-tony.html

map file - https://drive.google.com/file/d/1OEvAPIlJyM2kSOscwHOnXjMK3CNlLtry/view?usp=sharing 


as You can see, game map has weird sand textures and grass is weird:




pirmdiena, 2022. gada 3. oktobris

SORTING CAR PARTS FROM 3D OBJECTS BASED ON FACES AND VERTICES. DATABASE VERSION (psuedo code 3.October 2022)

 THIS VERSION TAKES PUTS DATA IN MYSQL database, if You really want to use it without database, You probably can.











<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>3D ONLINE GAME 2</title>
<link rel="stylesheet" href="/css/examples.css?ver=1.0.0" />
<script src="/js/examples.js?ver=1.1.1"></script>
<script src="/lib/phaser.min.js?ver=3.52.0"></script>
<script src="/lib/enable3d/enable3d.phaserExtension.0.25.0.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="info-text">Use WASD, SPACE and your Mouse.<br />Works on mobile and desktop.</div>
<script>
const {
enable3d,
Scene3D,
Canvas,
ThirdDimension,
THREE,
JoyStick,
PointerLock,
PointerDrag,
ExtendedObject3D,
ThirdPersonControls
} = ENABLE3D
/**
* Is touch device?
*/
const isTouchDevice = 'ontouchstart' in window
/**
* MainScene
*/
class MainScene extends Scene3D {
constructor() {
super({ key: 'MainScene' })
}
preload() {
//this.load.html('bridge', '/assets/svg/bridge.svg')
}
init() {
this.accessThirdDimension()
this.canJump = true
this.isJumping = false
this.move = false
this.moveTop = 0
this.moveRight = 0
}
create() {
this.third.warpSpeed('camera', 'sky', 'grid', 'ground', 'light')
// this.third.ground.body.setFriction(1)
// this.third.physics.debug.enable()
/**
* Create bridge
*/
//const svg = this.cache.html.get('bridge')
//const bridgeShape = this.third.transform.fromSVGtoShape(svg)
//const scale = 35
//const bridge = this.third.add.extrude({
//shape: bridgeShape[0],
//depth: 120
//})
//bridge.scale.set(1 / scale, 1 / -scale, 1 / scale)
//bridge.shape = 'concave'
//bridge.position.setY(bridge.geometry.boundingBox.max.y / scale)
//this.third.physics.add.existing(bridge)
//bridge.body.setAngularFactor(0, 0, 0)
//bridge.body.setLinearFactor(0, 0, 0)
//bridge.body.setFriction(0.8)
/**
* Create Player
*/
/**
* box_man.glb by Jan Bláha
* https://github.com/swift502/Sketchbook
* CC-0 license 2018
*/


//gets an array from files in folder
var files = <?php $out = array();
foreach (glob('/var/www/www/assets/cardoors/*.glb') as $filename) {
$p = pathinfo($filename);
$out[] = $p['filename'];
}
$DAMN = json_encode($out);

ECHO $DAMN;


?>;
//gets lenght of file array
var mashinasdetaljuskaits = files.length;
//gets filenames
var detalas = files;
// console.log("det", detalas);
console.log("iekshas", mashinasdetaljuskaits);

//array we will store values for sorting
const arejaismasivs = [];
var ciparumasivs = [];
var titlemasivs = [];
var sakartotaismasivs = [];
console.log("sakartotaismasivs",sakartotaismasivs);

//loop that will get count of faces based on object
for(let i = 0; i < mashinasdetaljuskaits; i++){
let detalja = detalas[i];
var stringi = "/assets/cardoors/" + detalja + ".glb";


//loads every car detail from folder to make an array with number attached
this.third.load.gltf(stringi).then(object => {
const tbolt = object.scene.children[0]
this.tbolt = new ExtendedObject3D()
this.tbolt.name = 'bolt'
this.tbolt.add(tbolt)

this.tbolt.traverse(child => {
if (child.isMesh) {
const faceCount = child.geometry.attributes.position.count / 3;
//console.log("wtf");
//console.log("facecount push", faceCount, i);
console.log("dert", detalja);
//arejaismasivs.push(detalja);
let kopair = detalja + " *" + faceCount;
console.log("kopair", kopair);

/// pushes object name and face count to array outside
arejaismasivs.push(kopair);
//vajag sarindot
child.shape = 'convex'
child.castShadow = child.receiveShadow = true
// https://discourse.threejs.org/t/cant-export-material-from-blender-gltf/12258
child.material.roughness = 1
child.material.metalness = 0
}
})
})





}



//lenght of array outside
var mashinasdetaljuskaits2 = arejaismasivs.length;






// program to check if an object is an array

function checkObject(arr) {
// check if arr is array
const result = Array.isArray(arr);
if(result) {
console.log(`detalu masivs [${arr}] is an array.`);
}
else {
console.log(`detalu masivs ${arr} is not an array.`);
}
}



//SORTING INTERVAL
setInterval(function(){

//console.log("awawmasivatips",typeof(arejaismasivs));

//console.log("awawgarums",arejaismasivs.length);
//console.log("awawkey",arejaismasivs[0]);
//console.log("awawmasivs",arejaismasivs);
//checkObject(arejaismasivs);

//console.log("9999y");




//for each element sort based on face count
for(let i = 0; i < arejaismasivs.length; i++){

//console.log("sk", arejaismasivs[i].substring(arejaismasivs[i].indexOf("*") + 1));

var skaitlis = arejaismasivs[i].substring(arejaismasivs[i].indexOf("*") + 1) // skaitlis
var title = arejaismasivs[i].substring(0, arejaismasivs[i].indexOf("*"));

//console.log("title", title);


//pushes only numbers to ciparumasivs
ciparumasivs.push(arejaismasivs[i].substring(arejaismasivs[i].indexOf("*") + 1));
titlemasivs.push(arejaismasivs[i].substring(0, arejaismasivs[i].indexOf("*")));
//if(arejaismasivs[i].includes(arejaismasivs[i].substring(arejaismasivs[i].indexOf("*") + 1)){

//}

//console.log(ciparumasivs);




}

//sorts number array
ciparumasivs.sort(); // it could be sorted with titles?


var ALEN = arejaismasivs.length; //PIEŅEMSIM 53
var SLEN = sakartotaismasivs.length; // PIESKAITA PA VIENAM 53+PIEVIENOTAIS 1 IEKŠ FOR CIKLA LAI NEAPSTĀTOS





var skaititajs = 0;
///for arejaismasivs if it contains number from ciparu masivs and sakartotais masivs does not have this number contained
// if it does not, pushes title of the detail to arranged array....

for(let i = 0; i < mashinasdetaljuskaits + skaititajs; i++){
///it is not doing all elements due fact loop goes trought and some elements don't match if
// so for cycle should work first till arejais masivs length and
/// then look till sakartotais masivs length matches arejais masivs length

//arejaismasivs[i].includes(ciparumasivs[i]) means that it looks if number matches sorted ciparumasivs in iteration
//!sakartotaismasivs.includes(ciparumasivs[i]) means that it looks if number does not already match some number in sorted array (sakartotaismasivs)
//!sakartotaismasivs.includes(arejaismasivs[i]) means that it looks if entry in sorted array does not match array outside

var kopa = titlemasivs[i] + "*" + ciparumasivs[i];

//console.log("kopa", kopa);
//console.log("kopaA", arejaismasivs);
//console.log("kopaA2", arejaismasivs[i].split('*')[0]);

if(SLEN <= mashinasdetaljuskaits){
if(!arejaismasivs[i].includes(kopa) && !sakartotaismasivs.includes(arejaismasivs[i].split('*')[0])){
console.log("pushes everything", ciparumasivs[i]);
console.log("pushes everything2", arejaismasivs[i]);
sakartotaismasivs.push(arejaismasivs[i].split('*')[0]);


var data = arejaismasivs[i].split('*')[0]
console.log("sutamie dati", data);
if(data){
$.ajax({
type: "post",
url: "objdata.php",
data: {
data: data
},
cache: false,
success: function(html) {
console.log("aizsutija");
}



});
}

//console.log("SAKARTOTAIS MASIVS", sakartotaismasivs);
} else {
skaititajs+1;
}



}



}
}, 1000);






var sakartotaismasivs2 = [];
$.ajax({
type: "GET",
async: false,
url: 'loaddata.php',
data: {},
success: function (data) {
sakartotaismasivs2 = data.split(",").map(String);
}
});



var garums = sakartotaismasivs2.length;

console.log("sakartotaismasivs2", garums);
console.log("sakartotaismasivs2 NO DB", sakartotaismasivs2);



// let detaljaS = sakartotaismasivs2[i];

//console.log("arejais", sakartotaismasivs2);
//console.log("detaljaS", detaljaS);
for(let i = 0; i < garums; i++){
console.log("notiek");
let detalja2 = sakartotaismasivs2[i];
let detalja = detalja2.trim();

const pos = { x: 520, y: 920, z: 40 }
var stringi = "/assets/cardoors/" + detalja + ".glb";
this.third.load.gltf(stringi).then(object => {
const bolt = object.scene.children[0]
this.bolt = new ExtendedObject3D()
this.bolt.name = 'bolt'
this.bolt.rotateY(Math.PI + 0.1) // a hack
this.bolt.add(bolt)
// add shadow
this.bolt.traverse(child => {
if (child.isMesh) {
child.shape = 'convex'
child.castShadow = child.receiveShadow = true
// https://discourse.threejs.org/t/cant-export-material-from-blender-gltf/12258
child.material.roughness = 1
child.material.metalness = 0
}
})
/**
* Animations
*/
this.third.animationMixers.add(this.bolt.anims.mixer)
object.animations.forEach(animation => {
if (animation.name) {
/**
* This is a hack, because I could not adjust the scale with this.bolt.scale.set()
* This is not a bug from enable3d, this is how the assets a made :/
*/
animation.tracks.forEach(track => {
if (/(scale|position)/.test(track.name)) {
const newValues = track.values.map(v => v * 1)
track.values = newValues
}
})
this.bolt.anims.add(animation.name, animation)
}
})
this.bolt.anims.play('idle')
this.bolt.position.set(0, 2, 8)
/**
* Add the player to the scene with a body
*/
this.third.add.existing(this.bolt)
this.third.physics.add.existing(this.bolt, {
shape: 'capsule',
radius: 0.2,
height: 0.6,
offset: { y: -0.55 }
})
this.bolt.body.setFriction(0.8)
this.bolt.body.setAngularFactor(0, 0, 0)
///**
//* Add 3rd Person Controls
//*/
//this.controls = new ThirdPersonControls(this.third.camera, this.bolt, {
//offset: new THREE.Vector3(0, 1, 0),
//targetRadius: 3
//})
})
}
this.third.load.gltf('/assets/glb/box_man.glb').then(object2 => {
const man = object2.scene.children[0]
this.man = new ExtendedObject3D()
this.man.name = 'man'
this.man.rotateY(Math.PI + 0.1) // a hack
this.man.add(man)
// add shadow
this.man.traverse(child => {
if (child.isMesh) {
child.shape = 'convex'
child.castShadow = child.receiveShadow = true
// https://discourse.threejs.org/t/cant-export-material-from-blender-gltf/12258
child.material.roughness = 1
child.material.metalness = 0
}
})
/**
* Animations
*/
this.third.animationMixers.add(this.man.anims.mixer)
object2.animations.forEach(animation => {
if (animation.name) {
/**
* This is a hack, because I could not adjust the scale with this.man.scale.set()
* This is not a bug from enable3d, this is how the assets a made :/
*/
animation.tracks.forEach(track => {
if (/(scale|position)/.test(track.name)) {
const newValues = track.values.map(v => v * 1)
track.values = newValues
}
})
this.man.anims.add(animation.name, animation)
}
})
this.man.anims.play('idle')
this.man.position.set(0, 2, 8)
/**
* Add the player to the scene with a body
*/
this.third.add.existing(this.man)
this.third.physics.add.existing(this.man, {
shape: 'capsule',
radius: 0.2,
height: 0.6,
offset: { y: -0.55 }
})
this.man.body.setFriction(0.8)
this.man.body.setAngularFactor(0, 0, 0)
/**
* Add 3rd Person Controls
*/
this.controls = new ThirdPersonControls(this.third.camera, this.man, {
offset: new THREE.Vector3(0, 1, 0),
targetRadius: 3
})
});
/**
* Add Keys
*/
this.keys = {
a: this.input.keyboard.addKey('a'),
w: this.input.keyboard.addKey('w'),
d: this.input.keyboard.addKey('d'),
s: this.input.keyboard.addKey('s'),
space: this.input.keyboard.addKey(32)
}
/**
* PointerLock and PointerDrag
*/
if (!isTouchDevice) {
const pointerLock = new PointerLock(this.game.canvas)
const pointerDrag = new PointerDrag(this.game.canvas)
pointerDrag.onMove(delta => {
if (!pointerLock.isLocked()) return
const { x, y } = delta
this.moveTop = -y
this.moveRight = x
})
}
/**
* Add joystick
*/
if (isTouchDevice) {
const joystick = new JoyStick()
const axis = joystick.add.axis({
styles: { left: 35, bottom: 35, size: 100 }
})
axis.onMove(event => {
/**
* Update Camera
*/
const { top, right } = event
this.moveTop = top * 3
this.moveRight = right * 3
})
const buttonA = joystick.add.button({
letter: 'A',
styles: { right: 35, bottom: 110, size: 80 }
})
buttonA.onClick(() => this.jump())
const buttonB = joystick.add.button({
letter: 'B',
styles: { right: 110, bottom: 35, size: 80 }
})
buttonB.onClick(() => (this.move = true))
buttonB.onRelease(() => (this.move = false))
}
}
jump() {
if (!this.man) return
this.canJump = false
this.isJumping = true
this.man.anims.play('jump_running')
this.time.addEvent({
delay: 750,
callback: () => (this.canJump = true)
})
this.time.addEvent({
delay: 750,
callback: () => {
this.man.anims.play('idle')
this.isJumping = false
}
})
this.man.body.applyForceY(4)
}
update(time, delta) {
if (this.man && this.man.body && this.controls && this.controls.update) {
/**
* Update Controls
*/
this.controls.update(this.moveRight * 3, -this.moveTop * 3)
if (!isTouchDevice) this.moveRight = this.moveTop = 0
/**
* Player Turn
*/
const speed = 4
const v3 = new THREE.Vector3()
const rotation = this.third.camera.getWorldDirection(v3)
const theta = Math.atan2(rotation.x, rotation.z)
const rotationMan = this.man.getWorldDirection(v3)
const thetaMan = Math.atan2(rotationMan.x, rotationMan.z)
this.man.body.setAngularVelocityY(0)
const l = Math.abs(theta - thetaMan)
let rotationSpeed = isTouchDevice ? 2 : 4
let d = Math.PI / 24
if (l > d) {
if (l > Math.PI - d) rotationSpeed *= -1
if (theta < thetaMan) rotationSpeed *= -1
this.man.body.setAngularVelocityY(rotationSpeed)
}
/**
* Player Move
*/
if (this.keys.w.isDown || this.move) {
if (this.man.anims.current === 'idle' && !this.isJumping) this.man.anims.play('run')
const x = Math.sin(theta) * speed,
y = this.man.body.velocity.y,
z = Math.cos(theta) * speed
this.man.body.setVelocity(x, y, z)
} else {
if (this.man.anims.current === 'run' && !this.isJumping) this.man.anims.play('idle')
}
/**
* Player Jump
*/
if (this.keys.space.isDown && this.canJump) {
this.jump()
}
}
}
}
const config = {
type: Phaser.WEBGL,
transparent: true,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
width: window.innerWidth, // * Math.max(1, window.devicePixelRatio / 2),
height: window.innerHeight // * Math.max(1, window.devicePixelRatio / 2)
},
scene: [MainScene],
...Canvas({ antialias: true })
}
window.addEventListener('load', () => {
enable3d(() => new Phaser.Game(config)).withPhysics('/lib/ammo/kripken')
})
</script>
</body>
</html>