创建菜单与游戏页面

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;// 下一帧执行steprequestAnimationFrame(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,无墙falseconst 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_countfor (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.hqwc.cn/news/465416.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目学习记录

项目开发 创建项目环境配置关联git新增模块项目启动打印地址日志使用httpclient进行idea内部控制台测试使用AOP拦截器打印日志 创建项目 创建一个空项目&#xff0c;并勾选下面选项 然后进入pom.xml中修改项目配置 根据这个链接选则&#xff0c;修改项目的支持版本 链接&#…

【精选】java多态进阶——多态练习测试

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

C++学习笔记 | 基于Qt框架开发实时成绩显示排序系统1

目标&#xff1a;旨在开发一个用户友好的软件工具&#xff0c;用于协助用户基于输入对象的成绩数据进行排序。该工具的特色在于&#xff0c;新输入的数据将以红色高亮显示&#xff0c;从而直观地展现出排序过程中数据变化的每一个步骤。 结果展示&#xff1a; 本程序是一个基于…

Linux--基础开发工具篇(2)(vim)(配置白名单sudo)

目录 前言 1. vim 1.1vim的基本概念 1.2vim的基本操作 1.3vim命令模式命令集 1.4vim底行命令 1.5 异常问题 1.6 批量注释和批量去注释 1.7解决普通用户无法sudo的问题 1.8简单vim配置 前言 在前面我们学习了yum&#xff0c;也就是Linux系统的应用商店 Linux--基础开…

C#,卢卡斯数(Lucas Number)的算法与源代码

1 卢卡斯数&#xff08;Lucas Number&#xff09; 卢卡斯数&#xff08;Lucas Number&#xff09;是一个以数学家爱德华卢卡斯&#xff08;Edward Lucas&#xff09;命名的整数序列。爱德华卢卡斯既研究了这个数列&#xff0c;也研究了有密切关系的斐波那契数&#xff08;两个…

【十四】【C++】list 的常见用法

list 的初始化和遍历 /*list的初始化和遍历*/ #if 1 #include <list> #include <vector> #include <iostream> #include<algorithm> using namespace std;void TestList1(){list<int> L1;list<int> L2(10, 5);vector<int> v{1,2,3,4…

【Tauri】(1):使用Tauri1.5版本,进行桌面应用开发,在windows,linux进行桌面GUI应用程序开发,可以打包成功,使用 vite 最方便

1&#xff0c;视频地址&#xff1a; https://www.bilibili.com/video/BV1Pz421d7s4/ 【Tauri】&#xff08;1&#xff09;&#xff1a;使用Tauri1.5版本&#xff0c;进行桌面应用开发&#xff0c;在windows&#xff0c;linux进行桌面GUI应用程序开发&#xff0c;可以打包成功&…

前端面试题——二叉树遍历

前言 二叉树遍历在各种算法和数据结构问题中都有广泛的应用&#xff0c;如二叉搜索树、表达式的树形表示、堆的实现等。同时也是前端面试中的常客&#xff0c;掌握好二叉树遍历算法对于一名合格的前端工程师来说至关重要。 概念 二叉树遍历&#xff08;Binary Tree Traversa…

synchronized关键字以及底层实现

目录 基本使用 底层实现 synchronized锁升级 对象的内存结构 ⅰ. 对象头 1. ① 运行时元数据 (Mark Word) (占64位) a. 哈希值 (HashCode) b. GC分代年龄 c. 锁状态标记 2. ② 类型指针: (Klass Point) (占 32位) ⅱ. 实例数据 ⅲ. 对齐填充 Moniter重量级锁 轻量…

Linux第46步_通过“添加自定义菜单”来学习menuconfig图形化配置原理

通过“添加自定义菜单”来学习menuconfig图形化配置原理&#xff0c;将来移植linux要用到。 自定义菜单要求如下: ①、在主界面中添加一个名为“My test menu”&#xff0c;此菜单内部有一个配置项。 ②、配置项为“MY TESTCONFIG”&#xff0c;此配置项处于菜单“My test m…

Python 函数式编程进阶:map、filter、reduce

Python 函数式编程进阶&#xff1a;map、filter、reduce 介绍map 函数作用和语法使用 map 函数Lambda 函数的配合应用 filter 函数作用和语法使用 filter 函数Lambda 函数的结合运用 reduce 函数作用和语法使用 reduce 函数典型应用场景 介绍 在函数式编程中&#xff0c;map、…

联想thinkpad-E450双系统升级记

早期笔记本联想thinkpad-E450双系统 大约16年花4000多大洋&#xff0c;买了一台thinkpad-E450屏幕是16寸本&#xff0c;有AMD独立显卡&#xff0c;i5cpu&#xff0c;4G内存。 . 后来加了一个同型号4G内存组成双通道&#xff0c; . 加了一个三星固态500G&#xff0c; . 换了一个…