Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created December 20, 2025 13:04
Show Gist options
  • Select an option

  • Save EncodeTheCode/5fb17e1817c2da8a9db2ae4aa3e79626 to your computer and use it in GitHub Desktop.

Select an option

Save EncodeTheCode/5fb17e1817c2da8a9db2ae4aa3e79626 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rogue Talent Mock</title>
<style>
body {
margin:0;
background:#0b1220;
color:#e5e7eb;
font-family:Arial, sans-serif;
}
canvas {
display:block;
background:#020617;
}
#hud {
position:absolute;
top:10px;
left:10px;
background:rgba(0,0,0,.6);
padding:8px;
border-radius:6px;
}
#talentOverlay {
position:fixed;
inset:0;
background:rgba(0,0,0,.7);
display:none;
justify-content:center;
align-items:center;
}
#talentWindow {
width:1000px;
height:600px;
background:#020617;
border-radius:10px;
display:flex;
gap:10px;
padding:10px;
}
.tree {
flex:1;
background:#020617;
border:1px solid #1e293b;
border-radius:8px;
padding:8px;
}
.tree h3 { margin:4px 0; text-align:center; }
.tree .points { text-align:center; color:#38bdf8; }
.grid {
display:grid;
grid-template-columns:repeat(3,1fr);
grid-template-rows:repeat(5,1fr);
gap:6px;
margin-top:6px;
}
.node {
background:#020617;
border:1px solid #1e293b;
border-radius:6px;
padding:4px;
font-size:12px;
text-align:center;
}
.node.locked { opacity:.35 }
.node .count { font-size:11px; color:#38bdf8 }
.node button {
background:#020617;
color:#e5e7eb;
border:1px solid #1e293b;
cursor:pointer;
margin:2px;
}
.node button:disabled { opacity:.3; cursor:not-allowed }
</style>
</head>
<body>
<canvas id="game" width="900" height="600"></canvas>
<div id="hud">WASD move · Mouse aim · Press <b>K</b> for talents</div>
<div id="talentOverlay">
<div id="talentWindow"></div>
</div>
<script>
/* =====================
GAME (PLAYER + AIM)
===================== */
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const player = { x:450, y:300, speed:200, ax:450, ay:300 };
const keys = {};
window.addEventListener("keydown",e=>keys[e.key]=true);
window.addEventListener("keyup",e=>keys[e.key]=false);
canvas.addEventListener("mousemove",e=>{
const r=canvas.getBoundingClientRect();
player.ax=e.clientX-r.left;
player.ay=e.clientY-r.top;
});
let last=performance.now();
function loop(t){
const dt=(t-last)/1000; last=t;
let dx=0,dy=0;
if(keys.w)dy--; if(keys.s)dy++;
if(keys.a)dx--; if(keys.d)dx++;
if(dx||dy){
const l=Math.hypot(dx,dy); dx/=l; dy/=l;
player.x+=dx*player.speed*dt;
player.y+=dy*player.speed*dt;
}
ctx.clearRect(0,0,900,600);
ctx.beginPath();
ctx.moveTo(player.x,player.y);
ctx.lineTo(player.ax,player.ay);
ctx.strokeStyle="#000"; ctx.lineWidth=3; ctx.stroke();
ctx.beginPath();
ctx.arc(player.x,player.y,14,0,Math.PI*2);
ctx.fillStyle="#38bdf8"; ctx.fill();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
/* =====================
TALENT SYSTEM
===================== */
const TOTAL_POINTS = 51;
const TIER_REQ = [0,5,10,15,20];
let available = TOTAL_POINTS;
const trees = ["Stalker","Duelist","Nightblade"].map(name=>({
name,
talents:[],
}));
trees.forEach(tree=>{
for(let r=0;r<5;r++){
for(let c=0;c<3;c++){
tree.talents.push({
row:r,
name:`${tree.name} Talent`,
max:(r===0&&c===1)?3:1,
spent:0
});
}
}
});
const overlay=document.getElementById("talentOverlay");
const windowEl=document.getElementById("talentWindow");
function pointsInTree(t){
return t.talents.reduce((s,x)=>s+x.spent,0);
}
function buildUI(){
windowEl.innerHTML="";
trees.forEach(tree=>{
const div=document.createElement("div");
div.className="tree";
const pts=pointsInTree(tree);
div.innerHTML=`<h3>${tree.name}</h3>
<div class="points">${pts} pts</div>`;
const grid=document.createElement("div");
grid.className="grid";
tree.talents.forEach(t=>{
const unlocked = pts >= TIER_REQ[t.row];
const n=document.createElement("div");
n.className="node"+(unlocked?"":" locked");
n.innerHTML=`<div>${t.name}</div>
<div class="count">${t.spent}/${t.max}</div>`;
const plus=document.createElement("button");
plus.textContent="+";
plus.disabled=!unlocked||t.spent>=t.max||available<=0;
plus.onclick=()=>{
t.spent++; available--; buildUI();
};
const minus=document.createElement("button");
minus.textContent="-";
minus.disabled=t.spent<=0||pointsInTree(tree)-1<TIER_REQ[t.row];
minus.onclick=()=>{
t.spent--; available++; buildUI();
};
n.append(plus,minus);
grid.appendChild(n);
});
div.appendChild(grid);
windowEl.appendChild(div);
});
}
buildUI();
/* =====================
TOGGLE TALENTS
===================== */
let open=false;
window.addEventListener("keydown",e=>{
if(e.key.toLowerCase()==="k"){
open=!open;
overlay.style.display=open?"flex":"none";
buildUI();
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment