uniapp을 사용하여 스네이크 게임을 개발하는 방법은 무엇인가요? 다음 글은 uniapp에서 Snake 게임을 구현하는 과정을 단계별로 안내해드릴 것입니다. 도움이 되길 바랍니다.
처음 스네이크를 플레이했을 때, 아직도 어렴풋이 기억나죠? 나중에 아버지가 처음으로 해 주신 게임
이 미니 게임은 uniapp
자세한 내용은 언급하지 않겠습니다. https://juejin.cn/post/7085727363547283469#heading-14
자세한 코드 구조가 필요한 경우 github에 가서 확인하세요
크게 나누어져 있습니다 : 게임 시작, 플롯, 뱀 몸, 버그, 오염된 플롯, 게임 음향 효과
<template> <view ref="body" class="content"> <view>蛇蛇目前:{{snakes.length}}米长</view> <view class="game-field"> <!-- 地面板块 --> <view class="block" v-for="(x, i) in blocks" :key="i"></view> </view> <view v-show="!started || ended" class="game-board-wrap"> <view v-show="!started" class="game-board"> <view class="title">选择游戏难度</view> <radio-group name="radio" @change="bindLevelChange"> <label class="label"> <radio value="1" :checked="level==1" /><text>简单模式</text> </label> <label class="label"> <radio value="2" :checked="level==2" /><text>正常模式</text> </label> <label class="label"> <radio value="3" :checked="level==3" /><text>困难模式</text> </label> <label class="label"> <radio value="4" :checked="level==4" /><text>地狱模式</text> </label> </radio-group> <button type="primary" @click="start">开始游戏</button> </view> <view v-show="ended" class="settle-board"> <view class="title">游戏结束</view> <view class="result">您的蛇蛇达到了{{snakes.length}}米</view> <view class="btns"> <button type="primary" @click="reStart">再次挑战</button> <button type="primary" plain @click="rePick">重选难度</button> </view> </view> </view> </view> </template> <script> export default { data() { return { blocks: [], // 板块 worms: [], // 虫子 snakes: [0, 1, 2, 3], // 蛇身 direction: "right", // 蛇移动方向 }; }, onLoad() { this.initGame(); }, methods: { initGame() { this.blocks = new Array(100).fill(0); // 生成100个地面板块 this.worms = [Math.floor(Math.random() * 96) + 4]; // 随机生成虫子 this.snakes = [0, 1, 2, 3]; // 初始化蛇身位置 } } } </script>
우리 뱀을 코트에 넣어주세요
뱀 몸통의 렌더링은 snakes
(里边放着蛇的身体)来匹配地面板块的索引 从而找到对应的格格并修改背景图来渲染蛇身 蛇头和蛇尾就是取snakes
0번째와 마지막 숫자를 기준으로 해당 그리드를 찾아 현재 배경 이미지를 수정합니다
<template> <view class="game-field"> <view class="block" :style="`background-image: ${bg(x, i)}" v-for="(x, i) in blocks" :key="i"> </view> </view> </template> <script> import worm from "worm.png"; import snakeBody from "snake_body.png"; import snakeHead from "snake_head.png"; import snakeTail from "snake_tail.png"; import polluteBlock from "pollute.png"; import wormBoom from "worm_4.png"; export default { methods: { bg(type, index) { let bg = ""; switch (type) { case 0: // 地板 bg = "unset"; break; case 1: // 虫子 if (this.boom) { bg = `url(${wormBoom})`; } else { bg = `url(${worm})`; } break; case 2: // 蛇 let head = this.snakes[this.snakes.length - 1]; let tail = this.snakes[0]; if (index === head) { bg = `url(${snakeHead})`; } else if (index === tail) { bg = `url(${snakeTail})`; } else { bg = `url(${snakeBody})`; } break; case 3: // 污染的地块 bg = `url(${polluteBlock})`; break; } return bg; }, } } </scipt>
뱀의 방향을 제어합니다. PC측에서는, 키보드 이벤트를 듣고 해당 키보드 키를 찾습니다. 위, 아래, 왼쪽, 오른쪽 코드를 사용하여 뱀의 방향을 변경합니다. 휴대폰에서는 손가락 터치 지점과 슬라이딩 지점의 XY 축 값을 사용하여 방향을 결정합니다. of the snake
<template> <view ref="body" class="content" @keyup.left="bindLeft" @keyup.right="bindRight" @keyup.down="bindDown" @keyup.up="bindUp" @touchstart="handleTouchStart" @touchmove="handleTouchMove"> <view>蛇蛇目前:{{snakes.length}}米长</view> <view class="game-field"> <view class="block" :style="`background-image: ${bg(x, i)}; v-for="(x, i) in blocks" :key="i"></view> </view> </view> </template> <script> export default { data(){ return { direction: "right", started: false, // 游戏开始了 ended: false, // 游戏结束了 level: 1, // 游戏难度 lastX: 0, lastY: 0, } }, onLoad() { this.initGame(); }, methods:{ initGame() { this.blocks = new Array(100).fill(0); // 生成100个地面板块 this.worms = [Math.floor(Math.random() * 96) + 4]; // 随机生成虫子 this.snakes = [0, 1, 2, 3]; // 初始化蛇身位置 document.onkeydown = (e) => { switch (e.keyCode) { // 获取当前按下键盘键的编码 case 37: // 按下左箭头键 this.bindLeft(); break; case 39: // 按下右箭头键 this.bindRight(); break; case 38: // 按下上箭头键 if (!this.started) { this.level--; } else { this.bindUp(); } break; case 40: // 按下下箭头键 if (!this.started) { this.level++; } else { this.bindDown(); } break; } } }, handleTouchStart(e) { // 手指开始位置 this.lastX = e.touches[0].pageX; this.lastY = e.touches[0].pageY; }, handleTouchMove(e) { let lastX = e.touches[0].pageX; // 移动的x轴坐标 let lastY = e.touches[0].pageY; // 移动的y轴坐标 let touchX = lastX - this.lastX; let touchY = lastY - this.lastY if (Math.abs(touchX) > Math.abs(touchY)) { if (touchX < 0) { if(this.direction === "right") return; this.direction = 'left' } else if (touchX > 0) { if(this.direction === "left") return; this.direction = 'right' } } else { if (touchY < 0) { if(this.direction === "down") return; this.direction = 'up' } else if (touchY > 0) { if(this.direction === "up") return; this.direction = 'down' } } this.lastX = lastX; this.lastY = lastY; }, bindUp() { if (this.direction === "down") return; this.direction = "up"; }, bindDown() { if (this.direction === "up") return; this.direction = "down"; }, bindLeft() { if (this.direction === "right") return; this.direction = "left"; }, bindRight() { if (this.direction === "left") return; this.direction = "right"; }, } } </script>
게임에 대체감을 주기 위해 게임 음향 효과를 추가했습니다. 이제 뱀에 배경 음악을 추가해야 하고, 상호 작용 음악을 클릭해야 합니다. 방귀 음악, 뱀 먹는 음식, 벌레 폭발 카운트다운 음악 및 벌레 폭발 음악
먼저 배경 음악을 추가하세요. 다루기 힘든 사람들이 있으면 맵이 가득 찰 때까지 재생할 수 있습니다. 배경 음악을 반복하고 싶다면 우리만 있으면 됩니다.
uni.createInnerAudioContext
를 사용하여 내부 오디오 컨텍스트 innerAudioContext
개체를 생성 및 반환하여 음악 경로를 가져오고 자동 재생을 설정하세요uni.createInnerAudioContext
来创建并返回内部 audio 上下文 innerAudioContext
对象 拿到音乐的路径并且设置自动播放
<script> import bgm from 'bgm.mp3'; export default { data(){ return { bgmInnerAudioContext:null, } }, methods:{ start() { // 开始游戏 this.initGame(); this.handleBgmVoice() }, handleBgmVoice() { // 背景音乐 this.bgmInnerAudioContext = uni.createInnerAudioContext() // 创建上下文 this.bgmInnerAudioContext.autoplay = true; // 自动播放 this.bgmInnerAudioContext.src= bgm; // 音频地址 this.bgmInnerAudioContext.loop = true; // 循环播放 } } } <script>
背景音乐确实响起来了 蛇gameover后还一直响 顿时我听着就不耐烦 这时我们在蛇gameover后暂停背景音乐pause
音乐会暂停而不会清楚
<script> import bgm from 'bgm.mp3'; export default { data(){ return { bgmInnerAudioContext:null, } }, methods:{ start() { // 开始游戏 this.initGame(); this.handleBgmVoice() }, handleBgmVoice() { // 背景音乐 this.bgmInnerAudioContext = uni.createInnerAudioContext() // 创建上下文 this.bgmInnerAudioContext.autoplay = true; // 自动播放 this.bgmInnerAudioContext.src= bgm; // 音频地址 this.bgmInnerAudioContext.loop = true; // 循环播放 } checkGame(direction, next) { let gameover = false; let isSnake = this.snakes.indexOf(next) > -1; let isPollute = this.pollutes.indexOf(next) > -1; // 撞到蛇和被污染的地块游戏结束 if (isSnake || isPollute) { gameover = true; } // 撞到边界游戏结束 switch (direction) { case "up": if (next < 0) { gameover = true; } break; case "down": if (next >= 100) { gameover = true; } break; case "left": if (next % 10 === 9) { gameover = true; } break; case "right": if (next % 10 === 0) { gameover = true; } break; } return gameover; }, toWards(direction) { let gameover = this.checkGame(direction, next); if (gameover) { this.ended = true; this.handleDieVoice() this.bgmInnerAudioContext.pause() // 游戏结束 暂停背景音乐 clearInterval(this.timer); clearInterval(this.boomTimer); } else { // 游戏没结束 this.snakes.push(next); let nextType = this.blocks[next]; this.blocks[next] = 2; // 如果是空白格 if (nextType === 0) { this.snakes.shift(); } else { // 如果是虫子格 this.handleEatVoice() // 吃掉虫子后的音乐 this.worms = this.worms.filter((x) => x !== next); let nextWorm = this.createWorm(); this.worms.push(nextWorm); } this.blocks[tail] = 0; this.paint(); } }, } } <script>
首个音乐添加成功其他的也就简单多了 虫子爆炸倒计时也需要爆炸或者gameover后需要清楚倒计时音效stop
<script> export default { data() { return { bgmInnerAudioContext:null, clockInnerAudioContext:null, } }, watch: { boomCount(val) { if (val === 0) { // 超过爆炸时间还没吃到,则将虫子格子变成被污染的土地,并且重置爆炸状态,同时生成一只新的虫子: this.handleExplodeVoice() // 爆炸的音乐 this.clockInnerAudioContext.stop() // 清楚倒计时音乐 const boomWorm = this.worms.pop(); this.pollutes.push(boomWorm); this.blocks[boomWorm] = 3; // 被污染的地方我们用3表示 this.boom = false; this.worms.push(this.createWorm()); } } }, methods:{ // 蛇吃到食物后的声音 handleEatVoice() { const innerAudioContext = uni.createInnerAudioContext(); innerAudioContext.autoplay = true; innerAudioContext.src = eatVoice; }, // 虫子污染爆炸后的声音 handleExplodeVoice(){ const innerAudioContext = uni.createInnerAudioContext(); innerAudioContext.autoplay = true; innerAudioContext.src = explodeVoice; }, // 游戏背景音乐 handleBgmVoice() { this.bgmInnerAudioContext = uni.createInnerAudioContext() this.bgmInnerAudioContext.autoplay = true; this.bgmInnerAudioContext.src= bgm; this.bgmInnerAudioContext.loop = true; }, // 按钮点击的声音 handleClickVoice() { const innerAudioContext = uni.createInnerAudioContext() innerAudioContext.autoplay = true; innerAudioContext.src= click; }, // 爆炸倒计时的声音 handleClockVoice() { this.clockInnerAudioContext = uni.createInnerAudioContext() this.clockInnerAudioContext.autoplay = true; this.clockInnerAudioContext.src= clock; }, // 蛇gameover后的声音 handleDieVoice() { const innerAudioContext = uni.createInnerAudioContext() innerAudioContext.autoplay = true; innerAudioContext.src= die; }, checkGame(direction, next) { let gameover = false; let isSnake = this.snakes.indexOf(next) > -1; let isPollute = this.pollutes.indexOf(next) > -1; // 撞到蛇和被污染的地块游戏结束 if (isSnake || isPollute) { gameover = true; } // 撞到边界游戏结束 switch (direction) { case "up": if (next < 0) { gameover = true; } break; case "down": if (next >= 100) { gameover = true; } break; case "left": if (next % 10 === 9) { gameover = true; } break; case "right": if (next % 10 === 0) { gameover = true; } break; } return gameover; }, paint() { this.worms.forEach((x) => { this.blocks[x] = 1; }); this.snakes.forEach((x) => { this.blocks[x] = 2; }); this.$forceUpdate(); }, toWards(direction) { let gameover = this.checkGame(direction, next); if (gameover) { this.ended = true; this.handleDieVoice() this.bgmInnerAudioContext.pause() // 游戏结束 暂停背景音乐 this.clockInnerAudioContext && this.clockInnerAudioContext.stop() // 清楚倒计时音乐 clearInterval(this.timer); clearInterval(this.boomTimer); } else { // 游戏没结束 this.snakes.push(next); let nextType = this.blocks[next]; this.blocks[next] = 2; // 如果是空白格 if (nextType === 0) { this.snakes.shift(); } else { // 如果是虫子格 this.handleEatVoice() // 吃掉虫子后的音乐 this.worms = this.worms.filter((x) => x !== next); let nextWorm = this.createWorm(); this.worms.push(nextWorm); } this.blocks[tail] = 0; this.paint(); } }, // 生成下一只虫子 createWorm() { this.boom = false; let blocks = Array.from({ length: 100 }, (v, k) => k); // 在不是蛇和被污染的地方生成虫子 let restBlocks = blocks.filter(x => this.snakes.indexOf(x) < 0 && this.pollutes.indexOf(x) < 0); let worm = restBlocks[Math.floor(Math.random() * restBlocks.length)]; // 根据游戏难度,概率产出会爆炸的虫子: this.boom = Math.random() / this.level < 0.05; // 生成了新虫子说明吃到了那个爆炸的虫子,重置下爆炸 if (this.boom) { this.boomCount = 10; this.boomTimer && clearInterval(this.boomTimer); this.handleClockVoice() this.boomTimer = setInterval(() => { this.boomCount--; }, 1000) } else { this.clockInnerAudioContext && this.clockInnerAudioContext.stop() clearInterval(this.boomTimer); } return worm; }, } } <script>배경 음악이 소리를 내고 계속됩니다. 게임오버 후 갑자기 소리가 나서 조바심이 났습니다.
pause
음악이 명확하지 않게 일시중지되었습니다. stop
을 지워야 합니다(다음 재생은 처음부터 시작됩니다). 나머지 코드는 아래에 첨부되어 있습니다rrreee결론특별 감사합니다 @大marshalold ape
@아직 끝이 오지 않았습니다Dashuai 선생님의 지도력과 지도력, 매일 감독, 특별함에 감사드립니다. 팀원들의 도움과 지원에 감사드립니다
소스 코드 주소: https://github.com/MothWillion /snake_eat_worm 원본 주소: https://juejin.cn/post/7087525655478272008추천: "🎜uniapp 튜토리얼🎜"🎜
위 내용은 uniapp을 활용하여 스네이크 게임을 개발하는 방법에 대해 이야기해보겠습니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!