탭탭카드놀이) Screens, component 등등

2022. 3. 8. 20:46프로그래밍/개인프로젝트

개발 현황은 깃헙을 통해 확인 가능합니다

https://github.com/coqoa/tabtabcard

 

GitHub - coqoa/tabtabcard

Contribute to coqoa/tabtabcard development by creating an account on GitHub.

github.com

공부하면서 문제 해결하거나 기능 구현한 것들 위주로 작성하는 글입니다


로직

현재 작업중인 파일은 Menu.js와 WordPlay.js, CardDefault.js, wordCardArray.js, colors.js이다

 

Menu.js

단어놀이 / 수학놀이를 선택하기 위한 메뉴 screen이다

Menu.js

import React from "react";
import styled from "styled-components";


const Shell = styled.View`
    flex: 1;
    `
const BG = styled.ImageBackground`
    flex: 1;
    width: 100%;
    height: 100%;
    justify-content: center;
    align-items: center;
`
const MenuBoxShell = styled.View`
    flex: 1;
    justify-content: center;
    align-items: center;

`
const MenuBox = styled.TouchableOpacity`
    background-color: white;
    width: 250px;
    height: 80px;
    margin: 20px;
    justify-content: center;
    align-items: center;
    border-radius: 25px;
    box-shadow: 0px 3px 5px rgba(0,0,0,0.2) ;
`
const MenuText = styled.Text`
    font-size: 35px;
`
const Menu = ({navigation}) => {
    return(
    <Shell>
    <BG source={require("../asset/images/loginBg.png")} resizeMode="stretch">
        <MenuBoxShell>
            <MenuBox onPress={() => navigation.navigate('WordPlay')}>
                <MenuText>단어 놀이</MenuText>
            </MenuBox>
            <MenuBox>
                <MenuText>수학 놀이</MenuText>
            </MenuBox>
        </MenuBoxShell>
    </BG>
    </Shell>
    )
}
export default Menu;

WordPlay.js

단어놀이의 공통적인 부분을 구현해놓은 파일이다

뒤로가기버튼, 레벨표시, 메뉴버튼, 메뉴버튼 모달창, 카드화면을 구현해놓은 screen이고,

카드에 관련된 내용은 아래에 CardDefault.js에서 구현한다

import React, {useState, useEffect} from "react";
import { Text, ActivityIndicator, FlatList, ScrollView,Dimensions } from "react-native";
import styled from "styled-components";
import { colors } from "../component/color";
import { WordCard1LV, WordCard2LV, WordCard3LV } from "../component/CardDefault";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;

const Loader = styled.View`
    flex: 1;
    justify-content: center;
    align-items: center;
`;
const Shell = styled.View`
    flex: 1;
    background-color: white;
    align-items: center;
`
const Top = styled.View`
    height: 80px;
    flex-direction: row;
`
const GoBack = styled.View`
    width: 60px;
    align-items: center;
    justify-content: center;
`
const GoBackBtn = styled.Pressable`
    width: 60px;
    height: 60px;
`
const GoBackBtnImage = styled.Image`
    width: 100%;
    height: 100%;
`
const Star = styled.View`
    flex: 1;
    align-items: center;
    justify-content: center;
`
const StarView = styled.View`
    width: 170px;
    height: 60px;
    align-items: center;
    justify-content: center;
`
const StarViewImage = styled.ImageBackground`
    top: 2px;
    width: 220px;
    height: 70px;
`
const Menu = styled.View`
    width: 60px;
    align-items: center;
    justify-content: center;
`
const MenuBtn = styled.Pressable`
    top: 5px;
    width: 65px;
    height: 65px;
`
const MenuBtnImage = styled.ImageBackground`
    width: 100%;
    height: 100%;
`
const MenuModalBg = styled.Pressable``

const MenuModalContainer = styled.View`
    position: absolute;
    top: 60px;
    right: 10px;
    width: 200px;
    height: 200px;
    border-radius: 20px;
    align-items: center;
    justify-content: center;
    background-color: white;
    box-shadow: 0px 1px 5px rgba(0,0,0,0.3);
`
const MenuModal = styled.View`
    width: 90%;
    height: 90%;
`
const LevelBtn = styled.Pressable`
    flex: 1;
    align-items: center;
    justify-content: center;
    margin: 5px;
    border-radius: 15px;
    background-color: ${colors.LIGHTBLUE};
    box-shadow: 0px 1px 3px ${colors.LIGHTBLUE};
`
const Main = styled.View`
    flex: 5;
    flex-direction: row;
`


