티스토리 뷰

2017/03/23 - [Computer/Javascript] - (Phaser) phaser 로 간단한 웹게임 만들기 - 메뉴

2017/03/23 - [Computer/Javascript] - (Phaser) phaser 로 간단한 웹게임 만들기 - 뱀 그리기

2017/03/23 - [Computer/Javascript] - (Phaser) phaser 로 간단한 웹게임 만들기 - 뱀 움직이기




STEP 1) 구성 이해하기


충돌처리는 아래와 같은 단계로 이루어진다.


  1. 뱀의 이동
  2. 사과와의 충돌 체크 (점수 + 1, 길이 + 1)
  3. 벽과의 충돌 체크 (go to game_over.js)
  4. 자기 자신과의 충돌 체크 (go to game_over.js)

이 정도면 우리 머릿속에는 어떤 코드들이 추가되어야 하는지 나올거다.


우선, 이전 튜토리얼에서 했던 뱀의 이동처리(update) 맨 끝부분에 충돌체크하는 코드를 삽입해야 하고.

game_over 상태를 보여줘야 하며, 

main 에서 game_over 상태를 추가해 줘야 한다.

더불어 game_over에서 클릭시 다시 game.js 상태로 가야한다.


코딩을 한번 해보자.








STEP 2) game.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
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
var snake, apple, squareSize, score, speed,
    updateDelay, direction, new_direction,
    addNew, cursors, scoreTextValue, speedTextValue, 
    textStyle_Key, textStyle_Value;
 
