Flutter 기반 게임 개발 입문

아토믹데브_7_취업 준비생을 위한 모바일 게임 개발 여정

atomicdev 2024. 8. 27. 13:54
728x90

제7강: 캐릭터 이동 및 경로 설정


학습 목표:

이번 강의에서는 "BrainBox Delivery" 게임 내에서 캐릭터가 지정된 경로를 따라 움직이는 기능을 구현하는 방법을 학습합니다. 여러분은 드래그 앤 드롭(Drag and Drop) 또는 탭 기반(Tap-based) 이동 기능을 구현하고, 캐릭터가 경로 상에서 올바르게 이동하는 로직을 설정하며, 캐릭터와 목적지 간의 상호작용을 처리하는 방법을 익히게 됩니다.


1. 드래그 앤 드롭 또는 탭 기반의 이동 구현

게임 내 캐릭터의 이동은 사용자와의 주요 상호작용 중 하나입니다. 캐릭터를 드래그하여 움직이거나, 탭하여 이동할 수 있도록 구현하는 것이 이번 단계의 목표입니다.

1.1 React Native - 드래그 앤 드롭 기반 이동 구현

React Native에서는 PanResponder API를 사용하여 드래그 앤 드롭 기능을 구현할 수 있습니다. PanResponder는 사용자의 터치 동작을 감지하고 이를 처리할 수 있게 해줍니다.

import React, { useRef } from 'react';
import { View, Animated, PanResponder, StyleSheet } from 'react-native';

const DraggableCharacter = () => {
  const pan = useRef(new Animated.ValueXY()).current;

  const panResponder = useRef(
    PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderMove: Animated.event(
        [null, { dx: pan.x, dy: pan.y }],
        { useNativeDriver: false }
      ),
      onPanResponderRelease: () => {
        Animated.spring(pan, {
          toValue: { x: 0, y: 0 },
          useNativeDriver: false,
        }).start();
      },
    })
  ).current;

  return (
    <Animated.View
      {...panResponder.panHandlers}
      style={[pan.getLayout(), styles.box]}
    />
  );
};

const styles = StyleSheet.create({
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'blue',
  },
});

export default DraggableCharacter;
 

이 코드는 PanResponder를 사용하여 사용자가 캐릭터를 드래그할 수 있도록 합니다. Animated.ValueXY를 사용해 캐릭터의 위치를 관리하며, 드래그 후 캐릭터가 원래 위치로 돌아가는 애니메이션도 추가할 수 있습니다.

1.2 Flutter - 탭 기반의 이동 구현

Flutter에서는 GestureDetector 위젯을 사용하여 탭 기반 이동을 쉽게 구현할 수 있습니다. GestureDetector는 다양한 제스처(탭, 드래그, 스와이프 등)를 감지할 수 있습니다.

import 'package:flutter/material.dart';

class MovableCharacter extends StatefulWidget {
  @override
  _MovableCharacterState createState() => _MovableCharacterState();
}

class _MovableCharacterState extends State<MovableCharacter> {
  double xPosition = 0;
  double yPosition = 0;

  void _moveCharacter(TapDownDetails details) {
    setState(() {
      xPosition = details.localPosition.dx;
      yPosition = details.localPosition.dy;
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: _moveCharacter,
      child: Stack(
        children: [
          Positioned(
            left: xPosition,
            top: yPosition,
            child: Container(
              width: 50,
              height: 50,
              color: Colors.blue,
            ),
          ),
        ],
      ),
    );
  }
}
 

이 코드는 GestureDetector를 사용하여 사용자가 화면을 탭했을 때 캐릭터가 해당 위치로 이동하도록 구현합니다. Positioned 위젯을 사용해 캐릭터의 위치를 조정합니다.


2. 경로 상에서의 캐릭터 이동 로직 구현

캐릭터가 단순히 이동하는 것뿐만 아니라, 경로를 따라 움직이는 로직을 구현하는 것이 필요합니다. 이를 위해서는 캐릭터의 현재 위치와 목표 위치를 계산하고, 경로를 따라 자연스럽게 이동하도록 설정해야 합니다.

2.1 React Native - 경로 이동 로직

React Native에서 경로 이동 로직은 애니메이션과 함께 구현할 수 있습니다.

import React, { useState } from 'react';
import { View, Animated, Button } from 'react-native';

const CharacterPath = () => {
  const [position] = useState(new Animated.ValueXY({ x: 0, y: 0 }));

  const moveCharacter = () => {
    Animated.timing(position, {
      toValue: { x: 200, y: 300 },
      duration: 1000,
      useNativeDriver: false,
    }).start();
  };

  return (
    <View>
      <Animated.View style={position.getLayout()}>
        <View style={{ width: 50, height: 50, backgroundColor: 'blue' }} />
      </Animated.View>
      <Button title="Move" onPress={moveCharacter} />
    </View>
  );
};

export default CharacterPath;
 

이 코드는 버튼을 눌렀을 때 캐릭터가 지정된 경로를 따라 이동하는 애니메이션을 구현합니다. Animated.timing을 사용해 캐릭터의 위치를 애니메이션으로 변경합니다.

2.2 Flutter - 경로 이동 로직

Flutter에서는 AnimatedPositioned 위젯을 사용해 경로 이동을 애니메이션으로 구현할 수 있습니다.

import 'package:flutter/material.dart';

class CharacterPath extends StatefulWidget {
  @override
  _CharacterPathState createState() => _CharacterPathState();
}

class _CharacterPathState extends State<CharacterPath> {
  double xPosition = 0;
  double yPosition = 0;