const WordPlay = ({navigation}) => {
    const [loading, setLoading] = useState(true);
    
    const [cardSelector, setCardSelector] = useState();
    const [modalToggle, setModalToggle] = useState(false);
    
    const cardCheck = (e) => {
        setCardSelector(e);
        setModalToggle(!modalToggle);
        console.log(e);
    }

    const modalTogglePress = () => setModalToggle(!modalToggle)
    useEffect(() => {
        if(cardSelector == undefined) {
            setCardSelector("word1LV")
        } 
        setLoading(false)
    }, []);
    return( 
        loading ? (
            <Loader>
                <ActivityIndicator />
            </Loader>
        ) : (
            <Shell>
            <Top>
            	//뒤로가기버튼
                <GoBack>
                    <GoBackBtn onPress={() => navigation.goBack()}>
                        <GoBackBtnImage source={require("../asset/images/goBack1.png")}></GoBackBtnImage>
                    </GoBackBtn>
                </GoBack>
                //레벨표시
                <Star>
                    <StarView>
                        {(()=>{
                            if(cardSelector === "word1LV") return <StarViewImage source={require("../asset/images/Star1.png")}></StarViewImage>;
                            else if(cardSelector=="word2LV") return <StarViewImage source={require("../asset/images/Star2.png")}></StarViewImage>;
                            else if(cardSelector=="word3LV") return <StarViewImage source={require("../asset/images/Star3.png")}></StarViewImage>;
                            else return <StarViewImage source={require("../asset/images/Star1.png")}></StarViewImage>
                        })()}
                    </StarView>
                </Star>
                //메뉴버튼
                <Menu>
                    <MenuBtn onPress={() => modalTogglePress()}>
                        <MenuBtnImage source={require("../asset/images/MenuBar.png")}></MenuBtnImage>
                    </MenuBtn>
                </Menu>

            </Top>
            //카드섹션
            <Main>
                {(()=>{
                	// 조건을 통해 screen에 표시될 레벨을 정한다
                    if(cardSelector === "word1LV") return <WordCard1LV />;
                    else if(cardSelector=="word2LV") return <WordCard2LV />;
                    else if(cardSelector=="word3LV") return <WordCard3LV />;
                    else return <WordCard1LV />
                })()}
            </Main>
            // 모달토글을 체크해서 true면 screen에 표시해주고 false면 사라지게 한다
            {modalToggle == true ? (
                <MenuModalBg 
                style={{position:"absolute", width:SCREEN_WIDTH, height:SCREEN_HEIGHT, backgroundColor:"rgba(0,0,0,0)"}} 
                onPress={()=>{
                    modalTogglePress()
                }}>
                    <MenuModalContainer>
                        <MenuModal>
                            <LevelBtn onPress={()=>{cardCheck("word1LV")}}><Text>1레벨</Text></LevelBtn>
                            <LevelBtn onPress={()=>{cardCheck("word2LV")}}><Text>2레벨</Text></LevelBtn>
                            <LevelBtn onPress={()=>{cardCheck("word3LV")}}><Text>3레벨</Text></LevelBtn>
                        </MenuModal>
                    </MenuModalContainer>
                </MenuModalBg>
            ) : null
            }
            </Shell>
        )
    )
}
export default WordPlay;

CardDefault.js

카드들을 구현하기 위한 파일이다

WordCardArray.js와 colors.js를 import해서 데이터를 screen에 뿌려준다

FlatList를 통해 카드를 넘겨주도록 구현했는데 Animated를 활용하는 방법으로 바꿀 예정이다

import React, {useState, useEffect, useRef} from "react"
import {View, Dimensions, FlatList, Animated, PanResponder } from "react-native";
import styled from "styled-components"
import { WordCardArray } from "../asset/data/WordCardArray";
import { colors } from "./color";
import { Ionicons } from "@expo/vector-icons";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;

const CardSection = styled.View`
//Diemension쓰기위해 인라인 style 적용
`
const Card = styled.View`
    flex: 1;
    align-items: center;
    justify-content: center;
    margin:30px;
    border-radius: 15px;
    box-shadow: 0px 5px 10px rgba(0,0,0,0.4);
`
const CardImgShell = styled.View`
    /* flex: 3; */
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 80%;
    `
const CardImg = styled.Image`
    flex: 1;
    width: 100%;
    `
const CardContents = styled.View`
    width: 200px;
    height: 100px;
`
const CardName = styled.View`
    flex:1;
    align-items: center;
    justify-content: center;
`
const CardNameText = styled.Text`
    font-size: 65px;
    font-weight: 900;
    color: ${colors.REALDARKGRAY};
`

export const WordCard1LV = () => {

    return(
    <FlatList
        horizontal
        pagingEnabled
        data={WordCardArray}
        renderItem = {({item})=>(
            <CardSection style={{width:SCREEN_WIDTH}}> 
                <Card style={{backgroundColor : item.bgColor}}>
                    <CardImgShell>
                        <CardImg source={item.image} resizeMode="contain"></CardImg>
                    </CardImgShell>
                    <CardContents onPress={() => console.log(item.name)}>
                        <CardName>
                            <CardNameText>{item.name}</CardNameText>
                        </CardName>
                    </CardContents>
                </Card>
            </CardSection>
        )}
    />
    )
}

