目录

  • 简介
  • 实现导航栏
    • 创建一个组件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 创建菜单与游戏页面(上)相关推荐

  1. SpringBoot项目——创建菜单与游戏页面

    SpringBoot项目--vue 实现游戏页面 回顾: SpringBoot项目--配置git环境与项目创建 文章目录 SpringBoot项目--vue 实现游戏页面 vue 实现前端页面--We ...

  2. 项目实战——创建菜单与游戏页面(上)

    目录 PS:整篇文章全是实现前端的工作,如果大家不了解vue3,建议补一下前置知识~~ 一.整体框架 二.实现导航栏 三.导航栏中实现页面跳转 四.实现地图 五.实现墙体 六.生成障碍物 PS:整篇文 ...

  3. 项目实战——创建菜单与游戏页面(下)

    目录 一.整体框架 二.修改地图为中心对称 三. 画蛇 四.实现蛇的移动 五.读取键盘的操作 六.美化蛇和检测非法逻辑 一.整体框架 二.修改地图为中心对称 如果两条蛇,同时走到相同的格子,会造成平局 ...

  4. 3.2 创建菜单与游戏页面(下)

    目录 修改地图长宽 画蛇 结果 这节课是在上节课的基础上, 画蛇在图中. 先启动vue的脚手架, vue ui 修改地图长宽 上节课的问题:地图大小是13x13的,初始的时候,假如两条蛇起始的坐标为( ...

  5. UE4 UMG入门——创建和显示游戏菜单

    01 设置UMG UMG 是依赖于一些模块的,需要添加这些模块到"工程名.Build.cs"中. 在"HowTo_UMG.Build.CS",添加"U ...

  6. 如何在Web页面上直接打开、编辑、创建Office文档 (转载)

    有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在IE中被打开那样.想想这个问题应该很多人 ...

  7. [ZZ]如何在Web页面上直接打开、编辑、创建Office文档

    [作者:kaneboy,来源:博客堂] 有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在 ...

  8. 公众号创建菜单报错40001及菜单出现在先前公众号上的问题

    问题:在创建菜单时出现不定时的40001错误及菜单出现在先前公众号上问题(前提:APPID和APPSECRET都使用的新公众号的). 在创建公众号菜单时,报错40001 看代码是access_toke ...

  9. 在页面上根据数据,动态创建表格

    在页面上根据数据,动态创建表格 var arr = [ { name: 'Jack', age: 18, gender: '男' },{ name: 'Rose', age: 20, gender: ...

最新文章

  1. SQL--(MyBatis 实战)
  2. Verilog_Day2
  3. 如何打造高性能Web应用
  4. idea打印sql的插件_[Mybatis]-[基础支持层]-插件-自定义简易SQL打印插件
  5. python多线程共享全局变量_Python多线程-共享全局变量
  6. 基本STRUTS标签-学习笔记-Bean标签
  7. 从零开始学Android!渣本毕业两年经验,附超全教程文档
  8. Ubuntu将推桌面美化计划促市场份额提升
  9. 大连最快的dns服务器设置,大连联通50m宽带,本地dns
  10. android 动态表情包,搞笑斗图动态表情包
  11. FastDFS文件服务器升级内置nginx版本
  12. 车牌号正则表达式(含新能源车牌)
  13. 什么是GPU加速,如何使用GPU加速,GPU加速的缺点
  14. 以太网芯片MAC和PHY
  15. python编写12306窗体抢票软件(二)
  16. vivo手机关闭广告
  17. 电脑如何分盘、合盘?关于硬盘的分盘,你所不知道的那些事情
  18. 第二周(9.14-9.20)学习任务报告
  19. “深度学习“汉字国标码GB2312
  20. 指纹图片调对比度 c语言,手动调整图片打印深浅(亮度/对比度 Windows OS)

热门文章

  1. 【自问自答】armhf/arm64/aarch64异同学习
  2. docker 是否自动创建主机挂载目录(先看粗体字)
  3. 使用python爬取付费音乐
  4. 把 Number 四舍五入为指定小数位数的数字
  5. 全球及中国吊顶行业研究及十四五规划分析报告
  6. 人像后期的系统性后期处理
  7. 卸料装置弹性零件的计算方法_弹性卸料装置的基本零件包括
  8. 短信群发限制,你想了解的都在这里
  9. 5款非常好用,劲爆得很的软件
  10. ElasticSearch 集群搭建