Advertisement
Guest User

Watermelon

a guest
Apr 14th, 2025
495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.24 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Watermelon Physics Simulation</title>
  7. <style>
  8. body {
  9. margin: 0;
  10. padding: 0;
  11. display: flex;
  12. flex-direction: column;
  13. align-items: center;
  14. justify-content: center;
  15. min-height: 100vh;
  16. background-color: #f0f0f0;
  17. font-family: Arial, sans-serif;
  18. }
  19.  
  20. #canvas-container {
  21. position: relative;
  22. width: 800px;
  23. height: 600px;
  24. margin: 20px auto;
  25. box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  26. border-radius: 8px;
  27. overflow: hidden;
  28. }
  29.  
  30. canvas {
  31. background-color: #87CEEB;
  32. display: block;
  33. }
  34.  
  35. .controls {
  36. margin: 20px 0;
  37. display: flex;
  38. gap: 10px;
  39. }
  40.  
  41. button {
  42. padding: 10px 20px;
  43. background-color: #4CAF50;
  44. color: white;
  45. border: none;
  46. border-radius: 4px;
  47. cursor: pointer;
  48. font-size: 16px;
  49. transition: background-color 0.3s;
  50. }
  51.  
  52. button:hover {
  53. background-color: #45a049;
  54. }
  55.  
  56. .info {
  57. margin-top: 10px;
  58. text-align: center;
  59. color: #333;
  60. }
  61. </style>
  62. </head>
  63. <body>
  64. <h1>Watermelon Physics Simulation</h1>
  65.  
  66. <div id="canvas-container">
  67. <canvas id="simulationCanvas" width="800" height="600"></canvas>
  68. </div>
  69.  
  70. <div class="controls">
  71. <button id="restartBtn">Restart Simulation</button>
  72. </div>
  73.  
  74. <div class="info">
  75. Watch as the watermelon falls, hits the ground, and bursts into fragments!
  76. </div>
  77.  
  78. <script>
  79. // Canvas setup
  80. const canvas = document.getElementById('simulationCanvas');
  81. const ctx = canvas.getContext('2d');
  82. const width = canvas.width;
  83. const height = canvas.height;
  84.  
  85. // Physics constants
  86. const gravity = 0.2;
  87. const friction = 0.98;
  88. const restitution = 0.7; // Bounciness
  89.  
  90. // Watermelon properties
  91. let watermelon = {
  92. x: width / 2,
  93. y: 100,
  94. radiusX: 40,
  95. radiusY: 50,
  96. velocityX: 0,
  97. velocityY: 0,
  98. rotation: 0,
  99. rotationSpeed: 0,
  100. isBurst: false,
  101. burstHeight: 0
  102. };
  103.  
  104. // Fragment class
  105. class Fragment {
  106. constructor(x, y, radius, color, velocityX, velocityY, rotationSpeed) {
  107. this.x = x;
  108. this.y = y;
  109. this.radius = radius;
  110. this.color = color;
  111. this.velocityX = velocityX;
  112. this.velocityY = velocityY;
  113. this.rotation = Math.random() * Math.PI * 2;
  114. this.rotationSpeed = rotationSpeed;
  115. this.opacity = 1;
  116. }
  117.  
  118. update() {
  119. this.velocityY += gravity;
  120. this.x += this.velocityX;
  121. this.y += this.velocityY;
  122. this.velocityX *= friction;
  123. this.velocityY *= friction;
  124. this.rotation += this.rotationSpeed;
  125.  
  126. // Ground collision
  127. if (this.y + this.radius > height - 20) {
  128. this.y = height - 20 - this.radius;
  129. this.velocityY *= -restitution;
  130. this.velocityX *= friction;
  131. }
  132.  
  133. // Side walls collision
  134. if (this.x - this.radius < 0) {
  135. this.x = this.radius;
  136. this.velocityX *= -restitution;
  137. }
  138. if (this.x + this.radius > width) {
  139. this.x = width - this.radius;
  140. this.velocityX *= -restitution;
  141. }
  142. }
  143.  
  144. draw() {
  145. ctx.save();
  146. ctx.translate(this.x, this.y);
  147. ctx.rotate(this.rotation);
  148. ctx.globalAlpha = this.opacity;
  149.  
  150. // Draw fragment
  151. ctx.beginPath();
  152. ctx.arc(0, 0, this.radius, 0, Math.PI * 2);
  153. ctx.fillStyle = this.color;
  154. ctx.fill();
  155.  
  156. // Add seed details
  157. ctx.beginPath();
  158. ctx.arc(0, 0, this.radius * 0.7, 0, Math.PI * 2);
  159. ctx.fillStyle = '#ff6347';
  160. ctx.fill();
  161.  
  162. // Draw seed
  163. ctx.beginPath();
  164. ctx.ellipse(0, 0, this.radius * 0.3, this.radius * 0.15, 0, 0, Math.PI * 2);
  165. ctx.fillStyle = '#333';
  166. ctx.fill();
  167.  
  168. ctx.restore();
  169. }
  170. }
  171.  
  172. // Particle class for splash effect
  173. class Particle {
  174. constructor(x, y) {
  175. this.x = x;
  176. this.y = y;
  177. this.size = Math.random() * 5 + 2;
  178. this.velocityX = (Math.random() - 0.5) * 10;
  179. this.velocityY = (Math.random() - 0.5) * 10 - 5;
  180. this.gravity = 0.2;
  181. this.opacity = 1;
  182. this.color = `hsl(${Math.random() * 30 + 10}, 100%, 50%)`;
  183. }
  184.  
  185. update() {
  186. this.velocityY += this.gravity;
  187. this.x += this.velocityX;
  188. this.y += this.velocityY;
  189. this.opacity -= 0.02;
  190.  
  191. if (this.y + this.size > height - 20) {
  192. this.y = height - 20 - this.size;
  193. this.velocityY *= -0.6;
  194. }
  195. }
  196.  
  197. draw() {
  198. ctx.globalAlpha = this.opacity;
  199. ctx.fillStyle = this.color;
  200. ctx.beginPath();
  201. ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
  202. ctx.fill();
  203. ctx.globalAlpha = 1;
  204. }
  205. }
  206.  
  207. // Arrays to store fragments and particles
  208. let fragments = [];
  209. let particles = [];
  210.  
  211. // Draw ground
  212. function drawGround() {
  213. ctx.fillStyle = '#8B4513';
  214. ctx.fillRect(0, height - 20, width, 20);
  215.  
  216. // Add some texture to the ground
  217. ctx.fillStyle = '#6B3300';
  218. for (let i = 0; i < width; i += 20) {
  219. ctx.fillRect(i, height - 20, 10, 5);
  220. }
  221. }
  222.  
  223. // Draw watermelon
  224. function drawWatermelon() {
  225. ctx.save();
  226. ctx.translate(watermelon.x, watermelon.y);
  227. ctx.rotate(watermelon.rotation);
  228.  
  229. // Outer green rind
  230. ctx.beginPath();
  231. ctx.ellipse(0, 0, watermelon.radiusX, watermelon.radiusY, 0, 0, Math.PI * 2);
  232. ctx.fillStyle = '#2E8B57';
  233. ctx.fill();
  234.  
  235. // Inner red flesh
  236. ctx.beginPath();
  237. ctx.ellipse(0, 0, watermelon.radiusX * 0.8, watermelon.radiusY * 0.85, 0, 0, Math.PI * 2);
  238. ctx.fillStyle = '#FF6347';
  239. ctx.fill();
  240.  
  241. // Seeds
  242. for (let i = 0; i < 15; i++) {
  243. const angle = Math.random() * Math.PI * 2;
  244. const distance = Math.random() * watermelon.radiusX * 0.6;
  245. const x = Math.cos(angle) * distance;
  246. const y = Math.sin(angle) * distance;
  247.  
  248. ctx.beginPath();
  249. ctx.ellipse(x, y, 3, 6, angle, 0, Math.PI * 2);
  250. ctx.fillStyle = '#333';
  251. ctx.fill();
  252. }
  253.  
  254. ctx.restore();
  255. }
  256.  
  257. // Burst watermelon into fragments
  258. function burstWatermelon() {
  259. watermelon.isBurst = true;
  260.  
  261. // Create fragments
  262. const fragmentCount = 30;
  263. for (let i = 0; i < fragmentCount; i++) {
  264. const angle = Math.random() * Math.PI * 2;
  265. const distance = Math.random() * watermelon.radiusX * 0.8;
  266. const x = watermelon.x + Math.cos(angle) * distance;
  267. const y = watermelon.y + Math.sin(angle) * distance;
  268.  
  269. const radius = Math.random() * 15 + 10;
  270.  
  271. // Random color between green and red
  272. const colorChoice = Math.random() > 0.5 ? '#2E8B57' : '#FF6347';
  273.  
  274. // Velocity based on explosion force
  275. const power = 5 + Math.random() * 10;
  276. const velocityX = Math.cos(angle) * power;
  277. const velocityY = Math.sin(angle) * power - 5; // Upward bias
  278.  
  279. fragments.push(new Fragment(
  280. x, y, radius, colorChoice, velocityX, velocityY,
  281. (Math.random() - 0.5) * 0.2
  282. ));
  283. }
  284.  
  285. // Create splash particles
  286. for (let i = 0; i < 50; i++) {
  287. particles.push(new Particle(watermelon.x, watermelon.y));
  288. }
  289. }
  290.  
  291. // Update simulation
  292. function update() {
  293. // Clear canvas
  294. ctx.clearRect(0, 0, width, height);
  295.  
  296. // Draw sky background with gradient
  297. const gradient = ctx.createLinearGradient(0, 0, 0, height);
  298. gradient.addColorStop(0, '#87CEEB');
  299. gradient.addColorStop(1, '#E0F7FF');
  300. ctx.fillStyle = gradient;
  301. ctx.fillRect(0, 0, width, height);
  302.  
  303. // Draw ground
  304. drawGround();
  305.  
  306. // Update watermelon if not burst
  307. if (!watermelon.isBurst) {
  308. watermelon.velocityY += gravity;
  309. watermelon.y += watermelon.velocityY;
  310. watermelon.x += watermelon.velocityX;
  311. watermelon.rotation += watermelon.rotationSpeed;
  312.  
  313. // Check if watermelon hits the ground
  314. if (watermelon.y + watermelon.radiusY > height - 20) {
  315. watermelon.y = height - 20 - watermelon.radiusY;
  316. watermelon.velocityY *= -restitution;
  317. watermelon.velocityX *= friction;
  318. watermelon.rotationSpeed += (Math.random() - 0.5) * 0.1;
  319.  
  320. // Burst if velocity is high enough
  321. if (Math.abs(watermelon.velocityY) > 5) {
  322. burstWatermelon();
  323. }
  324. }
  325.  
  326. // Draw watermelon
  327. drawWatermelon();
  328. } else {
  329. // Update and draw fragments
  330. for (let i = fragments.length - 1; i >= 0; i--) {
  331. fragments[i].update();
  332. fragments[i].draw();
  333.  
  334. // Remove fragments that have stopped moving
  335. if (Math.abs(fragments[i].velocityX) < 0.1 &&
  336. Math.abs(fragments[i].velocityY) < 0.1 &&
  337. fragments[i].y + fragments[i].radius >= height - 20) {
  338. fragments.splice(i, 1);
  339. }
  340. }
  341.  
  342. // Update and draw particles
  343. for (let i = particles.length - 1; i >= 0; i--) {
  344. particles[i].update();
  345. particles[i].draw();
  346.  
  347. // Remove faded particles
  348. if (particles[i].opacity <= 0) {
  349. particles.splice(i, 1);
  350. }
  351. }
  352. }
  353.  
  354. requestAnimationFrame(update);
  355. }
  356.  
  357. // Initialize simulation
  358. function init() {
  359. // Reset watermelon
  360. watermelon = {
  361. x: width / 2,
  362. y: 100,
  363. radiusX: 40,
  364. radiusY: 50,
  365. velocityX: 0,
  366. velocityY: 0,
  367. rotation: 0,
  368. rotationSpeed: 0,
  369. isBurst: false,
  370. burstHeight: 0
  371. };
  372.  
  373. // Clear fragments and particles
  374. fragments = [];
  375. particles = [];
  376.  
  377. // Start animation
  378. update();
  379. }
  380.  
  381. // Event listeners
  382. document.getElementById('restartBtn').addEventListener('click', init);
  383.  
  384. // Add some initial velocity to make it more interesting
  385. watermelon.velocityX = (Math.random() - 0.5) * 2;
  386. watermelon.rotationSpeed = (Math.random() - 0.5) * 0.05;
  387.  
  388. // Start simulation
  389. init();
  390. </script>
  391. </body>
  392. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement