创建菜单与游戏页面

news2025/2/28 22:59:45

bootstrap地址

Bootstrap v5 中文文档 · Bootstrap 是全球最受欢迎的 HTML、CSS 和 JS 前端工具库。 | Bootstrap 中文网 (bootcss.com)

 

创建导航栏组件

web--src--components--NavBar.vue

<!-- html -->
<template>
    <nav class="navbar navbar-expand-lg  navbar-dark bg-dark">
        <div class="container">
            <!-- 刷新 -->
            <!-- <a class="navbar-brand" href="/">King Of Bots</a> -->
            <!-- 点击页面不刷新用router-link -->
            <router-link class="navbar-brand" :to="{ name: 'pk_index' }">King Of Bots</router-link>
            <div class="collapse navbar-collapse" id="navbarText">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    <li class="nav-item">
                        <!-- active高亮 -->
                        <!-- <router-link class="nav-link active " :to="{ name: 'pk_index' }">对战</router-link> -->
                        <!-- 选中的高亮 -->
                        <router-link :class="route_name == 'pk_index' ? 'nav-link active' : 'nav-link'"
                            :to="{ name: 'pk_index' }">对战</router-link>
                    </li>
                    <li class="nav-item">
                        <router-link :class="route_name == 'record_index' ? 'nav-link active' : 'nav-link'"
                            :to="{ name: 'record_index' }">对局列表</router-link>
                    </li>
                    <li class="nav-item">
                        <router-link :class="route_name == 'ranklist_index' ? 'nav-link active' : 'nav-link'"
                            :to="{ name: 'ranklist_index' }">排行榜</router-link>
                    </li>
                </ul>
                <ul class="navbar-nav ">
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
                            aria-expanded="false">
                            USERNAME
                        </a>
                        <ul class="dropdown-menu">
                            <li>
                                <router-link class="dropdown-item" :to="{ name: 'user_bot_index' }">my bot</router-link>
                            </li>
                            <li><a class="dropdown-item" href="#">exit</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</template>

<!-- js -->
<script >
// 实现选中的页面高亮
import { useRoute } from 'vue-router';
import { computed } from 'vue';
export default {
    setup() {
        const route = useRoute();
        let route_name = computed(() => route.name)
        return {
            route_name
        }
    }
}
</script>

<!-- css -->
<!-- scoped 作用:写的css会加上一个随机字符串,使得样式不会影响组件以外的部分 -->
<style scoped></style>

App.vue

<template>
  <NavBar />
  <router-view></router-view>
</template>

<script>
import NavBar from './components/NavBar.vue'
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap/dist/js/bootstrap"
export default {
  components: {
    NavBar
  }
}
</script>

<style>
body {
  background-image: url("@/assets/background.png");
  background-size: 100% 900%;
}
</style>

创建各页面组件

<template>
    <div>404</div>
</template>

<script>
</script>

<style scoped></style>
<template>
    <ContentField>
        对战
    </ContentField>
</template>

<script>
import ContentField from "../../components/ContentField.vue"
export default {
    components: {
        ContentField
    }
}
</script>

<style scoped></style>
<template>
    <ContentField>
        RankList排行榜
    </ContentField>
</template>

<script>
import ContentField from "../../components/ContentField.vue"
export default {
    components: {
        ContentField
    }
}
</script>

<style scoped></style>
<template>
    <ContentField>
        对局列表
    </ContentField>
</template>

<script>
import ContentField from "../../components/ContentField.vue"
export default {
    components: {
        ContentField
    }
}
</script>

<style scoped></style>
<template>
    <ContentField>
        我的Bot
    </ContentField>
</template>

<script>
import ContentField from "../../../components/ContentField.vue"
export default {
    components: {
        ContentField
    }
}
</script>

<style scoped></style>

 router---组件

import { createRouter, createWebHistory } from 'vue-router'
import NotFound from "../views/error/NotFound"
import PkIndexView from "../views/pk/PkIndexView"
import RanklistIndexView from "../views/ranklist/RanklistIndexView"
import RecordIndexView from "../views/record/RecordIndexView"
import UserBotIndexView from "../views/user/bot/UserBotIndexView"
const routes = [
  {
    path: "/pk/",
    name: "pk_index",
    component: PkIndexView
  },
  {
    path: "/error/",
    name: "404",
    component: NotFound
  },
  {
    path: "/record/",
    name: "record_index",
    component: RecordIndexView
  },
  {
    path: "/ranklist/",
    name: "ranklist_index",
    component: RanklistIndexView
  },
  {
    path: "/user/bot/",
    name: "user_bot_index",
    component: UserBotIndexView
  },
  // 重定向到404
  {
    path: "/:catchAll(.*)",
    redirect: "/error/"
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

 白板--组件

各页面白板构成一个组件components->ContentField.vue

<template>
    <div class="container content-field">
        <div class="card">
            <div class="card-body">
                <!-- 渲染的东西放到  slot 中 -->
                <slot></slot>
            </div>
        </div>
    </div>
</template>

<script>
</script>

<style scoped>
/* 20px的上边距 */
div.content-field {
    margin-top: 20px;
}
</style>

 游戏对象类

scrips---->ACGameObject.js

const AC_GAME_OBJECTS = []; //存储所有运动对象
export class AcGameObject {
    constructor() {
        AC_GAME_OBJECTS.push(this);
        // 走的距离=速度*时间间隔
        //当前帧执行的时刻距离上一帧执行时刻的间隔,浏览器每一帧时间间隔可能有误差不一样因此需要记录
        this.timedelta = 0;
        // 是否执行过start函数
        this.has_called_start = false;
    }
    start() {    //创建时,只执行一次

    }
    update() {  // 除了第一帧外每一帧执行一次

    }
    // 删除之前用到的回调函数
    on_destroyed() {

    }
    destroyed() {
        this.on_destroyed();
        for (let i in AC_GAME_OBJECTS) {
            const obj = AC_GAME_OBJECTS[i];
            if (obj == this) {
                AC_GAME_OBJECTS.splice(i);      //从数组删除
                break;
            }
        }
    }
}
let last_timestamp; //上一次执行的时刻
// requestAnimationFrame(函数) 函数在浏览器下一次渲染之前执行一遍
// 迭代执行step
// in是下标  of是值
const step = timestamp => {             // 每次调用会传入当前时刻
    for (let obj of AC_GAME_OBJECTS) {
        // 如果没执行start()
        if (!obj.has_called_start) {
            obj.has_called_start = true;
            obj.start();
        } else {
            obj.timedelta = obj.timestamp - last_timestamp;
            obj.update();
        }
    }
    last_timestamp = timestamp;
    // 下一帧执行step
    requestAnimationFrame(step)
}
requestAnimationFrame(step)

 地图

动起来:60帧/s

地图对象类


// export  import {}     export default import 

// 游戏地图的对象
import { AcGameObject } from "./AcGameObject";
import { Wall } from "./Wall";
export class GameMap extends AcGameObject {
    // 构造函数的两个参数,  画布,画布的父元素用于动态修改画布的长宽
    constructor(ctx, parent) {  // ctx表示画布,parent表示画布的父元素
        // 先执行AcGameObject的构造函数
        super();
        this.ctx = ctx;
        this.parent = parent;
        this.L = 0;  // 一个单位的绝对长度
        this.rows = 13;  // 地图的行数
        this.cols = 13;  // 地图的列数

        this.inner_walls_count = 6;
        this.wall = [];
    }
    check_connectivity(sx, sy, tx, ty, g) {
        if (sx == tx && sy == ty) return true;
        g[sx][sy] = true;
        let dx = [-1, 0, 1, 0], dy = [0, 1, 0, -1];
        for (let i = 0; i < 4; i++) {
            let x = sx + dx[i], y = sy + dy[i];
            // 没有撞墙,可以走到终点
            if (!g[x][y] && this.check_connectivity(x, y, tx, ty, g)) {
                return true;
            }
        }
        return false;
    }
    create_walls() {
        //new Wall(0, 0, this);

        // 墙true,无墙false
        const g = [];
        for (let r = 0; r < this.cols; r++) {
            g[r] = [];
            for (let c = 0; c < this.cols; c++) {
                g[r][c] = false;
            }
        }
        // 四周加上墙
        for (let r = 0; r < this.rows; r++) {
            g[r][0] = g[r][this.cols - 1] = true;
        }
        for (let c = 0; c < this.cols; c++) {
            g[0][c] = g[this.rows - 1][c] = true;
        }
        // 创建随机障碍物,数量为inner_walls_count
        for (let i = 0; i < this.inner_walls_count; i++) {
            for (let j = 0; j < 1000; j++) {
                let r = parseInt(Math.random() * this.rows);
                let c = parseInt(Math.random() * this.cols);
                if (g[r][c] || g[c][r]) continue;
                if ((r == this.rows - 2 && c == 1) || (r == 1 && c == this.cols - 2)) continue;
                g[r][c] = g[c][r] = true;
                break;
            }
        }
        // 转换成JSON再转换回来
        const copy_g = JSON.parse(JSON.stringify(g));
        if (!this.check_connectivity(this.rows - 2, 1, 1, this.cols - 2, copy_g)) {
            return false;
        }
        for (let r = 0; r < this.rows; r++) {
            for (let c = 0; c < this.cols; c++) {
                if (g[r][c]) {
                    this.wall.push(new Wall(r, c, this));
                }
            }
        }
        return true;
    }
    start() {
        for (let i = 0; i < 1000; i++) {
            if (this.create_walls())
                break;
        }
    }
    update_size() {  //每一帧都更新边长
        // 动态求最小正方形边长
        // 取整数
        this.L = Math.min(this.parent.clientWidth / this.cols, this.parent.clientHeight / this.rows);
        this.ctx.canvas.width = this.L * this.cols;
        this.ctx.canvas.height = this.L * this.rows;
    }
    update() {     //每帧渲染一次
        this.update_size();
        this.render();
    }

    render() {      //渲染  
        // 画地图
        const color_even = "#AAD751", color_odd = "#A2D149";
        for (let r = 0; r < this.rows; r++) {
            for (let c = 0; c < this.cols; c++) {
                if ((r + c) % 2 == 0) {
                    this.ctx.fillStyle = color_even;
                } else {
                    this.ctx.fillStyle = color_odd;
                }
                // 左上角左边,明确canvas坐标系
                this.ctx.fillRect(c * this.L, r * this.L, this.L, this.L);
            }

        }
    }
}

游戏区域

components--->PlayGround.vue

<!-- 游戏区域 -->
<template>
    <div class="playground">
        <GameMap />
    </div>
</template>
 
<script>
import GameMap from "./GameMap.vue";

export default {
    components: {
        GameMap,
    }
}
</script>

<style scoped>
div.playground {
    width: 60vw;
    height: 70vh;
    margin: 40px auto;
    background-color: rgb(247, 248, 248);
}
</style>

地图组件 

GameMap.vue

<template>
    <!-- ref映射关联 -->
    <div ref="parent" class="gamemap">
        <!-- 画布 -->
        <canvas ref="canvas"></canvas>
    </div>
</template>
  
<script>
import { ref, onMounted } from "vue";
import { GameMap } from "@/assets/scripts/GameMap";

export default {
    setup() {
        let parent = ref(null);
        let canvas = ref(null);
        //组件挂载完之后,创建GameMap对象
        onMounted(() => {
            new GameMap(canvas.value.getContext("2d"), parent.value);
        });

        return {
            parent,
            canvas,
        };
    },
};
</script>
  
<style scoped>
div.gamemap {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>
  

 实体墙

scrips----->wall.js

// 实体墙
import { AcGameObject } from "./AcGameObject";
export class Wall extends AcGameObject {
    constructor(r, c, gamemap) {
        super();
        this.r = r;
        this.c = c;
        this.gamemap = gamemap;
        this.color = "#B37226";
    }
    update() {

        this.render();
    }
    render() {
        const L = this.gamemap.L;
        const ctx = this.gamemap.ctx;
        ctx.fillStyle = this.color;
        ctx.fillRect(this.c * L, this.r * L, L, L);
    }
}

 参考

项目实战——创建菜单与游戏页面(上)_游戏页面是如何实现的-CSDN博客​​​​​​​

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1445319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux ipvlan详解(l2、l3、l3s和bridge、private和vepa模式)

Linux ipvlan详解&#xff0c;测试l2、l3、l3s和bridge、private和vepa模式。 最近在看Docker的网络&#xff0c;看到关于ipvlan网络的介绍。查阅了相关资料&#xff0c;记录如下。 参考 1.图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN 2.IPVlan 详…

假如程序员也分等级……

本次考试有10道题&#xff0c;一题10分&#xff0c;做完后可查看段位等级。 1.请问复制粘贴用什么快捷键&#xff1f; A.CtrlV,CtrlC B.CtrlC,CtrlV 2.计算机里用的是&#xff08; &#xff09;进制&#xff1f; A.二 B.十 3.对于输出“Hello world”正确的一项是&#…

Oracle 几种行转列的方式 sum+decode sum+case when pivot

目录 原始数据&#xff1a; 方式一&#xff1a; 方式二&#xff1a; 方式三&#xff1a; unpivot的使用&#xff1a; 原始数据&#xff1a; 方式一&#xff1a; select t_name,sum(decode(t_item, item1, t_num, 0)) item1,sum(decode(t_item, item2, t_num, 0)) item2,s…

洗地机买什么品牌好?最好的洗地机品牌

对于双职工家庭来说&#xff0c;日常家务活是一个很大的难题。所以就要借助洗地机来提升生活质量&#xff0c;确实智能家电能够帮助日常家务减负。市面上的洗地机的品牌是真的很多&#xff0c;笔者今天带大家一起来看看什么洗地机品牌好用。 该如何挑选适合自己的家用洗地机 …

nginx2

mkdir /usr/local/develop cd /usr/local/develop 下载 wget http://nginx.org/download/nginx-1.17.4.tar.gz 解压文件 tar zxmf nginx-1.17.4.tar.gz 进入解压目录 cd nginx-1.17.4/ 安装编译工具及依赖库 都安装成功后再次执行会有下面提示 yum -y install gcc pcre-de…

C++入门学习(二十七)跳转语句—continue语句

当在循环中遇到continue语句时&#xff0c;它会跳过当前迭代剩余的代码块&#xff0c;并立即开始下一次迭代。这意味着continue语句用于跳过循环中特定的执行步骤&#xff0c;而不是完全终止循环。 直接看一下下面的代码更清晰&#xff1a; 与上一节的break语句可以做一下对比…

编译OpenSSL时报错,Can‘t locate IPC/Cmd.pm in @INC

编译OpenSSL 3.0.1时报错&#xff0c;错误信息如下 解决方法&#xff1a; 安装perl-CPAN yum install -y perl-CPAN进入CPAN的shell模式&#xff0c;首次进入需要配置shell&#xff0c;按照提示操作即可&#xff08;本人perl小白&#xff0c;全部选择默认配置&#xff0c;高…

WSL下如何使用Ubuntu本地部署Vits2.3-Extra-v2:中文特化修复版(新手从0开始部署教程)

环境&#xff1a; 硬&#xff1a; 台式电脑 1.cpu:I5 11代以上 2.内存16G以上 3.硬盘固态500G以上 4.显卡N卡8G显存以上 20系2070以上 本案例英伟达4070 12G 5.网络可连github 软&#xff1a; Win10 专业版 19045以上 WSL2 -Ubuntu22.04 1.bert-Vits2.3 Extra-v2:…

Packet Tracer - Configure IOS Intrusion Prevention System (IPS) Using the CLI

Packet Tracer - 使用CLI配置IOS入侵防御系统&#xff08;IPS&#xff09; 地址表 目标 启用IOS入侵防御系统&#xff08;IPS&#xff09;。 配置日志记录功能。 修改IPS签名规则。 验证IPS配置。 背景/场景 您的任务是在R1上启用IPS&#xff0c;扫描进入192.168.1.0网络…

django报错:Cannot use ImageField because Pillow is not installed

1、问题概述 ERRORS: accounts.User.avatar: (fields.E210) Cannot use ImageField because Pillow is not installed. HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "python -m pip install Pillow". System check identified 1 …

98.网游逆向分析与插件开发-网络通信封包解析-定位明文发送数据的关键函数

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目需求与需求拆解 通过上一个内容有了对网络通信架构有一个简单认识了解&#xff0c;对于我们重要的点是 组织数据 到 加密数据之间的过程&#xff0c;这个过程的数据我们是可以看懂的&#xff0c;…

Duilib List 控件学习

这是自带的一个示例; 一开始运行的时候List中是空的,点击Search按钮以后就填充列表框; 先看一下列表框列头是在xml文件中形成的; <List name="domainlist" bkcolor="#FFFFFFFF" ... menu="true"> <ListHeader height="24…

【MySQL进阶之路】好友推荐系统索引设计实战

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

ADSelfService Plus发布离线MFA功能,强化远程工作安全性

ManageEngine ADSelfService Plus推出离线多因素身份验证&#xff0c;提升远程工作安全性确保通过先进的验证方法对企业数据进行授权访问&#xff0c;无论时间、地点或连接问题如何允许远程用户安全进行身份验证&#xff0c;即使未连接到认证服务器或互联网使用高度安全的基于T…

###C语言程序设计-----C语言学习(12)#进制间转换,十进制,二进制,八进制,十六进制

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 计算机处理的所有信息都以二进制形式表示&#xff0c;即数据的存储和计算都采…

协议-TCP协议-基础概念04-可能发生丢包的位置-linux配置项梳理(TCP连接的建立和断开、收发包过程)

可能发生丢包的位置-linux配置项梳理&#xff08;TCP连接的建立和断开、收发包过程&#xff09;-SYN Flood攻击和防御原理 参考来源&#xff1a; 极客时间-Linux性能优化实战 极客时间-Linux内核技术实战课 到底是哪里发生了丢包呢&#xff1f; Linux 的网络收发流程 从图中…

【java】12:封装

面向对象编程三大特征 1.基本介绍 面向对象编程有三大特征&#xff1a;封装、继承和多态。 2.封装介绍 封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起&#xff0c;数据被保护在内部&#xff0c;程序的其它部分只有通过被授权的操作[方法]&am…

3秒实现无痛基于Stable Diffusion WebUI安装ComfyUI!无需重复安装环境!无需重复下载模型!安装教程

标题略有夸张的表达了接下来这一套确实很简单&#xff0c;相较于直接下载或者通过秋叶包更新而言。大大节省磁盘空间&#xff0c;和下载时间。 这篇教程不需要你有&#xff1a; 代码基础。都是复制粘贴就完事。魔法。 这篇教程默认你已经有&#xff1a; 1. 本地能够正常使用…

python+flask+django农产品供销展销电子商务系统lkw43

供销社农产品展销系统的设计与实现&#xff0c;最主要的是满足使用者的使用需求&#xff0c;并且可以向使用者提供一些与系统配套的服务。本篇论文主要从实际出发&#xff0c;采用以对象为设计重点的设计方法&#xff0c;因此在进行系统总体的需求分时借助用例图可以更好的阐述…

Ainx-V0.2-简单的连接封装与业务绑定

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于Ainx系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列…