Spaces:
Runtime error
Runtime error
| ### Game-unknown Developer Script.md | |
| ## DR Studios "Game-Unknown" Developer script | |
| ## 3d game for hf(dunno name was just testn stuff out for a 3d world build idea. (see notes a1) | |
| # app.py | |
| import streamlit as st | |
| import streamlit.components.v1 as components | |
| st.set_page_config(page_title="Greek City Shooter", layout="wide") | |
| with open("index.html", "r", encoding="utf-8") as f: | |
| html = f.read() | |
| components.html(html, height=800) | |
| # new index.html | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <title>Greek City Shooter</title> | |
| <style> | |
| body { margin: 0; overflow: hidden; background: #000; } | |
| #ui { | |
| position: absolute; top: 10px; left: 10px; right: 10px; | |
| color: white; font-family: "Courier New", monospace; | |
| z-index: 10; pointer-events: none; | |
| display: flex; justify-content: space-between; padding: 10px; | |
| } | |
| #hp_bar { width: 200px; height: 15px; background: #333; border: 1px solid #fff; } | |
| #hp_fill { width: 100%; height: 100%; background: #ff4444; transition: width 0.2s; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="ui"> | |
| <div> | |
| <h2 style="margin:0;">GREEK CITY - RANGERS</h2> | |
| <div id="hp_bar"><div id="hp_fill"></div></div> | |
| </div> | |
| <div id="ammo" style="font-size: 24px;">AMMO: 30/30</div> | |
| </div> | |
| <div id="container"></div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/three@0.152/examples/js/loaders/GLTFLoader.js"></script> | |
| <script> | |
| // ---------- CONFIG ---------- | |
| const GameConfig = { | |
| worldPath: "greek city.glb", | |
| playerModelPath: "male.glb", | |
| playerSpawn: new THREE.Vector3(5, 1, 10), | |
| enemySpawns: [ | |
| new THREE.Vector3(10, 1, -5), | |
| new THREE.Vector3(-8, 1, -12), | |
| new THREE.Vector3(3, 1, -18) | |
| ], | |
| fogColor: 0x222529, | |
| skyColor: 0x222529 | |
| }; | |
| // ---------- GLOBALS ---------- | |
| let scene, camera, renderer, clock; | |
| let world = null; | |
| let player = null, playerSpeed = 20, playerHP = 100; | |
| let enemies = [], bullets = [], enemyBullets = [], particles = []; | |
| let keys = {}; | |
| let mouse = new THREE.Vector2(); | |
| let raycaster = new THREE.Raycaster(); | |
| let ammo = 30, maxAmmo = 30, reloadTime = 1.5, reloading = false; | |
| let timeMult = 1.0, shake = 0; | |
| let lastShotTime = 0, fireRate = 0.15; | |
| let lastEnemyFire = 0, enemyFireCooldown = 0.8; | |
| // ---------- INPUT ---------- | |
| window.addEventListener("keydown", e => { keys[e.key.toLowerCase()] = true; }); | |
| window.addEventListener("keyup", e => { keys[e.key.toLowerCase()] = false; }); | |
| window.addEventListener("mousemove", (event) => { | |
| if (!renderer) return; | |
| const rect = renderer.domElement.getBoundingClientRect(); | |
| mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; | |
| mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; | |
| }); | |
| window.addEventListener("mousedown", (event) => { | |
| if (event.button === 0) shoot(); | |
| }); | |
| // ---------- INIT ---------- | |
| function init() { | |
| scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(GameConfig.skyColor); | |
| scene.fog = new THREE.Fog(GameConfig.fogColor, 10, 120); | |
| camera = new THREE.PerspectiveCamera( | |
| 75, | |
| window.innerWidth / window.innerHeight, | |
| 0.1, | |
| 1000 | |
| ); | |
| clock = new THREE.Clock(); | |
| renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| document.getElementById("container").appendChild(renderer.domElement); | |
| // Lights | |
| scene.add(new THREE.AmbientLight(0x404040, 2)); | |
| const sun = new THREE.DirectionalLight(0xffffff, 1.0); | |
| sun.position.set(20, 40, 10); | |
| sun.castShadow = true; | |
| scene.add(sun); | |
| loadWorld(); | |
| createPlayer(); | |
| spawnEnemies(); | |
| window.addEventListener("resize", onWindowResize, false); | |
| animate(); | |
| } | |
| // ---------- WORLD ---------- | |
| function loadWorld() { | |
| const loader = new THREE.GLTFLoader(); | |
| loader.load( | |
| GameConfig.worldPath, | |
| (gltf) => { | |
| world = gltf.scene; | |
| world.scale.set(1, 1, 1); // tweak as needed | |
| world.position.set(0, 0, 0); // tweak as needed | |
| scene.add(world); | |
| }, | |
| undefined, | |
| (err) => console.error("Error loading world:", err) | |
| ); | |
| } | |
| // ---------- PLAYER ---------- | |
| function createPlayer() { | |
| const loader = new THREE.GLTFLoader(); | |
| loader.load( | |
| GameConfig.playerModelPath, | |
| (gltf) => { | |
| player = gltf.scene; | |
| player.scale.set(1, 1, 1); | |
| player.position.copy(GameConfig.playerSpawn); | |
| scene.add(player); | |
| }, | |
| undefined, | |
| (err) => { | |
| console.warn("Failed to load player model, using capsule:", err); | |
| const geom = new THREE.CapsuleGeometry(0.5, 1); | |
| const mat = new THREE.MeshStandardMaterial({ color: 0x2d5a27 }); | |
| player = new THREE.Mesh(geom, mat); | |
| player.position.copy(GameConfig.playerSpawn); | |
| scene.add(player); | |
| } | |
| ); | |
| } | |
| // ---------- ENEMIES ---------- | |
| function spawnEnemies() { | |
| GameConfig.enemySpawns.forEach((pos) => { | |
| const geom = new THREE.BoxGeometry(4, 4, 4); | |
| const mat = new THREE.MeshStandardMaterial({ color: 0x333333 }); | |
| const enemy = new THREE.Mesh(geom, mat); | |
| enemy.position.copy(pos); | |
| enemy.userData = { hp: 100 }; | |
| enemies.push(enemy); | |
| scene.add(enemy); | |
| }); | |
| } | |
| // ---------- MOVEMENT ---------- | |
| function handleMovement(dt) { | |
| if (!player) return; | |
| const moveVector = new THREE.Vector3(); | |
| const forward = new THREE.Vector3(0, 0, -1); | |
| const right = new THREE.Vector3(1, 0, 0); | |
| if (keys["w"]) moveVector.add(forward); | |
| if (keys["s"]) moveVector.sub(forward); | |
| if (keys["a"]) moveVector.sub(right); | |
| if (keys["d"]) moveVector.add(right); | |
| if (moveVector.lengthSq() > 0) { | |
| moveVector.normalize(); | |
| moveVector.multiplyScalar(playerSpeed * dt * timeMult); | |
| player.position.add(moveVector); | |
| } | |
| // Aim toward mouse on ground plane | |
| raycaster.setFromCamera(mouse, camera); | |
| const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); | |
| const intersectPoint = new THREE.Vector3(); | |
| raycaster.ray.intersectPlane(plane, intersectPoint); | |
| if (intersectPoint && player) { | |
| const dir = intersectPoint.clone().sub(player.position); | |
| const angle = Math.atan2(dir.x, dir.z); | |
| player.rotation.y = angle; | |
| } | |
| } | |
| // ---------- SHOOTING ---------- | |
| function shoot() { | |
| if (!player || reloading) return; | |
| const now = performance.now() / 1000; | |
| if (now - lastShotTime < fireRate) return; | |
| if (ammo <= 0) { | |
| startReload(); | |
| return; | |
| } | |
| lastShotTime = now; | |
| ammo -= 1; | |
| updateAmmoUI(); | |
| const bulletGeom = new THREE.SphereGeometry(0.15, 8, 8); | |
| const bulletMat = new THREE.MeshBasicMaterial({ color: 0xffff00 }); | |
| const bullet = new THREE.Mesh(bulletGeom, bulletMat); | |
| bullet.position.copy(player.position).add(new THREE.Vector3(0, 1.0, 0)); | |
| const dir = new THREE.Vector3(0, 0, -1); | |
| dir.applyAxisAngle(new THREE.Vector3(0, 1, 0), player.rotation.y); | |
| bullet.userData = { | |
| vel: dir.clone().multiplyScalar(80), | |
| friend: true | |
| }; | |
| bullets.push(bullet); | |
| scene.add(bullet); | |
| } | |
| function startReload() { | |
| if (reloading) return; | |
| reloading = true; | |
| const ammoDiv = document.getElementById("ammo"); | |
| ammoDiv.textContent = "RELOADING..."; | |
| setTimeout(() => { | |
| ammo = maxAmmo; | |
| reloading = false; | |
| updateAmmoUI(); | |
| }, reloadTime * 1000); | |
| } | |
| function updateAmmoUI() { | |
| const ammoDiv = document.getElementById("ammo"); | |
| ammoDiv.textContent = "AMMO: " + ammo + "/" + maxAmmo; | |
| } | |
| // ---------- ENEMY FIRE ---------- | |
| function enemyFire(dt) { | |
| const now = performance.now() / 1000; | |
| if (now - lastEnemyFire < enemyFireCooldown) return; | |
| lastEnemyFire = now; | |
| enemies.forEach((enemy) => { | |
| if (enemy.userData.hp <= 0 || !player) return; | |
| const dir = player.position.clone().sub(enemy.position); | |
| const dist = dir.length(); | |
| if (dist > 120) return; | |
| dir.normalize(); | |
| const bulletGeom = new THREE.SphereGeometry(0.15, 8, 8); | |
| const bulletMat = new THREE.MeshBasicMaterial({ color: 0xff4444 }); | |
| const bullet = new THREE.Mesh(bulletGeom, bulletMat); | |
| bullet.position.copy(enemy.position).add(new THREE.Vector3(0, 2.0, 0)); | |
| bullet.userData = { | |
| vel: dir.clone().multiplyScalar(60), | |
| friend: false | |
| }; | |
| enemyBullets.push(bullet); | |
| scene.add(bullet); | |
| }); | |
| } | |
| // ---------- EXPLOSIONS ---------- | |
| function createExplosion(pos, color = 0xff4400) { | |
| shake = 0.5; | |
| for (let i = 0; i < 20; i++) { | |
| const p = new THREE.Mesh( | |
| new THREE.SphereGeometry(0.2, 6, 6), | |
| new THREE.MeshBasicMaterial({ color }) | |
| ); | |
| p.position.copy(pos); | |
| p.userData = { | |
| vel: new THREE.Vector3( | |
| (Math.random() - 0.5) * 6, | |
| Math.random() * 6, | |
| (Math.random() - 0.5) * 6 | |
| ), | |
| life: 1.0 | |
| }; | |
| particles.push(p); | |
| scene.add(p); | |
| } | |
| } | |
| // ---------- LOOP ---------- | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| const dt = clock.getDelta(); | |
| timeMult = (playerHP < 30) ? 0.4 : 1.0; | |
| if (shake > 0) { | |
| camera.position.x += (Math.random() - 0.5) * shake; | |
| camera.position.y += (Math.random() - 0.5) * shake; | |
| shake *= 0.9; | |
| } | |
| handleMovement(dt); | |
| // Player bullets | |
| bullets = bullets.filter((b) => { | |
| b.position.add(b.userData.vel.clone().multiplyScalar(dt * timeMult)); | |
| let keep = true; | |
| enemies.forEach((enemy) => { | |
| if (enemy.userData.hp <= 0) return; | |
| if (b.position.distanceTo(enemy.position) < 3) { | |
| enemy.userData.hp -= 40; | |
| createExplosion(enemy.position.clone().add(new THREE.Vector3(0, 2, 0))); | |
| if (enemy.userData.hp <= 0) { | |
| scene.remove(enemy); | |
| } | |
| keep = false; | |
| } | |
| }); | |
| if (!keep) { | |
| scene.remove(b); | |
| return false; | |
| } | |
| if (b.position.length() > 500) { | |
| scene.remove(b); | |
| return false; | |
| } | |
| return true; | |
| }); | |
| // Enemy bullets | |
| enemyBullets = enemyBullets.filter((b) => { | |
| b.position.add(b.userData.vel.clone().multiplyScalar(dt * timeMult)); | |
| let keep = true; | |
| if (player && b.position.distanceTo(player.position) < 1.5) { | |
| playerHP -= 10; | |
| if (playerHP < 0) playerHP = 0; | |
| document.getElementById("hp_fill").style.width = playerHP + "%"; | |
| createExplosion(player.position.clone().add(new THREE.Vector3(0, 1, 0)), 0xff0000); | |
| keep = false; | |
| } | |
| if (!keep) { | |
| scene.remove(b); | |
| return false; | |
| } | |
| if (b.position.length() > 500) { | |
| scene.remove(b); | |
| return false; | |
| } | |
| return true; | |
| }); | |
| // Particles | |
| particles = particles.filter((p) => { | |
| p.position.add(p.userData.vel.clone().multiplyScalar(dt)); | |
| p.userData.life -= dt; | |
| if (p.userData.life <= 0) { | |
| scene.remove(p); | |
| return false; | |
| } | |
| return true; | |
| }); | |
| enemyFire(dt); | |
| // Camera follow | |
| if (player) { | |
| const camOffset = new THREE.Vector3(0, 8, 18); | |
| const camPos = player.position.clone().add(camOffset); | |
| camera.position.lerp(camPos, 0.1); | |
| const lookAtPos = player.position.clone().add(new THREE.Vector3(0, 2, -10)); | |
| camera.lookAt(lookAtPos); | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| // ---------- RESIZE ---------- | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| // ---------- START ---------- | |
| init(); | |
| </script> | |
| </body> | |
| </html> | |
| # <next script goes here.PlaceHolder> | |
| #ph# <script starts here> | |
| # note from Dave:(notes a1) | |
| what my end result/ hope to Accomplish is: A HF Space that consist of a GUI that lets you choose from a preset of 3d world environments, then user uploads There own: glb, obj, .ghlt 3d Model (or chose one of preset models from drop down menu), then choose from a couple of creator(me) defined world environments, and then hits "Enter" button on screen to jump on in a game world environment and tryout, experiment, kill some monsters or just !@$!@ around and Explore (with there model in a 3d environment, try it out, or show it off, etc..) a 3d game environment (choose from various preset environments [currently only 1 uploaded greek city.glb plan on more]) and do some stuff (not fully defined yet[ ideas i got though small open world can walk, talk, shoot simple npcs, fly, box others would be cool otherwise npc , explore shit like that]) and if i would be lucky and make a stretch a small lobby so multiple users could possibly interact with each other and of course they for any of this probably would have to enter in there own hf-tolken. { in summary this is the mission plan on this un-named project } |