# data[].attributes.headline
달의 공전 궤도 추가하기

# data[].attributes.subject
달의 공전 궤도 추가하기

# data[].attributes.body
import pygame

import math

# 화면 설정

pygame.init()

width, height = 1000, 1000

screen = pygame.display.set_mode((width, height))

pygame.display.set_caption("태양계 공전 시뮬레이션")

# 색깔

white = (255, 255, 255)

yellow = (255, 255, 0)

blue = (0, 0, 255)

red = (255, 0, 0)

green = (0, 255, 0)

gray = (169, 169, 169)

# 행성 초기 설정

sun_radius = 50

mercury_radius = 10

venus_radius = 15

earth_radius = 20

mars_radius = 18

moon_radius = 5 # 달의 반지름

mercury_distance = 100

venus_distance = 150

earth_distance = 220

mars_distance = 300

moon_distance = 30 # 지구로부터 달까지의 거리

mercury_angle = 0

venus_angle = 0

earth_angle = 0

mars_angle = 0

moon_angle = 0 # 달의 초기 각도

# 각 행성별 공전 속도 설정 (더 느린 값)

mercury_speed = 0.017

venus_speed = 0.016

earth_speed = 0.015

mars_speed = 0.014

moon_speed = 0.05 # 달의 공전 속도 (지구보다 빠름)

# 메인 루프

running = True

while running:

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

screen.fill((0, 0, 0))

# 태양 그리기

