-
Notifications
You must be signed in to change notification settings - Fork 839
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
389 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# **Pottery-Game** | ||
|
||
--- | ||
|
||
<br> | ||
|
||
## **Description 📃** | ||
<!-- Add your game description here --> | ||
- Game_Name is an interactive 3D pottery game where players can sculpt and customize virtual pottery creations using various controls and options. | ||
|
||
<br> | ||
|
||
## **Functionalities 🎮** | ||
<!-- Add functionalities over here --> | ||
- Shape controls: Widen, narrow, heighten, shorten, indent, bulge. | ||
- Texture options: Apply stripes or polka dots textures. | ||
- Baking and coloring: Bake the pottery and apply custom colors. | ||
- Progress tracking: Track user interactions and display progress. | ||
- Reset: Reset the pottery to its initial shape. | ||
- Randomize: Generate a random pottery shape. | ||
- Save to gallery: Save created pottery images to a gallery. | ||
- Share: Share pottery creations on social media. | ||
|
||
<br> | ||
|
||
## **How to Play? 🕹️** | ||
<!-- Add the steps how to play the game --> | ||
- Click on the buttons to shape the pottery: | ||
- Use "Widen" and "Narrow" to adjust width. | ||
- Use "Heighten" and "Shorten" to adjust height. | ||
- Use "Indent" and "Bulge" for asymmetrical shapes. | ||
- Click "Bake" to finalize the shape with a baked appearance. | ||
- Click "Color" to apply a custom color to the pottery. | ||
- Use "Reset" to start over with a new pottery shape. | ||
- Explore "Randomize" for a surprise pottery shape. | ||
- Save your favorite creations to the gallery and share them! | ||
|
||
<br> | ||
|
||
## **Screenshots 📸** | ||
|
||
<br> | ||
<!-- Add your screenshots like this --> | ||
<!-- ![image](url) --> | ||
|
||
<br> | ||
|
||
## **Working Video 📹** | ||
<!-- Add your working video over here --> | ||
<!-- Write a brief description of what the video shows --> | ||
|
||
<br> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,325 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>3D Pottery Game</title> | ||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"> | ||
<style> | ||
body { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
min-height: 100vh; | ||
background-color: #f0f4f8; | ||
padding: 20px; | ||
} | ||
canvas { | ||
border: 1px solid #ccc; | ||
} | ||
.controls { | ||
display: flex; | ||
justify-content: center; | ||
margin-top: 20px; | ||
gap: 10px; | ||
flex-wrap: wrap; | ||
} | ||
.btn { | ||
padding: 10px 20px; | ||
border: none; | ||
border-radius: 5px; | ||
color: #fff; | ||
cursor: pointer; | ||
font-size: 16px; | ||
transition: background 0.3s, transform 0.3s; | ||
} | ||
.btn:hover { | ||
transform: scale(1.05); | ||
} | ||
.btn-widen { background-color: #4caf50; } | ||
.btn-narrow { background-color: #f44336; } | ||
.btn-heighten { background-color: #2196f3; } | ||
.btn-shorten { background-color: #ffeb3b; } | ||
.btn-indent { background-color: #ff5722; } | ||
.btn-bulge { background-color: #3f51b5; } | ||
.btn-bake { background-color: #8b4513; } | ||
.btn-color { background-color: #9c27b0; } | ||
.btn-reset { background-color: #009688; } | ||
.btn-randomize { background-color: #e91e63; } | ||
.btn-texture { background-color: #795548; } | ||
.btn-gallery { background-color: #607d8b; } | ||
.btn-share { background-color: #ff9800; } | ||
.progress, .gallery { | ||
margin-top: 20px; | ||
text-align: center; | ||
} | ||
.progress p, .gallery p { | ||
margin: 5px 0; | ||
} | ||
.gallery { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
} | ||
.gallery img { | ||
max-width: 100px; | ||
margin: 5px; | ||
} | ||
</style> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/framer-motion/6.0.7/framer-motion.umd.js"></script> | ||
</head> | ||
<body> | ||
|
||
<div class="text-center mb-6"> | ||
<h1 class="text-4xl font-bold title">3D Pottery Game</h1> | ||
<p class="mt-2 text-lg">Shape your pot by clicking the buttons below!</p> | ||
</div> | ||
|
||
<div id="container" class="flex justify-center mb-6"></div> | ||
|
||
<div class="controls"> | ||
<button onclick="widenPot()" class="btn btn-widen">Widen</button> | ||
<button onclick="narrowPot()" class="btn btn-narrow">Narrow</button> | ||
<button onclick="heightenPot()" class="btn btn-heighten">Heighten</button> | ||
<button onclick="shortenPot()" class="btn btn-shorten">Shorten</button> | ||
<button onclick="indentPot()" class="btn btn-indent">Indent</button> | ||
<button onclick="bulgePot()" class="btn btn-bulge">Bulge</button> | ||
<button onclick="bakePot()" class="btn btn-bake">Bake</button> | ||
<button onclick="colorPot()" class="btn btn-color">Color</button> | ||
<button onclick="resetPot()" class="btn btn-reset">Reset</button> | ||
<button onclick="randomizePot()" class="btn btn-randomize">Randomize</button> | ||
<button onclick="applyTexture()" class="btn btn-texture">Texture</button> | ||
<button onclick="saveToGallery()" class="btn btn-gallery">Save to Gallery</button> | ||
<button onclick="sharePot()" class="btn btn-share">Share</button> | ||
</div> | ||
|
||
<div class="progress mt-6 p-4 bg-white rounded-lg shadow-lg w-full text-center" id="progress"> | ||
<p class="font-bold text-xl mb-4">Progress:</p> | ||
<p class="mb-2">Widen clicks: <span id="widen-count" class="text-blue-500">0</span></p> | ||
<p class="mb-2">Narrow clicks: <span id="narrow-count" class="text-blue-500">0</span></p> | ||
<p class="mb-2">Heighten clicks: <span id="heighten-count" class="text-blue-500">0</span></p> | ||
<p class="mb-2">Shorten clicks: <span id="shorten-count" class="text-blue-500">0</span></p> | ||
<p class="mb-2">Baked: <span id="baked-status" class="text-blue-500">No</span></p> | ||
<p class="mb-2">Colored: <span id="colored-status" class="text-blue-500">No</span></p> | ||
<p class="mb-2">Texture: <span id="texture-status" class="text-blue-500">None</span></p> | ||
</div> | ||
|
||
<div class="gallery mt-6 p-4 bg-white rounded-lg shadow-lg w-full text-center" id="gallery"> | ||
<p class="font-bold text-xl mb-4">Gallery:</p> | ||
<div id="gallery-container"></div> | ||
</div> | ||
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> | ||
<script> | ||
let scene, camera, renderer, pot, light; | ||
let points = []; | ||
const baseY = -2.5; // Maintain the base of the pot | ||
let baked = false; | ||
let colored = false; | ||
let texture = 'None'; | ||
let widenCount = 0, narrowCount = 0, heightenCount = 0, shortenCount = 0; | ||
const sounds = { | ||
click: new Audio('click.mp3'), | ||
shape: new Audio('shape.mp3'), | ||
bake: new Audio('bake.mp3') | ||
}; | ||
|
||
function init() { | ||
scene = new THREE.Scene(); | ||
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | ||
camera.position.z = 5; | ||
|
||
renderer = new THREE.WebGLRenderer(); | ||
renderer.setSize(window.innerWidth, window.innerHeight); | ||
document.getElementById('container').appendChild(renderer.domElement); | ||
|
||
points = getLathePoints(); | ||
const geometry = new THREE.LatheGeometry(points); | ||
const material = new THREE.MeshPhongMaterial({ color: 0x8b5e3c }); | ||
pot = new THREE.Mesh(geometry, material); | ||
scene.add(pot); | ||
|
||
light = new THREE.PointLight(0xffffff, 1, 100); | ||
light.position.set(10, 10, 10); | ||
scene.add(light); | ||
|
||
animate(); | ||
} | ||
|
||
function getLathePoints() { | ||
const newPoints = []; | ||
for (let i = 0; i < 10; i++) { | ||
newPoints.push(new THREE.Vector2(Math.sin(i * 0.2) * 0.5 + 0.5, (i - 5) * 0.5)); | ||
} | ||
return newPoints; | ||
} | ||
|
||
function updatePot() { | ||
pot.geometry.dispose(); | ||
pot.geometry = new THREE.LatheGeometry(points); | ||
updateProgress(); | ||
} | ||
|
||
function animate() { | ||
requestAnimationFrame(animate); | ||
pot.rotation.y += 0.01; | ||
renderer.render(scene, camera); | ||
} | ||
|
||
function playSound(sound) { | ||
sounds[sound].currentTime = 0; | ||
sounds[sound].play(); | ||
} | ||
|
||
function widenPot() { | ||
points.forEach(point => point.x += 0.1); | ||
widenCount++; | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function narrowPot() { | ||
points.forEach(point => point.x = Math.max(point.x - 0.1, 0.1)); | ||
narrowCount++; | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function heightenPot() { | ||
points.forEach((point, index) => point.y = baseY + (index / (points.length - 1)) * 5.5 + 0.1); | ||
heightenCount++; | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function shortenPot() { | ||
points.forEach((point, index) => point.y = baseY + (index / (points.length - 1)) * 5.5 - 0.1); | ||
shortenCount++; | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function indentPot() { | ||
points.forEach((point, index) => { | ||
if (index > points.length / 2) { | ||
point.x -= 0.1; | ||
} | ||
}); | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function bulgePot() { | ||
points.forEach((point, index) => { | ||
if (index < points.length / 2) { | ||
point.x += 0.1; | ||
} | ||
}); | ||
updatePot(); | ||
playSound('shape'); | ||
} | ||
|
||
function bakePot() { | ||
if (!baked) { | ||
pot.material.color.set(0x8b4513); // Darker baked color | ||
pot.material.shininess = 10; // Add some shininess | ||
baked = true; | ||
updateProgress(); | ||
playSound('bake'); | ||
} | ||
} | ||
|
||
function colorPot() { | ||
const color = prompt("Enter a hex color code (e.g., #ff5733):"); | ||
if (/^#[0-9A-F]{6}$/i.test(color)) { | ||
pot.material.color.set(color); | ||
colored = true; | ||
updateProgress(); | ||
playSound('click'); | ||
} else { | ||
alert("Invalid color code. Please try again."); | ||
} | ||
} | ||
|
||
function resetPot() { | ||
points = getLathePoints(); | ||
baked = false; | ||
colored = false; | ||
texture = 'None'; | ||
widenCount = 0; | ||
narrowCount = 0; | ||
heightenCount = 0; | ||
shortenCount = 0; | ||
updatePot(); | ||
playSound('click'); | ||
} | ||
|
||
function randomizePot() { | ||
points = getLathePoints().map(point => new THREE.Vector2(point.x * Math.random(), point.y * Math.random())); | ||
updatePot(); | ||
playSound('click'); | ||
} | ||
|
||
function applyTexture() { | ||
const textures = ['None', 'Stripes', 'Polka Dots']; | ||
texture = prompt(`Enter a texture: ${textures.join(', ')}`); | ||
if (textures.includes(texture)) { | ||
if (texture === 'Stripes') { | ||
pot.material.map = new THREE.TextureLoader().load('stripes.png'); | ||
} else if (texture === 'Polka Dots') { | ||
pot.material.map = new THREE.TextureLoader().load('polka_dots.png'); | ||
} else { | ||
pot.material.map = null; | ||
} | ||
pot.material.needsUpdate = true; | ||
updateProgress(); | ||
playSound('click'); | ||
} else { | ||
alert("Invalid texture. Please try again."); | ||
} | ||
} | ||
|
||
function saveToGallery() { | ||
renderer.render(scene, camera); | ||
const dataURL = renderer.domElement.toDataURL(); | ||
const img = document.createElement('img'); | ||
img.src = dataURL; | ||
document.getElementById('gallery-container').appendChild(img); | ||
playSound('click'); | ||
} | ||
|
||
function sharePot() { | ||
renderer.render(scene, camera); | ||
const dataURL = renderer.domElement.toDataURL(); | ||
const shareData = { | ||
title: 'My 3D Pot', | ||
text: 'Check out my 3D pot!', | ||
url: dataURL | ||
}; | ||
navigator.share(shareData).catch(err => console.log('Error sharing:', err)); | ||
playSound('click'); | ||
} | ||
|
||
function updateProgress() { | ||
document.getElementById('widen-count').innerText = widenCount; | ||
document.getElementById('narrow-count').innerText = narrowCount; | ||
document.getElementById('heighten-count').innerText = heightenCount; | ||
document.getElementById('shorten-count').innerText = shortenCount; | ||
document.getElementById('baked-status').innerText = baked ? "Yes" : "No"; | ||
document.getElementById('colored-status').innerText = colored ? "Yes" : "No"; | ||
document.getElementById('texture-status').innerText = texture; | ||
|
||
// Using Framer Motion for smooth animations on progress update | ||
const progress = document.getElementById('progress'); | ||
framerMotion.motion.animate(progress, { | ||
scale: [1, 1.1, 1], | ||
transition: { duration: 0.5 }, | ||
}); | ||
} | ||
|
||
window.onload = init; | ||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.