目次
Greedyにあげてください ヘビに効果音を追加します
uni.createInnerAudioContext を使用して内部オーディオ コンテキストを作成して返します innerAudioContext
ホームページ ウェブフロントエンド uni-app uniapp を使用してスネーク ゲームを開発する方法について話しましょう。

uniapp を使用してスネーク ゲームを開発する方法について話しましょう。

May 20, 2022 pm 07:56 PM
uni-app

uniapp を使用してスネーク ゲームを開発するにはどうすればよいですか?次の記事では、Uniapp に Snake ゲームを実装する手順を段階的に説明します。お役に立てば幸いです。

uniapp を使用してスネーク ゲームを開発する方法について話しましょう。

私が初めてスネークをプレイしたとき、それがその後、父が私にプレイさせてくれた最初のゲームだったことを今でも漠然と覚えています ?️

このミニ ゲームでは # が使用されています# #uniapp開発

事前の詳細については説明しません: https://juejin.cn/post/7085727363547283469#Heading-14

GameDemo

uniapp を使用してスネーク ゲームを開発する方法について話しましょう。

コード構造

詳細なコード構造が必要な場合は、

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

(ヘビの体が内部にある) に基づいて、床パネルのインデックスと一致して対応するグリッドを見つけ、背景画像を変更してヘビの体、ヘビの頭、およびヘビの頭をレンダリングします。尻尾 (##ヘビ##) #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軸値でヘビの方向を決定します
<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 = &#39;left&#39;
                    } else if (touchX > 0) {
                        if(this.direction === "left") return;
                        this.direction = &#39;right&#39;
                    }
                } else {
                    if (touchY < 0) {
                        if(this.direction === "down") return;
                        this.direction = &#39;up&#39;
                    } else if (touchY > 0) {
                        if(this.direction === "up") return;
                        this.direction = &#39;down&#39;
                    }
                }
                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>
ログイン後にコピー

Greedyにあげてください ヘビに効果音を追加します

ゲームの効果音を追加すると、ゲームがより没入型になります。次に、バックグラウンド ミュージック、クリック インタラクティブ ミュージック、ヘビのおならの音楽、ヘビが食べ物を食べる音楽をヘビに追加する必要があります。バグの爆発へのカウントダウンの音楽と、バグ爆発

まず、BGM を追加します。マップがいっぱいになるまでプレイする悪質な人々が常に存在します。BGM をループ再生するには、次の操作を行うだけです。

uni.createInnerAudioContext を使用して内部オーディオ コンテキストを作成して返します innerAudioContext

オブジェクトは音楽のパスを取得し、自動再生を設定します

<script>
import bgm from &#39;bgm.mp3&#39;;
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>
ログイン後にコピー

バックグラウンド ミュージックが鳴りますヘビのゲームオーバー後 ずっと鳴り続けて焦ったので、ヘビのゲームオーバー後にBGMを一時停止しました

pause音楽がクリアにならずに一時停止されました。

<script>
import bgm from &#39;bgm.mp3&#39;;
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>
ログイン後にコピー
最初の音楽が追加されましたバグ爆発のカウントダウンも爆発させるか、ゲームオーバー後にカウントダウン効果音 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>
ログイン後にコピー
EpilogueSpecial thanks

@大ショウ老元@

Dashuai 氏のリーダーシップ、指導、日々の監督に感謝します。チームメイトからの支援とサポート

ソース コード アドレス: https://github.com/MothWillion /snake_eat_worm##元のアドレス: https://juejin.cn /post/7087525655478272008

著者: Sophora

推奨: "
uniapp チュートリアル
"

以上がuniapp を使用してスネーク ゲームを開発する方法について話しましょう。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

VSCode でユニアプリを開発するにはどうすればよいですか? (チュートリアルの共有) VSCode でユニアプリを開発するにはどうすればよいですか? (チュートリアルの共有) May 13, 2022 pm 08:11 PM

VSCode でユニアプリを開発するにはどうすればよいですか?次の記事では、VSCode でのユニアプリ開発に関するチュートリアルを紹介します。これは、おそらく最も詳細なチュートリアルです。ぜひ見に来てください!

uniapp を使用してシンプルなマップ ナビゲーションを開発する uniapp を使用してシンプルなマップ ナビゲーションを開発する Jun 09, 2022 pm 07:46 PM

uniapp を使用してシンプルなマップ ナビゲーションを開発するにはどうすればよいですか?この記事では簡単な地図の作り方を紹介しますので、ぜひ参考にしてください。

uniapp を使用してスネーク ゲームを開発する方法について話しましょう。 uniapp を使用してスネーク ゲームを開発する方法について話しましょう。 May 20, 2022 pm 07:56 PM

uniapp を使用してスネーク ゲームを開発するにはどうすればよいですか?次の記事では、Uniapp に Snake ゲームを実装する手順を段階的に説明します。お役に立てば幸いです。

uni-app vue3 インターフェイスリクエストをカプセル化する方法 uni-app vue3 インターフェイスリクエストをカプセル化する方法 May 11, 2023 pm 07:28 PM

uni-app インターフェイス、グローバル メソッドのカプセル化 1. ルート ディレクトリに API ファイルを作成し、API フォルダーに api.js、baseUrl.js、および http.js ファイルを作成します。 2.baseUrl.js ファイル コード exportdefault"https://XXXX .test03.qcw800.com/api/"3.http.js ファイル コードexportfunctionhttps(opts,data){lethttpDefaultOpts={url:opts.url,data:data,method:opts.method

ユニアプリ カレンダー プラグインを開発 (および公開) する手順を段階的に説明します。 ユニアプリ カレンダー プラグインを開発 (および公開) する手順を段階的に説明します。 Jun 30, 2022 pm 08:13 PM

この記事では、ユニアプリ カレンダー プラグインの開発をステップごとに説明し、次期カレンダー プラグインの開発からリリースまでの手順を紹介します。

uniapp が複数選択ボックスの全選択機能を実装する方法を説明する例 uniapp が複数選択ボックスの全選択機能を実装する方法を説明する例 Jun 22, 2022 am 11:57 AM

この記事では、uniapp に関する関連知識を提供します。主に、複数選択ボックスの全選択機能の実装に関する問題を整理します。全選択機能が実装できない理由は、チェックボックスのチェックされたフィールドがオンになっている場合です。動的に変更されると、インターフェイス上のステータスはリアルタイムに変更されますが、checkbox-group の変更イベントはトリガーされません。

uniapp のスクロールビュー ドロップダウンの読み込みについて話しましょう uniapp のスクロールビュー ドロップダウンの読み込みについて話しましょう Jul 14, 2022 pm 09:07 PM

uniapp はスクロールビューのドロップダウン読み込みをどのように実装しますか?次の記事では、uniapp WeChat アプレットのスクロールビューのドロップダウン読み込みについて説明しています。

uniapp が電話録音機能を実装する方法の詳細な例 (コード付き) uniapp が電話録音機能を実装する方法の詳細な例 (コード付き) Jan 05, 2023 pm 04:41 PM

この記事では、uniapp に関する関連知識を皆さんに提供します。主に uniapp を使用して電話をかける方法と同期録音する方法を紹介します。興味のある友人はぜひご覧ください。皆様のお役に立てれば幸いです。

See all articles