HTML

[javascript] 마시마로 잡기 게임

소댓 2023. 4. 16. 23:06

 

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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>game14.html</title>
    <style>
        * { 
            margin: 0;
            padding: 0;
            /* 조준경 좌표 위치 조절을 위해 모든 마진과 패딩 없앰 */
        }
        canvas { background-color: rgb(255255255);}
        </style>
    <script>
        var bg1 = new Image();
        var bg2 = new Image(); // 배경 이어지게 하기 위해 배경 한 장 더 필요!
        var rabbit1 = new Image();
        var rabbit2 = new Image();
        
        // score 변수 선언
        var score = 0;
        
        // 구멍(hole) 배열
        var holeList = [];
        
        // hole 이미지 객체
        var hole = new Image();
        hole.src = "../images/hole.png"// source 가져오기
        
        // hole 좌표 변수 선언 > 화면에 보이지 않는 값을 기본값으로
        // var holeX = -250;
        // var holeY = -250;
        
        // 조준경 이미지 객체
        var snipe = new Image();
        snipe.src = "../images/snipe.png"// source 가져오기
        
        // 조준경 좌표 변수 선언
        var snipeX = 200;
        var snipeY = 200;
        
        // 배경 X좌표 변수 선언
        var bg1X = 0;
        var bg2X = 800;
        bg1.src = "../images/bg.jpg";
        bg2.src = "../images/bg.jpg";
        
        // 토끼 좌표
        var rabbitX = 100;
        var rabbitY = 100;
        
        rabbit1.src = "../images/rabbit1.PNG";
        rabbit2.src = "../images/rabbit2.PNG";
        
        
        // 재장전 오디오 객체
        var reloadSound = new Audio("../sounds/reload.wav");
        
        // 반동 y값
        var reboundY = 0;
 
        // 재장전 중인지 판단하는 변수
        var isReload = false// 리로드 = false면 총이 나가도록
 
 
        // 토끼 비명소리 객체
        var scream = new Audio("../sounds/scream.wav");
 
        // 총소리 객체
        var fireSound = new Audio("../sounds/fire.wav");
 
        // 배경음악 객체
        var bgMusic = new Audio("../sounds/backsound.mp3"); // 생성자 호출
        // sounds는 day7의 상위폴더인 devs/vscode_workspace에 위치해야 함!
        
        var ctx; // ctx를 전역변수로 선언해서 다른 함수해서도 사용 가능하도록 
        var counter = 0// setInterval > drawScreen 확인용 변수
        
        window.onload=function(){
            var canvas = document.getElementById("myCanvas"); // 캔버스 객체 읽어오기
            ctx = canvas.getContext("2d"); // 2d 컨텍스트 객체 가져오기
            // 붓 준비완료
 
            // 캔버스 위에서 마우스가 움직일 때 
            // canvas.onmousemove=함수명;
            canvas.onmousemove=moveSnipe;
            // 조준경을 움직이게 
 
            // 총 발사 이벤트
            // canvas.onmousedown = 함수명;
            canvas.onmousedown = fire;
 
 
            // body 태그 객체 얻어오기
            // console.dir(document); => body 확인용
            var body = document.body;
            // body.onkeydown = 함수명; => onkeydown : 키를 누르면 / onkeyup : 키를 떼면
            body.onkeydown = moveRabbit; // () 없이 함수 이름만!
 
            // drawScreen(); // 함수 호출
            // window.setTimeout(drawScreen, 1000); // 시간 지연(1회)
            window.setInterval(drawScreen, 70); // 시간 지연 반복
 
        }
 
        function fire(e){
            // console.log(e); // 클릭한 지점의 좌표값 참고 가능
            console.log("발사!");
 
            var holeX = e.pageX;
            var holeY = e.pageY;
 
            // 장전 중이라면 발사 안되게
            // isReload가 참이라면, return 되게! 
            // => return: 아래 코드를 실행하지 않고 다시 위로 돌아가도록
            if(isReload) return// true일땐 실행 안되고 return
 
            isReload = true;
 
            // 총 발사 후 조준경을 약간 위로 올라가게
            reboundY = 50;
 
 
            // 토끼가 총에 맞으면..
            // 토끼가 총에 맞았는지 거리 계산\
            var dis = pythagoras(rabbitX, rabbitY, holeX, holeY); // 토끼의 위치와 구멍의 좌표
 
            console.log("토끼와 구멍까지의 거리 : "+dis);
 
            if(dis<=40) {
            // 좌표로 자바스크립트 객체 생성
    
            // 구멍의 좌표를
            // 토끼 기준으로 상대적 위치로 저장
            // (기존은 이벤트가 일어난 위치에 저장 됐었음!)
            holeX -= rabbitX;
            holeY -= rabbitY;
 
            var h = { // h라는 객체 생성됨 >> 배열에 담기
                x : holeX, 
                y : holeY
            }
            // 배열에 담기
            holeList.push(h);
 
            
            // window.setTimeout(함수명, 지연시간);
            // window.setInterval(함수명, 지연간격);
            
            // 원거리에서 저격하는 느낌 : 0.5초 지연
            window.setTimeout(function(){ // 익명함수로 작성
                // 토끼 비명소리 추가
                scream.currentTime=0;// 다시 쏠 때 기존의 소리 0으로 설정
                scream.play();
            }, 500);
            
            // 토끼가 맞았다면 score변수 점수 올라가게..
            score += 100;
 
            // randomPosition();
 
            fireSound.currentTime=0// 쏘고 다시 쏠 때 기존의 소리를 0으로.. 바로 소리 날 수 있음
            fireSound.play();
        
 
            // 배열에 담은 객체의 내용 확인
            console.log(holeList);
 
            }
        }
 
        // 조준경 마우스 움직일 때 > 함수
        function moveSnipe(e) {
            // console.log(e); // pageX, pageY 로 좌표값 확인 가능
            snipeX = e.pageX;
            snipeY = e.pageY;
 
            // console.log("조준경 마우스 움직이는 함수");
        }
 
        function drawScreen() {
            bg1X--// 배경 좌표 감소
            bg2X--;
 
            // 쏘고 조준경 올라간 거.. 다시 내려오게
            if(reboundY >= 3
                reboundY -= 3;
           
            if(reboundY < 3) {// 조준경이 재위치에 다 왔을 때,
                if(isReload){ // true일 때만 relaod
                    reloadSound.currentTime = 0;
                    reloadSound.play(); // 재장전 소리 내주고
 
                    reboundY = 0// 조준경 0으로 맞춰준 다음
                    isReload = false
                    // 다시 총알 발사 가능
                }
            }
 
 
 
            if(bg1X <= -800) {// 첫번째 배경이 완전히 화면 밖으로 나가면
                bg1X = 800;
                bg2X = 0;
            } else if(bg2X <= -800) {
                bg2X = 800;
                bg1X = 0;
            }
 
 
            counter ++;
            // console.log(counter);
            
            
            ctx.drawImage(bg1, bg1X, 0800600);
            ctx.drawImage(bg2, bg2X, 0800600);
 
            if(counter%2 == 1){
            // 조준 좌표를 위해 토끼 x좌표, y좌표에서 50씩 마이너스
                ctx.drawImage(rabbit1, rabbitX-50, rabbitY-50100100);
          
           }else  {
            // ctx.drawImage(bg, 0, 0, 800, 600);
                ctx.drawImage(rabbit2, rabbitX-50, rabbitY-50100100);
            }
 
            // 구멍 그리기(토끼보다 위에!)
            // ctx.drawImage(hole, holeX, holeY, 10, 10);
            // 배열에서 한개씩 꺼내서 구멍 그리기
            for(var i = 0; i<holeList.length; i++) {
                var h = holeList[i];
                // 토끼가 움직인 것이 반영된 위치에 구멍이 그려짐
                ctx.drawImage(hole,h.x + rabbitX, h.y+rabbitY, 1010); // 배열 안의 그림을 꺼내서 그리기
            }
                        
 
            // 조준경 그리기 ==> 쏠 때마다 조준경 위치 위로 올라가게!(-reboundY 추가)
            ctx.drawImage(snipe, snipeX-50, snipeY-50-reboundY, 100100); 
            
            // 마우스 커서 대비 조준경 (페이지)s좌표 위치 조절 => snipe이미지 크기 절반 만큼 좌표에서 빼기
            // 모든 패딩과 마진을 없앰 => style에서!
 
  
            // score 출력
            ctx.font = "35px 고딕";
            ctx.fillStyle = "red";
            ctx.fillText("SCORE : "+score, 30050);
 
            // 토끼가 랜덤으로 나타나는 빈도를 줄이기 위해
            // counter 변수가 5가 될 때마다 랜덤 포지션 호출
            if (counter%7 == 0)randomPosition();
 
        }
 
        function randomPosition() {
            rabbitX = Math.floor(Math.random()*650 + 50);
            rabbitY = Math.floor(Math.random()*450 + 50);
        }
        
        function pythagoras(x1, y1, x2, y2) {
           return  Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); 
        }
 
 
        function moveRabbit(e) {
            console.log(e);
            // console.log(pos);
            // if(pos == 8)
            //     rabbitY -= 5;
            // else if(pos == 4)
            //     rabbitX -= 5;
            // else if(pos == 6)
            //     rabbitX += 5;
            // else if(pos == 2)
            //     rabbitY += 5;1
 
        
        if( e.keyCode == 38) rabbitY -= 5;
            else if (e.keyCode == 39) rabbitX += 5;
            else if (e.keyCode == 37) rabbitX -= 5;
            else if(e.keyCode == 40) rabbitY += 5;
 
 
        }
 
        function startMusic() {
            console.log("배경음악 시작 플레이중");
            bgMusic.play(); // 오디오 플레이
        }
 
        function stopMusic() {
            console.log("배경음악 중지");
            bgMusic.currentTime=0// 플레이 시점을 처음으로 되돌림(되감기)
            bgMusic.pause(); // 오디오 중지
        }
 
 
    </script>
</head>
<body>
 
    <canvas id="myCanvas" width="800" height="600"></canvas>
    <br>
    <input type="button" value="배경음악시작" onclick="startMusic();">
    <input type="button" value="배경음악중지" onclick="stopMusic();"><br>
 
 
</body>
</html>
cs