├── README.md
├── res
├── g.png
├── bg.png
├── atlas.png
├── birdy.png
├── blood.png
├── board.png
├── icon.png
├── over.png
├── reset.png
├── start.png
├── tube.png
├── tube2.png
├── birddie.png
├── sfx_die.mp3
├── sfx_hit.mp3
├── sfx_wing.mp3
├── iconweixin.png
├── sfx_point.mp3
└── sfx_swooshing.mp3
├── bower_components
└── phaser
│ ├── bower.json
│ ├── README.md
│ └── .bower.json
├── .gitignore
├── gulpfile.coffee
├── bower.json
├── package.json
├── gulpfile.js
├── LICENSE
├── index.html
├── index.coffee
└── index.js
/README.md:
--------------------------------------------------------------------------------
1 | FlappyTube
2 | ==========
3 |
--------------------------------------------------------------------------------
/res/g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/g.png
--------------------------------------------------------------------------------
/res/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/bg.png
--------------------------------------------------------------------------------
/res/atlas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/atlas.png
--------------------------------------------------------------------------------
/res/birdy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/birdy.png
--------------------------------------------------------------------------------
/res/blood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/blood.png
--------------------------------------------------------------------------------
/res/board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/board.png
--------------------------------------------------------------------------------
/res/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/icon.png
--------------------------------------------------------------------------------
/res/over.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/over.png
--------------------------------------------------------------------------------
/res/reset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/reset.png
--------------------------------------------------------------------------------
/res/start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/start.png
--------------------------------------------------------------------------------
/res/tube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/tube.png
--------------------------------------------------------------------------------
/res/tube2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/tube2.png
--------------------------------------------------------------------------------
/res/birddie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/birddie.png
--------------------------------------------------------------------------------
/res/sfx_die.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/sfx_die.mp3
--------------------------------------------------------------------------------
/res/sfx_hit.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/sfx_hit.mp3
--------------------------------------------------------------------------------
/res/sfx_wing.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/sfx_wing.mp3
--------------------------------------------------------------------------------
/res/iconweixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/iconweixin.png
--------------------------------------------------------------------------------
/res/sfx_point.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/sfx_point.mp3
--------------------------------------------------------------------------------
/res/sfx_swooshing.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flynngao/FlappyTube/HEAD/res/sfx_swooshing.mp3
--------------------------------------------------------------------------------
/bower_components/phaser/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phaser",
3 | "version": "1.1.4",
4 | "main": "./phaser.js"
5 | }
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib-cov
2 | *.seed
3 | *.log
4 | *.csv
5 | *.dat
6 | *.out
7 | *.pid
8 | *.gz
9 |
10 | pids
11 | logs
12 | results
13 |
14 | npm-debug.log
15 | node_modules
16 | res
--------------------------------------------------------------------------------
/bower_components/phaser/README.md:
--------------------------------------------------------------------------------
1 | # bower-phaser
2 |
3 | The source for this package is in the [main Phaser repo](https://github.com/photonstorm/phaser).
4 |
5 | ## Install
6 |
7 | Install with `bower`:
8 |
9 | ```shell
10 | bower install phaser
11 | ```
12 |
13 | Add a `
17 | ```
18 |
--------------------------------------------------------------------------------
/bower_components/phaser/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phaser",
3 | "version": "1.1.4",
4 | "main": "./phaser.js",
5 | "homepage": "https://github.com/nDmitry/bower-phaser",
6 | "_release": "1.1.4",
7 | "_resolution": {
8 | "type": "version",
9 | "tag": "1.1.4",
10 | "commit": "22afbebdaa47f373cf5f99fe4403052a0b887fff"
11 | },
12 | "_source": "git://github.com/nDmitry/bower-phaser.git",
13 | "_target": "~1.1.4",
14 | "_originalSource": "phaser"
15 | }
--------------------------------------------------------------------------------
/gulpfile.coffee:
--------------------------------------------------------------------------------
1 | gulp = require 'gulp'
2 | coffee = require 'gulp-coffee'
3 | gutil = require 'gulp-util'
4 | connect = require 'gulp-connect'
5 |
6 | gulp.task 'coffee', ->
7 | gulp.src ['index.coffee','!gulpfile.coffee']
8 | .pipe coffee( bare: true ).on('error', gutil.log)
9 |
10 | gulp.task 'watch', ->
11 | gulp.watch ['index.html','index.coffee', '!gulpfile.coffee'], ['coffee']
12 |
13 | gulp.task "connect", connect.server(
14 | root: __dirname
15 | port: 3000
16 | livereload: true
17 | )
18 |
19 | gulp.task 'default', ['coffee','connect','watch']
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flappytube",
3 | "version": "0.0.1",
4 | "homepage": "https://github.com/flynngao/FlappyTube",
5 | "authors": [
6 | "Flynn Gao "
7 | ],
8 | "description": "Flappy Tube",
9 | "main": "index.html",
10 | "keywords": [
11 | "H5",
12 | "games",
13 | "flappy"
14 | ],
15 | "license": "MIT",
16 | "private": true,
17 | "ignore": [
18 | "**/.*",
19 | "node_modules",
20 | "bower_components",
21 | "test",
22 | "tests"
23 | ],
24 | "dependencies":{
25 | "phaser": "~1.1.4"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flappytube",
3 | "version": "0.0.1",
4 | "description": "Flppay Tube",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "game",
11 | "flappy",
12 | "tube"
13 | ],
14 | "repository": {
15 | "type": "git",
16 | "url": "git@github.com:flynngao/FlappyTube.git"
17 | },
18 | "devDependencies": {
19 | "gulp": "~3.5.2",
20 | "coffee-script": "*",
21 | "gulp-coffee": "*",
22 | "gulp-util": "~2.2.14",
23 | "gulp-connect": "*"
24 | },
25 | "author": "Flynn Gao",
26 | "license": "MIT"
27 | }
28 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.7.1
2 | var coffee, connect, gulp, gutil;
3 |
4 | gulp = require('gulp');
5 |
6 | coffee = require('gulp-coffee');
7 |
8 | gutil = require('gulp-util');
9 |
10 | connect = require('gulp-connect');
11 |
12 | gulp.task('coffee', function() {
13 | return gulp.src(['index.coffee', '!gulpfile.coffee']).pipe(coffee({
14 | bare: true
15 | }).on('error', gutil.log));
16 | });
17 |
18 | gulp.task('watch', function() {
19 | return gulp.watch(['index.html', 'index.coffee', '!gulpfile.coffee'], ['coffee']);
20 | });
21 |
22 | gulp.task("connect", connect.server({
23 | root: __dirname,
24 | port: 3000,
25 | livereload: true
26 | }));
27 |
28 | gulp.task('default', ['coffee', 'connect', 'watch']);
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Flynngao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flappy Tube
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
45 |
46 |
47 |
48 | Code and Design by FlynnGao
49 |
50 |
51 |
52 |
53 |
63 |
71 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/index.coffee:
--------------------------------------------------------------------------------
1 | DEBUG = false
2 | SPEED = 160
3 | GRAVITY = 600
4 | SPAWN_RATE = 1 / 1200
5 |
6 | HEIGHT = 480
7 | WIDTH = 320
8 | GAME_HEIGHT = 336
9 | GROUND_HEIGHT = 64
10 | GROUND_Y = HEIGHT - GROUND_HEIGHT
11 | HARD = 250
12 |
13 | # Object
14 | tube = null
15 | birds = null
16 | birddie = null
17 | ground = null
18 | bg = null
19 | blood = null
20 | bloods = null
21 | # Game Flow
22 | gameStart = false
23 | gameOver = false
24 | birdsTimer = null
25 | dieRate = null
26 | # Game Texts
27 | score = null
28 | bestScore = 0
29 | bestText = null
30 | comingsoon = null
31 | scoreText = null
32 | instText = null
33 | gameOverText = null
34 | resetText = null
35 | gameStartText = null
36 | avoidText = null
37 | board = null
38 | # Sounds
39 | flapSnd = null
40 | scoreSnd = null
41 | hurtSnd = null
42 | fallSnd = null
43 | swooshSnd = null
44 |
45 | floor = Math.floor
46 |
47 | main = ->
48 |
49 | hitBirds = (tube,bird)->
50 |
51 | bird.kill()
52 |
53 | score += 1
54 | bestScore = if score > bestScore then score else bestScore
55 | scoreText.setText score
56 |
57 | b = bloods.getFirstDead()
58 | b.reset(bird.body.x,bird.body.y)
59 | b.play('blood',20,false,true)
60 | hurtSnd.play()
61 | return
62 |
63 | createBirds = ->
64 |
65 | dieRate = score / HARD
66 | birds.forEachAlive (bird) ->
67 | if bird.x + bird.width < game.world.bounds.left
68 | bird.kill()
69 | return
70 | birddie.forEachAlive (bird) ->
71 | if bird.x + bird.width < game.world.bounds.left
72 | bird.kill()
73 | return
74 |
75 | for i in [(parseInt(Math.random()*10)%4+8)...0]
76 | raceName = if Math.random() > dieRate then 'birdy' else 'birddie'
77 | race = if raceName == 'birdy' then birds else birddie
78 | bird = race.create(game.world.width-(Math.random()-0.5)*120, i * (35-(Math.random()-0.5)*5), raceName)
79 | bird.anchor.setTo 0.5, 0.5
80 | bird.body.velocity.x = -SPEED * 1.5
81 |
82 |
83 | return
84 |
85 | flap = ->
86 |
87 | start() unless gameStart
88 |
89 | unless gameOver
90 | tube.body.velocity.y = -200;
91 | tube.body.gravity.y = 0;
92 |
93 | tween = game.add.tween(tube.body.velocity).to(y:-280, 25, Phaser.Easing.Bounce.In,true);
94 | tween.onComplete.add ->
95 | tube.body.gravity.y = GRAVITY
96 |
97 | flapSnd.play()
98 |
99 |
100 | return
101 |
102 | start = ->
103 | gameStart = true
104 | gameStartText.renderable = false
105 | comingsoon.renderable = false
106 | # SPAWN birds!
107 | birdsTimer = game.time.events.loop 1 / SPAWN_RATE, createBirds
108 | scoreText.setText score
109 | avoidText.renderable = false
110 | return
111 |
112 | over = ->
113 | gameOver = true
114 |
115 | gameOverText.renderable = true
116 | resetText.renderable = true
117 | board.renderable = true
118 | bestText.renderable = true
119 | bestText.setText bestScore
120 | bestText.x = 210
121 | bestText.y = 240
122 | scoreText.x = 210
123 | scoreText.y = 195
124 |
125 | document.getElementById('star').style.display = 'block';
126 | # Stop spawning tubes
127 | game.time.events.remove(birdsTimer)
128 |
129 |
130 | game.time.events.add 1000, ->
131 | game.input.onTap.addOnce ->
132 | reset()
133 | fallSnd.play()
134 | return
135 |
136 | preload = ->
137 | assets =
138 | image:
139 | "bg" : 'res/bg.png'
140 | "birdy" : 'res/birdy.png'
141 | "birddie": 'res/birddie.png'
142 | "g" : 'res/g.png'
143 | "tube" : 'res/tube.png'
144 | "start" : 'res/start.png'
145 | "reset" : 'res/reset.png'
146 | "over" : 'res/over.png'
147 | "board" : 'res/board.png'
148 | audio:
149 | "die" : 'res/sfx_die.mp3'
150 | "hit" : 'res/sfx_hit.mp3'
151 | "point" : 'res/sfx_point.mp3'
152 | "flap" : 'res/sfx_wing.mp3'
153 | spritesheet:
154 | "blood" : ['res/blood.png',64, 64]
155 |
156 |
157 |
158 | Object.keys(assets).forEach (type) ->
159 | Object.keys(assets[type]).forEach (id) ->
160 | game.load[type].apply game.load, [id].concat(assets[type][id])
161 | return
162 | return
163 | return
164 |
165 | create = ->
166 |
167 | Phaser.Canvas.setSmoothingEnabled(game.context, false)
168 | game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL
169 | game.stage.scale.setScreenSize(true)
170 | game.world.width = WIDTH
171 | game.world.height = HEIGHT
172 |
173 |
174 | # bg
175 | bg = game.add.tileSprite(0, 0,WIDTH,HEIGHT,'bg');
176 |
177 | # ground
178 | ground = game.add.tileSprite(0,GROUND_Y,WIDTH,GROUND_HEIGHT,'g');
179 |
180 | # Add Birds
181 | birds = game.add.group()
182 | birddie = game.add.group()
183 |
184 | tube = game.add.sprite(0,0,"tube")
185 | tube.anchor.setTo(0.5 , 0.5)
186 |
187 | # Add sounds
188 | flapSnd = game.add.audio("flap")
189 | scoreSnd = game.add.audio("point")
190 | hurtSnd = game.add.audio("hit")
191 | fallSnd = game.add.audio("die")
192 |
193 | #bloods
194 | bloods = game.add.group()
195 | bloods.createMultiple(20,'blood')
196 | bloods.forEach((x)->
197 | x.anchor.x = 0.5
198 | x.anchor.y = 0.5
199 | x.animations.add('blood')
200 | return
201 | this)
202 |
203 | board = game.add.sprite(game.world.width / 2 ,game.world.height / 2.3,'board')
204 | board.anchor.setTo 0.5, 0.5
205 | board.scale.setTo 1, 1
206 | board.renderable = false
207 |
208 | #score
209 | scoreText = game.add.text(game.world.width / 2, game.world.height / 6, "",
210 | font: "20px \"sans\""
211 | fill: "#fff"
212 | stroke:"#111"
213 | strokeThickness:4
214 | align:"center")
215 | scoreText.anchor.setTo 0.5 , 0.5
216 |
217 | bestText = game.add.text(game.world.width / 2, game.world.height / 6, "",
218 | font: "20px \"sans\""
219 | fill: "#fff"
220 | stroke:"#111"
221 | strokeThickness:4
222 | align:"center")
223 | bestText.anchor.setTo 0.5 , 0.5
224 | bestText.renderable = false
225 |
226 | avoidText = game.add.text(game.world.width / 2, game.world.height / 2.7, "",
227 | font: "14px \"sans\""
228 | fill: "#fff"
229 | stroke:"#111"
230 | strokeThickness:4
231 | align:"center")
232 | avoidText.anchor.setTo 0.5 , 0.5
233 | avoidText.setText("Avoid this")
234 |
235 | gameStartText = game.add.sprite(game.world.width / 2, game.world.height / 2,'start')
236 | gameStartText.anchor.setTo 0.5, 0.5
237 | gameStartText.scale.setTo 1, 1
238 | # Add game over text
239 | gameOverText = game.add.sprite(game.world.width / 2, game.world.height / 4,'over')
240 | gameOverText.anchor.setTo 0.5, 0.5
241 | gameOverText.scale.setTo 1, 1
242 | gameOverText.renderable = false
243 |
244 | comingsoon = game.add.text(game.world.width / 1.5, game.world.height / 4.5,'',
245 | font: "12px \"sans\""
246 | fill: "#d9d12b"
247 | stroke:"#111"
248 | strokeThickness:3
249 | align:"center")
250 | comingsoon.anchor.setTo 0.5, 0.5
251 | comingsoon.scale.setTo 1, 1
252 | comingsoon.setText(' ^\nComing soon!')
253 |
254 |
255 |
256 |
257 | resetText = game.add.sprite(game.world.width/ 2, game.world.height / 1.5,'reset')
258 | resetText.anchor.setTo 0.5, 0.5
259 | resetText.scale.setTo 1, 1
260 | resetText.renderable = false
261 |
262 | # control
263 | game.input.onDown.add flap
264 |
265 |
266 | reset()
267 |
268 | return
269 |
270 | update = ->
271 | if gameStart
272 |
273 | unless gameOver
274 | # Check game over
275 | game.physics.overlap tube, birddie, ->
276 | over()
277 | fallSnd.play()
278 | over() if not gameOver and tube.body.bottom >= GROUND_Y
279 |
280 | game.physics.overlap tube, birds, hitBirds, null ,this
281 |
282 | # Scroll ground
283 | ground.tilePosition.x -= game.time.physicsElapsed * SPEED / 2 unless gameOver
284 | bg.tilePosition.x -= game.time.physicsElapsed * SPEED unless gameOver
285 |
286 |
287 | else
288 |
289 | if tube.body.bottom >= GROUND_Y + 3
290 | tube.y = GROUND_Y - 13
291 | tube.body.velocity.y = 0
292 | tube.body.allowGravity = false
293 | tube.body.gravity.y = 0
294 |
295 | return
296 |
297 | render = ->
298 | return
299 |
300 | reset = ->
301 |
302 | gameStart = false
303 | gameOver = false
304 | gameOverText.renderable = false
305 | resetText.renderable = false
306 | gameStartText.renderable = true
307 | board.renderable = false
308 | bestText.renderable = false
309 | avoidText.renderable = true
310 | comingsoon.renderable = true
311 | document.getElementById('star').style.display = 'none';
312 | score = 0
313 | scoreText.setText('Flappy Tube 2')
314 | scoreText.x = game.world.width / 2
315 | scoreText.y = game.world.height / 6
316 | birds.removeAll()
317 | tube.reset game.world.width * 0.25, game.world.height /2.3
318 |
319 |
320 | return
321 |
322 |
323 | state =
324 | preload : preload
325 | create : create
326 | update : update
327 | render : render
328 |
329 | game = new Phaser.Game(WIDTH, HEIGHT, Phaser.CANVAS, 'screem', state, false)
330 |
331 |
332 | main()
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.7.1
2 | var DEBUG, GAME_HEIGHT, GRAVITY, GROUND_HEIGHT, GROUND_Y, HARD, HEIGHT, SPAWN_RATE, SPEED, WIDTH, avoidText, bestScore, bestText, bg, birddie, birds, birdsTimer, blood, bloods, board, comingsoon, dieRate, fallSnd, flapSnd, floor, gameOver, gameOverText, gameStart, gameStartText, ground, hurtSnd, instText, main, resetText, score, scoreSnd, scoreText, swooshSnd, tube;
3 |
4 | DEBUG = false;
5 |
6 | SPEED = 160;
7 |
8 | GRAVITY = 600;
9 |
10 | SPAWN_RATE = 1 / 1200;
11 |
12 | HEIGHT = 480;
13 |
14 | WIDTH = 320;
15 |
16 | GAME_HEIGHT = 336;
17 |
18 | GROUND_HEIGHT = 64;
19 |
20 | GROUND_Y = HEIGHT - GROUND_HEIGHT;
21 |
22 | HARD = 250;
23 |
24 | tube = null;
25 |
26 | birds = null;
27 |
28 | birddie = null;
29 |
30 | ground = null;
31 |
32 | bg = null;
33 |
34 | blood = null;
35 |
36 | bloods = null;
37 |
38 | gameStart = false;
39 |
40 | gameOver = false;
41 |
42 | birdsTimer = null;
43 |
44 | dieRate = null;
45 |
46 | score = null;
47 |
48 | bestScore = 0;
49 |
50 | bestText = null;
51 |
52 | comingsoon = null;
53 |
54 | scoreText = null;
55 |
56 | instText = null;
57 |
58 | gameOverText = null;
59 |
60 | resetText = null;
61 |
62 | gameStartText = null;
63 |
64 | avoidText = null;
65 |
66 | board = null;
67 |
68 | flapSnd = null;
69 |
70 | scoreSnd = null;
71 |
72 | hurtSnd = null;
73 |
74 | fallSnd = null;
75 |
76 | swooshSnd = null;
77 |
78 | floor = Math.floor;
79 |
80 | main = function() {
81 | var create, createBirds, flap, game, hitBirds, over, preload, render, reset, start, state, update;
82 | hitBirds = function(tube, bird) {
83 | var b;
84 | bird.kill();
85 | score += 1;
86 | bestScore = score > bestScore ? score : bestScore;
87 | scoreText.setText(score);
88 | b = bloods.getFirstDead();
89 | b.reset(bird.body.x, bird.body.y);
90 | b.play('blood', 20, false, true);
91 | hurtSnd.play();
92 | };
93 | createBirds = function() {
94 | var bird, i, race, raceName, _i, _ref;
95 | dieRate = score / HARD;
96 | birds.forEachAlive(function(bird) {
97 | if (bird.x + bird.width < game.world.bounds.left) {
98 | bird.kill();
99 | }
100 | });
101 | birddie.forEachAlive(function(bird) {
102 | if (bird.x + bird.width < game.world.bounds.left) {
103 | bird.kill();
104 | }
105 | });
106 | for (i = _i = _ref = parseInt(Math.random() * 10) % 4 + 8; _ref <= 0 ? _i < 0 : _i > 0; i = _ref <= 0 ? ++_i : --_i) {
107 | raceName = Math.random() > dieRate ? 'birdy' : 'birddie';
108 | race = raceName === 'birdy' ? birds : birddie;
109 | bird = race.create(game.world.width - (Math.random() - 0.5) * 120, i * (35 - (Math.random() - 0.5) * 5), raceName);
110 | bird.anchor.setTo(0.5, 0.5);
111 | bird.body.velocity.x = -SPEED * 1.5;
112 | }
113 | };
114 | flap = function() {
115 | var tween;
116 | if (!gameStart) {
117 | start();
118 | }
119 | if (!gameOver) {
120 | tube.body.velocity.y = -200;
121 | tube.body.gravity.y = 0;
122 | tween = game.add.tween(tube.body.velocity).to({
123 | y: -280
124 | }, 25, Phaser.Easing.Bounce.In, true);
125 | tween.onComplete.add(function() {
126 | return tube.body.gravity.y = GRAVITY;
127 | });
128 | flapSnd.play();
129 | }
130 | };
131 | start = function() {
132 | gameStart = true;
133 | gameStartText.renderable = false;
134 | comingsoon.renderable = false;
135 | birdsTimer = game.time.events.loop(1 / SPAWN_RATE, createBirds);
136 | scoreText.setText(score);
137 | avoidText.renderable = false;
138 | };
139 | over = function() {
140 | gameOver = true;
141 | gameOverText.renderable = true;
142 | resetText.renderable = true;
143 | board.renderable = true;
144 | bestText.renderable = true;
145 | bestText.setText(bestScore);
146 | bestText.x = 210;
147 | bestText.y = 240;
148 | scoreText.x = 210;
149 | scoreText.y = 195;
150 | document.getElementById('star').style.display = 'block';
151 | game.time.events.remove(birdsTimer);
152 | game.time.events.add(1000, function() {
153 | return game.input.onTap.addOnce(function() {
154 | return reset();
155 | });
156 | });
157 | fallSnd.play();
158 | };
159 | preload = function() {
160 | var assets;
161 | assets = {
162 | image: {
163 | "bg": 'res/bg.png',
164 | "birdy": 'res/birdy.png',
165 | "birddie": 'res/birddie.png',
166 | "g": 'res/g.png',
167 | "tube": 'res/tube.png',
168 | "start": 'res/start.png',
169 | "reset": 'res/reset.png',
170 | "over": 'res/over.png',
171 | "board": 'res/board.png'
172 | },
173 | audio: {
174 | "die": 'res/sfx_die.mp3',
175 | "hit": 'res/sfx_hit.mp3',
176 | "point": 'res/sfx_point.mp3',
177 | "flap": 'res/sfx_wing.mp3'
178 | },
179 | spritesheet: {
180 | "blood": ['res/blood.png', 64, 64]
181 | }
182 | };
183 | Object.keys(assets).forEach(function(type) {
184 | Object.keys(assets[type]).forEach(function(id) {
185 | game.load[type].apply(game.load, [id].concat(assets[type][id]));
186 | });
187 | });
188 | };
189 | create = function() {
190 | Phaser.Canvas.setSmoothingEnabled(game.context, false);
191 | game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL;
192 | game.stage.scale.setScreenSize(true);
193 | game.world.width = WIDTH;
194 | game.world.height = HEIGHT;
195 | bg = game.add.tileSprite(0, 0, WIDTH, HEIGHT, 'bg');
196 | ground = game.add.tileSprite(0, GROUND_Y, WIDTH, GROUND_HEIGHT, 'g');
197 | birds = game.add.group();
198 | birddie = game.add.group();
199 | tube = game.add.sprite(0, 0, "tube");
200 | tube.anchor.setTo(0.5, 0.5);
201 | flapSnd = game.add.audio("flap");
202 | scoreSnd = game.add.audio("point");
203 | hurtSnd = game.add.audio("hit");
204 | fallSnd = game.add.audio("die");
205 | bloods = game.add.group();
206 | bloods.createMultiple(20, 'blood');
207 | bloods.forEach(function(x) {
208 | x.anchor.x = 0.5;
209 | x.anchor.y = 0.5;
210 | x.animations.add('blood');
211 | return;
212 | return this;
213 | });
214 | board = game.add.sprite(game.world.width / 2, game.world.height / 2.3, 'board');
215 | board.anchor.setTo(0.5, 0.5);
216 | board.scale.setTo(1, 1);
217 | board.renderable = false;
218 | scoreText = game.add.text(game.world.width / 2, game.world.height / 6, "", {
219 | font: "20px \"sans\"",
220 | fill: "#fff",
221 | stroke: "#111",
222 | strokeThickness: 4,
223 | align: "center"
224 | });
225 | scoreText.anchor.setTo(0.5, 0.5);
226 | bestText = game.add.text(game.world.width / 2, game.world.height / 6, "", {
227 | font: "20px \"sans\"",
228 | fill: "#fff",
229 | stroke: "#111",
230 | strokeThickness: 4,
231 | align: "center"
232 | });
233 | bestText.anchor.setTo(0.5, 0.5);
234 | bestText.renderable = false;
235 | avoidText = game.add.text(game.world.width / 2, game.world.height / 2.7, "", {
236 | font: "14px \"sans\"",
237 | fill: "#fff",
238 | stroke: "#111",
239 | strokeThickness: 4,
240 | align: "center"
241 | });
242 | avoidText.anchor.setTo(0.5, 0.5);
243 | avoidText.setText("Avoid this");
244 | gameStartText = game.add.sprite(game.world.width / 2, game.world.height / 2, 'start');
245 | gameStartText.anchor.setTo(0.5, 0.5);
246 | gameStartText.scale.setTo(1, 1);
247 | gameOverText = game.add.sprite(game.world.width / 2, game.world.height / 4, 'over');
248 | gameOverText.anchor.setTo(0.5, 0.5);
249 | gameOverText.scale.setTo(1, 1);
250 | gameOverText.renderable = false;
251 | comingsoon = game.add.text(game.world.width / 1.5, game.world.height / 4.5, '', {
252 | font: "12px \"sans\"",
253 | fill: "#d9d12b",
254 | stroke: "#111",
255 | strokeThickness: 3,
256 | align: "center"
257 | });
258 | comingsoon.anchor.setTo(0.5, 0.5);
259 | comingsoon.scale.setTo(1, 1);
260 | comingsoon.setText(' ^\nComing soon!');
261 | resetText = game.add.sprite(game.world.width / 2, game.world.height / 1.5, 'reset');
262 | resetText.anchor.setTo(0.5, 0.5);
263 | resetText.scale.setTo(1, 1);
264 | resetText.renderable = false;
265 | game.input.onDown.add(flap);
266 | reset();
267 | };
268 | update = function() {
269 | if (gameStart) {
270 | if (!gameOver) {
271 | game.physics.overlap(tube, birddie, function() {
272 | over();
273 | return fallSnd.play();
274 | });
275 | if (!gameOver && tube.body.bottom >= GROUND_Y) {
276 | over();
277 | }
278 | game.physics.overlap(tube, birds, hitBirds, null, this);
279 | if (!gameOver) {
280 | ground.tilePosition.x -= game.time.physicsElapsed * SPEED / 2;
281 | }
282 | if (!gameOver) {
283 | bg.tilePosition.x -= game.time.physicsElapsed * SPEED;
284 | }
285 | } else {
286 | if (tube.body.bottom >= GROUND_Y + 3) {
287 | tube.y = GROUND_Y - 13;
288 | tube.body.velocity.y = 0;
289 | tube.body.allowGravity = false;
290 | tube.body.gravity.y = 0;
291 | }
292 | }
293 | }
294 | };
295 | render = function() {};
296 | reset = function() {
297 | gameStart = false;
298 | gameOver = false;
299 | gameOverText.renderable = false;
300 | resetText.renderable = false;
301 | gameStartText.renderable = true;
302 | board.renderable = false;
303 | bestText.renderable = false;
304 | avoidText.renderable = true;
305 | comingsoon.renderable = true;
306 | document.getElementById('star').style.display = 'none';
307 | score = 0;
308 | scoreText.setText('Flappy Tube 2');
309 | scoreText.x = game.world.width / 2;
310 | scoreText.y = game.world.height / 6;
311 | birds.removeAll();
312 | tube.reset(game.world.width * 0.25, game.world.height / 2.3);
313 | };
314 | state = {
315 | preload: preload,
316 | create: create,
317 | update: update,
318 | render: render
319 | };
320 | return game = new Phaser.Game(WIDTH, HEIGHT, Phaser.CANVAS, 'screem', state, false);
321 | };
322 |
323 | main();
324 |
--------------------------------------------------------------------------------