[Dragon Boat Festival Special] Use React to make interactive games, let you enjoy the Dragon Boat Festival!

Dumplings for Dragon Boat Festival

The Dragon Boat Festival is coming! I don't know how to make zongzi, so use the React framework to make a few zongzi, and learn from me.
First, we need to add a Zongzi picture and place it on the page. In React, we can use <img>tags to add images like this:

import React from "react";
import "./App.css";
import zongzi from "./zongzi.png";
function App() {
    
    
  return (
    <div className="App">
      <img src={
    
    zongzi} alt="zongzi" />
    </div>
  );
}
export default App;

In the above code, I imported an zongzi.pngimage called from local and put it in <div>the middle of the element.
Next, I add some animation effects to the zongzi. We can use CSS animations to achieve this. Here is a simple example:

@keyframes drop {
    
    
  0% {
    
    
    transform: translateY(-400px);
  }
  100% {
    
    
    transform: translateY(800px);
  }
}
img {
    
    
  animation-name: drop;
  animation-duration: 5s;
  animation-iteration-count: infinite;
}

In the code above, I've defined a dropCSS animation named , which will drop the zongzi down from the top. I also set the duration of the animation to 5 seconds and it repeats infinitely.
Now, I have successfully placed the Dragon Boat Festival rice dumpling on the page and added a falling animation effect to it.

pick up rice dumplings game

Next, I will add a small game to my Dragon Boat Festival game: picking up zongzi. In the game, the user needs to click on the zongzi on the screen to score points.
First, we need to add some zongzi to the page and use CSS to make them appear randomly on the page.

import React, {
    
     useState, useEffect } from "react";
import "./App.css";
import zongzi from "./zongzi.png";
const ZONGZI_SIZE = 50;
function App() {
    
    
  const [zongzis, setZongzis] = useState([]);
  useEffect(() => {
    
    
    const interval = setInterval(() => {
    
    
      const x = Math.random() * window.innerWidth;
      const y = Math.random() * window.innerHeight;
      setZongzis((zongzis) => [...zongzis, {
    
     x, y }]);
    }, 1000);
    return () => clearInterval(interval);
  }, []);
  return (
    <div className="App" onClick={
    
    handleClick}>
      {
    
    zongzis.map((zongzi, index) => (
        <img
          key={
    
    index}
          src={
    
    zongziImage}
          alt="zongzi"
          style={
    
    {
    
    
            position: "absolute",
            left: zongzi.x,
            top: zongzi.y,
            width: ZONGZI_SIZE,
            height: ZONGZI_SIZE,
            cursor: "pointer",
          }}
        />
      ))}
    </div>
  );
}
export default App;

In the code, I use useState()hooks to manage all the zongzi, and use useEffect()the hook to randomly generate a new zongzi at regular intervals. I also set a random coordinate for each zongzi and render it to the screen.
Next, we need to add a function that handles the click event to let the user click on the zongzi to score.

function handleClick(event) {
    
    
  const x = event.clientX;
  const y = event.clientY;
  setZongzis((zongzis) => {
    
    
    const clickedZongzi = zongzis.find((zongzi) => {
    
    
      const left = zongzi.x;
      const right = zongzi.x + ZONGZI_SIZE;
      const top = zongzi.y;
      const bottom = zongzi.y + ZONGZI_SIZE;
      return x >= left && x <= right && y >= top && y <= bottom;
    });
    if (clickedZongzi) {
    
    
      return zongzis.filter((zongzi) => zongzi !== clickedZongzi);
    }
    return zongzis;
  });
}

In the code above, I check if the user's clicked position is within range of any of the zongzi. If it is, we will remove the zongzi from the zongzi list and increase the score. Otherwise, we don't do anything.
See the full code below:

import React, {
    
     useState, useEffect } from "react";
