1 创建导航栏
在components 文件夹下创建组件: NavBar.vue
在template 下导入 bootstrap 模版
自己在bootstrap官网选择一个自己喜欢的样式
然后在App.vue页面导入我们新建的navbar
然后去浏览器 看 发现报错!!!哈哈哈哈
其实需要添加@popperjs/core依赖 刷新一下
然后页面就创建完成啦
然后我们改一改 改成自己喜欢的样子
然后我们就要添加路由啦
需要用到 5 个界面
pk + record + ranklist + user + 404
模版如下
在 router/index.js 下面定义网址
import { createRouter, createWebHistory } from 'vue-router';
import PkIndexView from '@/views/pk/PkIndexView';
import RankListIndexView from '@/views/ranklist/RankListIndexView';
import RecordIndexView from '@/views/record/RecordIndexView';
import UserBotsIndexView from '@/views/user/userbots/UserBotsIndexView';
import UserInfoIndexView from '@/views/user/userinfo/UserInfoIndexView';
const routes = [
{
path: "/",
name: "home",
redirect: "/pk/"
},
{
path: "/pk/",
name: "pk_index",
component: PkIndexView,
},
{
path: "/record/",
name: "record_index",
component: RecordIndexView,
},
{
path: "/ranklist/",
name: "ranklist_index",
component: RankListIndexView,
},
{
path: "/user/bot/",
name: "user_bot_index",
component: UserBotsIndexView,
},
{
path: "/user/info/",
name: "user_info_index",
component: UserInfoIndexView,
},
{
path: "/404/",
name: "404",
component: NotFound,
},
{
path: "/:catchAll(.*)",
redirect: "/404/",
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
同时在NavBar里修改herf
在NavBar下修改:把 换成
对战
实现每个页面的框 由于这几个页面都需要用到边框,所有我们可以把这个公共的部分作为一个组件 ContentField.vue
创建好组件后、我们可以在不同的界面引入组件,例如在聊天界面:
3. 实现地图
地图特征:
1 大小:13 * 13
2 地图中心对称,边缘是是墙,左下角和右下角生成两条蛇,且左下角和右下角连通
3 地图上会随机生成不同的障碍物。
绘制游戏区域
所有的static文件都放在 assets下面
在 assets 目录下新建文件夹 命名为 scripts 新建一个游戏类 名字为 : AcGameObject.js
requestAnimationFrame(func)
该函数会在下次浏览器刷新页面之前执行一次,通常会用递归写法使其每秒执行60次func函数。调用时会传入一个参数,表示函数执行的时间戳,单位为毫秒。
例如:
let step = (timestamp) => { // 每帧将div的宽度增加1像素
let div = document.querySelector('div');
div.style.width = div.clientWidth + 1 + 'px';
requestAnimationFrame(step);
};
requestAnimationFrame(step);
const AC_GAME_OBJECTS = [];
export class AcGameObject{
constructor(){
AC_GAME_OBJECTS.push(this);
this.timedelta = 0;
this.has_called_start = false;
}
start(){// 只执行一次
}
update(){ //每一帧执行一次
}
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);
}
requestAnimationFrame(step);
实现地图类:GameMap.js
import { AcGameObject } from "./AcGameObject";
export class GameMap extends AcGameObject{
constructor(ctx,parent){
super();
this.ctx = ctx;
this.parent = parent;
this.L = 0;
}
start(){
}
update(){
}
render() {
}
}
绘制游戏区域 在 pk 界面创建一个游戏区域,用来显示对战。
在 commponts 写一个组件: PlayGround.vue
然后在 pk_index 中引入这个
因为在 pk 界面可能还包含记分板等不同的东西。所以开一个新组件存放别的类型的组件 GameMap.vue
在 PlayGround.vue 中引入 GameMap.vue
在 GameMap.vue 中添加 canvas
至此 地图初步形成
随着窗口大小的变化 我们的地图也应该变化 保证它是一个正方形
import { AcGameObject } from "./AcGameObject";
export class GameMap extends AcGameObject{
constructor(ctx,parent){
super();
this.ctx = ctx;
this.parent = parent;
this.L = 0;
this.rows = 13;
this.cols = 13;
}
start(){
}
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() {
this.ctx.fillStyle = "green";
this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);
}
}
如何让区域居中 — > 在GameMap.vue中添加
div.gamemap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
奇偶显示正方形区域内的小格子:
import { AcGameObject } from "./AcGameObject";
export class GameMap extends AcGameObject{
constructor(ctx,parent){
super();
this.ctx = ctx;
this.parent = parent;
this.L = 0;
this.rows = 13;
this.cols = 13;
}
start(){
}
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_eve = "green",color_odd = "#55afa9";
for(let r = 0;r
设计墙
在 scripts 新建一个 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 = "#0f171f";
}
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);
}
}
修改 GameMap.js , 引入 Wall
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.wall = [];
}
start(){
this.create_walls();
}
create_walls(){
墙 true 无 false
const g = [];
for(let r = 0;r
生成地图 修改 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.wall = [];
}
start(){
this.create_walls();
}
create_walls(){
墙 true 无 false
const g = [];
for(let r = 0;r
使两个块连通 使用 flood fill 算法
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.wall = [];
}
start(){
for(let i = 0;i<1000;i++){
if(this.create_walls()){
break;
}
}
}
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(){
墙 true 无 false
const g = [];
for(let r = 0;r
这样就能保证 游戏可以进行下去啦
不要忘记把代码 上传到云端哟~~