럿고의 개발 노트

[인프런] 웹 게임을 만들며 배우는 Vue 5. 가위바위보 본문

Vue.js Note/[인프런] 웹 게임을 만들며 배우는 Vue(동영상 강의)

[인프런] 웹 게임을 만들며 배우는 Vue 5. 가위바위보

KimSeYun 2019. 11. 14. 10:08

[인프런] 웹 게임을 만들며 배우는 Vue

5. 가위바위보

5.1. vue-devtools와 기타 정보들

5.2. :class와 :style

5.3. vue 라이프사이클

5.4. 가위바위보 완성과 devtools 분석


- 예제(웹 게임)을 통해 Vue를 만나는 시간으로, 예제를 풀면서 주석으로 배운 내용과 알아야 할 내용을 최대한 적어 놓았습니다. 코드와 주석을 참고해주세요!. 노드와 웹팩을 사용하여 설정파일들이 존재합니다. 아래 깃허브를 참고해주세요.

[main.js]

1
2
3
4
5
import Vue from 'Vue'// Vue를 불러오는 것
 
import RockScissorsPaper from './RockScissorsPaper'// NumberBaseball.vue를 가져오는 것
 
new Vue(RockScissorsPaper).$mount('#root'); // Vue 인스턴스, 인스턴스안에 사용할 컴포넌트를 넣어줘야 함.
cs


[package.json]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "name""response-Check",
  "version""1.0.0",
  "description""",
  "main""index.js",
  "scripts": {
    "bulid""webpack --watch",
    "dev""webpack-dev-server --hot"
  },
  "author""",
  "license""ISC",
  "dependencies": {
    "vue""^2.6.10",
    "vue-loader""^15.7.2",
    "vue-template-compiler""^2.6.10",
    "webpack""^4.41.2",
    "webpack-cli""^3.3.10"
  },
  "devDependencies": {
    "css-loader""^3.2.0",
    "vue-style-loader""^4.1.2",
    "webpack-dev-server""^3.9.0"
  }
}
 
cs


[RockScissorsPaper.html]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>가위바위보</title>
</head>
<body>
    <!-- vue이름을 두단어 이상으로 적으라고 공식문서에 적혀있음
        webpack-dev-server를 사용하면 app.js가 보여지지가 않음. 그 이유는 웹팩 데브서버는 output를 파일로 만들어서
        저장하는게 아니라 메모리에 저장하기 때문에 눈에 보이지 않음
        꼭 publicPath를 적어줘야 webpack-dev-server가 제대로 작동함.(app.js를 적음)
    -->
    <div id="root"></div>
    <script src="./dist/app.js"></script>
</body>
</html>
cs


[RockScissorsPaper.vue]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!-- style과 class는 객체형식으로 사용 가능함
    class -> { state: true, hello: false}라고 하면 최종결과로는 state만 가능
    style -> { backgroundImage: '', fontsize: '14px' } 이렇게 객체 형식 가능
    style은 뷰에서 사용할때 background-image = backgroundImage처럼 하이픈이 있는 곳은 하이픈은 빼고 하이픈 뒤 글자 하나를 대문자로 쓸것!-->
 
<template>
    <div>
        <div id="computer" :style="computedStyleObject"></div>
        <div>
            <button @click="onClickButton('바위')">바위</button>
            <button @click="onClickButton('가위')">가위</button>
            <button @click="onClickButton('보')"></button>
        </div>
        <div>{{result}}</div>
        <div>현재 {{score}}점</div>
    </div>
</template>
 