  void moveCharacter() {
    setState(() {
      xPosition = 200;
      yPosition = 300;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        AnimatedPositioned(
          left: xPosition,
          top: yPosition,
          duration: Duration(seconds: 1),
          child: Container(
            width: 50,
            height: 50,
            color: Colors.blue,
          ),
        ),
        Positioned(
          top: 400,
          left: 100,
          child: ElevatedButton(
            onPressed: moveCharacter,
            child: Text('Move'),
          ),
        ),
      ],
    );
  }
}
 

이 Flutter 코드에서는 AnimatedPositioned를 사용해 캐릭터가 지정된 경로로 부드럽게 이동하는 애니메이션을 구현했습니다.


3. 캐릭터와 목적지 간의 상호작용 처리

캐릭터가 경로를 따라 이동할 때, 목적지에 도달하면 상호작용을 처리해야 합니다. 이 상호작용은 점수 증가, 아이템 배달 완료 등의 게임 이벤트를 발생시키는 중요한 요소입니다.

3.1 React Native - 상호작용 처리

React Native에서 캐릭터와 목적지 간의 충돌을 감지하고, 이를 처리하는 코드를 작성할 수 있습니다.

import React, { useState, useEffect } from 'react';
import { View, Animated, Text } from 'react-native';

const CharacterInteraction = () => {
  const [position] = useState(new Animated.ValueXY({ x: 0, y: 0 }));
  const [reached, setReached] = useState(false);

  useEffect(() => {
    if (position.x._value === 200 && position.y._value === 300) {
      setReached(true);
    }
  }, [position]);

  const moveCharacter = () => {
    Animated.timing(position, {
      toValue: { x: 200, y: 300 },
      duration: 1000,
      useNativeDriver: false,
    }).start();
  };

  return (
    <View>
      <Animated.View style={position.getLayout()}>
        <View style={{ width: 50, height: 50, backgroundColor: 'blue' }} />
      </Animated.View>
      <View style={{ position: 'absolute', left: 200, top: 300 }}>
        <Text>Destination</Text>
      </View>
      <Button title="Move" onPress={moveCharacter} />
      {reached && <Text>Item Delivered!</Text>}
    </View>
  );
};

export default CharacterInteraction;

이 코드에서는 캐릭터가 목적지에 도달했는지를 감지하고, 도달했을 때 "Item Delivered!" 메시지를 표시합니다.

3.2 Flutter - 상호작용 처리

Flutter에서는 캐릭터와 목적지 간의 상호작용을 간단하게 처리할 수 있습니다.

import 'package:flutter/material.dart';

class CharacterInteraction extends StatefulWidget {
  @override
  _CharacterInteractionState createState() => _CharacterInteractionState();
}

class _CharacterInteractionState extends State<CharacterInteraction> {
  double xPosition = 0;
  double yPosition = 0;
  bool reached = false;

  void moveCharacter() {
    setState(() {
      xPosition = 200;
      yPosition = 300;
      if (xPosition == 200 && yPosition == 300) {
        reached = true;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        AnimatedPositioned(
          left: xPosition,
          top: yPosition,
          duration: Duration(seconds: 1),
          child: Container(
            width: 50,
            height: 50,
            color: Colors.blue,
          ),
        ),
        Positioned(
          left: 200,
          top: 300,
          child: Text('Destination'),
        ),
        Positioned(
          top: 400,
          left: 100,
          child: ElevatedButton(
            onPressed: moveCharacter,
            child: Text('Move'),
          ),
        ),
        if (reached)
          Positioned(
            top: 450,
            left: 100,
            child: Text('Item Delivered!'),
          ),
      ],
    );
  }
}
 

이 Flutter 코드에서는 캐릭터가 목적지에 도달했을 때 "Item Delivered!" 메시지를 표시하는 로직을 구현했습니다.

 


이 강의를 통해 여러분은 "BrainBox Delivery" 게임의 캐릭터 이동과 상호작용 로직을 구현하는 데 필요한 기술을 습득하게 되었습니다. 앞으로의 강의에서는 이러한 기초를 바탕으로 게임을 더욱 풍부하게 만들어 나갈 것입니다.

728x90