const Record = styled.View`
    height: 30px;
    flex-direction: row;
`
const CheckRecord = styled.View`
    flex:1;
    flex-direction: row;
    justify-content: center;
    align-items: center;
`
const CheckRecordImage = styled.ImageBackground`
    width: 24px;
    height: 24px;
    width: 40px;
    `
const CheckRecordText = styled.Text`
    color: green;
    font-size: 17px;
    bottom: 1px;
`

export const WordCard2LV = () => {

    return(
    <View>
        <Record>
            <CheckRecord>
                <CheckRecordImage source={require("../asset/images/Check.png")} resizeMode="contain"></CheckRecordImage>
                <CheckRecordText>2레벨</CheckRecordText>
            </CheckRecord>
        </Record>

        <FlatList
            horizontal
            pagingEnabled
            data={WordCardArray}
            renderItem = {({item})=>(
                
                <CardSection style={{width:SCREEN_WIDTH}}> 
                    <Card>
                        <CardImgShell>
                            <CardImg source={item.image} resizeMode="contain"></CardImg>
                        </CardImgShell>
                        <CardContents onPress={() => console.log(item.name)}>
                            <CardName>
                                <CardNameText>{item.name}</CardNameText>
                            </CardName>
                        </CardContents>
                    </Card>
                </CardSection>
            )}
        />
    </View>
    )
}

WordCardArray.js

카드에 표시될 데이터들을 담은 배열파일이다

import { colors } from "../../component/color"


export const WordCardArray = [
    {
        "id" : 0, 
        "image" : require("../images/Lion1.png"), 
        "bgColor" : colors.ORANGE, 
        "name" : "사자",
        "check" : true
    }, 
    {
        "id" : 1, 
        "image" : require("../images/Speaker.png"), 
        "bgColor" : colors.LIGHTBLUE, 
        "name" : "말",
        "check" : false
    }, 
    {
        "id" : 2, 
        "image" : require("../images/Star.png"),
        "bgColor" : colors.TOMATO,  
        "name" : "강아지",
        "check" : false
    }, 
    {
        "id" : 3, 
        "image" : require("../images/Random.png"), 
        "bgColor" : colors.BEIGE, 
        "name" : "고양이",
        "check" : false
    }, 
    {
        "id" : 4, 
        "image" : require("../images/Heart1.png"), 
        "bgColor" : colors.NAVY, 
        "name" : "쥐",
        "check" : false
    }, 
    {
        "id" : 5, 
        "image" : require("../images/Heart2.png"), 
        "bgColor" : colors.PASTELBLUE, 
        "name" : "소",
        "check" : false
    },

    {
        "id" : 6, 
        "image" : require("../images/Heart3.png"), 
        "bgColor" : colors.REALLIGHTGRAY, 
        "name" : "6",
        "check" : false
    }, 
    {
        "id" : 7, 
        "image" : require("../images/Lion2.png"), 
        "bgColor" : colors.LIGHTGRAY, 
        "name" : "7",
        "check" : false
    }, 
    {
        "id" : 8, 
        "image" : require("../images/LeftArrow.png"), 
        "bgColor" : colors.ORANGE, 
        "name" : "8",
        "check" : false
    }, 
    {
        "id" : 9, 
        "image" : require("../images/RightArrow.png"), 
        "bgColor" : colors.BEIGE, 
        "name" : "9",
        "check" : false
    }, 





    {
        "id" : 9999, 
        "image" : require("../images/RightArrow.png"), 
        "bgColor" : colors.BEIGE, 
        "name" : "끝",
        "check" : false
    }, 
    {
        "id" : 10000, 
        "image" :require("../images/RightArrow.png"), 
        "bgColor" : " ", 
        "name" : " ",
        "check" : false
    }
]

colors.js

사용하기 위한 컬러들을 모아놓은 컬러변수파일이다

export const colors = {
    bgColor : "#F9EBEB",
    PINK:"#FF5384",
    PASTELBLUE:"#3772E6",
    LIGHTBLUE:"#c0dfff",
    NAVY: "#163976",
    TOMATO : "#FF8D8D",
    REALLIGHTGRAY : "#D0D0D0",
    LIGHTGRAY : "#BCBCBC",
    GRAY : "#9B9B9B",
    DARKGRAY:"#747474",
    REALDARKGRAY:"#505050",
    BEIGE:"#f5f5dc",
    ORANGE:"#FED784",
};

 

디자인도 손봐야되고 이벤트들도 만들어야되고 데이터도 저장해야되고...할일이 정말 많다

기본기능구현을 먼저하고 하나씩하나씩 구현해나갈 예정이다 

화이팅