<script>
// LifeCycle : created, mounted, updated, destroyed
// created : 처음 컴포넌트가 만들어 질때(화면 나타나기 전)
// mounted : 컴포넌트가 화면에 나타난 후
const rspCoords = {
    바위: '0',
    가위: '-142px',
    보: '-284px',
};
const scores = {
    가위: 1,
    바위: 0,
    보: -1,
};
const computerChoice = (imgCoord) => {
    return Object.entries(rspCoords).find(function (v) {
        return v[1=== imgCoord;
    })[0];
};
 
let interval = null;
export default {
 data(){
     return{
         imgCoord: rspCoords.바위,
         result:'',
         score:0,
     };
 }, 
 computed: {
     computedStyleObject() {
         return{
             background: `url(https://en.pimg.jp/023/182/267/1/23182267.jpg) ${this.imgCoord} 0`,
         };
     }
 },
 methods: {
     changeHand(){
        interval = setInterval(() => { // 기준 간격을 두고 주기적으로 이벤트를 발생 시키고 싶을때 사용, 기간은 milisecond
        if(this.imgCoord === rspCoords.바위){
        this.imgCoord = rspCoords.가위;
         }else if(this.imgCoord === rspCoords.가위){
         this.imgCoord = rspCoords.보;
         }else if (this.imgCoord === rspCoords.보){
         this.imgCoord = rspCoords.바위;
         }
     }, 100);
     },
     onClickButton(choice){
         clearInterval(interval); // 버튼을 클릭하면 손가락 움직이는 사진이 멈춤
        const myScore = scores[choice];
        const cpuScore = scores[computerChoice(this.imgCoord)];
        const diff = myScore - cpuScore;
        if(diff === 0){
            this.result = '비겼습니다.';
        }else if([-12].includes(diff)){
            this.result = '이겼습니다.';
            this.score += 1;
        }else{
            this.result = '졌습니다.';
            this.score -= 1;
        }
        setTimeout(() => {
         this.changeHand();
        }, 1000);
     }
 },
 beforeCreate() {
     console.log('beforeCreate');
 },
 created(){ // 컴포넌트가 만들어 질때(화면에 나타나기 전)
     console.log('Createed');
 }, 
 beforeMount() {
    console.log('beforeMount');
 
 },
 mounted(){ // 컴포넌트가 화면에 보여질때
     console.log('Mounted');
    this.changeHand();
 },
 beforeUpdate() {
    console.log('beforeUpdate');
 },
 updated(){ // 데이터가 변경되어 화면이 다시 그려질때
     console.log('updated');
 },
 beforeDestroy() {
    console.log('beforeDestory');
    clearInterval(interval); // 중지하고 싶을때 사용, 매개변수는 setInterval 함수가 리턴해주는 값을 사용
 },
 destroyed() { // 컴포넌트가 사라질때
    console.log('destroyed');
 },
};
</script>
 
<style scoped> 
#computer{
    width: 142px;
    height: 200px;
    background-position: 0 0;
}
</style>
cs


[webpack.config.js]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const path = require('path'); // 경로 불러오는 것
 
module.exports = { // 노드에 모듈을 만듬, 이안에 웹팩 모든 설정을 넣으면 됨.
    mode:'development'// 배포할건지 개발한건지
    devtool: 'eval'// 개발할때는 eval, 배포할때는 hid,den-source-map
    resolve: {
        extensions: ['.js''.vue'], // 이걸 하면 import할때 확장자를 넣어줄 필요가 없다.
    },
    entry: { // 스크립트를 모인것 중에서 대표적인 스크립트
        app : path.join(__dirname, 'main.js'), // app은 하나로 합친 스크립트 이름
    },
    module: { // 웹팩의 핵심 // entry로 처리하다가 이상한거 나오면 loader를 실행
        rules: [{ // 합칠때 어떻게 합칠지를 설정해주는 것
            test: /\.vue$/// .vue로 끝나는 파일은 vue-loader를 사용하겠다, 정규표현식
            loader: 'vue-loader'// npm i vue-loader
        },{
            test: /\.css$/
            use: [ // loader와 user는 똑같은 기능
                'vue-style-loader',
                'css-loader',
            ]
        }],
    },
    plugins: [
        new VueLoaderPlugin(),
    ],
    output: {
        filename: '[name].js'// 출력할 파일 이름(최종결과)
        path: path.join(__dirname, 'dist'), // 폴더 경로
        publicPath: '/dist'// webpack-dev-server 세팅시 필요
    },
};
 
// entry, module, plugins, output이 주 설정 나머지는 부가적인 설정
cs


깃허브 주소

https://github.com/ksy90101/Vue.js/tree/master/vue-Webgame-inflearn/Chapter05




출처

https://www.inflearn.com/course/web-game-vue/dashboard


Comments