3.1 创建菜单与游戏页面(上)
目录
- 简介
- 实现导航栏
- 创建一个组件NavBar
- router
- router-link
- bootsrap 卡片
- 实现游戏地图
简介
这节课只涉及前端知识
bootsrap是让程序员实现美工的效果
建议先不跟着敲代码,可以先写笔记
工欲善其事,必先利其器;
启动脚手架 ,powershell中使用 vue ui
上节课实现前端最终的效果,如下
实现导航栏
分析页面:
网站导航栏都一样,先实现导航栏组件NavBar.vue
;接在在bootstrap找到一个合适的导航栏模板前端代码;粘贴到标签中
导航栏都是一样的,不怎么改变,因此可以把导航栏提取出来,作为一个组件,复用。
创建一个组件NavBar
在App.vue中import NavBar from './components/NavBar.vue'
利用bootsrap来快速实现
https://v5.bootcss.com/docs/components/navbar/
导航栏分析:
对应要写的各个页面,vue文件,推荐在views文件夹创建对应的文件夹。每个页面包含三个标签
router
知识点1:写完每个页面,需要和地址url关联起来 ;会使用到router路由组件。
<router-view>
会自动根据网址来变。定义的方式在router/index.js文件定义;
router-link
知识点2:实现点击每个导航栏,填写
<a href>
标签就跳转相应页面;
但是页面会重新刷新,前后端分离为了不让页面刷新;在NavBar.vue页面使用router-link
标签,代替<a href>
<router-link class="navbar-brand" :to="{ name: 'home' }">King of Bots</router-link>
bootsrap 卡片
知识点3:内容页面使用card,在bootstrap框起来-
bootsrap 网址:https://v5.bootcss.com/docs/components/card/
每个页面的内容都要使用card框起来。会发现这个框是公共的部分。因此单做一个组件ContentField.vue
<template><!-- 这可以当作公共内容,实现一个白框 --><div class="container"><div class="card"><div class="card-body"><!-- 框内填充的内容写在slot里面 --><slot></slot> </div></div></div>
</template><script>
</script><style>
div.content-field {margin-top: 20px;
}
</style>
之后把每个页面使用这个组件就可以。
例如,NotFound页面先引入组件;
<template><ContentField>404 Not Found</ContentField>
</template><script>import ContentField from '../../components/ContentField.vue'export default {components: {ContentField}
}
</script><style>
</style>
另外一个功能就是点击每个导航栏,显示聚焦效果,高亮;
在标签里面加active;
点击那个页面,使得哪个栏高亮;
方法:
用到userRoute
API; 在NavBar中。
import { useRoute } from "vue-router"
// 实时计算
import { computed } from "vue"export default {setup() {const route = useRoute();//获得当前页面的名称let route_name = computed(() => route.name)return {route_name}}
}
获取之后怎样使用?
需要在<router-link >
里面加:
表达式,写法如下;
<router-link :class="route_name == 'pk_index' ? 'nav-link active' : 'nav-link'" :to="{ name: 'pk_index' }">对战</router-link>
实现游戏地图
13*13 的地图,周围一圈都是墙,里面有些随机是墙。保证从左下角能够走到右上角。
生成合法地图,每次刷新都可以生成新的地图。
游戏里面怎移动的?
游戏动画的原理;
假设每秒刷新60次,每秒画面渲染60次,60帧;每一帧的位置在哪里,放60张图片就会显示物体在移动;
需要写一个基类(工具),实现公共的功能;移动的物体。
每秒刷新60次;每个物体都需要60次;
代码脚本放到assest文件、里面
每一帧都要渲染一次
移动的基类:
const AC_GAME_OBJECTS = [];export class AcGameObject {constructor() {AC_GAME_OBJECTS.push(this);// 移动的速度涉及到时间间隔,每一帧执行的额时间不一定是均匀的this.timedelta = 0;this.has_called_start = false;}start() { //只执行一次}upadate() { //每帧执行一次,除了第一帧之外}on_destroy() { //删除之前执行一些函数}// 语法看不懂很正常,抄一遍就会写了// 删除当前对象destroy() {this.on_destroy();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;// 辅助变量,上依次执行的时刻const step = timestamp => {// 遍历所有的物体,所有对象for (let obj of AC_GAME_OBJECTS) {if (!obj.has_called_start) {obj.has_called_start = true;obj.start();} else {obj.timedelta = timestamp - last_timestamp;obj.update();}}last_timestamp = timestamp;// 每一帧都执行这个函数requestAnimationFrame(step)
}
// 这个函数会在下一帧刷新的时候,一般浏览器默认刷新60次,传入一个函数
requestAnimationFrame(step)
墙或者障碍物每一帧都需要渲染一遍;
游戏里面每一个组件都是一个类;
创建地图类:
游戏的地图随着浏览器界面的变化,会自动发生界面变化;所以距离在写的时候不要使用绝对距离,而要使用相对距离。
整个地图单位是13x13
在PK界面,内容框没有用,直接删区,需要把地图界面显示到这个页面;
可以写一个组件,让游戏地图显示在这个区域;
PlayGroud.vue
playground
<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;/* 删掉背景 *//* background: lightblue; *//* 距离上下左右四个方向的距离 */margin: 40px auto;
}
</style>
需要在PkIndexView.vue
页面把playground
引入
之后对局页面会显示方框,方框会随着浏览器大小自动变化使其变为正方形;
创建一个板子GameMap.vue
首先需要在PlayGround.vue
引入GameMap.vue
plyground
GameMap.vue
<template><div ref="parent" class="gamemap"><!-- 画布 --><canvas ref="cannas"></canvas></div>
</template><script>
import { GameMap } from "@/assets/scripts/GameMap";
import { ref, onMounted } from 'vue'export default {setup() {let parent = ref(null);let canvas = ref(null);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>
MDN 前端资料网站
接下来全程写GameMap.js文件~
需要求被这个方框包裹的最大面积的方块;
数组坐标系 ,往下是行,往右是列
canva坐标系颠倒了 横着的是行x 竖着的是列y
课后一定要抄代,而不是复制代码,一个字母一个字母。
这节课实现结果如下:
代码保存一下
打开kob这个项目文件夹,打开git bash
$ git status
$ git add .
$ git commit -m “实现了导航栏+对战页面的地图和障碍物”
$ git push
学会浏览器调错;
GameMap.js
import { AcGameObject } from "./AcGameObject"; // 先引入刚才写的移动基类
import { Wall } from "./Wall";export class GameMap extends AcGameObject {constructor(ctx, parent) {super();this.ctx = ctx;this.parent = parent;this.L = 0; //地图的距离设置为绝对单位this.rows = 13;this.cols = 13;this.inner_walls_count = 20;this.walls = [];}// flood_fill算法 判断是否连通check_connectivity(g, sx, sy, tx, ty) {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(g, x, y, tx, ty)) {return true;}}return false;}create_walls() {// new Wall(0, 0, this);const g = [];for (let r = 0; r < this.rows; 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;}// 创建随机障碍物for (let i = 0; i < this.inner_walls_count / 2; 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;}}const copy_g = JSON.parse(JSON.stringify(g));if (!this.check_connectivity(copy_g, this.rows - 2, 1, 1, this.cols - 2)) {return false;}for (let r = 0; r < this.rows; r++) {for (let c = 0; c < this.cols; c++) {if (g[r][c]) {this.walls.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 = parseInt(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() {// this.ctx.fillStyle ='green';// this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.vanvas.height);const color_event = "#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_event;} else {this.ctx.fillStyle = color_odd;}// 画矩形,注意这里与与正常坐标系的坐标是相反的this.ctx.fillRect(c * this.L, r * this.L, this.L, this.L)}}}}
这节课效果如下,地图和蛇已经完成
3.1 创建菜单与游戏页面(上)相关推荐
- SpringBoot项目——创建菜单与游戏页面
SpringBoot项目--vue 实现游戏页面 回顾: SpringBoot项目--配置git环境与项目创建 文章目录 SpringBoot项目--vue 实现游戏页面 vue 实现前端页面--We ...
- 项目实战——创建菜单与游戏页面(上)
目录 PS:整篇文章全是实现前端的工作,如果大家不了解vue3,建议补一下前置知识~~ 一.整体框架 二.实现导航栏 三.导航栏中实现页面跳转 四.实现地图 五.实现墙体 六.生成障碍物 PS:整篇文 ...
- 项目实战——创建菜单与游戏页面(下)
目录 一.整体框架 二.修改地图为中心对称 三. 画蛇 四.实现蛇的移动 五.读取键盘的操作 六.美化蛇和检测非法逻辑 一.整体框架 二.修改地图为中心对称 如果两条蛇,同时走到相同的格子,会造成平局 ...
- 3.2 创建菜单与游戏页面(下)
目录 修改地图长宽 画蛇 结果 这节课是在上节课的基础上, 画蛇在图中. 先启动vue的脚手架, vue ui 修改地图长宽 上节课的问题:地图大小是13x13的,初始的时候,假如两条蛇起始的坐标为( ...
- UE4 UMG入门——创建和显示游戏菜单
01 设置UMG UMG 是依赖于一些模块的,需要添加这些模块到"工程名.Build.cs"中. 在"HowTo_UMG.Build.CS",添加"U ...
- 如何在Web页面上直接打开、编辑、创建Office文档 (转载)
有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在IE中被打开那样.想想这个问题应该很多人 ...
- [ZZ]如何在Web页面上直接打开、编辑、创建Office文档
[作者:kaneboy,来源:博客堂] 有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在 ...
- 公众号创建菜单报错40001及菜单出现在先前公众号上的问题
问题:在创建菜单时出现不定时的40001错误及菜单出现在先前公众号上问题(前提:APPID和APPSECRET都使用的新公众号的). 在创建公众号菜单时,报错40001 看代码是access_toke ...
- 在页面上根据数据,动态创建表格
在页面上根据数据,动态创建表格 var arr = [ { name: 'Jack', age: 18, gender: '男' },{ name: 'Rose', age: 20, gender: ...
最新文章
- SQL--(MyBatis 实战)
- Verilog_Day2
- 如何打造高性能Web应用
- idea打印sql的插件_[Mybatis]-[基础支持层]-插件-自定义简易SQL打印插件
- python多线程共享全局变量_Python多线程-共享全局变量
- 基本STRUTS标签-学习笔记-Bean标签
- 从零开始学Android!渣本毕业两年经验,附超全教程文档
- Ubuntu将推桌面美化计划促市场份额提升
- 大连最快的dns服务器设置,大连联通50m宽带,本地dns
- android 动态表情包,搞笑斗图动态表情包
- FastDFS文件服务器升级内置nginx版本
- 车牌号正则表达式(含新能源车牌)
- 什么是GPU加速,如何使用GPU加速,GPU加速的缺点
- 以太网芯片MAC和PHY
- python编写12306窗体抢票软件(二)
- vivo手机关闭广告
- 电脑如何分盘、合盘?关于硬盘的分盘,你所不知道的那些事情
- 第二周(9.14-9.20)学习任务报告
- “深度学习“汉字国标码GB2312
- 指纹图片调对比度 c语言,手动调整图片打印深浅(亮度/对比度 Windows OS)