Flutter 기반 게임 개발 입문

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

atomicdev 2024. 8. 29. 08:53
728x90

제13강: 애니메이션과 시각적 효과


학습 목표:

이번 강의에서는 "BrainBox Delivery" 게임의 시각적 매력을 높이기 위해 애니메이션과 시각적 효과를 추가하는 방법을 학습합니다. 기본적인 애니메이션 구현부터, React Native에서는 Reanimated 라이브러리, Flutter에서는 AnimationController를 활용하여 상태 변화에 따른 다양한 시각적 효과를 구현하는 방법을 익히게 됩니다.


1. 기본적인 애니메이션 구현

애니메이션은 게임의 시각적 경험을 풍부하게 하며, 플레이어가 게임에 몰입할 수 있도록 돕는 중요한 요소입니다. 이 섹션에서는 아이템 픽업 시 나타나는 간단한 애니메이션을 구현해보겠습니다.

1.1 React Native - 아이템 픽업 애니메이션 구현

React Native에서는 react-native-reanimated 라이브러리를 사용하여 애니메이션을 쉽게 구현할 수 있습니다.

  1. 설치 및 설정:
  2. bash
    npm install react-native-reanimated

     
  3. 아이템 픽업 애니메이션 코드:
    import React from 'react';
    import { View, Text, TouchableOpacity } from 'react-native';
    import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
    
    const PickupItem = () => {
      const scale = useSharedValue(1);
    
      const animatedStyle = useAnimatedStyle(() => {
        return {
          transform: [{ scale: scale.value }],
        };
      });
    
      const handlePickup = () => {
        scale.value = withTiming(1.5, { duration: 200 }, () => {
          scale.value = withTiming(1, { duration: 200 });
        });
      };
    
      return (
        <TouchableOpacity onPress={handlePickup}>
          <Animated.View style={[{ width: 100, height: 100, backgroundColor: 'blue' }, animatedStyle]}>
            <Text style={{ color: 'white', textAlign: 'center', marginTop: 35 }}>Pick Me</Text>
          </Animated.View>
        </TouchableOpacity>
      );
    };
    
    export default PickupItem;

이 코드는 아이템을 클릭할 때 크기가 커졌다가 다시 원래 크기로 돌아오는 간단한 애니메이션을 구현합니다.

1.2 Flutter - 아이템 픽업 애니메이션 구현

Flutter에서는 AnimationController와 Tween을 사용하여 애니메이션을 구현할 수 있습니다.

  1. 애니메이션 코드:
    import 'package:flutter/material.dart';
    
    class PickupItem extends StatefulWidget {
      @override
      _PickupItemState createState() => _PickupItemState();
    }
    
    class _PickupItemState extends State<PickupItem> with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _scaleAnimation;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(milliseconds: 200),
          vsync: this,
        )..addListener(() {
            setState(() {});
          });
    
        _scaleAnimation = Tween<double>(begin: 1.0, end: 1.5).animate(_controller);
      }
    
      void handlePickup() {
        _controller.forward().then((_) => _controller.reverse());
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: handlePickup,
          child: Transform.scale(
            scale: _scaleAnimation.value,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
              child: Center(
                child: Text('Pick Me', style: TextStyle(color: Colors.white)),
              ),
            ),
          ),
        );
      }
    }

이 Flutter 코드는 아이템을 탭할 때 크기가 커졌다가 다시 원래 크기로 돌아오는 애니메이션을 구현합니다.


2. React Native Reanimated 또는 Flutter의 AnimationController 사용법

React Native와 Flutter 모두 강력한 애니메이션 라이브러리를 제공합니다. 이 도구들을 사용하면 복잡한 애니메이션을 간단하게 구현할 수 있습니다.

2.1 React Native - Reanimated 사용법

react-native-reanimated 라이브러리는 애니메이션을 부드럽게 구현할 수 있는 강력한 도구입니다.

import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';

const scale = useSharedValue(1);

const animatedStyle = useAnimatedStyle(() => {
  return {
    transform: [{ scale: scale.value }],
  };
});

const handlePress = () => {
  scale.value = withTiming(2, { duration: 500 });
};

이 코드는 useSharedValue와 useAnimatedStyle을 사용하여 간단한 애니메이션을 구현하는 예제입니다.

2.2 Flutter - AnimationController 사용법

Flutter에서 애니메이션을 제어하기 위해 AnimationController와 Tween을 사용합니다.

final AnimationController _controller = AnimationController(
  duration: const Duration(seconds: 2),
  vsync: this,
);

final Animation<double> _animation = Tween<double>(begin: 0, end: 1).animate(_controller);
 

이 코드는 AnimationController를 사용하여 애니메이션을 제어하는 기본적인 예제입니다.


3. 상태 변화에 따른 시각적 효과 구현

상태 변화에 따른 시각적 효과는 플레이어의 행동에 대한 피드백을 제공하는 중요한 요소입니다. 이 섹션에서는 상태 변화에 따른 간단한 시각적 효과를 구현합니다.

3.1 React Native - 상태 변화에 따른 효과

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

const StatusEffect = () => {
  const [active, setActive] = useState(false);
  const opacity = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => {
    return {
      opacity: opacity.value,
    };
  });

  const toggleStatus = () => {
    setActive(!active);
    opacity.value = withTiming(active ? 0.5 : 1, { duration: 300 });
  };

  return (
    <View>
      <Button title="Toggle Status" onPress={toggleStatus} />
      <Animated.View style={[{ width: 100, height: 100, backgroundColor: 'blue' }, animatedStyle]} />
    </View>
  );
};

이 코드는 상태에 따라 아이템의 투명도가 변화하는 시각적 효과를 구현합니다.

3.2 Flutter - 상태 변화에 따른 효과

import 'package:flutter/material.dart';

class StatusEffect extends StatefulWidget {
  @override
  _StatusEffectState createState() => _StatusEffectState();
}

class _StatusEffectState extends State<StatusEffect> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _opacityAnimation;

  bool isActive = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );

    _opacityAnimation = Tween<double>(begin: 1, end: 0.5).animate(_controller);
  }

  void toggleStatus() {
    setState(() {
      isActive = !isActive;
      if (isActive) {
        _controller.forward();
      } else {
        _controller.reverse();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Status Effect'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: toggleStatus,
          child: AnimatedBuilder(
            animation: _controller,
            builder: (context, child) {
              return Opacity(
                opacity: _opacityAnimation.value,
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.blue,
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

이 Flutter 코드는 상태에 따라 아이템의 투명도가 변화하는 시각적 효과를 구현합니다.


이 강의를 통해 여러분은 "BrainBox Delivery" 게임에 애니메이션과 시각적 효과를 추가하여 게임의 시각적 매력을 높이는 방법을 습득하게 되었습니다. 앞으로의 강의에서는 게임의 완성도를 더욱 높이는 기술을 익히게 될 것입니다.

728x90