見出し画像

Claude AIを使って1分でゲームを作る

Command: Create a simple, playable 2d survial game using React and SVG graphics.
Claude: Certainly! I'll create a simple 2D survival game using React and SVG graphics. This game will feature a player character who must collect food and avoid enemies to survive. Let's call it "Forest Survivor".

import React, { useState, useEffect } from 'react';
import { Moon, Apple } from 'lucide-react';

const GAME_WIDTH = 400;
const GAME_HEIGHT = 300;
const PLAYER_SIZE = 20;
const FOOD_SIZE = 15;
const ENEMY_SIZE = 25;

const ForestSurvivor = () => {
  const [playerPos, setPlayerPos] = useState({ x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 });
  const [food, setFood] = useState({ x: 0, y: 0 });
  const [enemy, setEnemy] = useState({ x: 0, y: 0 });
  const [score, setScore] = useState(0);
  const [gameOver, setGameOver] = useState(false);

  useEffect(() => {
    const handleKeyPress = (e) => {
      if (gameOver) return;
      const speed = 10;
      switch (e.key) {
        case 'ArrowUp':
          setPlayerPos(prev => ({ ...prev, y: Math.max(prev.y - speed, 0) }));
          break;
        case 'ArrowDown':
          setPlayerPos(prev => ({ ...prev, y: Math.min(prev.y + speed, GAME_HEIGHT - PLAYER_SIZE) }));
          break;
        case 'ArrowLeft':
          setPlayerPos(prev => ({ ...prev, x: Math.max(prev.x - speed, 0) }));
          break;
        case 'ArrowRight':
          setPlayerPos(prev => ({ ...prev, x: Math.min(prev.x + speed, GAME_WIDTH - PLAYER_SIZE) }));
          break;
      }
    };

    window.addEventListener('keydown', handleKeyPress);
    return () => window.removeEventListener('keydown', handleKeyPress);
  }, [gameOver]);

  useEffect(() => {
    if (gameOver) return;

    const moveEnemy = () => {
      setEnemy(prev => ({
        x: Math.max(0, Math.min(GAME_WIDTH - ENEMY_SIZE, prev.x + (Math.random() - 0.5) * 20)),
        y: Math.max(0, Math.min(GAME_HEIGHT - ENEMY_SIZE, prev.y + (Math.random() - 0.5) * 20))
      }));
    };

    const enemyInterval = setInterval(moveEnemy, 500);
    return () => clearInterval(enemyInterval);
  }, [gameOver]);

  useEffect(() => {
    const checkCollisions = () => {
      // Check food collision
      if (
        Math.abs(playerPos.x - food.x) < (PLAYER_SIZE + FOOD_SIZE) / 2 &&
        Math.abs(playerPos.y - food.y) < (PLAYER_SIZE + FOOD_SIZE) / 2
      ) {
        setScore(prev => prev + 1);
        spawnFood();
      }

      // Check enemy collision
      if (
        Math.abs(playerPos.x - enemy.x) < (PLAYER_SIZE + ENEMY_SIZE) / 2 &&
        Math.abs(playerPos.y - enemy.y) < (PLAYER_SIZE + ENEMY_SIZE) / 2
      ) {
        setGameOver(true);
      }
    };

    const gameLoop = setInterval(checkCollisions, 100);
    return () => clearInterval(gameLoop);
  }, [playerPos, food, enemy]);

  const spawnFood = () => {
    setFood({
      x: Math.random() * (GAME_WIDTH - FOOD_SIZE),
      y: Math.random() * (GAME_HEIGHT - FOOD_SIZE)
    });
  };

  useEffect(() => {
    spawnFood();
    setEnemy({
      x: Math.random() * (GAME_WIDTH - ENEMY_SIZE),
      y: Math.random() * (GAME_HEIGHT - ENEMY_SIZE)
    });
  }, []);

  const restartGame = () => {
    setPlayerPos({ x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 });
    spawnFood();
    setEnemy({
      x: Math.random() * (GAME_WIDTH - ENEMY_SIZE),
      y: Math.random() * (GAME_HEIGHT - ENEMY_SIZE)
    });
    setScore(0);
    setGameOver(false);
  };

  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <h1 className="text-3xl font-bold mb-4">Forest Survivor</h1>
      <div className="relative" style={{ width: GAME_WIDTH, height: GAME_HEIGHT }}>
        <svg width={GAME_WIDTH} height={GAME_HEIGHT} className="bg-green-200 border-2 border-green-600">
          {/* Player */}
          <circle cx={playerPos.x + PLAYER_SIZE / 2} cy={playerPos.y + PLAYER_SIZE / 2} r={PLAYER_SIZE / 2} fill="blue" />
          
          {/* Food */}
          <Apple color="red" size={FOOD_SIZE} x={food.x} y={food.y} />
          
          {/* Enemy */}
          <Moon color="purple" size={ENEMY_SIZE} x={enemy.x} y={enemy.y} />
        </svg>
        {gameOver && (
          <div className="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
            <div className="bg-white p-4 rounded">
              <h2 className="text-2xl font-bold mb-2">Game Over</h2>
              <p className="mb-4">Your score: {score}</p>
              <button
                className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                onClick={restartGame}
              >
                Restart
              </button>
            </div>
          </div>
        )}
      </div>
      <div className="mt-4">
        <p className="text-xl">Score: {score}</p>
        <p className="text-sm mt-2">Use arrow keys to move</p>
      </div>
    </div>
  );
};

export default ForestSurvivor;

I've created a simple 2D survival game using React and SVG graphics. Here's a breakdown of the game:

  1. The game is called "Forest Survivor".

  2. The player controls a blue circle using arrow keys.

  3. The objective is to collect red apples (food) to increase the score.

  4. A purple moon (enemy) moves randomly around the screen.

  5. If the player touches the enemy, the game ends.

  6. The game keeps track of the score and allows restarting when it's over.

To play the game:

  1. Use the arrow keys to move the blue circle (player).

  2. Try to collect as many red apples as possible to increase your score.

  3. Avoid the purple moon, as touching it will end the game.

  4. When the game is over, you can restart by clicking the "Restart" button.

The game uses React hooks for state management and side effects. SVG is used for rendering the game elements, and the Lucide React library is used for the food (apple) and enemy (moon) icons.

Would you like me to explain any specific part of the code or make any modifications to the game?


この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?