├── README.md ├── app.js ├── app.json ├── app.wxss ├── images ├── bg.jpg ├── bomb.png ├── cartridge.png ├── cartridge_power.png ├── die1.png ├── die2.png ├── loading1.png ├── loading2.png ├── loading3.png ├── logo.png ├── me.png ├── me_2.png ├── me_die1.png ├── me_die2.png ├── me_die3.png ├── me_die4.png ├── plain1.png ├── plain1_die1.png ├── plain1_die2.png ├── plain1_die3.png ├── plain2.png ├── plain2_die1.png ├── plain2_die2.png ├── plain2_die3.png ├── plain2_die4.png ├── plain2_hurt.png ├── plain3.png ├── plain3_2.png ├── plain3_die1.png ├── plain3_die2.png ├── plain3_die3.png ├── plain3_die4.png ├── plain3_die5.png ├── plain3_die6.png ├── plain3_hurt.png ├── prop1.png └── prop2.png ├── lib ├── images.js └── wxplain.js ├── pages ├── index │ ├── index.js │ ├── index.wxml │ └── index.wxss ├── logs │ ├── logs.js │ ├── logs.json │ ├── logs.wxml │ └── logs.wxss └── plain │ ├── plain.js │ ├── plain.json │ ├── plain.wxml │ └── plain.wxss └── utils ├── emitter.js └── util.js /README.md: -------------------------------------------------------------------------------- 1 | # we_plain 2 | 微信小程序-打飞机游戏 3 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | //调用API从本地缓存中获取数据 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | }, 9 | getUserInfo:function(cb){ 10 | var that = this 11 | if(this.globalData.userInfo){ 12 | typeof cb == "function" && cb(this.globalData.userInfo) 13 | }else{ 14 | //调用登录接口 15 | wx.login({ 16 | success: function () { 17 | wx.getUserInfo({ 18 | success: function (res) { 19 | that.globalData.userInfo = res.userInfo 20 | typeof cb == "function" && cb(that.globalData.userInfo) 21 | } 22 | }) 23 | } 24 | }) 25 | } 26 | }, 27 | globalData:{ 28 | userInfo:null 29 | } 30 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/plain/plain", 4 | "pages/index/index", 5 | "pages/logs/logs" 6 | ], 7 | "window":{ 8 | "backgroundTextStyle":"light", 9 | "navigationBarBackgroundColor": "#fff", 10 | "navigationBarTitleText": "WeChat", 11 | "navigationBarTextStyle":"black" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | .canvas { 12 | width: 375px; 13 | height: 625px; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/bg.jpg -------------------------------------------------------------------------------- /images/bomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/bomb.png -------------------------------------------------------------------------------- /images/cartridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/cartridge.png -------------------------------------------------------------------------------- /images/cartridge_power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/cartridge_power.png -------------------------------------------------------------------------------- /images/die1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/die1.png -------------------------------------------------------------------------------- /images/die2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/die2.png -------------------------------------------------------------------------------- /images/loading1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/loading1.png -------------------------------------------------------------------------------- /images/loading2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/loading2.png -------------------------------------------------------------------------------- /images/loading3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/loading3.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/logo.png -------------------------------------------------------------------------------- /images/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me.png -------------------------------------------------------------------------------- /images/me_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me_2.png -------------------------------------------------------------------------------- /images/me_die1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me_die1.png -------------------------------------------------------------------------------- /images/me_die2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me_die2.png -------------------------------------------------------------------------------- /images/me_die3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me_die3.png -------------------------------------------------------------------------------- /images/me_die4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/me_die4.png -------------------------------------------------------------------------------- /images/plain1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain1.png -------------------------------------------------------------------------------- /images/plain1_die1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain1_die1.png -------------------------------------------------------------------------------- /images/plain1_die2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain1_die2.png -------------------------------------------------------------------------------- /images/plain1_die3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain1_die3.png -------------------------------------------------------------------------------- /images/plain2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2.png -------------------------------------------------------------------------------- /images/plain2_die1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2_die1.png -------------------------------------------------------------------------------- /images/plain2_die2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2_die2.png -------------------------------------------------------------------------------- /images/plain2_die3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2_die3.png -------------------------------------------------------------------------------- /images/plain2_die4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2_die4.png -------------------------------------------------------------------------------- /images/plain2_hurt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain2_hurt.png -------------------------------------------------------------------------------- /images/plain3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3.png -------------------------------------------------------------------------------- /images/plain3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_2.png -------------------------------------------------------------------------------- /images/plain3_die1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die1.png -------------------------------------------------------------------------------- /images/plain3_die2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die2.png -------------------------------------------------------------------------------- /images/plain3_die3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die3.png -------------------------------------------------------------------------------- /images/plain3_die4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die4.png -------------------------------------------------------------------------------- /images/plain3_die5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die5.png -------------------------------------------------------------------------------- /images/plain3_die6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_die6.png -------------------------------------------------------------------------------- /images/plain3_hurt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/plain3_hurt.png -------------------------------------------------------------------------------- /images/prop1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/prop1.png -------------------------------------------------------------------------------- /images/prop2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qutz/we_plain/e8ab47cbdb35130316ddf98308c63b2e6d044198/images/prop2.png -------------------------------------------------------------------------------- /lib/images.js: -------------------------------------------------------------------------------- 1 | 2 | const imageSrc = "../../images/"; //图片url前缀 3 | 4 | var gameImg = { 5 | "bg": { 6 | "src": imageSrc + "bg.jpg", 7 | "width": 375, 8 | "height": 666 9 | }, 10 | "loading1": { 11 | "src": imageSrc + "loading1.png", 12 | "width": 192, 13 | "height": 41 14 | }, 15 | "loading2": { 16 | "src": imageSrc + "loading2.png", 17 | "width": 192, 18 | "height": 40 19 | }, 20 | "loading3": { 21 | "src": imageSrc + "loading3.png", 22 | "width": 200, 23 | "height": 42 24 | }, 25 | "logo": { 26 | "src": imageSrc + "logo.png", 27 | "width": 375, 28 | "height": 87 29 | }, 30 | "bomb": { 31 | "src": imageSrc + "bomb.png", 32 | "width": 60, 33 | "height": 53 34 | }, 35 | "cartridge": { 36 | "src": imageSrc + "cartridge.png", 37 | "width": 9, 38 | "height": 21 39 | }, 40 | "cartridge_power": { 41 | "src": imageSrc + "cartridge_power.png", 42 | "width": 9, 43 | "height": 21 44 | }, 45 | "die1": { 46 | "src": imageSrc + "die1.png", 47 | "width": 41, 48 | "height": 39 49 | }, 50 | "die2": { 51 | "src": imageSrc + "die2.png", 52 | "width": 40, 53 | "height": 43 54 | }, 55 | "me": { 56 | "src": imageSrc + "me.png", 57 | "width": 98, 58 | "height": 122 59 | }, 60 | "me_2": { 61 | "src": imageSrc + "me_2.png", 62 | "width": 98, 63 | "height": 122 64 | }, 65 | "me_die1": { 66 | "src": imageSrc + "me_die1.png", 67 | "width": 98, 68 | "height": 122 69 | }, 70 | "me_die2": { 71 | "src": imageSrc + "me_die2.png", 72 | "width": 98, 73 | "height": 122 74 | }, 75 | "me_die3": { 76 | "src": imageSrc + "me_die3.png", 77 | "width": 98, 78 | "height": 122 79 | }, 80 | "me_die4": { 81 | "src": imageSrc + "me_die4.png", 82 | "width": 98, 83 | "height": 122 84 | }, 85 | "plain1": { 86 | "src": imageSrc + "plain1.png", 87 | "width": 59, 88 | "height": 36 89 | }, 90 | "plain1_die1": { 91 | "src": imageSrc + "plain1_die1.png", 92 | "width": 59, 93 | "height": 36 94 | }, 95 | "plain1_die2": { 96 | "src": imageSrc + "plain1_die2.png", 97 | "width": 59, 98 | "height": 36 99 | }, 100 | "plain1_die3": { 101 | "src": imageSrc + "plain1_die3.png", 102 | "width": 59, 103 | "height": 36 104 | }, 105 | "plain2": { 106 | "src": imageSrc + "plain2.png", 107 | "width": 70, 108 | "height": 92 109 | }, 110 | "plain2_die1": { 111 | "src": imageSrc + "plain2_die1.png", 112 | "width": 70, 113 | "height": 92 114 | }, 115 | "plain2_die2": { 116 | "src": imageSrc + "plain2_die2.png", 117 | "width": 70, 118 | "height": 92 119 | }, 120 | "plain2_die3": { 121 | "src": imageSrc + "plain2_die3.png", 122 | "width": 70, 123 | "height": 92 124 | }, 125 | "plain2_die4": { 126 | "src": imageSrc + "plain2_die4.png", 127 | "width": 70, 128 | "height": 92 129 | }, 130 | "plain2_hurt": { 131 | "src": imageSrc + "plain2_hurt.png", 132 | "width": 70, 133 | "height": 92 134 | }, 135 | "plain3": { 136 | "src": imageSrc + "plain3.png", 137 | "width": 165, 138 | "height": 256 139 | }, 140 | "plain3_2": { 141 | "src": imageSrc + "plain3_2.png", 142 | "width": 165, 143 | "height": 256 144 | }, 145 | "plain3_die1": { 146 | "src": imageSrc + "plain3_die1.png", 147 | "width": 165, 148 | "height": 256 149 | }, 150 | "plain3_die2": { 151 | "src": imageSrc + "plain3_die2.png", 152 | "width": 165, 153 | "height": 256 154 | }, 155 | "plain3_die3": { 156 | "src": imageSrc + "plain3_die3.png", 157 | "width": 165, 158 | "height": 256 159 | }, 160 | "plain3_die4": { 161 | "src": imageSrc + "plain3_die4.png", 162 | "width": 165, 163 | "height": 256 164 | }, 165 | "plain3_die5": { 166 | "src": imageSrc + "plain3_die5.png", 167 | "width": 165, 168 | "height": 256 169 | }, 170 | "plain3_die6": { 171 | "src": imageSrc + "plain3_die6.png", 172 | "width": 165, 173 | "height": 256 174 | }, 175 | "plain3_hurt": { 176 | "src": imageSrc + "plain3_hurt.png", 177 | "width": 165, 178 | "height": 256 179 | }, 180 | "prop1": { 181 | "src": imageSrc + "prop1.png", 182 | "width": 59, 183 | "height": 103 184 | }, 185 | "prop2": { 186 | "src": imageSrc + "prop2.png", 187 | "width": 59, 188 | "height": 103 189 | } 190 | } 191 | 192 | module.exports = gameImg -------------------------------------------------------------------------------- /lib/wxplain.js: -------------------------------------------------------------------------------- 1 | const flyimages = require( './images.js' ); 2 | const emitter = require( '../utils/emitter.js' ); 3 | 4 | //游戏配置 5 | var config = { 6 | "gameSpeed": 8, //游戏速度 7 | "cartridgeSpeed": 10 //子弹速度 8 | }; 9 | 10 | function flyGame( opts ) { 11 | var c_width = this.c_width = opts.width; 12 | var c_height = this.c_height = opts.height; //画布的高和宽 13 | var cxt = this.cxt = opts.ctx; 14 | var id = this.id = opts.id; 15 | this.cxt.setFontSize( 30 ); 16 | this.cxt.setFillStyle( "#333" ); 17 | 18 | //等待时间 19 | var loadingTime = 0; 20 | 21 | //等待动画刷新事件 22 | var refresh = function() { 23 | drawBg(); 24 | drawLogo(); 25 | load(); 26 | loadingTime++; 27 | wx.drawCanvas( { 28 | canvasId: id, 29 | actions: cxt.getActions() 30 | }) 31 | } 32 | 33 | //设置背景 34 | function drawBg() { 35 | var bg_img = flyimages[ "bg" ]; 36 | var bg_img_width = bg_img.width; 37 | var bg_img_height = bg_img.height; 38 | cxt.drawImage( bg_img.src, 0, 0, bg_img_width, bg_img_height ); 39 | } 40 | 41 | //构造logo 42 | function drawLogo() { 43 | var logo_img = flyimages[ "logo" ]; 44 | var logo_width = logo_img.width; 45 | var logo_height = logo_img.height; 46 | 47 | var y = 100; 48 | cxt.drawImage( logo_img.src, 0, y, logo_width, logo_height ); 49 | } 50 | 51 | //等待动画 52 | function load() { 53 | if( loadingTime == 600 ) { 54 | loadingTime = 0; 55 | clearInterval( loadingClock ); 56 | game.start(); 57 | } 58 | 59 | //loadingTime每隔200换一张图, 实现等待动画 60 | var pic = flyimages[ "loading" + ( parseInt( loadingTime / 200 ) + 1 ) + "" ]; 61 | var pic_width = pic.width; 62 | var pic_height = pic.height; 63 | 64 | var x = ( c_width - pic_width ) / 3; 65 | cxt.drawImage( pic.src, x, 220, pic_width, pic_height ); 66 | } 67 | 68 | //开始动画 69 | var loadingClock = setInterval( refresh, 1 ); 70 | 71 | var player = this.player = {}; 72 | player.x; 73 | player.y; 74 | player.lastX; 75 | player.lastY; 76 | player.bomb = 0; 77 | player.status = true; 78 | player.model = flyimages[ "me" ]; 79 | player.model2 = flyimages[ "me_2" ]; 80 | player.width = c_width / 375 * player.model.width; 81 | player.height = player.width / player.model.width * player.model.height; 82 | player.move = function( x, y ) { 83 | player.lastX = player.x; 84 | player.lastY = player.y; 85 | player.x = x - player.width / 2; 86 | player.y = y - player.height / 2; 87 | player.x = player.x > c_width - player.width ? c_width - player.width : player.x; 88 | player.x = player.x < 0 ? 0 : player.x; 89 | player.y = player.y > c_height - player.height ? c_height - player.height : player.y; 90 | player.y = player.y < 0 ? 0 : player.y; 91 | } 92 | player.moveing = function() { 93 | if( !player.status ) { 94 | return; 95 | } 96 | 97 | cxt.drawImage( game.time % 30 > 15 ? player.model.src : player.model2.src, player.x, player.y, player.width, player.height ); 98 | player.attacking(); 99 | } 100 | player.cartridges = []; 101 | player.attackTime = 0; 102 | player.attackPower = false; 103 | player.attack = function() { 104 | if( !player.status ) { 105 | return; 106 | } 107 | 108 | player.attackTime++; 109 | if( ( player.attackTime * game.refreshInterval ) % ( game.refreshInterval * 20 ) != 0 ) { 110 | return; 111 | } 112 | 113 | player.attackTime = 0; 114 | //playAudio( "fire_bullet.mp3" ); 115 | var cartridges; 116 | if( player.attackPower ) { 117 | cartridges = [ ( new cartridge( player.x - ( player.width / 5 ), player.y, 2, player ) ), ( new cartridge( player.x + ( player.width / 5 ), player.y, 2, player ) ) ]; 118 | } else { 119 | cartridges = [ ( new cartridge( player.x, player.y, 1, player ) ) ]; 120 | } 121 | Array.prototype.push.apply( player.cartridges, cartridges ); 122 | } 123 | player.attacking = function() { 124 | player.attack(); 125 | var cartridgeSpeed = config.cartridgeSpeed; 126 | var cartridges_length = player.cartridges.length; 127 | firstloop: for( var i = cartridges_length;i--; ) { 128 | var cartridge = player.cartridges[ i ]; 129 | cxt.drawImage( cartridge.model.src, cartridge.x, cartridge.y, cartridge.width, cartridge.height ); 130 | if( cartridge.y <= 0 ) { 131 | player.cartridges.splice( i, 1 ); 132 | continue firstloop; 133 | } 134 | 135 | var plain_length = game.plains.length; 136 | secondloop: for( var j = plain_length;j--; ) { 137 | var plain = game.plains[ j ]; 138 | var X = cartridge.x; 139 | var Y = cartridge.y; 140 | var nextY = Y - cartridgeSpeed; 141 | if( 142 | X > plain.x 143 | && X < ( plain.x + plain.width ) 144 | && nextY < ( plain.y + plain.height + plain.speed ) 145 | && Y >= ( plain.y + plain.height ) 146 | ) { 147 | plain.byAttack(); 148 | player.cartridges.splice( i, 1 ); 149 | continue firstloop; 150 | } 151 | } 152 | 153 | cartridge.y = cartridge.y - cartridgeSpeed; //子弹向上移动 154 | } 155 | } 156 | player.useBomb = function() { 157 | if( game.player.bomb <= 0 ) { 158 | return; 159 | } 160 | game.player.bomb--; 161 | //playAudio( "use_bomb.mp3" ); 162 | var plains_length = game.plains.length; 163 | for( var i = plains_length;i--; ) { 164 | var plain = game.plains[ i ]; 165 | plain.die(); 166 | } 167 | } 168 | player.die = function() { 169 | if( !player.status ) { 170 | return; 171 | } 172 | 173 | player.status = false; 174 | //playAudio( "game_over.mp3" ); 175 | var dieSpeed = 20; 176 | var x = player.x; 177 | var y = player.y; 178 | var h = player.height; 179 | var w = player.width; 180 | 181 | game.plainsDies.push(( new playerDie() ) ); 182 | 183 | function playerDie() { 184 | var dieTime = 4 * dieSpeed; 185 | this.animationTime = 4 * dieSpeed; 186 | 187 | this.call = function() { 188 | if( this.animationTime == 1 ) { 189 | game.over(); 190 | } 191 | var dieModel = flyimages[ "me_die" + ( parseInt(( dieTime - this.animationTime ) / dieSpeed ) + 1 ) + "" ]; 192 | cxt.drawImage( dieModel.src, x, y, w, h ); 193 | this.animationTime--; 194 | } 195 | } 196 | } 197 | 198 | var game = this.game = {}; 199 | game.fire = this.__proto__.fire; 200 | game.score = 0; 201 | game.time = 0; 202 | game.player = player; 203 | game.bgImg = flyimages[ "bg" ]; 204 | game.refreshInterval = config.gameSpeed; 205 | game.refresh = function() { 206 | game.time++; 207 | game.bgScroll(); 208 | game.plainsScroll(); 209 | game.plainsDying(); 210 | game.player.moveing(); 211 | game.propShow(); 212 | game.refreshMessage(); 213 | wx.drawCanvas( { 214 | canvasId: id, 215 | actions: cxt.getActions() 216 | }) 217 | } 218 | game.bgScrollTime = 0; 219 | game.bgScroll = function() { 220 | var bg_img_height = game.bgImg.height; 221 | var bg_img_width = game.bgImg.width; 222 | game.bgScrollTime += 0.5; 223 | if( game.bgScrollTime > bg_img_height ) { 224 | game.bgScrollTime = 0; 225 | } 226 | cxt.drawImage( game.bgImg.src, 0, game.bgScrollTime - bg_img_height, bg_img_width, bg_img_height ); 227 | cxt.drawImage( game.bgImg.src, 0, game.bgScrollTime, bg_img_width, bg_img_height ); 228 | } 229 | game.props = []; 230 | game.addProp = function() { 231 | var interval = 10; 232 | if( ( game.time * game.refreshInterval ) % ( interval * 1000 ) == 0 ) { 233 | game.props.push(( new prop( parseInt( Math.random() * 1.8 + 1.1 ) ) ) ); 234 | //playAudio( "show_prop.mp3" ); 235 | } 236 | } 237 | game.propShow = function() { 238 | game.addProp(); 239 | var props_length = game.props.length; 240 | for( var i = props_length;i--; ) { 241 | var prop = game.props[ i ]; 242 | if( prop.isDeleted == true ) { 243 | game.props.splice( i, 1 ); 244 | continue; 245 | } 246 | 247 | prop[ prop.status ](); 248 | 249 | if( prop.y > c_height ) { 250 | game.props.splice( i, 1 ); 251 | continue; 252 | } 253 | } 254 | } 255 | game.plains = []; 256 | game.plainsNum = 0; 257 | game.addPlain = function() { 258 | if( game.time % 60 != 0 ) { 259 | return; 260 | } 261 | 262 | if( game.plainsNum == 26 ) { 263 | game.plainsNum = 0; 264 | } 265 | 266 | game.plainsNum++; 267 | switch( true ) { 268 | case game.plainsNum % 13 == 0: 269 | game.plains.push( new plain( 3 ) ); 270 | break; 271 | case game.plainsNum % 6 == 0: 272 | game.plains.push( new plain( 2 ) ); 273 | break; 274 | default: 275 | game.plains.push( new plain( 1 ) ); 276 | break; 277 | } 278 | 279 | } 280 | game.plainsScroll = function() { 281 | game.addPlain(); 282 | var removePlain = []; 283 | var plains_length = game.plains.length; 284 | for( var i = plains_length;i--; ) { 285 | var plain = game.plains[ i ]; 286 | if( plain.y > c_height || plain.status == false ) { 287 | game.plains.splice( i, 1 ); 288 | continue; 289 | } 290 | 291 | plain.show(); 292 | 293 | if( isCollide( plain ) ) { 294 | game.player.die(); 295 | } 296 | 297 | plain.y = plain.y + plain.speed; 298 | } 299 | 300 | //判断是否和玩家的飞机碰撞 301 | function isCollide( plain ) { 302 | var plainTopLeft = [ plain.x, plain.y ]; 303 | var plainBottomRight = [ plain.x + plain.width, plain.y + plain.height ]; 304 | var meTopLeft = [ game.player.x + game.player.width / 3, game.player.y ]; 305 | var meBottomRight = [ game.player.x + ( game.player.width * 2 / 3 ), game.player.y + ( game.player.height * 2 / 3 ) ]; 306 | 307 | var collideTopLeft = [ Math.max( plainTopLeft[ 0 ], meTopLeft[ 0 ] ), Math.max( plainTopLeft[ 1 ], meTopLeft[ 1 ] ) ]; 308 | var collideBottomRight = [ Math.min( plainBottomRight[ 0 ], meBottomRight[ 0 ] ), Math.min( plainBottomRight[ 1 ], meBottomRight[ 1 ] ) ]; 309 | 310 | if( collideTopLeft[ 0 ] < collideBottomRight[ 0 ] && collideTopLeft[ 1 ] < collideBottomRight[ 1 ] ) { 311 | return true; 312 | } 313 | 314 | return false; 315 | } 316 | } 317 | game.plainsDies = []; 318 | game.plainsDying = function() { 319 | var plainsDies_length = game.plainsDies.length; 320 | for( var i = plainsDies_length;i--; ) { 321 | var plainDie = game.plainsDies[ i ]; 322 | if( plainDie.animationTime == 0 ) { 323 | game.plainsDies.splice( i, 1 ); 324 | continue; 325 | } 326 | plainDie.call(); 327 | } 328 | } 329 | game.over = function() { 330 | //game.music.pause(); 331 | clearInterval( game.clock ); 332 | game.fire( 'over', { score: game.score }); 333 | } 334 | game.clear = function() { 335 | game.player.x = ( c_width - game.player.width ) / 2; 336 | game.player.y = c_height - game.player.height; 337 | 338 | game.plains = []; 339 | game.plainsDies = []; 340 | game.plainsNum = 0; 341 | game.time = 0; 342 | game.bgScrollTime = 0; 343 | game.score = 0; 344 | game.player.status = true; 345 | game.player.bomb = 0; 346 | game.player.attackPower = false; 347 | clearTimeout( game.player.attackPowerClock ); 348 | } 349 | //game.music = creatAudio( "game_music.mp3" ); 350 | game.start = function() { 351 | // game.music.currentTime = 0; 352 | // game.music.loop = true; 353 | // game.music.play(); 354 | 355 | game.clear(); 356 | game.clock = setInterval( function() { 357 | game.refresh(); 358 | }, game.refreshInterval ); 359 | } 360 | game.refreshMessage = function() { 361 | cxt.fillText( game.score, 20, 44 ); 362 | 363 | if( game.player.bomb > 0 ) { 364 | var bombModel = flyimages[ "bomb" ]; 365 | cxt.drawImage( bombModel.src, 10, c_height - bombModel.height - 10, bombModel.width, bombModel.height ); 366 | cxt.fillText( game.player.bomb, 20 + bombModel.width, c_height - bombModel.height + 28 ); 367 | } 368 | } 369 | 370 | function prop( type ) { 371 | this.type = type; 372 | this.status = "show"; 373 | this.isDeleted = false; 374 | this.modelImg; 375 | this.getSound; 376 | switch( type ) { 377 | case 1: 378 | this.modelImg = "prop1"; 379 | this.getSound = "get_bomb.mp3"; 380 | break; 381 | case 2: 382 | this.modelImg = "prop2"; 383 | this.getSound = "get_double_laser.mp3"; 384 | break; 385 | } 386 | this.model = flyimages[ this.modelImg ]; 387 | this.width = c_width / 375 * this.model.width; 388 | this.height = this.model.height / this.model.width * this.width; 389 | this.x = Math.random() * ( c_width - this.width ); 390 | this.y = -this.height; 391 | 392 | var speed = this.speed = 6; 393 | var animateTime = this.animateTime = 70; 394 | this.showType = "down"; 395 | this.show = function() { 396 | if( this.animateTime <= animateTime / 2 ) { 397 | this.showType = "up"; 398 | } 399 | cxt.drawImage( this.model.src, this.x, this.y, this.width, this.height ); 400 | if( isGain( this ) ) { 401 | this.isDeleted = true; 402 | this.byGain(); 403 | return; 404 | } 405 | var move = ( ( c_height + this.height ) / 3 ) / ( animateTime / 2 ); 406 | this.speed = move; 407 | if( this.showType == "down" ) { 408 | this.y += move; 409 | } else { 410 | this.y -= move; 411 | } 412 | this.animateTime--; 413 | if( this.animateTime <= 0 ) { 414 | this.speed = speed; 415 | this.status = "move"; 416 | } 417 | } 418 | this.move = function() { 419 | this.y += this.speed; 420 | cxt.drawImage( this.model.src, this.x, this.y, this.width, this.height ); 421 | if( isGain( this ) ) { 422 | this.isDeleted = true; 423 | this.byGain(); 424 | return; 425 | } 426 | } 427 | 428 | this.byGain = function() { 429 | switch( this.type ) { 430 | case 1: 431 | game.player.bomb++; 432 | break; 433 | case 2: 434 | game.player.attackPower = true; 435 | game.player.attackPowerClock = setTimeout( function() { 436 | game.player.attackPower = false; 437 | }, 15000 ); 438 | break; 439 | } 440 | //playAudio( this.getSound ); 441 | } 442 | 443 | //判断有没有吃到道具 444 | var isGain = function( prop ) { 445 | var leftX = prop.x; 446 | var rightX = prop.x + prop.width; 447 | if( rightX < game.player.x || leftX > ( game.player.x + game.player.width ) ) { 448 | return false; 449 | } 450 | var removing = prop.status == "move" ? prop.speed : ( prop.showType == "down" ? prop.speed : -prop.speed ); 451 | var nextY = prop.y + removing; 452 | if( ( ( prop.y + prop.height ) > game.player.y || ( nextY + prop.height ) < game.player.y ) && game.player.lastY > ( prop.y + prop.height ) ) { 453 | return false; 454 | } 455 | return true; 456 | } 457 | } 458 | 459 | function plain( type ) { 460 | this.type = type; 461 | this.hp; //飞机生命值 462 | this.height; 463 | this.width; 464 | this.maxSpeed; 465 | this.dieTime; 466 | this.status = true; //飞机死了没 467 | var dieSpeed = 20; //死亡动画播放速度 468 | 469 | switch( type ) { 470 | case 1: 471 | this.hp = 1; 472 | this.score = 1000; 473 | this.maxSpeed = 5; 474 | this.dieTime = dieSpeed * 3; 475 | break; 476 | case 2: 477 | this.hp = 8; 478 | this.score = 8000; 479 | this.maxSpeed = 2; 480 | this.dieTime = dieSpeed * 4; 481 | break; 482 | case 3: 483 | this.hp = 18; 484 | this.score = 30000; 485 | this.maxSpeed = 1; 486 | this.dieTime = dieSpeed * 6; 487 | break; 488 | } 489 | 490 | this.dieSound = "plain" + this.type + "_die.mp3"; 491 | this.modelimg = "plain" + this.type + ""; 492 | this.model = flyimages[ this.modelimg ]; 493 | 494 | if( this.type == 3 ) { 495 | this.modelimg2 = "plain3_2"; 496 | this.model2 = flyimages[ this.modelimg2 ]; 497 | } 498 | 499 | this.width = c_width / 375 * this.model.width; 500 | this.height = this.width / this.model.width * this.model.height; 501 | 502 | this.x = Math.random() * ( c_width - this.width ); 503 | this.y = -( this.height ); 504 | 505 | var maxSpeed = game.time / 1000 > 10 ? 10 : game.time / 1000; 506 | this.speed = Math.random() * ( maxSpeed - 1 ) + 1; 507 | this.speed = this.speed < 0.5 ? Math.random() * 0.5 + 0.5 : this.speed; 508 | this.speed = this.speed > this.maxSpeed ? this.maxSpeed : this.speed; 509 | 510 | this.show = function() { 511 | if( this.type == 3 ) { 512 | cxt.drawImage( game.time % 30 > 15 ? this.model.src : this.model2.src, this.x, this.y, this.width, this.height ); 513 | return; 514 | } 515 | cxt.drawImage( this.model.src, this.x, this.y, this.width, this.height ); 516 | } 517 | 518 | this.die = function() { 519 | var plainType = this.type; 520 | var plainX = this.x; 521 | var plainY = this.y; 522 | var plainW = this.width; 523 | var plainH = this.height; 524 | 525 | game.plainsDies.push(( new die( this.dieTime ) ) ); 526 | 527 | game.score += this.score; 528 | this.status = false; 529 | 530 | function die( dieTime ) { 531 | var dieTime = dieTime; 532 | this.animationTime = dieTime; 533 | 534 | this.call = function() { 535 | if( this.animationTime <= 0 ) { 536 | return; 537 | } 538 | var dieModel = flyimages[ "plain" + plainType + "_die" + ( parseInt(( dieTime - this.animationTime ) / dieSpeed ) + 1 ) + "" ]; 539 | cxt.drawImage( dieModel.src, plainX, plainY, plainW, plainH ); 540 | this.animationTime--; 541 | } 542 | } 543 | } 544 | 545 | var hp = this.hp; 546 | this.byAttack = function() { 547 | this.hp--; 548 | if( this.hp <= 0 ) { 549 | this.die(); 550 | //playAudio( this.dieSound ); 551 | return; 552 | } 553 | 554 | if( this.hp <= hp / 3 ) { 555 | this.model = flyimages[ "plain" + this.type + "_hurt" ]; 556 | } 557 | } 558 | } 559 | 560 | function cartridge( x, y, type, player ) { 561 | this.model = flyimages[ type == 2 ? "cartridge_power" : "cartridge" ]; 562 | 563 | this.width = c_width / 375 * this.model.width; 564 | this.height = this.width / this.model.width * this.model.height; 565 | this.x = x + ( player.width - this.width ) / 2; 566 | this.y = y - this.height; 567 | } 568 | } 569 | 570 | flyGame.prototype.startGame = function() { 571 | this.game.start(); 572 | } 573 | 574 | flyGame.prototype.touchmove = function( x, y ) { 575 | this.game.player.move( x, y ); 576 | } 577 | 578 | flyGame.prototype.touchclick = function() { 579 | this.game.player.useBomb(); 580 | } 581 | 582 | emitter.setup( flyGame.prototype ); 583 | 584 | module.exports = flyGame; -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | var app = getApp() 4 | Page({ 5 | data: { 6 | motto: 'Hello World', 7 | userInfo: {} 8 | }, 9 | //事件处理函数 10 | bindViewTap: function() { 11 | wx.navigateTo({ 12 | url: '../logs/logs' 13 | }) 14 | }, 15 | onLoad: function () { 16 | console.log('onLoad') 17 | var that = this 18 | //调用应用实例的方法获取全局数据 19 | app.getUserInfo(function(userInfo){ 20 | //更新数据 21 | that.setData({ 22 | userInfo:userInfo 23 | }) 24 | }) 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{userInfo.nickName}} 6 | 7 | 8 | {{motto}} 9 | 10 | 11 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .usermotto { 20 | margin-top: 200px; 21 | } -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | var util = require('../../utils/util.js') 3 | Page({ 4 | data: { 5 | logs: [] 6 | }, 7 | onLoad: function () { 8 | this.setData({ 9 | logs: (wx.getStorageSync('logs') || []).map(function (log) { 10 | return util.formatTime(new Date(log)) 11 | }) 12 | }) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志" 3 | } -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /pages/plain/plain.js: -------------------------------------------------------------------------------- 1 | const WxFly = require('../../lib/wxplain.js'); 2 | 3 | Page({ 4 | data: { 5 | modalHidden: "modal_hide", 6 | score: '0' 7 | }, 8 | onLoad: function (options) { 9 | // 页面初始化 options为页面跳转所带来的参数 10 | }, 11 | onReady: function () { 12 | // 页面渲染完成 13 | }, 14 | startGame: function () { 15 | const fly = this.fly; 16 | this.setData({ score: 0, modalHidden: "modal_hide" }); 17 | fly.startGame(); 18 | }, 19 | move: function (event) { 20 | const fly = this.fly; 21 | var x = event.touches[0].x; 22 | var y = event.touches[0].y; 23 | fly.touchmove(x, y); 24 | }, 25 | click: function () { 26 | const fly = this.fly; 27 | fly.touchclick(); 28 | }, 29 | onShow: function () { 30 | const fly = this.fly = new WxFly( 31 | { 32 | ctx: wx.createContext(), 33 | id: 'plainId', 34 | height: 625, 35 | width: 375, 36 | }); 37 | fly.on('over', packet => { 38 | this.setData({ score: packet.score, modalHidden: "" }); 39 | }); 40 | }, 41 | onHide: function () { 42 | // 页面隐藏 43 | }, 44 | onUnload: function () { 45 | // 页面关闭 46 | } 47 | }) -------------------------------------------------------------------------------- /pages/plain/plain.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "打飞机" 3 | } -------------------------------------------------------------------------------- /pages/plain/plain.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 飞机大战分数 5 | {{score}} 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /pages/plain/plain.wxss: -------------------------------------------------------------------------------- 1 | .modal { 2 | width: 360px; 3 | height: 300px; 4 | top: 100px; 5 | left: 55%; 6 | margin-left: -200px; 7 | border: #666 solid 2px; 8 | border-radius: 8px; 9 | position: absolute; 10 | font-size: 20px; 11 | background-color: #dddddd; 12 | z-index: 1002; 13 | } 14 | 15 | .modal_hide { 16 | display: none; 17 | } 18 | 19 | .header { 20 | height: 45px; 21 | line-height: 45px; 22 | font-weight: bold; 23 | text-align: center; 24 | border-bottom: #666 solid 2px; 25 | } 26 | 27 | .content { 28 | height: 210px; 29 | line-height: 210px; 30 | font-weight: bold; 31 | text-align: center; 32 | } 33 | 34 | .footer { 35 | height: 45px; 36 | line-height: 45px; 37 | text-align: center; 38 | border-top: #666 solid 2px; 39 | } 40 | 41 | .footer button { 42 | width: 120px; 43 | height: 42px; 44 | border: #666 solid 2px; 45 | border-radius: 15px; 46 | font-size: 15px; 47 | font-weight: bold; 48 | position: absolute; 49 | left: 50%; 50 | margin-left: -60px; 51 | color: #333; 52 | cursor: pointer; 53 | } -------------------------------------------------------------------------------- /utils/emitter.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | setup(target) { 4 | let listeners = []; 5 | 6 | Object.assign(target, { 7 | on(type, handle) { 8 | if (typeof handle == 'function') { 9 | listeners.push([type, handle]); 10 | } 11 | }, 12 | fire(type, ...params) { 13 | listeners.forEach(([listenType, handle]) => type == listenType && handle(...params)); 14 | }, 15 | removeAllListeners() { 16 | listeners = []; 17 | } 18 | }) 19 | } 20 | } -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds() 9 | 10 | 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | module.exports = { 20 | formatTime: formatTime 21 | } 22 | --------------------------------------------------------------------------------