pygame.draw.circle(screen, yellow, (width//2, height//2), sun_radius)

# 수성 공전

mercury_x = int(width//2 + mercury_distance * math.cos(mercury_angle))

mercury_y = int(height//2 + mercury_distance * math.sin(mercury_angle))

pygame.draw.circle(screen, gray, (mercury_x, mercury_y), mercury_radius)

mercury_angle += mercury_speed

# 금성 공전

venus_x = int(width//2 + venus_distance * math.cos(venus_angle))

venus_y = int(height//2 + venus_distance * math.sin(venus_angle))

pygame.draw.circle(screen, blue, (venus_x, venus_y), venus_radius)

venus_angle += venus_speed

# 지구 공전

earth_x = int(width//2 + earth_distance * math.cos(earth_angle))

earth_y = int(height//2 + earth_distance * math.sin(earth_angle))

pygame.draw.circle(screen, green, (earth_x, earth_y), earth_radius)

earth_angle += earth_speed

# 달 공전

moon_x = int(earth_x + moon_distance * math.cos(moon_angle))

moon_y = int(earth_y + moon_distance * math.sin(moon_angle))

pygame.draw.circle(screen, white, (moon_x, moon_y), moon_radius)

moon_angle += moon_speed

# 화성 공전

mars_x = int(width//2 + mars_distance * math.cos(mars_angle))

mars_y = int(height//2 + mars_distance * math.sin(mars_angle))

pygame.draw.circle(screen, red, (mars_x, mars_y), mars_radius)

mars_angle += mars_speed

pygame.display.flip()

pygame.time.delay(10)

pygame.quit()

# data[].attributes.headline
반복되는 로직을 함수로 변경하기

# data[].attributes.subject
반복되는 로직을 함수로 변경하기

# data[].attributes.body
import pygame

import math

# 화면 설정

pygame.init()

width, height = 1000, 1000

screen = pygame.display.set_mode((width, height))

pygame.display.set_caption("태양계 공전 시뮬레이션")

# 색깔

white = (255, 255, 255)

yellow = (255, 255, 0)

blue = (0, 0, 255)

red = (255, 0, 0)

green = (0, 255, 0)

gray = (169, 169, 169)

# 행성 초기 설정

sun_radius = 50

mercury_radius = 10

venus_radius = 15

earth_radius = 20

mars_radius = 18

moon_radius = 5

mercury_distance = 100

venus_distance = 150

earth_distance = 220

mars_distance = 300

moon_distance = 30

# 각 행성별 공전 속도

mercury_speed = 0.017

venus_speed = 0.016

earth_speed = 0.015

mars_speed = 0.014

moon_speed = 0.05

# 초기 각도

mercury_angle = 0

venus_angle = 0

earth_angle = 0

mars_angle = 0

moon_angle = 0

# 공전 및 그리기 함수 정의

def draw_orbiting_body(center_x, center_y, distance, angle, radius, color):

x = int(center_x + distance * math.cos(angle))

y = int(center_y + distance * math.sin(angle))

pygame.draw.circle(screen, color, (x, y), radius)

return x, y # 위치 반환

# 메인 루프

running = True

while running:

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

screen.fill((0, 0, 0))

# 태양 그리기

pygame.draw.circle(screen, yellow, (width // 2, height // 2), sun_radius)

# 수성

mercury_x, mercury_y = draw_orbiting_body(width // 2, height // 2, mercury_distance, mercury_angle, mercury_radius, gray)

mercury_angle += mercury_speed

# 금성

venus_x, venus_y = draw_orbiting_body(width // 2, height // 2, venus_distance, venus_angle, venus_radius, blue)

venus_angle += venus_speed

# 지구

earth_x, earth_y = draw_orbiting_body(width // 2, height // 2, earth_distance, earth_angle, earth_radius, green)

earth_angle += earth_speed

# 달 (지구를 중심으로 공전)

draw_orbiting_body(earth_x, earth_y, moon_distance, moon_angle, moon_radius, white)

moon_angle += moon_speed

# 화성

mars_x, mars_y = draw_orbiting_body(width // 2, height // 2, mars_distance, mars_angle, mars_radius, red)

mars_angle += mars_speed

pygame.display.flip()

pygame.time.delay(10)

pygame.quit()

# data[].attributes.headline
각도 초기화 (360도 되었을 때)

# data[].attributes.subject
각도 초기화 (360도 되었을 때)

# data[].attributes.body
import pygame

import math

# 화면 설정

pygame.init()

width, height = 1000, 1000

screen = pygame.display.set_mode((width, height))

pygame.display.set_caption("태양계 공전 시뮬레이션")

# 색깔

white = (255, 255, 255)

yellow = (255, 255, 0)

blue = (0, 0, 255)

red = (255, 0, 0)

green = (0, 255, 0)

gray = (169, 169, 169)

# 행성 초기 설정

sun_radius = 50

mercury_radius = 10

venus_radius = 15

earth_radius = 20

mars_radius = 18

moon_radius = 5

mercury_distance = 100

venus_distance = 150

earth_distance = 220

mars_distance = 300

moon_distance = 30

# 각 행성별 공전 속도

mercury_speed = 0.017

venus_speed = 0.016

earth_speed = 0.015

mars_speed = 0.014

moon_speed = 0.05

# 초기 각도

mercury_angle = 0

venus_angle = 0

earth_angle = 0

mars_angle = 0

moon_angle = 0

# 공전 및 그리기 함수 정의

def draw_orbiting_body(center_x, center_y, distance, angle, radius, color):

x = int(center_x + distance * math.cos(angle))

y = int(center_y + distance * math.sin(angle))

pygame.draw.circle(screen, color, (x, y), radius)

return x, y # 위치 반환

# 메인 루프

running = True

while running:

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

screen.fill((0, 0, 0))

# 태양 그리기

pygame.draw.circle(screen, yellow, (width // 2, height // 2), sun_radius)

# 수성

mercury_x, mercury_y = draw_orbiting_body(width // 2, height // 2, mercury_distance, mercury_angle, mercury_radius, gray)

mercury_angle = (mercury_angle + mercury_speed) % (2 * math.pi)

# 금성

venus_x, venus_y = draw_orbiting_body(width // 2, height // 2, venus_distance, venus_angle, venus_radius, blue)

venus_angle = (venus_angle + venus_speed) % (2 * math.pi)

# 지구

earth_x, earth_y = draw_orbiting_body(width // 2, height // 2, earth_distance, earth_angle, earth_radius, green)

earth_angle = (earth_angle + earth_speed) % (2 * math.pi)

# 달 (지구를 중심으로 공전)

draw_orbiting_body(earth_x, earth_y, moon_distance, moon_angle, moon_radius, white)

moon_angle = (moon_angle + moon_speed) % (2 * math.pi)

# 화성

mars_x, mars_y = draw_orbiting_body(width // 2, height // 2, mars_distance, mars_angle, mars_radius, red)

mars_angle = (mars_angle + mars_speed) % (2 * math.pi)

pygame.display.flip()

pygame.time.delay(10)

pygame.quit()

# data[].attributes.headline
게임 실행하며 개발 순서도 작성하기(메모장에)

# data[].attributes.subject
게임 실행하며 개발 순서도 작성하기(메모장에)

# data[].attributes.attachment_link.title
Sputnika Game (Demo, Now on Steam!) by egunan, Wone

# data[].attributes.attachment_link.description
Suika-style game with space gravity physics

# data[].attributes.headline
개발 순서도 수정 및 개발 시작하기

# data[].attributes.subject
개발 순서도 수정 및 개발 시작하기

# data[].attributes.body
def euclidean_distance(A, B):

distance = 0

for i in range(len(A)):

distance += (A[i] - B[i]) ** 2

return distance ** 0.5

print(euclidean_distance(A=[1, 5, 7, 9], B=[2, 3, 6, 15]))

# data[].attributes.headline
우주수박 코딩 게임 구현하기(main.js 코드)

# data[].attributes.subject
우주수박 코딩 게임 구현하기(main.js 코드)

# data[].attributes.body
import { Engine, Render, Runner, World, Bodies, Body, Events, Composite } from 'matter-js';
import { PLANETS } from './planets';
import './style.css';

const engine = Engine.create()
const world = engine.world;

engine.gravity.scale = 0;

const render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 1000,
    height: 600,
    wireframes: false
  }
});

Render.run(render);
Runner.run(engine);

const clientRect = render.canvas.getBoundingClientRect();

const centerGravity = Bodies.circle(700, 300, 30, {
  isStatic: true,
  render: {
    fillStyle: 'transparent',
    strokeStyle: 'white',
    lineWidth: 3
  }
});

const gameOverCircle = Bodies.circle(700, 300, 200, {
  name: 'gameOverCircle',
  isStatic: true,
  isSensor: true,
  render: {
    fillStyle: 'transparent',
    strokeStyle: 'white',
    lineWidth: 3
  }
});

World.add(world, [centerGravity, gameOverCircle]);

let shootingPlanet;
let initialMousePosition = { x: 0, y: 0 };
let isDragging = false;
let isShooting = false;
let disableAction = false;

const createPlanet = () => {
  const index = Math.floor(Math.random() * 2);
  const planet = PLANETS[index]

  shootingPlanet = Bodies.circle(200, 300, planet.radius, {
    name: 'shootingPlanet',
    index: index,
    isStatic: true,
    render: {
      sprite: { texture: `./${planet.name}.png` }
    },
  });

  World.add(world, shootingPlanet);
};

render.canvas.addEventListener('mousedown', (event) => {
  const mousePosition = {
    x: event.clientX - clientRect.left,
    y: event.clientY - clientRect.top
  };
  const distanceToPlanet = Math.sqrt((mousePosition.x - shootingPlanet.position.x) ** 2 + (mousePosition.y - shootingPlanet.position.y) ** 2);

  if (distanceToPlanet <= shootingPlanet.circleRadius) {
    isDragging = true;
    initialMousePosition.x = mousePosition.x;
    initialMousePosition.y = mousePosition.y;
  }
});

window.addEventListener('mousemove', (event) => {
  if (isDragging) {
    const newPosition = { x: event.clientX, y: event.clientY };
    Body.setPosition(shootingPlanet, {
      x: newPosition.x - clientRect.left,
      y: newPosition.y - clientRect.top
    });
  }
});

window.addEventListener('mouseup', (event) => {
  if (isDragging) {
    isShooting = true;
  } else {
    return;
  }

  if (isShooting) {
    disableAction = true;

    Body.setStatic(shootingPlanet, false);

    const releasePosition = {
      x: event.clientX - clientRect.left,
      y: event.clientY - clientRect.top
    };
    const forceMagnitude = 0.0005;
    const forceDirection = {
      x:initialMousePosition.x - releasePosition.x,
      y: initialMousePosition.y - releasePosition.y,
    };

    Body.applyForce(shootingPlanet, shootingPlanet.position, {
      x: forceDirection.x * forceMagnitude,
      y: forceDirection.y * forceMagnitude,
    });

    isDragging = false;
    isShooting = false;

    setTimeout(() => {
      disableAction = false;
      shootingPlanet.name = null;
      createPlanet();
    }, 2500);
  }
});

Events.on(engine, 'beforeUpdate', function(event) {
  const bodies = Composite.allBodies(world);

  bodies.forEach(body => {
    const dx = centerGravity.position.x - body.position.x;
    const dy = centerGravity.position.y - body.position.y;

    const distanceSquared = dx * dx + dy * dy;
    const forceMagnitude = 0.3 * body.mass / distanceSquared;

    Body.applyForce(body, body.position, { x: forceMagnitude * dx, y: forceMagnitude * dy });

    if (!disableAction && body.name != 'shootingPlanet' && body.name != 'gameOverCircle') {
      const dist = Math.sqrt((body.position.x - centerGravity.position.x) ** 2 + (body.position.y - centerGravity.position.y) ** 2);

      if (dist > gameOverCircle.circleRadius) {
        alert('Game Over');
      }
    }
  });
});

Events.on(engine, 'collisionStart', (event) => {
  event.pairs.forEach((collision) => {
    if (collision.bodyA.index === collision.bodyB.index) {
      const index = collision.bodyA.index;

      if (index === PLANETS.length - 1) {
        return;
      }

      World.remove(world, [collision.bodyA, collision.bodyB]);

      const newPlanet = PLANETS[index + 1];

      const newBody = Bodies.circle(
        collision.collision.supports[0].x,
        collision.collision.supports[0].y,
        newPlanet.radius,
        {
          index: index + 1,
          render: {
            sprite: { texture: `./${newPlanet.name}.png` }
          },
        },
      );

      World.add(world, newBody);
    }
  });
});

createPlanet();

# data[].attributes.headline
우주수박코딩게임 버전 업그레이드 부분 찾아보기

# data[].attributes.subject
우주수박코딩게임 버전 업그레이드 부분 찾아보기

# data[].attributes.body
1. 프로젝트 디렉터리 열기

VSCode를 열고 프로젝트 디렉터리를 선택해서 엽니다.

2. Node.js와 npm 설치 확인

터미널에서 아래 명령어로 Node.js와 npm이 설치되어 있는지 확인합니다

3. 프로젝트 의존성 설치

프로젝트 디렉터리에서 터미널을 열고 npm install 명령어를 실행해 의존성을 설치합니다:

4. Vite 개발 서버 실행

package.json 파일을 열어 scripts 섹션을 확인합니다. 일반적으로 Vite 프로젝트에는 dev 스크립트가 있습니다.

터미널에서 아래 명령어를 실행해 개발 서버를 시작합니다. (nmp run dev)

# data[].attributes.headline
비트(vite) 프로젝트 생성(터미널)-바닐라로 시작하기

# data[].attributes.subject
비트(vite) 프로젝트 생성(터미널)-바닐라로 시작하기

# data[].attributes.body
https://velog.io/@ljs923/Node.js-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EB%B0%8F-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

# data[].attributes.attachment_link.description
Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.

# data[].attributes.headline
오류 대처 방법(버전 오류 / 터미널 설치 오류 등)

# data[].attributes.subject
오류 대처 방법(버전 오류 / 터미널 설치 오류 등)

# data[].attributes.body
1. Vite Project 생성하기

vite project생성 명령어 실행

y 입력 후 엔터로 vite pakages 설치

npm create vite@least

project name 입력

vite를 사용할 framework 선택 (vanilla)

사용할 스크립터 언어 선택(javascript)

프로젝트 생성 완료

npm install 실행

npm run dev 명령어로 서버 실행

2. vscode로 열기

# data[].attributes.body
인터넷에서 찾아보고 실제 친구와 배포해보기

# data[].attributes.body
const PLANETS = [
    {
      name: "0",
      radius: 47 / 2,
    },
    {
      name: "1",
      radius: 62 / 2,
    },
    {
      name: "2",
      radius: 78 / 2,
    },
    {
      name: "3",
      radius: 103 / 2,
    },
    {
      name: "4",
      radius: 120 / 2,
    }
  ];

  export { PLANETS };