var Game = {
    preload : function() {
        // 뱀의 몸통과 사과 이미지 두개를 preload 해놓는다.
        game.load.image('snake''./assets/images/snake.png');
        game.load.image('apple''./assets/images/apple.png');
    },
 
    create : function() {
        snake = [];                     // sanke.png 를 얼마나 표시할지를 나타낼 변수
        apple = {};                     // 사과
        squareSize = 15;                // 사과/뱀의 1 블럭 사이즈
        score = 0;                      // Game score.
        speed = 0;                      // Game speed.
        updateDelay = 0;                // 키 입력시 얼만큼의 delay 후 방향을 변경할 지
        direction = 'right';            // 시작시 뱀의 방향
        new_direction = null;           // 키 입력시 변경될 뱀의 방향
        addNew = false;                 // 뱀이 사과를 먹었을 때, 새로운 사과를 놓을지 여부
 
        // 기본 Phaser 컨트롤러를 keyboard input 으로 받겠다고 명시
        cursors = game.input.keyboard.createCursorKeys();
        game.stage.backgroundColor = '#061f27';
 
        
        for(var i = 0; i < 10; i++) {
            snake[i] = game.add.sprite(150 + i * squareSize, 150'snake');  // Parameters are (X coordinate, Y coordinate, image)
        }
 
        // 첫 사과 배치
        this.generateApple();
        
        // 상단의 텍스트 (점수, 속도)
        textStyle_Key = { font: "bold 14px sans-serif", fill: "#46c0f9", align: "center" };
        textStyle_Value = { font: "bold 18px sans-serif", fill: "#fff", align: "center" };
 
        // Score.
        game.add.text(3020"SCORE", textStyle_Key);
        scoreTextValue = game.add.text(9018, score.toString(), textStyle_Value);
        
        // Speed.
        game.add.text(50020"SPEED", textStyle_Key);
        speedTextValue = game.add.text(55818, speed.toString(), textStyle_Value);
 
    },
 
 
    update: function() {
        //    키 입력 처리
        if (cursors.right.isDown && direction!='left') {
            new_direction = 'right';
        } else if (cursors.left.isDown && direction!='right') {
            new_direction = 'left';
        } else if (cursors.up.isDown && direction!='down') {
            new_direction = 'up';
        } else if (cursors.down.isDown && direction!='up') {
            new_direction = 'down';
        }
 
 
        // A formula to calculate game speed based on the score.
        // The higher the score, the higher the game speed, with a maximum of 10;
        speed = Math.min(10, Math.floor(score/5));
        
        // Update speed value on game screen.
        speedTextValue.text = '' + speed;
 
        // Since the update function of Phaser has an update rate of around 60 FPS,
        // we need to slow that down make the game playable.
 
        // Increase a counter on every update call.
        updateDelay++;
 
        // Do game stuff only if the counter is aliquot to (10 - the game speed).
        // The higher the speed, the more frequently this is fulfilled,
        // making the snake move faster.
        if (updateDelay % (10 - speed) == 0) {
            // Snake movement
            var firstCell = snake[snake.length - 1],
                lastCell = snake.shift(),
                oldLastCellx = lastCell.x,
                oldLastCelly = lastCell.y;
 
            // If a new direction has been chosen from the keyboard, make it the direction of the snake now.
            if(new_direction) {
                direction = new_direction;
                new_direction = null;
            }
 
 
            // Change the last cell's coordinates relative to the head of the snake, according to the direction.
 
            if(direction == 'right') {
                lastCell.x = firstCell.x + 15;
                lastCell.y = firstCell.y;
            } else if(direction == 'left') {
                lastCell.x = firstCell.x - 15;
                lastCell.y = firstCell.y;
            } else if(direction == 'up') {
                lastCell.x = firstCell.x;
                lastCell.y = firstCell.y - 15;
            } else if(direction == 'down') {
                lastCell.x = firstCell.x;
                lastCell.y = firstCell.y + 15;
            }
 
 
            // Place the last cell in the front of the stack.
            // Mark it the first cell.
 
            snake.push(lastCell);
            firstCell = lastCell;
 
        if(addNew) {
            snake.unshift(game.add.sprite(oldLastCellx, oldLastCelly, 'snake'));
            addNew = false;
        }
 
        // Check for apple collision.
        this.appleCollision();
 
        // Check for collision with self. Parameter is the head of the snake.
        this.selfCollision(firstCell);
 
        // Check with collision with wall. Parameter is the head of the snake.
        this.wallCollision(firstCell);
        }
    },
 
    generateApple: function() {
        // 사과를 랜덤 위치에 놓는다.
        var randomX = Math.floor(Math.random() * 40 ) * squareSize,
            randomY = Math.floor(Math.random() * 30 ) * squareSize;
 
        // Add a new apple.
        apple = game.add.sprite(randomX, randomY, 'apple');        
    },
    
    appleCollision: function() {
        // Check if any part of the snake is overlapping the apple.
        // This is needed if the apple spawns inside of the snake.
        for(var i = 0; i < snake.length; i++) {
            if(snake[i].x == apple.x && snake[i].y == apple.y) {
                // Next time the snake moves, a new block will be added to its length.
                addNew = true;
 
                // Destroy the old apple.
                apple.destroy();
 
                // Make a new one.
                this.generateApple();
 
                // Increase score.
                score++;
 
                // Refresh scoreboard.
                scoreTextValue.text = score.toString();
 
            }
        }
 
    },
 
    selfCollision: function(head) {
        // Check if the head of the snake overlaps with any part of the snake.
        for(var i = 0; i < snake.length - 1; i++) {
            if(head.x == snake[i].x && head.y == snake[i].y) {
                // If so, go to game over screen.
                game.state.start('Game_Over');
            }
        }
    },
 
    wallCollision: function(head) {
        // Check if the head of the snake is in the boundaries of the game field.
        if(head.x >= 600 || head.x < 0 || head.y >= 450 || head.y < 0) {
            // If it's not in, we've hit a wall. Go to game over screen.
            game.state.start('Game_Over');
        }
    }
};
cs





STEP 3) main.js


1
2
3
4
5
6
7
8
9
var game;
 
game = new Phaser.Game(600450, Phaser.AUTO, '');
 
game.state.add('Menu', Menu);
game.state.add('Game', Game);
game.state.add('Game_Over', Game_Over);
 
game.state.start('Menu');
cs





STEP 4) game_over.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
var Game_Over = {
 
    preload : function() {
        // Load the needed image for this game screen.
        game.load.image('gameover''./assets/images/gameover.png');
    },
 
    create : function() {
 
        // Create button to start game like in Menu.
        this.add.button(00'gameover', this.startGame, this);
 
        // Add text with information about the score from last game.
        game.add.text(235350"LAST SCORE", { font: "bold 16px sans-serif", fill: "#46c0f9", align: "center"});
        game.add.text(350348, score.toString(), { font: "bold 20px sans-serif", fill: "#fff", align: "center" });
 
    },
 
    startGame: function () {
 
        // Change the state back to Game.
        this.state.start('Game');
 
    }
};
cs




STEP 5) 실행







공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함