Skip to content

Instantly share code, notes, and snippets.

@solanoize
Created August 8, 2023 21:09
Show Gist options
  • Select an option

  • Save solanoize/8b8424c3fecc5c387a4fdfc8e7c52fd2 to your computer and use it in GitHub Desktop.

Select an option

Save solanoize/8b8424c3fecc5c387a4fdfc8e7c52fd2 to your computer and use it in GitHub Desktop.
/**
* Yanwar Solahudin
* ================
* I built this simple code to implement the game logic of card combat and
* using energy scores. I enjoyed it, and the code is rudimentary as it
* needs to be updated to take advantage of the defense features and possibly
* additional game logic if the cards go over two.
*/
let temmplatePlayer = {
name: "",
player: null,
lifePoint: 18000,
attack: 0,
defence: 0,
};
let gamePlayers = [];
let gameBoard = null;
let STATE_ON = false;
let SHAKE = true;
function attackEffect(enemy) {
let position = enemy.player.parentElement.object3D;
let scene = enemy.player.parentElement;
let effect = document.createElement("a-gltf-model");
effect.setAttribute("src", "#attack-effect");
effect.setAttribute("crossFadeDuration", "2");
effect.setAttribute("position", {
x: position.x,
y: position.y,
z: position.z,
});
// effect.setAttribute("rotation", {
// x: -90,
// y: 0,
// z: 0,
// });
effect.setAttribute("animation-mixer", "clip: *");
// effect.setAttribute("scale", "0.6 0.6 0.6");
scene.appendChild(effect);
let time = setTimeout(() => {
effect.remove();
clearTimeout(time);
}, 4000);
}
function gameStatus(player, flip, timer = 0) {
let statusMessage = `N: ${player.name.toUpperCase()}`;
statusMessage += `\nE: ${player.energy}`;
statusMessage += `\nA: ${player.attack}`;
statusMessage += `\nD: ${player.defence}`;
statusMessage += `\nR: ${flip}`;
if (player.status) {
player.status.setAttribute("value", statusMessage);
}
}
function gameBoardStatus(player, timer, winner = false) {
let statusMessage = "";
if (winner) {
statusMessage = `${player.name.toUpperCase()} IS LOST!!!`;
gameBoard.setAttribute("value", statusMessage);
} else {
if (player) {
statusMessage = `${player.name.toUpperCase()} attack mode...`;
}
statusMessage += `\nProgress ${(timer * 0.1).toFixed()}%`;
}
try {
gameBoard.setAttribute("value", statusMessage);
} catch (error) {}
}
function fight(player, enemy) {
console.log("Dia ", player.name, "Attack -> ", enemy.name);
player.player.setAttribute(
"animation-mixer",
`clip: ${player.activity.attack}`
);
let out = setTimeout(() => {
player.player.setAttribute(
"animation-mixer",
`clip: ${player.activity.idle}`
);
clearTimeout(out);
}, 3000);
attackEffect(enemy);
enemy.energy -= player.attack;
return { player, enemy };
}
AFRAME.registerComponent("loaded", {
init: function () {
let el = this.el;
el.addEventListener("markerFound", (e) => {
// emit to register
if (e.target.getAttribute("preset") === "kanji") {
gameBoard = e.target.childNodes[1];
console.log(e.target.childNodes);
} else {
let p = e.target.childNodes[1];
let activity = {};
for (let obj of p.components["gltf-model"].model.animations) {
activity[obj.name.toLowerCase()] = obj.name;
}
console.log(activity);
el.emit("onPlayerRegister", {
player: {
player: p,
position: p.object3D.position,
energy: 18000,
attack: parseInt(p.dataset.attack),
defence: parseInt(p.dataset.defence),
status: document.querySelector(`#text-${p.dataset.player}`),
name: p.dataset.player,
activity,
},
});
}
});
},
});
AFRAME.registerComponent("player-register", {
init: function () {
let el = this.el;
this.timer = 0;
this.flip = false;
this.start = false;
this.playerRun = null;
this.enemy = null;
el.addEventListener("onPlayerRegister", (e) => {
gamePlayers.push(e.detail.player);
gameStatus(e.detail.player);
});
},
tick: function (time, dt) {
if (gamePlayers.length === 2) {
this.start = true;
for (let obj of gamePlayers) {
console.log("OBJ", obj);
if (obj.energy <= 1) {
gameBoardStatus(obj, 0, true);
this.start = false;
gamePlayers = [];
}
}
}
if (this.start) {
this.timer += 1;
gameBoardStatus(this.playerRun, this.timer);
if (this.timer > 100) {
let rand = Math.random() < 0.5;
this.playerRun = gamePlayers[rand ? 1 : 0];
this.enemy = gamePlayers[rand ? 0 : 1];
gameBoardStatus(this.playerRun, time);
const { player, enemy } = fight(this.playerRun, this.enemy);
this.playerRun = player;
this.enemy = enemy;
console.log("E", this.enemy);
gameStatus(this.enemy);
SHAKE = !SHAKE;
this.timer = 0;
}
}
},
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<title>Hello World!</title>
<!-- include A-Frame obviously -->
<script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.0.0/dist/aframe-extras.min.js"></script>
<!-- include ar.js for A-Frame -->
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script src="./script.js"></script>
<script src="./ais.js"></script>
<script>
AFRAME.registerComponent("anim", {
tick: function () {
// console.log(this.el.components['gltf-model'])
}
})
</script>
</head>
<body style="margin: 0px; overflow: hidden">
<a-scene
player-register
arjs="trackingMethod: best; sourceType: webcam; debugUIEnabled: false;"
embedded
renderer="logarithmicDepthBuffer: true;"
vr-mode-ui="enabled: false"
id="scene"
>
<a-assets>
<!-- Run, Idle, Walk -->
<a-asset-item id="halldora" src="./assets/3d/Halldora.glb"></a-asset-item>
<a-asset-item id="sveinn" src="./assets/3d/Sveinn2.glb"></a-asset-item>
<a-asset-item id="taintvine" src="./assets/3d/Taintvine.glb"></a-asset-item>
<a-asset-item id="voodooghoul" src="./assets/3d/Voodooghoul.glb"></a-asset-item>
<a-asset-item id="effect" src="./assets/3d/effect.glb"></a-asset-item>
<a-asset-item id="attack-effect" src="./assets/3d/attack-effect.glb"></a-asset-item>
<a-asset-item id="candle" src="./assets/3d/candle.glb"></a-asset-item>
</a-assets>
<a-light type="point" color="blue" position="0 5 0"></a-light>
<a-light type="point" color="red" position="0 5 4"></a-light>
<a-light type="point" color="cyan" position="0 5 -4"></a-light>
<a-light type="point" color="yellow" position="4 5 -4"></a-light>
<a-light type="point" color="green" position="-4 5 -4"></a-light>
<a-light type="point" color="black" position="-4 5 -4"></a-light>
<a-marker type='pattern' loaded url='./assets/patt/Halldora.patt'>
<a-gltf-model src="#halldora" data-attack="2000" data-defence="5000" rotation="0 180 0" data-player="halldora" position="0 0.6 0" animation-mixer="clip: Idle" scale="0.3 0.3 0.3"></a-gltf-model>
<a-gltf-model src="#effect" anim id="effect" position="0 0.3 0" animation-mixer></a-gltf-model>
<a-text position="1.5 0 0" rotation="-90 0 0" id="text-halldora" value="Loading..." width="6" color="red"></a-text>
<a-light type="ambient" color="#222"></a-light>
</a-marker>
<a-marker type='pattern' loaded url='./assets/patt/Sveinn.patt'>
<a-gltf-model src="#sveinn" data-attack="4000" data-defence="3000" data-player="sveinn" position="0 0.6 0" rotation="0 -180 0" animation-mixer></a-gltf-model>
<a-gltf-model src="#effect" anim id="effect" position="0 0.3 0" animation-mixer></a-gltf-model>
<a-text position="1.5 0 0" rotation="-90 0 0" id="text-sveinn" value="Sveinn\nEnergi: 18000\nATC: 2000" width="6" color="red"></a-text>
<a-light type="ambient" color="#222"></a-light>
</a-marker>
<!-- <a-gltf-model src="#attack-effect" anim id="effect" rotation="-90 0 0" scale="0.5 0.5 0.5" position="0 0.3 0" animation-mixer></a-gltf-model> -->
<a-marker type='pattern' loaded url='./assets/patt/Taintvine.patt'>
<a-gltf-model src="#taintvine" data-attack="2000" data-defence="5000" data-player="taintvine" position="0 0.6 0" scale="0.1 0.1 0.1"></a-gltf-model>
<a-gltf-model src="#effect" anim id="effect" position="0 0.3 0" animation-mixer></a-gltf-model>
<a-text position="1.5 0 0" rotation="-90 0 0" id="text-taintvine" value="Taintvine\nEnergi: 18000\nATC: 2000" width="6" color="red"></a-text>
<a-light type="ambient" color="#222"></a-light>
</a-marker>
<a-marker type='pattern' loaded url='./assets/patt/Voodooghoul.patt'>
<a-gltf-model src="#voodooghoul" data-attack="2000" data-defence="5000" data-player="voodooghoul" position="0 0.6 0" animation-mixer="clip: *" ></a-gltf-model>
<a-gltf-model src="#effect" anim id="effect" position="0 0.3 0" animation-mixer></a-gltf-model>
<a-text position="1.5 0 0" rotation="-90 0 0" id="text-voodooghoul" value="Loading..." width="6" color="red"></a-text>
<a-light type="ambient" color="#222"></a-light>
</a-marker>
<a-marker preset='kanji' loaded>
<a-text align="center" position="0 0 1" rotation="-90 0 0" id="text-kanji" value="Loading..." width="3.5" color="red"></a-text>
<a-gltf-model src="#voodooghoul" scale="0.4 0.4 0.4" animation="property: rotation; to: 0 360 0; loop: true; dur: 10000" animation-mixer="clip: *" ></a-gltf-model>
<!-- <a-plane position="0 0 0" rotation="-90 0 0" animation="property: rotation; to: 0 360 0; loop: true; dur: 10000" width="0.5" height="0.5" color="#000000"></a-plane> -->
<!-- <a-light type="point" color="blue" position="0 5 0"></a-light> -->
<!-- <a-box opacity="0.3" rotation="-90 0 0" depth="0.2"></a-box> -->
<!-- <a-box opacity="0.4" rotation="-90 0 -2" depth="0.5"></a-box> -->
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment