Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>3D Card Game with Interactive Drag and Drop</title> | |
<style> | |
body { margin: 0; } | |
canvas { display: block; } | |
</style> | |
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> | |
</head> | |
<body> | |
<canvas id="gameCanvas"></canvas> | |
<script> | |
var scene = new THREE.Scene(); | |
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
camera.position.set(0, 20, 50); | |
var renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('gameCanvas') }); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
// Lighting | |
var ambientLight = new THREE.AmbientLight(0x404040); // Soft white light | |
scene.add(ambientLight); | |
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); | |
directionalLight.position.set(0, 1, 1); | |
scene.add(directionalLight); | |
// Table | |
var tableGeometry = new THREE.BoxGeometry(100, 1, 100); | |
var tableMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); | |
var table = new THREE.Mesh(tableGeometry, tableMaterial); | |
table.position.set(0, -0.5, 0); | |
scene.add(table); | |
// Cards | |
var cardGeometry = new THREE.BoxGeometry(5, 0.1, 7); | |
var cards = []; | |
// Generate and place cards | |
for (let i = 0; i < 52; i++) { | |
var cardMaterial = new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }); | |
var card = new THREE.Mesh(cardGeometry, cardMaterial); | |
card.position.set(Math.random() * 10 - 5, 0.1 * i, Math.random() * 10 - 5); | |
scene.add(card); | |
cards.push(card); | |
} | |
var raycaster = new THREE.Raycaster(); | |
var mouse = new THREE.Vector2(); | |
var selectedCard = null; | |
var offset = new THREE.Vector3(); | |
function onMouseMove(event) { | |
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
if (selectedCard) { | |
raycaster.setFromCamera(mouse, camera); | |
var intersects = raycaster.intersectObject(table, true); | |
if (intersects.length > 0) { | |
var intersect = intersects[0]; | |
selectedCard.position.copy(intersect.point.add(offset)); | |
} | |
} | |
} | |
function onMouseDown(event) { | |
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
raycaster.setFromCamera(mouse, camera); | |
var intersects = raycaster.intersectObjects(cards, true); | |
if (intersects.length > 0) { | |
selectedCard = intersects[0].object; | |
var intersects = raycaster.intersectObject(table, true); | |
if (intersects.length > 0) { | |
var intersect = intersects[0]; | |
offset.subVectors(selectedCard.position, intersect.point); | |
} | |
} | |
} | |
function onMouseUp(event) { | |
selectedCard = null; | |
} | |
window.addEventListener('mousemove', onMouseMove, false); | |
window.addEventListener('mousedown', onMouseDown, false); | |
window.addEventListener('mouseup', onMouseUp, false); | |
function animate() { | |
requestAnimationFrame(animate); | |
renderer.render(scene, camera); | |
} | |
animate(); | |
</script> | |
</body> | |
</html> |