How to use uniapp to develop a snake game? The following article will take you step by step to implement the Snake game in uniapp. I hope it will be helpful to you!
The first time I played Snake, I still vaguely remember it being the first game my father played for me after ??
This mini game uses uniapp
Development
I won’t go into details about the pre-details: https://juejin.cn/post/7085727363547283469#heading-14
GameDemo
Code structure
If you need the detailed code structure, please go to github to view
It is mainly divided into : Start the game, plots, snake bodies, bugs, contaminated plots, game sound effects
<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">游戲結(jié)束</view> <view class="result">您的蛇蛇達到了{{snakes.length}}米</view> <view class="btns"> <button type="primary" @click="reStart">再次挑戰(zhàn)</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>
Rendering snake body
Put our snake in his coat
The rendering of the snake body is based on snakes
(with the snake's body inside) to match the index of the floor panel to find the corresponding grid and modify the background image to render the snake body, snake head and tail, which is snakes
The 0th and last digits and find the corresponding grid to modify the current background image
<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>
Control the direction of the snake
Control the direction of the snake on the PC side, we monitor the keyboard The event finds the code of the corresponding keyboard key up, down, left, and right to change the direction of the snake. On the mobile phone, we use the XY axis value of the finger touch point and sliding point at the touch time to determine the direction 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, // 游戲結(jié)束了 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) { // 獲取當(dāng)前按下鍵盤鍵的編碼 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軸坐標(biāo) let lastY = e.touches[0].pageY; // 移動的y軸坐標(biāo) 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>
Give it to Greedy Adding sound effects to snakes
Adding game sound effects will make the game more immersive. Now we need to add background music, click interactive music, snake fart music, and snake eating food music to the snake. The music for the countdown to the bug explosion and the music for the bug explosion
First add the background music. There are always unscrupulous people who can play until the map is full. To play the background music in a loop, we only need to
Use uni.createInnerAudioContext
to create and return the internal audio context innerAudioContext
The object gets the path of the music and sets up automatic playback
<script> import bgm from 'bgm.mp3'; export default { data(){ return { bgmInnerAudioContext:null, } }, methods:{ start() { // 開始游戲 this.initGame(); this.handleBgmVoice() }, handleBgmVoice() { // 背景音樂 this.bgmInnerAudioContext = uni.createInnerAudioContext() // 創(chuàng)建上下文 this.bgmInnerAudioContext.autoplay = true; // 自動播放 this.bgmInnerAudioContext.src= bgm; // 音頻地址 this.bgmInnerAudioContext.loop = true; // 循環(huán)播放 } } } <script>
The background music does sound after the snake gameover It kept ringing and I became impatient. Then we paused the background music after the snake gameover. pause
The music was paused without being clear.
<script> import bgm from 'bgm.mp3'; export default { data(){ return { bgmInnerAudioContext:null, } }, methods:{ start() { // 開始游戲 this.initGame(); this.handleBgmVoice() }, handleBgmVoice() { // 背景音樂 this.bgmInnerAudioContext = uni.createInnerAudioContext() // 創(chuàng)建上下文 this.bgmInnerAudioContext.autoplay = true; // 自動播放 this.bgmInnerAudioContext.src= bgm; // 音頻地址 this.bgmInnerAudioContext.loop = true; // 循環(huán)播放 } checkGame(direction, next) { let gameover = false; let isSnake = this.snakes.indexOf(next) > -1; let isPollute = this.pollutes.indexOf(next) > -1; // 撞到蛇和被污染的地塊游戲結(jié)束 if (isSnake || isPollute) { gameover = true; } // 撞到邊界游戲結(jié)束 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() // 游戲結(jié)束 暫停背景音樂 clearInterval(this.timer); clearInterval(this.boomTimer); } else { // 游戲沒結(jié)束 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>
The first music was added successfully and the rest were It’s much simpler. The countdown for bug explosion also needs to explode or after gameover, you need to clear the countdown sound effect stop
(the next playback will start from the beginning). The rest does not need to clear the sound effect and loop playback. The remaining code is attached below
<script> export default { data() { return { bgmInnerAudioContext:null, clockInnerAudioContext:null, } }, watch: { boomCount(val) { if (val === 0) { // 超過爆炸時間還沒吃到,則將蟲子格子變成被污染的土地,并且重置爆炸狀態(tài),同時生成一只新的蟲子: 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; // 撞到蛇和被污染的地塊游戲結(jié)束 if (isSnake || isPollute) { gameover = true; } // 撞到邊界游戲結(jié)束 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() // 游戲結(jié)束 暫停背景音樂 this.clockInnerAudioContext && this.clockInnerAudioContext.stop() // 清楚倒計時音樂 clearInterval(this.timer); clearInterval(this.boomTimer); } else { // 游戲沒結(jié)束 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)]; // 根據(jù)游戲難度,概率產(chǎn)出會爆炸的蟲子: 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>
Epilogue
Special thanks@大肖老元@無碼 Thanks to Mr. Dashuai for his leadership and guidance and daily supervision, and special thanks as well. Help and support from teammates
Source code address: https://github.com/MothWillion/snake_eat_worm
##Original address: https://juejin.cn /post/7087525655478272008Author: SophoraRecommended: "
uniapp tutorial"
The above is the detailed content of Let's talk about how to use uniapp to develop a snake game!. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

How to develop uni-app in VSCode? The following article will share with you a tutorial on developing uni-app in VSCode. This may be the best and most detailed tutorial. Come and take a look!

How to use uniapp to develop a simple map navigation? This article will provide you with an idea for making a simple map. I hope it will be helpful to you!

uni-app interface, global method encapsulation 1. Create an api file in the root directory, create api.js, baseUrl.js and http.js files in the api folder 2.baseUrl.js file code exportdefault"https://XXXX .test03.qcw800.com/api/"3.http.js file code exportfunctionhttps(opts,data){lethttpDefaultOpts={url:opts.url,data:data,method:opts.method

This article will guide you step by step in developing a uni-app calendar plug-in, and introduce how the next calendar plug-in is developed from development to release. I hope it will be helpful to you!

How to use uniapp to develop a snake game? The following article will take you step by step to implement the Snake game in uniapp. I hope it will be helpful to you!

This article brings you relevant knowledge about uniapp. It mainly introduces how to use uniapp to make calls and synchronize recording. Friends who are interested should take a look at it. I hope it will be helpful to everyone.

This article brings you relevant knowledge about uniapp, which mainly organizes the related issues of implementing the select-all function of the multi-select box. The reason why the select-all function cannot be implemented is that when the checked field of the checkbox is dynamically modified, the status on the interface can Real-time changes, but the change event of checkbox-group cannot be triggered. Let's take a look at it. I hope it will be helpful to everyone.

How does uniapp implement scroll-view drop-down loading? The following article talks about the drop-down loading of the uniapp WeChat applet scroll-view. I hope it will be helpful to everyone!