import "./App.css";
import zongziImage from "./zongzi.png";
const ZONGZI_SIZE = 50;
function App() {
    
    
  const [zongzis, setZongzis] = useState([]);
  useEffect(() => {
    
    
    const interval = setInterval(() => {
    
    
      const x = Math.random() * window.innerWidth;
      const y = Math.random() * window.innerHeight;
      setZongzis((zongzis) => [...zongzis, {
    
     x, y }]);
    }, 1000);
    return () => clearInterval(interval);
  }, []);
  function handleClick(event) {
    
    
    const x = event.clientX;
    const y = event.clientY;
    setZongzis((zongzis) => {
    
    
      const clickedZongzi = zongzis.find((zongzi) => {
    
    
        const left = zongzi.x;
        const right = zongzi.x + ZONGZI_SIZE;
        const top = zongzi.y;
        const bottom = zongzi.y + ZONGZI_SIZE;
        return x >= left && x <= right && y >= top && y <= bottom;
      });
      if (clickedZongzi) {
    
    
        return zongzis.filter((zongzi) => zongzi !== clickedZongzi);
      }
      return zongzis;
    });
  }
  return (
    <div className="App" onClick={
    
    handleClick}>
      {
    
    zongzis.map((zongzi, index) => (
        <img
          key={
    
    index}
          src={
    
    zongziImage}
          alt="zongzi"
          style={
    
    {
    
    
            position: "absolute",
            left: zongzi.x,
            top: zongzi.y,
            width: ZONGZI_SIZE,
            height: ZONGZI_SIZE,
            cursor: "pointer",
          }}
        />
      ))}
    </div>
  );
}
export default App;

useState()In the above code, I used and hook in React useEffect()to manage my list of zongzi and the timer to generate new zongzi. I also wrote a handleClick()function to handle the user's click event and remove the clicked zongzi from the zongzi list to increase the score.
We also set the class in CSS styles .Appto be full screen and the background color to yellow to make the game more interesting. Here's the full CSS code:

.App {
    
    
  background-color: yellow;
  height: 100vh;
  width: 100vw;
}

Finally, I need to add some extra functionality to the game, such as scoring and game over handling. We can add a scoreboard to the page and update it every time a score is scored. We can handleClick()check whether the zongzi list is empty in the function to determine whether the game is over, and display a prompt box at the end. The complete code is as follows:

import React, {
    
     useState, useEffect } from "react";
import "./App.css";
import zongziImage from "./zongzi.png";
const ZONGZI_SIZE = 50;
function App() {
    
    
  const [zongzis, setZongzis] = useState([]);
  const [score, setScore] = useState(0);
  const [gameOver, setGameOver] = useState(false);
  useEffect(() => {
    
    
    if (zongzis.length === 0) {
    
    
      setGameOver(true);
    }
  }, [zongzis]);
  useEffect(() => {
    
    
    const interval = setInterval(() => {
    
    
      const x = Math.random() * window.innerWidth;
      const y = Math.random() * window.innerHeight;
      setZongzis((zongzis) => [...zongzis, {
    
     x, y }]);
    }, 1000);
    return () => clearInterval(interval);
  }, []);
  function handleClick(event) {
    
    
    const x = event.clientX;
    const y = event.clientY;
    setZongzis((zongzis) => {
    
    
      const clickedZongzi = zongzis.find((zongzi) => {
    
    
        const left = zongzi.x;
        const right = zongzi.x + ZONGZI_SIZE;
        const top = zongzi.y;
        const bottom = zongzi.y + ZONGZI_SIZE;
        return x >= left && x <= right && y >= top && y <= bottom;
      });
      if (clickedZongzi) {
    
    
        setScore((score) => score + 1);
        return zongzis.filter((zongzi) => zongzi !== clickedZongzi);
      }
      return zongzis;
    });
  }
  return (
    <div className="App" onClick={
    
    handleClick}>
      <div className="score-board">Score: {
    
    score}</div>
      {
    
    gameOver && <div className="game-over">Game Over!</div>}
      {
    
    zongzis.map((zongzi, index) => (
        <img
          key={
    
    index}
          src={
    
    zongziImage}
          alt="zongzi"
          style={
    
    {
    
    
            position: "absolute",
            left: zongzi.x,
            top: zongzi.y,
            width: ZONGZI_SIZE,
            height: ZONGZI_SIZE,
            cursor: "pointer",
          }}
        />
      ))}
    </div>
  );
}
export default App;

In the above code, I added a scorestate called to record the user's score. I also added a gameOverstate called to indicate if the game is over, and display a tooltip to the user when the game is over.
Finally, we add some simple CSS styling for the scoreboard and game over tooltip:

.score-board {
    
    
  position: fixed;
  top: 10px;
  left: 10px;
  font-size: 24px;
  font-weight: bold;
}
.game-over {
    
    
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 48px;
  font-weight: bold;
  color: red;
}

Now, I have completed the code and idea of ​​using React to make Dragon Boat Festival Zongzi and a small game with Zongzi dropping. I hope this article can help you better understand the use of React and how to use React to make simple interactive games.

Guess you like

Origin blog.csdn.net/weixin_46254812/article/details/131325524