検索
ホームページウェブフロントエンドuni-appuniapp を使用してスネーク ゲームを開発する方法について話しましょう。

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>
Epilogue

Special thanks

@大ショウ老元@

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

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

著者: Sophora

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

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

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
さまざまなプラットフォーム(モバイル、Webなど)で問題をどのようにデバッグしますか?さまざまなプラットフォーム(モバイル、Webなど)で問題をどのようにデバッグしますか?Mar 27, 2025 pm 05:07 PM

この記事では、モバイルプラットフォームとWebプラットフォームのデバッグ戦略について説明し、Android Studio、Xcode、Chrome Devtoolsなどのツールを強調し、OSとパフォーマンスの最適化全体で一貫した結果を得るためのテクニックについて説明します。

UNIAPP開発に利用できるデバッグツールは何ですか?UNIAPP開発に利用できるデバッグツールは何ですか?Mar 27, 2025 pm 05:05 PM

この記事では、Hbuilderx、Wechat開発者ツール、Chrome Devtoolsなどのツールに焦点を当てたUniapp開発のためのデバッグツールとベストプラクティスについて説明します。

UNIAPPアプリケーションのエンドツーエンドテストをどのように実行しますか?UNIAPPアプリケーションのエンドツーエンドテストをどのように実行しますか?Mar 27, 2025 pm 05:04 PM

この記事では、複数のプラットフォームにわたるUNIAPPアプリケーションのエンドツーエンドテストについて説明します。テストシナリオの定義、Appiumやサイプレスなどのツールの選択、環境のセットアップ、テストの書き込みと実行、結果の分析、インテグラートをカバーします

UNIAPPアプリケーションで実行できるさまざまなタイプのテストは何ですか?UNIAPPアプリケーションで実行できるさまざまなタイプのテストは何ですか?Mar 27, 2025 pm 04:59 PM

この記事では、ユニット、統合、機能、UI/UX、パフォーマンス、クロスプラットフォーム、セキュリティテストなど、UNIAPPアプリケーションのさまざまなテストタイプについて説明します。また、クロスプラットフォームの互換性を確保し、JESのようなツールを推奨しています

Uniappの一般的なパフォーマンスアンチパターンは何ですか?Uniappの一般的なパフォーマンスアンチパターンは何ですか?Mar 27, 2025 pm 04:58 PM

この記事では、過剰なグローバルデータの使用や非効率的なデータバインディングなど、UNIAPP開発における一般的なパフォーマンスアンチパターンについて説明し、これらの問題を特定して緩和してアプリのパフォーマンスを向上させる戦略を提供します。

プロファイリングツールを使用して、UNIAPPでパフォーマンスボトルネックを識別するにはどうすればよいですか?プロファイリングツールを使用して、UNIAPPでパフォーマンスボトルネックを識別するにはどうすればよいですか?Mar 27, 2025 pm 04:57 PM

この記事では、プロファイリングツールを使用して、Uniappのパフォーマンスボトルネックを識別および解決し、セットアップ、データ分析、最適化に焦点を当てています。

Uniappでネットワークリクエストを最適化するにはどうすればよいですか?Uniappでネットワークリクエストを最適化するにはどうすればよいですか?Mar 27, 2025 pm 04:52 PM

この記事では、Uniappでネットワーク要求を最適化するための戦略について説明し、遅延の削減、キャッシュの実装、および監視ツールを使用してアプリケーションのパフォーマンスを向上させることに焦点を当てています。

UniappのWebパフォーマンスのために画像を最適化するにはどうすればよいですか?UniappのWebパフォーマンスのために画像を最適化するにはどうすればよいですか?Mar 27, 2025 pm 04:50 PM

この記事では、圧縮、レスポンシブデザイン、怠zyなロード、キャッシング、およびWebP形式の使用を通じて、Webパフォーマンスを向上させるために、Uniappの画像の最適化について説明します。

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール