本紅包雨項目是基于HTML5的游戲框架Phaser寫的,最終形成的是一個canvas,所以性能很好,但是必須要說的是這個框架比較大,壓縮后也有700K左右,所以請慎用.
代碼地址: http://github.com/AmosXu/red-packet-rain
1. 效果展示圖片依次是倒計時頁面,搶紅包頁面,拆紅包頁,紅包展示頁,這些頁面都是寫在一個canvas里面的,無刷新的切換效果,性能超級棒
2.代碼展示貼上主要的代碼js代碼和注釋
//初始化圖片 let imgjishi = assets/img/daojishi.png let bgPlan = assets/img/bg-plan.jpg let bgRainer = assets/img/bg-rainer.jpg let redpacket = assets/img/redpacket.png let close = assets/img/close.png let dialogExit = assets/img/dialog-exit.png let buttonCancel = assets/img/button-cancel.png let buttonExit = assets/img/button-exit.png let openRedpacket = assets/img/open-redpacket.png let open = assets/img/open.png let redpacketResult = assets/img/redpacket-result.png let buttonUseTicket = assets/img/button-use-ticket.png let buttonContinue = assets/img/button-continue.png let cursorAnimation = assets/img/cursor-animation.png let states = {} let QingLvGroup; let hitNum = 0; let config = { selfPool:40, selfPic: redpacket , rate:0.5, maxSpeed:1200, minSpeed:400, max:95 let ids = [0, 1, 2, 3, 4, 5] let redpackets = [ 全場優(yōu)惠50元 , 20元代金券 , 全場優(yōu)惠50元 , 20元代金券 , 全場優(yōu)惠50元 , 20元代金券 ] let time = 25; let getIds = [] let radio = document.documentElement.clientWidth/375; let e; function rfuc(n){ return n*radio; //初始化紅包 function QingLv(config, game){ this.init = function(){ this.config = config; QingLvGroup = game.add.group(); QingLvGroup.enableBody = true; QingLvGroup.createMultiple(config.selfPool, config.selfPic); //初始化多個紅包 QingLvGroup.setAll( anchor.y ,1) QingLvGroup.setAll( outOfBoundsKill , true); QingLvGroup.setAll( checkWorldBounds , true); this.maxWidth = game.width + 300; game.time.events.loop(Phaser.Timer.SECOND * config.rate, this.createQL, this); this.createQL = function(){ e = QingLvGroup.getFirstExists(false); if(e) { if(hitNum = config.max) { return; hitNum++; e.events.onInputDown.removeAll(); var ram= Math.random(); ram =ram 0.5?ram+=0.5: ram; e.loadTexture(this.config.selfPic) e.alpha = 1; e.angle = 30 // e.scale.setTo(rfuc(ram)); e.reset(game.rnd.integerInRange(100, this.maxWidth), 100) //紅包生成的位置 e.body.velocity.x = game.rnd.integerInRange(-300, -150); //紅包移動的速度 e.body.velocity.y = game.rnd.integerInRange(config.minSpeed, config.maxSpeed); e.inputEnabled = true; e.events.onInputDown.add(this.hitted, this) this.hitted = function(sprite){ if(Math.random() 1/4 ids.length 0) { sprite.kill(); //點擊獲得紅包,游戲暫停 game.paused = true; //背景 let hexGraphics = new Phaser.Graphics().beginFill(0x000000, 0.5).drawRect(0,0,document.documentElement.clientWidth,document.documentElement.clientHeight + 2); let pausedMask = game.add.sprite(0, 0, hexGraphics.generateTexture()) let openDialog = game.add.sprite(rfuc(62), rfuc(150), openRedpacket ) let open = game.add.sprite(rfuc(130), rfuc(300), open ) open.inputEnabled = true; let result = game.add.sprite(rfuc(0), rfuc(120), redpacketResult ) result.visible = false let userTicket = game.add.sprite(rfuc(78), rfuc(445), buttonUseTicket ) userTicket.visible = false let goOn = game.add.sprite(rfuc(198), rfuc(445), buttonContinue ) goOn.visible = false let ticketText = {}; let link = //拆紅包 let clickOpen = function() { //游戲暫停時,點擊事件無效,只能通過這種畫熱點的形式來綁定事件 let openRect = new Phaser.Rectangle(rfuc(130), rfuc(315), 239, 239).copyFrom(open); if (openRect.contains(game.input.x, game.input.y)) { let currentWidth = open.width //拆紅包動畫 let tempArr = [2, 4, 8, 4, 2, 1] let index = 0; let timer = setInterval(function() { if (index tempArr.length-1) { index = 0 } open.width = currentWidth / tempArr[index] open.height = open.height open.left = game.world.centerX - open.width / 2 ++index }, 200) game.input.onDown.remove(clickOpen, this); let arrIndex = Math.floor(Math.random() * ids.length) let redpacketId = ids.splice(arrIndex, 1) getIds.push(redpacketId[0]) setTimeout(()= { timer clearInterval(timer) document.getElementById( audioOpen ).play() let text = redpackets[redpacketId[0]] ticketText=game.add.text(0, rfuc(338),text,{fill: #ffe67d ,fontSize: 46px ,fontWeight: bolder }) ticketText.left = game.world.centerX - ticketText.width / 2 //文字相對于屏幕左右居中 openDialog.visible = false open.visible = false result.visible = true userTicket.visible = true goOn.visible = true game.input.onDown.add(clickButton, this) }, 1000) let clickButton = function() { let userTicketRect = new Phaser.Rectangle(rfuc(78), rfuc(445), 194, 66).copyFrom(userTicket); let continueRect = new Phaser.Rectangle(rfuc(198), rfuc(445), 194, 66).copyFrom(goOn); if (userTicketRect.contains(game.input.x, game.input.y)) { window.location.replace(link) game.input.onDown.remove(clickButton, this); } else if (continueRect.contains(game.input.x, game.input.y)) { result.visible = false userTicket.visible = false goOn.visible = false pausedMask.visible = false ticketText.visible = false game.paused = false game.input.onDown.remove(clickButton, this); game.input.onDown.add(clickOpen, this) } else { sprite.inputEnabled = false; var anim = sprite.animations.add(config.selfPic); sprite.play(config.selfPic, 40, false); anim.onComplete.add(this.fade, this, sprite) this.fade = function(sprite){ var tween = game.add.tween(sprite).to({alpha:0}, 300, Linear , true) tween.onComplete.add(this.killed, this, sprite); this.killed = function(sprite){ sprite.kill(); states.boot = function(game) { this.preload = function() { if (typeof(GAME) !== undefined ) { this.load.baseURL = GAME + / if (!game.device.desktop) { this.scale.scaleMode = Phaser.ScaleManager.EXACT_FIT; this.scale.forcePortrait = true; this.scale.refresh(); this.create = function() { game.stage.backgroundColor = #FFF game.state.start( preload states.preload = function(game) { this.preload = function(game) { //加載圖片 game.load.spritesheet( daojishi , imgjishi, 250,120, 4) game.load.image( bgPlan , bgPlan) game.load.image( bgRainer , bgRainer) game.load.spritesheet( redpacket , redpacket, 144, 173, 2) game.load.image( close , close) game.load.image( dialogExit , dialogExit) game.load.image( buttonExit , buttonExit) game.load.image( buttonCancel , buttonCancel) game.load.image( openRedpacket , openRedpacket) game.load.image( open , open) game.load.image( redpacketResult , redpacketResult) game.load.image( buttonContinue , buttonContinue) game.load.image( buttonUseTicket , buttonUseTicket) game.load.spritesheet( cursorAnimation , cursorAnimation, 74, 108, 2) this.create = function() { game.state.start( main states.main = function(game) { this.create = function() { // 物理系統(tǒng) game.physics.startSystem(Phaser.Physics.ARCADE); // 背景圖 var bgPlan = game.add.sprite(0, 0, bgPlan bgPlan.width = game.width; bgPlan.height = game.height; var cursorPointer = game.add.sprite(game.world.centerX - 36, game.world.centerY + 86, cursorAnimation var anim = cursorPointer.animations.add( cursorAnimation cursorPointer.play( cursorAnimation , 2, true); document.getElementById( audioCountDown ).play() // 開始游戲倒計時 var daojishi = game.add.sprite(game.world.centerX - 140, game.world.centerY - 400, daojishi var anim = daojishi.animations.add( daojishi daojishi.play( daojishi , 1, false); anim.onComplete.add(this.startGame, this, daojishi); this.startGame = function(daojishi){ this.leftTime = time let bgRainer = game.add.sprite(0, 0, bgRainer bgRainer.width = game.width; bgRainer.height = game.height; daojishi.visible = false; this.createQingLv(); //添加按鈕,并綁定事件 let closeImg = game.add.button(rfuc(20), rfuc(20), close , function(){ game.paused = true pausedMask.visible = true exitDialog.visible = true exitButton.visible = true cancelButton.visible = true game.input.onDown.add(buttonClick, this) }.bind(this)) // 剩余時間 this.leftTimeText = game.add.text(0, 0, this.leftTime, {fill: #FFF , fontSize: 40px , fontWeight: bolder }) this.leftTimeText.scale.setTo(rfuc(1)) this.leftTimeText.fixedToCamera = true; this.leftTimeText.cameraOffset.setTo(game.camera.width - rfuc(80), rfuc(20)); let hexGraphics = new Phaser.Graphics().beginFill(0x000000, 0.5).drawRect(0,0,document.documentElement.clientWidth,document.documentElement.clientHeight + 2); let pausedMask = game.add.sprite(0, 0, hexGraphics.generateTexture()) pausedMask.visible = false; let exitDialog = game.add.sprite(rfuc(62), rfuc(150), dialogExit ) exitDialog.visible = false; let exitButton = game.add.button(rfuc(80), rfuc(315), buttonExit ) exitButton.visible = false; let isExit = false let cancelButton = game.add.button(rfuc(200), rfuc(315), buttonCancel ) cancelButton.visible = false; game.time.events.repeat(Phaser.Timer.SECOND, this.leftTime, this.refreshTime, this) let buttonClick = function() { let cancelRect = new Phaser.Rectangle(rfuc(200), rfuc(315), 194, 66).copyFrom(cancelButton); if (cancelRect.contains(game.input.x, game.input.y)) { game.input.onDown.remove(buttonClick, this) game.paused = false pausedMask.visible = false exitDialog.visible = false exitButton.visible = false cancelButton.visible = false this.createQingLv = function(){ this.qinglv = new QingLv(config, game); this.qinglv.init(); this.qinglv = new QingLv(config, game); this.qinglv.init(); this.refreshTime = function(){ this.leftTime--; var tem = this.leftTime; this.leftTimeText.text = tem; if(this.leftTime === 0) { game.paused = true; //生成游戲 let game = null if (game == null) { game = new Phaser.Game(document.documentElement.clientWidth, document.documentElement.clientHeight + 2, Phaser.AUTO, document.getElementById( gameScreen game.state.add( boot , states.boot.bind(game)); game.state.add( preload , states.preload.bind(game)); game.state.add( main , states.main.bind(game)); game.state.start( boot }3. 疑難問題1. 游戲暫停時,點擊事件無效,需要點擊,怎么解決
答: 通過全局事件畫熱點的形式綁定事件,一定要記得移除事件,一定一定要記得
game.input.onDown.add(clickOpen, this) //給游戲綁定全局事件let userTicket = game.add.sprite(rfuc(78), rfuc(445), buttonUseTicket ) let userTicketRect = new Phaser.Rectangle(78, 445, 194, 66).copyFrom(userTicket); //獲得button的區(qū)域//如果點擊的位置為button的位置就執(zhí)行下一步if (userTicketRect.contains(game.input.x, game.input.y)) { //移除全局事件 game.input.onDown.remove(clickButton, this);}2. 文字或圖片相對于屏幕居中(暫時只能做屏幕居中)
答: 添加文字到游戲中,文字向左的偏移量等于游戲屏幕的寬度減去文字寬度的一般,就能達到居中的效果
ticketText = game.add.text(0, rfuc(338), 我想居中 , {fill: #ffe67d , fontSize: 46px , fontWeight: bolder })ticketText.left = game.world.centerX - ticketText.width / 2 //文字相對于屏幕左右居中
代碼地址: http://github.com/AmosXu/red-packet-rain
總結(jié):以上就是本篇文的全部內(nèi)容,希望能對大家的學(xué)習(xí)有所幫助。更多相關(guān)教程請訪問 HTML視頻教程,Html5視頻教程,bootstrap視頻教程!
以上就是html5仿淘寶,京東實現(xiàn)紅包雨效果(代碼實例)的詳細內(nèi)容,其它編程語言
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答