• uni app 打肉肉(打飞机)小游戏


    都给老婆和孩子写了 合十  钓鱼了,给自己写个打飞机吧。没找飞机怪兽的图片。就用馒头和肉肉代替了。有问题不要私信我。自己改哈

    1. <template>
    2. <view class="page_main">
    3. <view class="contentone">
    4. <canvas class="canvas_cla" style="z-index: 1;" canvas-id="myCanvas" id="myCanvas"></canvas>
    5. </view>
    6. <view class="contentone">
    7. <canvas class="canvas_cla" style="z-index: 2;" canvas-id="myCanvasb" id="myCanvasb"></canvas>
    8. </view>
    9. <view class="contenttwo">
    10. <canvas class="canvas_cla" style="z-index: 9;" canvas-id="myCanvasa" id="myCanvasa" @touchstart="touchstart"
    11. @touchend="touchend" @touchmove="touchmove"></canvas>
    12. </view>
    13. <view class="zhezhao" v-if="isshowstart">
    14. <view class="dialog_back">
    15. <cover-view class="add_button_ef" style=" color: #07a5a6;" @tap.stop.prevent="start_zhezhao">
    16. 开始
    17. </cover-view>
    18. <cover-view class="add_button_ef" style="color: #07a5a6;" @tap.stop.prevent="back_zhezhao">
    19. 返回
    20. </cover-view>
    21. </view>
    22. </view>
    23. </view>
    24. </template>
    25. <script>
    26. export default {
    27. data() {
    28. return {
    29. isshowstart: true,
    30. canvaswidth: 0,
    31. canvasheight: 0,
    32. ctx: null, // canvas 上下文
    33. ctxtwo: null, // canvas 上下文
    34. ctxthree: null, // canvas 上下文
    35. background: {
    36. images: ['../static/fangzi1.png', '../static/fangzi1.png'], // 图片资源数组
    37. speed: 2, // 滚动速度
    38. position: 0, // 图片当前位置
    39. },
    40. zhujue: {
    41. x: 0,
    42. y: 0,
    43. image: '../static/addpeople.png',
    44. size: 50,
    45. speed: 2,
    46. ismoveing: false,
    47. value: 200,
    48. zdvalue: 20,
    49. fstime: 120,
    50. zdsize: 10,
    51. lives: 5,
    52. wdtime: 0,
    53. isdie: false,
    54. },
    55. zhujpz: false,
    56. zjzdlist: [],
    57. gslist: [],
    58. bosslist: [],
    59. guankadefen: 0,
    60. defen: 0,
    61. guanka: 1,
    62. isboos: false,
    63. ytimerX: null, // requestAnimationFrame 的 ID
    64. zjfszdtimer: '',
    65. jspztimer: '',
    66. };
    67. },
    68. onLoad() {
    69. },
    70. onReady() {
    71. this.init()
    72. },
    73. /**
    74. * 生命周期函数--监听页面卸载
    75. */
    76. onUnload: function() {
    77. this.game_stop()
    78. },
    79. methods: {
    80. start_zhezhao: function() {
    81. this.isshowstart = false
    82. this.game_start(); // 开始滚动
    83. },
    84. back_zhezhao: function() {
    85. uni.navigateBack({
    86. delta: 1
    87. })
    88. },
    89. init: function() {
    90. this.ctx = uni.createCanvasContext('myCanvas');
    91. this.ctxtwo = uni.createCanvasContext('myCanvasa');
    92. this.ctxthree = uni.createCanvasContext('myCanvasb');
    93. let canvas = uni.createSelectorQuery().select('#myCanvas');
    94. canvas.boundingClientRect(rect => {
    95. this.canvaswidth = rect.width
    96. this.canvasheight = rect.height
    97. this.zhujue.x = (rect.width - this.zhujue.size) / 2
    98. this.zhujue.y = rect.height - this.zhujue.size - 50
    99. this.drawzj()
    100. }).exec();
    101. this.drawbackg();
    102. },
    103. drawzj: function() {
    104. if (this.zhujue.x < 0) {
    105. this.zhujue.x = 0
    106. }
    107. if (this.zhujue.x > this.canvaswidth - this.zhujue.size) {
    108. this.zhujue.x = this.canvaswidth - this.zhujue.size
    109. }
    110. if (this.zhujue.y < 0) {
    111. this.zhujue.y = 0
    112. }
    113. if (this.zhujue.y > this.canvasheight - this.zhujue.size) {
    114. this.zhujue.y = this.canvasheight - this.zhujue.size
    115. }
    116. if (this.zhujpz) {
    117. this.ctxtwo.drawImage('../static/mantou.png', this.zhujue.x, this.zhujue.y - 30, this.zhujue.size -
    118. 20, this.zhujue.size - 20); // 绘制图片
    119. this.zjdrawbaopo()
    120. }
    121. this.ctxtwo.drawImage(this.zhujue.image, this.zhujue.x, this.zhujue.y, this.zhujue.size, this.zhujue
    122. .size); // 绘制图片
    123. this.ctxtwo.draw();
    124. },
    125. drawzjzd: function() {
    126. for (var i = 0; i < this.zjzdlist.length; i++) {
    127. if (this.zjzdlist[i].isuse) {
    128. this.zjzdlist.splice(i, 1)
    129. i--
    130. } else {
    131. this.ctxthree.drawImage(this.zjzdlist[i].image, this.zjzdlist[i].x, this.zjzdlist[i].y,
    132. this.zhujue.zdsize, this.zhujue.zdsize); // 绘制图片
    133. }
    134. }
    135. if (this.isboos) {
    136. this.drawboos()
    137. } else {
    138. this.drawgs()
    139. }
    140. this.ctxthree.draw();
    141. },
    142. zjfszd: function() {
    143. this.zjfszdtimer = setInterval(() => {
    144. var zd = {
    145. x: this.zhujue.x + this.zhujue.size / 2 - this.zhujue.zdsize / 2,
    146. y: this.zhujue.y,
    147. image: '../static/mantou.png',
    148. speed: 3,
    149. isuse: false
    150. }
    151. this.zjzdlist.push(zd)
    152. }, this.zhujue.fstime);
    153. },
    154. scgs: function() {
    155. let gs = {
    156. x: this.getRandomInt(50, this.canvaswidth - 50),
    157. y: -45,
    158. size: 20 + this.guanka * 3,
    159. image: "../static/rou.png",
    160. value: 100 * this.guanka * 0.8,
    161. speed: 0.5 * this.guanka * 0.8,
    162. isfszd: this.getRandomInt(0, 1),
    163. isdj: this.getRandomInt(0, 2), // 怪兽携带道具 0 不带 1 子弹威力+0.1 2 发射速度-0.5
    164. zdspeed: 5 * this.guanka * 0.5,
    165. isover: false
    166. }
    167. this.gslist.push(gs)
    168. },
    169. drawgs: function() {
    170. for (var i = 0; i < this.gslist.length; i++) {
    171. if (this.gslist[i].isover) {
    172. this.drawbaopo(this.gslist[i])
    173. this.gslist.splice(i, 1)
    174. i--
    175. } else {
    176. this.gslist[i].y += this.gslist[i].speed
    177. this.ctxthree.drawImage(this.gslist[i].image, this.gslist[i].x, this.gslist[i].y, this
    178. .gslist[i].size, this.gslist[i].size); // 绘制图片
    179. }
    180. }
    181. },
    182. drawboos: function() {
    183. var that = this
    184. // 计算物体A需要移动的距离和方向
    185. const dx = that.bosslist[0].x + that.bosslist[0].size / 2 - that.bosslist[0].mbx; // 水平移动距离
    186. const dy = that.bosslist[0].y + that.bosslist[0].size / 2 - that.bosslist[0]
    187. .mby // 垂直移动距离为0,因为我们只想在水平方向上移动
    188. if (dx > 10) {
    189. that.bosslist[0].x = that.bosslist[0].x - that.bosslist[0].speed
    190. } else if (dx < -10) {
    191. that.bosslist[0].x = that.bosslist[0].x + that.bosslist[0].speed
    192. }
    193. if (dy > 10) {
    194. that.bosslist[0].y = that.bosslist[0].y - that.bosslist[0].speed
    195. } else if (dy < -10) {
    196. that.bosslist[0].y = that.bosslist[0].y + that.bosslist[0].speed
    197. }
    198. that.ctxthree.drawImage(that.bosslist[0].image, that.bosslist[0].x, that.bosslist[0].y,
    199. that.bosslist[0].size, that.bosslist[0].size); // 绘制图片
    200. if (dy <= 10 && dy >= -10 && dx <= 10 && dx >= -10) {
    201. if (!that.bosslist[0].isover) {
    202. that.bosslist[0].mbx = that.getRandomInt(50, that.canvaswidth - 50)
    203. that.bosslist[0].mby = that.getRandomInt(50, that.canvasheight - 50)
    204. that.bosslist[0].speed = that.getRandomInt(1, 5)
    205. }
    206. }
    207. },
    208. drawbaopo: function(bean) {
    209. var that = this
    210. let counter = 0; // 计数器,记录执行次数
    211. const intervalId = setInterval(function() {
    212. // 这里是你的操作代码
    213. that.ctxthree.drawImage("../static/mantou.png", bean.x, bean.y, bean.size, bean
    214. .size); // 绘制图片
    215. counter++; // 每次执行,计数器加1
    216. // 检查是否达到了执行三次的条件
    217. if (counter >= 10) {
    218. clearInterval(intervalId); // 清除定时器
    219. }
    220. }, 100); // 每秒执行一次(1000毫秒)
    221. },
    222. zjdrawbaopo: function() {
    223. var that = this
    224. let counter = 0; // 计数器,记录执行次数
    225. const intervalId = setInterval(function() {
    226. // 这里是你的操作代码
    227. counter++; // 每次执行,计数器加1
    228. // 检查是否达到了执行三次的条件
    229. if (counter >= 10) {
    230. that.zhujpz = false
    231. clearInterval(intervalId); // 清除定时器
    232. }
    233. }, 100); // 每秒执行一次(1000毫秒)
    234. },
    235. /**
    236. * 触摸屏幕开始 记录开始坐标
    237. */
    238. touchstart: function(e) {
    239. let startx = e.touches[0].x
    240. let starty = e.touches[0].y
    241. if (startx > this.zhujue.x && startx < this.zhujue.x + this.zhujue.size && starty > this.zhujue.y &&
    242. starty < this.zhujue.y + this.zhujue.size) {
    243. this.zhujue.x = startx - this.zhujue.size / 2
    244. this.zhujue.y = starty - this.zhujue.size / 2
    245. this.zhujue.ismoveing = true
    246. this.drawzj()
    247. }
    248. },
    249. /**
    250. * 触摸屏幕结束 计算
    251. */
    252. touchend: function(e) {
    253. let x = e.changedTouches[0].x
    254. let y = e.changedTouches[0].y
    255. this.zhujue.ismoveing = false
    256. },
    257. /**
    258. * 触摸屏幕移动 画框
    259. */
    260. touchmove: function(e) {
    261. let x = e.touches[0].x
    262. let y = e.touches[0].y
    263. if (this.zhujue.ismoveing) {
    264. this.zhujue.x = x - this.zhujue.size / 2
    265. this.zhujue.y = y - this.zhujue.size / 2
    266. this.drawzj()
    267. }
    268. },
    269. drawbackg: function() {
    270. this.background.position += this.background.speed; // 更新图片位置
    271. if (this.background.position > this.canvasheight) { // 如果图片完全移出视口
    272. this.background.position = 0; // 将图片重新放置在视口的另一端
    273. }
    274. this.ctx.clearRect(0, 0, this.canvaswidth, this.canvaswidth); // 清除画布
    275. this.ctx.drawImage(this.background.images[0], 0, this.background.position, this.canvaswidth, this
    276. .canvasheight); // 绘制图片
    277. this.ctx.drawImage(this.background.images[1], 0, this.background.position - this.canvasheight, this
    278. .canvaswidth, this
    279. .canvasheight); // 绘制图片
    280. this.ctx.setFontSize(14); // 设置字体大小
    281. this.ctx.setFillStyle('white'); // 设置填充颜色为白色
    282. this.ctx.setTextAlign('center'); // 设置文本水平对齐方式为居中
    283. this.ctx.setTextBaseline('middle'); // 设置文本垂直对齐方式为中间
    284. this.ctx.fillText('剩余' + this.zhujue.lives, 40, 30); // 在圆心位置绘制文本“按钮”
    285. this.ctx.setFontSize(14); // 设置字体大小
    286. this.ctx.setFillStyle('white'); // 设置填充颜色为白色
    287. this.ctx.setTextAlign('center'); // 设置文本水平对齐方式为居中
    288. this.ctx.setTextBaseline('middle'); // 设置文本垂直对齐方式为中间
    289. this.ctx.fillText('总得分' + this.defen, 120, 30); // 在圆心位置绘制文本“按钮”
    290. this.ctx.setFontSize(14); // 设置字体大小
    291. this.ctx.setFillStyle('white'); // 设置填充颜色为白色
    292. this.ctx.setTextAlign('center'); // 设置文本水平对齐方式为居中
    293. this.ctx.setTextBaseline('middle'); // 设置文本垂直对齐方式为中间
    294. this.ctx.fillText('关卡' + this.guanka, 200, 30); // 在圆心位置绘制文本“按钮”
    295. this.ctx.setFontSize(14); // 设置字体大小
    296. this.ctx.setFillStyle('white'); // 设置填充颜色为白色
    297. this.ctx.setTextAlign('center'); // 设置文本水平对齐方式为居中
    298. this.ctx.setTextBaseline('middle'); // 设置文本垂直对齐方式为中间
    299. this.ctx.fillText('关卡得分' + this.guankadefen, 280, 30); // 在圆心位置绘制文本“按钮”
    300. this.ctx.draw();
    301. },
    302. game_start: function() {
    303. this.zjfszd()
    304. this.jisuanpz()
    305. this.ytimerX = setInterval(() => {
    306. for (var i = 0; i < this.zjzdlist.length; i++) {
    307. this.zjzdlist[i].y -= this.zjzdlist[i].speed
    308. if (this.zjzdlist[i].y < 0) {
    309. this.zjzdlist.splice(i, 1)
    310. }
    311. }
    312. if (this.isboos) {
    313. if (this.bosslist.length == 0) {
    314. this.bosslist = [{
    315. x: this.canvaswidth / 2,
    316. y: 0,
    317. size: 30 + this.guanka * 8,
    318. image: "../static/rou.png",
    319. value: 1000 * this.guanka * 0.8,
    320. speed: this.getRandomInt(1, 5),
    321. isfszd: this.getRandomInt(0, 1),
    322. zdspeed: 5,
    323. isover: false,
    324. mbx: this.getRandomInt(50, this.canvaswidth - 50),
    325. mby: this.getRandomInt(50, this.canvasheight - 50),
    326. }]
    327. }
    328. } else {
    329. if (this.gslist.length == 0) {
    330. this.scgs()
    331. }
    332. for (var i = 0; i < this.gslist.length; i++) {
    333. this.gslist[i].y += this.gslist[i].speed
    334. if (this.gslist.length < 12 && this.gslist[this.gslist.length - 1].y > 80) {
    335. this.scgs()
    336. }
    337. if (this.gslist[i].y > this.canvasheight) {
    338. this.gslist[i].y = -45
    339. }
    340. }
    341. }
    342. this.drawbackg();
    343. this.drawzjzd()
    344. }, 16); //100毫秒更新一次位置
    345. },
    346. jisuanpz: function() {
    347. this.jspztimer = setInterval(() => {
    348. if (this.zhujue.wdtime > 0) {
    349. this.zhujue.wdtime -= 1
    350. }
    351. this.isCollidingbyzjzdAndGS()
    352. this.isCollidingbyzjAndGS()
    353. }, 16); //100毫秒更新一次位置
    354. },
    355. game_stop: function() {
    356. clearInterval(this.ytimerX); // 停止动画
    357. clearInterval(this.zjfszdtimer);
    358. clearInterval(this.jspztimer);
    359. this.isshowstart = true
    360. },
    361. /**
    362. * 生成min 到 max 的随机数
    363. */
    364. getRandomInt: function(min, max) {
    365. min = Math.ceil(min);
    366. max = Math.floor(max);
    367. return Math.floor(Math.random() * (max - min + 1)) + min;
    368. },
    369. isCollidingbyzjzdAndGS: function() {
    370. var arr
    371. if (this.isboos) {
    372. arr = this.bosslist
    373. } else {
    374. arr = this.gslist
    375. }
    376. for (var j = 0; j < arr.length; j++) {
    377. let gsbean = arr[j]
    378. if (!gsbean.isover && gsbean.y > 0) {
    379. for (var i = 0; i < this.zjzdlist.length; i++) {
    380. let zjzdbean = this.zjzdlist[i]
    381. if (!zjzdbean.isuse) {
    382. let zdx = zjzdbean.x + this.zhujue.zdsize / 2
    383. let zdy = zjzdbean.y + this.zhujue.zdsize / 2
    384. if (zdx > gsbean.x && zdx < gsbean.x + gsbean.size && zdy > gsbean.y && zdy < gsbean
    385. .y + gsbean.size) {
    386. this.zjzdlist[i].isuse = true
    387. if (this.isboos) {
    388. this.defen += 10
    389. this.guankadefen += 10
    390. gsbean.value = gsbean.value - this.zhujue.zdvalue
    391. if (gsbean.value <= 0) {
    392. //消灭怪兽
    393. console.log(JSON.stringify(gsbean))
    394. if (gsbean.isdj == 1) {
    395. this.zhujue.zdvalue += 0.1
    396. }
    397. if (gsbean.isdj == 2) {
    398. this.zhujue.fstime -= 0.5
    399. }
    400. this.bosslist[j].isover = true
    401. this.defen += 100
    402. this.bosslist = []
    403. this.isboos = false
    404. this.guanka += 1
    405. this.guankadefen = 0
    406. this.zhujue.zdvalue += 5
    407. this.zhujue.fstime -= 1
    408. if (this.guanka % 2 == 0) {
    409. this.zhujue.lives += 1
    410. }
    411. }
    412. } else {
    413. //产生碰撞
    414. this.defen += 5
    415. this.guankadefen += 5
    416. gsbean.value = gsbean.value - this.zhujue.zdvalue
    417. if (gsbean.value <= 0) {
    418. //消灭怪兽
    419. console.log(JSON.stringify(gsbean))
    420. if (gsbean.isdj == 1) {
    421. this.zhujue.zdvalue += 0.1
    422. }
    423. if (gsbean.isdj == 2) {
    424. this.zhujue.fstime -= 0.5
    425. }
    426. this.gslist[j].isover = true
    427. this.defen += 5
    428. this.guankadefen += 5
    429. }
    430. }
    431. if (this.guankadefen >= 1000 * this.guanka * 1) {
    432. this.isboos = true
    433. this.gslist = []
    434. }
    435. }
    436. }
    437. }
    438. }
    439. }
    440. },
    441. isCollidingbyzjAndGS: function() {
    442. let zjx = this.zhujue.x + this.zhujue.size / 2
    443. let zjy = this.zhujue.y + this.zhujue.size / 2
    444. var arr
    445. if (this.isboos) {
    446. arr = this.bosslist
    447. } else {
    448. arr = this.gslist
    449. }
    450. for (var j = 0; j < arr.length; j++) {
    451. let gsbean = arr[j]
    452. if (!gsbean.isover) {
    453. let gsx = gsbean.x
    454. let gsy = gsbean.y
    455. let gssize = gsbean.size
    456. if (zjx < gsx + gssize && zjx > gsx && zjy < gsy + gssize && zjy > gsy) {
    457. console.log("11111")
    458. console.log("主角发生碰撞", this.zhujue.wdtime)
    459. if (this.zhujue.wdtime <= 0) {
    460. if (this.isboos) {
    461. this.zhujue.value -= gsbean.value
    462. } else {
    463. this.gslist[j].isover = true
    464. this.zhujue.value -= gsbean.value
    465. this.zhujpz = true
    466. }
    467. }
    468. if (this.zhujue.value <= 0) {
    469. console.log("主角死了。结束")
    470. this.zhujue.lives -= 1
    471. this.zhujue.wdtime = 300
    472. if (this.zhujue.lives < 0) {
    473. this.game_stop()
    474. } else {
    475. this.zhujue.value = 200
    476. }
    477. }
    478. }
    479. }
    480. }
    481. },
    482. }
    483. };
    484. </script>
    485. <style scoped>
    486. .contentone {
    487. width: 100vw;
    488. height: 100vh;
    489. position: absolute;
    490. display: flex;
    491. justify-content: center;
    492. }
    493. .contenttwo {
    494. width: 100vw;
    495. height: 100vh;
    496. position: absolute;
    497. display: flex;
    498. justify-content: center;
    499. }
    500. .canvas_cla {
    501. width: 100vw;
    502. height: 100vh;
    503. }
    504. .top_linear {
    505. display: flex;
    506. flex-direction: row;
    507. justify-content: space-between;
    508. display: flex;
    509. flex-direction: row;
    510. height: 80rpx;
    511. }
    512. .top_mean_left {
    513. margin-left: 32rpx;
    514. }
    515. .top_mean_right {
    516. margin-right: 32rpx;
    517. }
    518. .top_mean_tv {
    519. color: #07a5a6;
    520. }
    521. .page_main {
    522. position: fixed;
    523. overflow: hidden;
    524. width: 100vw;
    525. height: 100vh;
    526. background-color: #efefef;
    527. }
    528. .zhezhao {
    529. position: fixed;
    530. top: 0;
    531. bottom: 0;
    532. width: 100vw;
    533. height: 100vh;
    534. display: flex;
    535. justify-content: center;
    536. align-items: center;
    537. background-color: rgba(0, 0, 0, 0.4);
    538. z-index: 9999;
    539. }
    540. .dialog_back {
    541. position: fixed;
    542. z-index: 12;
    543. top: 0;
    544. right: 0;
    545. left: 0;
    546. bottom: 0;
    547. background: rgba(0, 0, 0, 0.3);
    548. justify-content: center;
    549. align-items: center;
    550. display: flex;
    551. }
    552. .add_button_ef {
    553. margin-left: 32rpx;
    554. margin-right: 32rpx;
    555. padding-top: 30rpx;
    556. padding-bottom: 30rpx;
    557. width: 300rpx;
    558. border: solid 2rpx #efefef;
    559. color: #999;
    560. background: #efefef;
    561. font-size: 32rpx;
    562. border-radius: 10rpx;
    563. display: flex;
    564. align-items: center;
    565. justify-content: center;
    566. text-align: center;
    567. vertical-align: center;
    568. }
    569. </style>

  • 相关阅读:
    【Java-Web】利用Session和Filter进行权限管理
    NSS [鹤城杯 2021]EasyP
    docker-compose安装sonarqube
    分布式—大量热点数据打散分布的一致性哈希算法
    TCP/IP(十一)TCP的连接管理(八)socket网络编程
    LeetCode每日一题——891. 子序列宽度之和
    《算法图解》阅读笔记
    python 图片爬虫记录
    华为GAUSSDB集成
    云端智创 | 批量化生产,如何利用Timeline快速合成短视频?
  • 原文地址:https://blog.csdn.net/yuehua_zhang/article/details/136740930