Vue+Websocket实现多人在线王者飞机(一)
2018-03-01 01:21
591 查看
看了Vue官方教程(貌似和自己写的框架差别不大,听前前端同事一直吹Vue,于是学习了一下,和自己写的框架好像也没强哪里去嘛,就是要傲娇哈哈),等有空也整理自己的框架,开源好了),想找个项目练练手(没找到好的),就写个飞机大战吧。
飞机大战总共三个页面:登录、匹配、游戏页面,三个页面的功能:
1、 登录:玩家填写用户名,socket连接
2、匹配:等待其他玩家准备
3、游戏:战斗页面
上述流程仿照了王者荣耀,所以就叫王者飞机(当然和王者荣耀相差十万八千里)最终效果:
git地址:https://gitee.com/djxfire/PlaneWar.git
根据上面的设计,Vue套餐基本就都用上了。
首先,先编写游戏页面(让飞机动起来):
我们定义一下玩家类player.js:
玩家类的具体信息参照注释。
接下来编写Game.vue组件
现在点击方向盘飞机就动起来了,然而需要不停的点击按键,显然不合理,所以我们使用requestAnimationFrame()方法实现动画,在Game组件中添加代码:
添加player的onframe代码:
当方向盘touchstart时own.state置为1,当touchend时置为0,修改方法:
至此,当按下方向键时,飞机开始运动,当放开方向键时,飞机停止运动。
下一篇将实现NodeJs实现WebSocket游戏服务端的逻辑
飞机大战总共三个页面:登录、匹配、游戏页面,三个页面的功能:
1、 登录:玩家填写用户名,socket连接
2、匹配:等待其他玩家准备
3、游戏:战斗页面
上述流程仿照了王者荣耀,所以就叫王者飞机(当然和王者荣耀相差十万八千里)最终效果:
git地址:https://gitee.com/djxfire/PlaneWar.git
根据上面的设计,Vue套餐基本就都用上了。
首先,先编写游戏页面(让飞机动起来):
我们定义一下玩家类player.js:
export default class Player { constructor (name, x, y, enermy = false) { this.name = name // 玩家名称 this.position = {} // 位置 this.position.x = x this.position.y = y this.speed = 1 this.direct = 0 // 方向0:朝上,1朝左,2朝下,3朝右 this.attack = 1 // 攻击力 this.flood = 5 // 血量 this.sock = null // socket连接 this.state = 0 // 0:停止,1:移动 this.bullets = [] // 发射的子弹 this.enermys = [] // 敌人 if (!enermy) { this.init() } } init () { // TODO: WebSocket连接 } move (direct) { this.direct = direct switch (direct) { case 0: if (this.position.y > 0) { this.position.y -= this.speed } break case 1: if (this.position.x > 0) { this.position.x -= this.speed } break case 2: if (this.position.y < window.innerHeight - 55) { this.position.y += this.speed } break case 3: if (this.position.x < window.innerWidth - 55) { this.position.x += this.speed } break } } }
玩家类的具体信息参照注释。
接下来编写Game.vue组件
<template> <div class = "scene"> <div v-for="(monster,index) of monsters" :key="index" class="monster" :style="{left:monster.position.x + 'px',top:monster.position.y + 'px'}"> <img src="../assets/monster.png" :class="{'turn-left':monster.direct == 1,'turn-right':monster.direct == 3,'turn-up':monster.direct == 0,'turn-down':monster.direct == 2}"/> <p>{{ monster.name }}</p> </div> <span v-for="(monster,index) of monsters" :key="index"> <div class="bullet" v-for="(bullet,index2) of monster.bullets" :key = "index2" :style="{left:bullet.position.x + 'px',top:bullet.position.y + 'px'}"> </div> </span> <div class = "monster" :style="{left:own.position.x + 'px',top:own.position.y + 'px'}"> <img src="../assets/monster.png" :class="{'turn-left':own.direct == 1,'turn-right':own.direct == 3,'turn-up':own.direct == 0,'turn-down':own.direct == 2}"/> <p>{{ own.name }}</p> </div> <div class="bullet" v-for="(bullet,index) of own.bullets" :key = "index" :style="{left:bullet.position.x + 'px',top:bullet.position.y + 'px'}"> </div> <div class = "play-control"> <div> <div @touchstart="turn(0)" @touchend="turnEnd()" class="up"></div> </div> <div style="text-align: initial;"> <div @touchstart="turn(1)" @touchend="turnEnd()" class="left"></div> <div @touchstart="turn(3)" @touchend="turnEnd()" class="right"></div> <div class="clear"></div> </div> <div> <div @touchstart="turn(2)" @touchend="turnEnd()" class = "down"></div> </div> </div> <div class = "shoot-control" @touchstart="shoot()"> </div> </div> </template> <script> import Player from '../player' export default { name: 'game', data () { return { own: new Player('test', Math.round(Math.random() * window.innerWidth), Math.round(Math.random() * window.innerHeight)), monsters: [] } }, methods: { turn (direct) { this.own.move(direct) }, turnEnd () { }, shoot () { } } } </script> <style scoped> .scene{ position: relative; overflow: hidden; width:100%; height:calc(100vh); } .bomb{ animation:bombframe 3s; -webkit-animation: bombframe 3s; } .turn-right{ -webkit-transform: rotate(270deg); -moz-transform: rotate(270deg); -ms-transform: rotate(270deg); -o-transform:rotate(270deg) ; transform: rotate(270deg); } .turn-left{ -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } .turn-up{ -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); -o-transform: rotate(180deg); transform: rotate(180deg); } .turn-down{ -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); -ms-transform: rotate(0deg); -o-transform: rotate(0deg); transform: rotate(0deg); } .monster{ position: absolute; display: inline-block; text-align: center; } .bullet{ position: absolute; display: inline-block; width: 4px; height:4px; background: #000; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .play-control{ position: fixed; text-align:center; bottom:0; left:0; background: #E9E9E9; width:100px; height:100px; opacity: 0.5; z-index: 999; -webkit-border-radius: 100px; -moz-border-radius: 100px; border-radius: 200px; } .clear{ clear: both; } .play-control .left{ display: inline-block; width:0; height:0; float: left; border-top: 25px solid transparent; border-right: 25px solid #A8A8A8; border-bottom: 25px solid transparent; vertical-align: middle; } .play-control .right{ display: inline-block; width:0; height:0; float: right; vertical-align: middle; border-top: 25px solid transparent; border-left: 25px solid #A8A8A8; border-bottom: 25px solid transparent; } .play-control .up{ display: inline-block; vertical-align: top; width:0; height:0; border-right: 25px solid transparent; border-bottom: 25px solid #A8A8A8; border-left: 25px solid transparent; } .play-control .down{ display: inline-block; vertical-align: bottom; width:0; height:0; border-right: 25px solid transparent; border-top: 25px solid #A8A8A8; border-left: 25px solid transparent; } .play-control .left:active{ border-right: 25px solid #A88888; } .play-control .right:active{ border-left: 25px solid #A88888; } .play-control .up:active{ border-bottom: 25px solid #A88888; } .play-control .down:active{ border-top: 25px solid #A88888; } .shoot-control{ position: fixed; text-align:center; bottom:0; right:0; background: #E9E9E9; width:100px; height:100px; opacity: 0.5; z-index: 999; -webkit-border-radius: 100px; -moz-border-radius: 100px; border-radius: 200px; background-size: 100%; background: url(../assets/BButton.png) no-repeat; } </style>
现在点击方向盘飞机就动起来了,然而需要不停的点击按键,显然不合理,所以我们使用requestAnimationFrame()方法实现动画,在Game组件中添加代码:
mounted () { let that = this function _callback () { for (let monster of that.own.enermys) { monster.onframe() for (let bullet of monster.bullets) { bullet.onframe() } } that.own.onframe() for (let bullet of that.own.bullets) { bullet.onframe() } requestAnimationFrame(_callback) } _callback() }
添加player的onframe代码:
onframe () { if (this.state === 1) { this.move(this.direct) this.send({ opt: 'upposition', name: this.name, x: this.position.x, y: this.position.y, direct: this.direct }) } }
当方向盘touchstart时own.state置为1,当touchend时置为0,修改方法:
turn (direct) { this.$store.dispatch('move', direct) }, turnEnd () { this.$store.dispatch('turnEnd') },
至此,当按下方向键时,飞机开始运动,当放开方向键时,飞机停止运动。
下一篇将实现NodeJs实现WebSocket游戏服务端的逻辑
相关文章推荐
- tomcat websocket 实现网页在线即时聊天
- 基于webSocket实现的一对一在线聊天系统
- tomcat websocket 实现网页在线即时聊天
- springMVC使用websocket实现在线客服
- 基于Struts2和hibernate的WebSocket聊天室的实现教程二:发送在线列表
- 在线聊天室的实现(1)--websocket协议和javascript版的api
- WebSocket+HTML5实现在线聊天室
- 【微信支付】分享一个失败的案例 跨域405(Method Not Allowed)问题 关于IM的一些思考与实践 基于WebSocketSharp 的IM 简单实现 【css3】旋转倒计时 【Html5】-- 塔台管制 H5情景意识 --飞机 谈谈转行
- Spring -websocket实现简易在线聊天
- websocket实现在线客服
- springboot整合tomcat自带的websocket实现在线聊天及象棋网页对战功能
- Java中使用websocket实现在线聊天功能
- 入门WebSocket和socket.io,实现在线实时聊天室
- 使用websocket实现在线聊天功能
- JSP实现在线考试与成绩评测
- 实现QQ在线交流
- 利用图标字体实现在线地图上的地点标注与颜色渲染
- 在线解析xml文件. 实现城市三级联动
- PHP在线生成二维码(google api)的实现代码详解
- fck实现htm在线编辑