西安的电子商城网站建设网页设计实训报告300字

diannao/2026/1/20 1:16:42/文章来源:
西安的电子商城网站建设,网页设计实训报告300字,网站上点击图片局部放大如何做,雄县网站建设公司Typescriptvitesass手把手实现五子棋游戏#xff08;放置类#xff09; 下面有图片和gif可能没加载出来 上面有图片和gif可能没加载出来 导言 最近练习Typescript#xff0c;觉得差不多了#xff0c;就用这个项目练练手#xff0c;使用Typescript纯面向对象编程。 开源…Typescriptvitesass手把手实现五子棋游戏放置类 下面有图片和gif可能没加载出来 上面有图片和gif可能没加载出来 导言 最近练习Typescript觉得差不多了就用这个项目练练手使用Typescript纯面向对象编程。 开源地址 试玩地址试玩地址 (zou-hong-run.github.io) 代码地址zou-hong-run/dobang: Typescriptvitesass拖拽放置五子棋 (github.com) 视频演示地址https://www.bilibili.com/video/BV1JX4y1L7XS/ 功能介绍 用户将棋子放置在棋盘上首先将五颗棋子连成线的用户胜利 游戏功能 开始游戏用户开始交替放置棋子放置棋子后该棋子会被禁用直到对方下子方可解五子连成线胜利重新游戏 项目介绍 使用Typescriptvitesass构建项目 typescript:类型提示不要太爽。 vite:轻松编译打包项目减少配置时间 sass:简化css书写 项目搭建 使用vite初始化项目 这里使用vite作为脚手架搭建 因为可以很好的将Typescript和html等结合到一块 打包压缩更方便 支持热更新 你可以使用npmyarn或pnpm npm create vitelatestyarn create vitepnpm create vite这里我使用的pnpm pnpm create vite// 项目名√ Project name: ... gobang// 原生代码没有框架支持√ Select a framework: » Vanilla// 使用ts√ Select a variant: » TypeScriptcd gobang pnpm installpnpm run dev安装sass 方便书写scss-D装开发依赖 pnpm add sass -D项目目录结构 dist 最终打包文件 public 图片资源等 src 源码入口 css 样式 script ts代码放置 main.ts 代码主入口 index.html 网页文件 tsconfig.json ts配置文件 package.json 包管理文件 前端页面布局 index.html布局 游戏首页index.html #black_piece左边黑子#white_piece右边白子#container_center棋盘#restart 重新游戏 !doctype htmlhtml langzh​headmeta charsetUTF-8 /link relicon typeimage/svgxml href/vite.svg /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleTypescript五子棋/title/head​bodydiv idcontainerdiv idcontainer_lefth1黑棋/h1button idblack_piece/button/divdiv idcontainer_centerdiv idtitle五子棋对决等待白棋落子/divdiv idgame/div/divdiv idcontainer_righth1白棋/h1button idwhite_piece/button/divdiv idrestart classnonebutton/button/div/divscript typemodule src./src/main.ts/script/body​/htmlsass样式 src/css/style.scss 比原生css简直不要太舒服 use sass:math;​* {padding: 0;margin: 0;box-sizing: border-box;}​html,body {min-width: 660px;min-height: 660px;width: 100%;height: 100%;}​$centerWidthAndHeight: 660px;$leftAndRightWidth: calc((100% - $centerWidthAndHeight)/2);// $centerWidth: 100% - $leftAndRightWidth * 2;// $pieceWidthAndHeight:math.div(100%,1);$pieceWidthAndHeight: 60px;​.none{display: none !important;}#container {width: 100%;height: 100%;display: flex;text-align: center;user-select: none;​h1 {user-select: none;}​_left,_right {min-width: 100px;width: $leftAndRightWidth;height: 100%;display: flex;justify-content: center;align-items: center;background-color: #C6BA8A;}// 这里的样式共用#black_piece {width: $pieceWidthAndHeight;height: $pieceWidthAndHeight;background-image: url(../public/imgs/blackPiece.png);background-size: 100% 100%;border-radius: 50%;user-select: all;}​#black_piece:hover {border: 2px double white;}​#white_piece {width: $pieceWidthAndHeight;height: $pieceWidthAndHeight;background-image: url(../public/imgs/whitePiece.png);background-size: 100% 100%;border-radius: 50%;user-select: all;}​#white_piece:hover {border: 2px double black;}​​_center {width: $centerWidthAndHeight;height: 100%;background-image: url(../public/imgs/background.png);background-repeat: no-repeat;background-size: cover;​#title {background-color: #C6BA8A;// opacity: .9;height: calc(100% - $centerWidthAndHeight);}​#game {// user-select: all;width: $centerWidthAndHeight;height: $centerWidthAndHeight;position: relative;display: flex;flex-wrap: wrap;}}​#restart{width: 100%;height: 100%;position: absolute;display: flex;justify-content: center;align-items: center;background-color: rgba(133, 132, 132,0.5);button{width: 25%;height: 20%;background: url(../../public/imgs/restart.png);background-size: 100% 100%;}}}工具类封装 src/Utils.ts 此类封装了公用的静态方法 clone 克隆元素设置属性 export default class Utils {static clone(target: HTMLElement,options: Partial{width: string,height: string,draggable: boolean,userSelect: string,x:string,y:string}): HTMLElement {let { width, height, draggable, userSelect,x,y } options;let cloneNode target.cloneNode(true) as HTMLButtonElement;if (width) {cloneNode.style.cssText width:${width};}if (height) {cloneNode.style.cssText height:${height};;}cloneNode.draggable draggable as boolean;// 根据父元素的坐标记录该元素的坐标cloneNode.dataset.x x;cloneNode.dataset.y y;if (userSelect) {cloneNode.style.cssText user-select:${userSelect};}return cloneNode;​​}​}游戏逻辑 项目入口 main.ts 导入scss样式实例化Game类 import ./css/style.scssimport Game from ./script/Game​// 白子优先new Game()Game类 src/Game.ts 游戏控制类控制各个类的协调工作 初始参数 创建棋盘 new Board 创建黑/白棋子 new Piece 等待Board触发的回调函数 countPieceCallBack 传入最新棋子数和当前的放在棋盘的棋子 判断胜负 isWin 根据isPieceFullFive函数判断是否胜利 isPieceFullFive 判断落子点的四周是否五子连续 重新游戏功能 改变标题 import Board from ./Board;import Piece from ./Piece;​​export type countPieceCallBack (count: number, currentPiece: HTMLElement) voidtype plainArr ({posX: number;posY: number;name: string;} | {posX: number;posY: number;name: null;})[]​export default class Game {// 标题元素public titleEle:HTMLElement;// 白字优先public firstWhite: boolean;// 棋盘对象public board: Board;// 黑子对象public blackPiece: Piece;// 白子对象public whitePiece: Piece;​// 当前棋盘棋子数量public pieceCount: number;// 当前落子public currentPiece: HTMLElement | undefinedconstructor() {this.titleEle document.querySelector(#title)!;this.firstWhite true;// 白子优先this.board new Board(this.countPieceCallBack.bind(this)); // 初始化棋盘// 初始化白棋子this.blackPiece new Piece(black_piece, this.firstWhite);// 初始化黑棋子this.whitePiece new Piece(white_piece, this.firstWhite);// 刚开始为零this.pieceCount 0;}// 传给Board触发的回调函数countPieceCallBack(count: number, currentPiece: HTMLElement) {// board告诉game棋子数量变化了console.log(board计数, count);// 实时记录最新棋子数量this.pieceCount count// 交换顺序this.firstWhite !this.firstWhite;// 通知棋子修改显示状态this.blackPiece.setFirstWhite(this.firstWhite)this.whitePiece.setFirstWhite(this.firstWhite);// 记录当前棋子this.currentPiece currentPiece// 当前棋子是什么名字let currentPieceName this.currentPiece?.id;// 改变标题this.changeTitle(currentPieceName);// 判断胜负if(this.isWin()){if(currentPieceNameblack_piece){alert(黑子获胜!!!);this.changeBackGround(currentPieceName)}else{alert(白子获胜!!!)this.changeBackGround(currentPieceName)}this.addRestartPage()}}addRestartPage(){(document.querySelector(#restart)as HTMLDivElement).classList.remove(none);(document.querySelector(#restart button)as HTMLButtonElement).addEventListener(click,(){window.location.reload()})}changeBackGround(currentPieceName:string){let bodycontainer_center document.querySelector(#container_center) as HTMLDivElementif(currentPieceNameblack_piece){bodycontainer_center.style.background url(../imgs/blackWin.png)}else{bodycontainer_center.style.background url(../imgs/whiteWin.png)}}changeTitle(currentPieceName:string){this.titleEle.innerText (currentPieceNamewhite_piece?(等待黑子落子)-:(等待白子落子)-)总步数this.pieceCount;}// 判断胜负isWin():boolean{// 两种判断一种全盘判断一种判断当前落子及其周围是否连成五子// 这里判断当前落子地方及其周围是否连成五子即可if (this.pieceCount 8) {let allPiece this.board.getAllPiece();let dataset this.currentPiece?.dataset;let { x, y } dataset!;let currentPieceName this.currentPiece?.id;let currentPieceposX parseInt(x!);let currentPieceposY parseInt(y!);// 提纯allPiecelet plainArr Array.from(allPiece).map(item {let children item.children[0] as HTMLButtonElementif (children) {let name children.id;let { x, y } children.dataset;return {posX: parseInt(x!),posY: parseInt(y!),name}}return {posX: parseInt(x!),posY: parseInt(y!),name: null}})// 当前落子的位置let currentPiecePos {X: currentPieceposX,Y: currentPieceposY,name: currentPieceName!}// 判断是否五子// 竖直方向if(this.isPieceFullFive(currentPiecePos, plainArr,0,1)){return true;}// 横向if(this.isPieceFullFive(currentPiecePos, plainArr,1,0)){return true}// 45度向if(this.isPieceFullFive(currentPiecePos, plainArr,1,1)){return true}// 135度向if(this.isPieceFullFive(currentPiecePos, plainArr,-1,1)){return true}}if (this.pieceCount 255) {alert(平局);return true;}return false}// 检查从当前位置的竖向横向45度向135度向的棋子数量是否大于五isPieceFullFive(currentPiecePos: { X: number, Y: number, name: string }, plainArr:plainArr,directX:number,directY:number):boolean {let { X, Y, name } currentPiecePos;let tempPos {x:0,y:0};let count 0;// 从落点位置分为 正方向和反方向// 反方向for(let i1;i5;i){tempPos.x X - directX*i;tempPos.y Y - directY*i;if(!plainArr.find(itemitem.name nameitem.posX tempPos.xitem.posYtempPos.y)){break;}count;}// 正方向for(let i1;i5;i){tempPos.x X directX*i;tempPos.y Y directY*i;if(!plainArr.find(itemitem.name nameitem.posX tempPos.xitem.posYtempPos.y)){break;}count;}// if(count4){// 当前棋子count5 游戏胜利return true;}return false}}Board类 src/Board.ts 棋盘类控制棋盘格子生成 初始化棋盘参数 初始化棋盘 emitGameCountPiece Game传来的回调函数 initBoard 创建15*15的棋盘 addEventListenerSetGrid 给每个棋盘格子都监听放置事件棋子放置到网格才触发 addEventListenerSetPiece 只要有落子就会触发该函数触发Game传来的回调函数emitGameCountPiece getAllPiece 得到棋盘并且包括棋盘中的所有棋子 import Utils from ./Utilsimport {type countPieceCallBack} from ./Gameexport default class Board {// 棋盘行和列private row: number;private col: number;// 网页游戏区域宽高// 游戏区域private game: Element;private gameWidth: number;private gameHeight: number;// 棋盘网格中的单个元素宽高private oneGridWidth: numberprivate oneGridHeight: number// 记录棋盘中的棋子数量public pieceCount: number;// Game传过来的函数告诉game当前棋盘上的棋子数public emitGameCountPiece: countPieceCallBack;// 记录当前放置的棋子public crrentPiece:HTMLElement|undefined;constructor(emitGameCountPiece:countPieceCallBack) {this.row 15;this.col 15;this.game document.querySelector(#game)!;this.gameWidth this.game?.clientWidth!this.gameHeight this.game?.clientHeight!this.oneGridWidth this.gameWidth / this.rowthis.oneGridHeight this.gameHeight / this.colthis.pieceCount 0;this.emitGameCountPiece emitGameCountPiece;​this.initBoard()}initBoard() {this.initGrid()this.addEventListenerSetPiece()}// 初始化棋盘网格initGrid() {let fragment document.createDocumentFragment();for (let i 0; i this.col; i) {for (let j 0; j this.row; j) {// 添加网格let grid document.createElement(div);grid.style.cssText border:1px solid black;width:${this.oneGridWidth}px;height:${this.oneGridHeight}px;user-select:none;position:relative;grid.draggable false;grid.dataset.x j ;grid.dataset.y i ;​// 给每个网格监听放置棋子事件this.addEventListenerSetGrid(grid)// 给文档片段添加元素fragment.appendChild(grid);}}this.game.appendChild(fragment)}// 每一个网格都设置一个放置事件addEventListenerSetGrid(ele: Element) {let that this;// 我们可以看到对于被拖拽元素事件触发顺序是 dragstart-drag-dragend// 对于目标元素事件触发的顺序是 dragenter-dragover-drop/dropleave。ele.addEventListener(dragover, (e) {// e.stopPropagation()e.preventDefault()});// 防止一个网格放置多个棋子const disableSecondDrop function () {// 棋盘监听放子会加一所以这里我们减一that.pieceCount--;// 告诉Game类型that.emitGameCountPiece(that.pieceCount,that.crrentPiece!)alert(此处已经放置元素);return false;}// 一个网格放置一个棋子const drop function (e: Event) {let parent ele as HTMLElement;let parentWidth parent.style.width;let parentHeight parent.style.height;let x parent.dataset.x;let y parent.dataset.y;if (e instanceof DragEvent) {console.log(棋子放置在棋盘上,得到ID);let pieceId e.dataTransfer?.getData(ID);let pieceEle document.getElementById(${pieceId})!;// 克隆一个新的棋子let clonePiece Utils.clone(pieceEle,{width: parentWidth,height: parentHeight, draggable: false, userSelect: none,x:x,y:y});// 添加到网格中parent.appendChild(clonePiece!)// 记录该棋子的坐标that.crrentPiece clonePiece;// 禁止该网格放置多个元素parent.addEventListener(drop, disableSecondDrop)// 清除放置事件parent.removeEventListener(drop, drop)}}ele.addEventListener(drop, drop)​}// 监听棋子放置事件addEventListenerSetPiece() {this.game.addEventListener(dragover, (e) {e.preventDefault()})this.game.addEventListener(drop, () {console.log(棋盘监听到棋子放下);this.pieceCount;console.log(棋盘上的棋子数加一, this.pieceCount);// 告诉Game类 数量改变this.emitGameCountPiece(this.pieceCount,this.crrentPiece!)})}// 得到棋盘并且包括棋盘中的所有棋子getAllPiece(){let gameChild this.game.children;return gameChild;}​}Piece类 src/Piece.ts 棋子类控制棋子的各种属性 初始化棋子信息 addEventListenerDrag 给黑白棋子添加拖拽事件监听 togglePiece 切换黑白棋子放子顺序 setFirstWhite 修改当前黑白棋子放子顺序 ​export default class Piece {private piece: HTMLButtonElement;private firstWhite: boolean;public name: string;constructor(name: string, firstWhite: boolean) {this.name name;this.firstWhite firstWhite;this.piece document.getElementById(${name}) as HTMLButtonElement;this.addEventListenerDrag()this.togglePiece()}// 修改当前棋子状态setFirstWhite(value: boolean) {this.firstWhite value;this.togglePiece()}// 根据isBlack的值禁用左边或者右边棋盘togglePiece() {// 判断当前是黑棋还是白棋let isBlack this.name black_pieceif (isBlack) {// 黑棋白棋先手禁用黑棋this.firstWhite ? (this.piece.draggable false) : (this.piece.draggable true);this.firstWhite ? (this.piece.disabled true) : (this.piece.disabled false);this.firstWhite ? (this.piece.style.opacity 0.5) : (this.piece.style.opacity 1);console.log(黑棋先手,draggable:,this.piece.draggable,disabled:,this.piece.disabled,this.piece.style.opacity);​}else{// 白棋 白棋先手 显示白棋this.firstWhite ? (this.piece.draggable true) : (this.piece.draggable false)this.firstWhite ? (this.piece.disabled false) : (this.piece.disabled true);this.firstWhite ? (this.piece.style.opacity 1) : (this.piece.style.opacity 0.5);console.log(白棋先手,draggable:,this.piece.draggable,disabled:,this.piece.disabled,this.piece.style.opacity);}​}// 监听器棋子被拖拽addEventListenerDrag() {// 我们可以看到对于被拖拽元素事件触发顺序是 dragstart-drag-dragend// 对于目标元素事件触发的顺序是 dragenter-dragover-drop/dropleave。this.piece.addEventListener(dragstart, (e) {console.log(棋子开始被拖拽设置ID);if (e instanceof DragEvent) {e.dataTransfer?.setData(ID, (e.target as Element).id)}});this.piece.addEventListener(drag, (e) {// e.stopPropagation()e.preventDefault()});this.piece.addEventListener(dragend, (e) {if (e instanceof DragEvent) {// console.log(棋子被放置);}})}​}总结 练习本项目可以提高Typescript使用技巧理解面向对象知识提示编码能力项目还很有多不足请大家多多指教大佬们觉得不错的话请三连支持一下

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

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

相关文章

python 微信网站开发黄山自驾游旅游攻略

django ninja通过paginate装饰器即可进行分页。内置了两个分页管理器LimitOffsetPagination和PageNumberPagination,能够实现基本的分页要求。当内置分页器不满足要求时,可以继承PaginationBase进行扩展自己的分页管理器。 1 使用分页器 from ninja.pa…

网站的建设原始代码山西优化seo

一:基本概念 1.1 基数排序(桶排序)介绍 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是…

什么软件能把做的网站上传wordpress自定义表单插件

vue通过下标修改数组里面内容,同时通过下标修改数组对象里面的内容,然后页面数组更新了??? 项目里面一直都是知道vue通过下标修改数组里面内容是触发不了页面的更新的,需要用其他方式,当我写其…

网站开发客户需求wordpress如何实现用户注册

本文作者Balaji Viswanathan通过对Google、Apple、Facebook、Android、Openstack项目等案例进行分析,总结了企业在开源上的战略性选择,是很有可能帮助企业战胜对手的绝好手段。大多数公司通过使用开源软件获得了很多竞争上的优势,这一点毋庸置…

怎么用ps做网站超链接银川网站建设公司哪家好

我的需求是一个可以批量下载文件或文件夹的接口,下载一个文件就正常下载,下载多个文件或单个多个文件夹都压缩成zip下载 本来想的是直接用hutool里面的ziputil工具类就行,但是我这里报错的文件都是用随机字符串命名的,直接用ZipUt…

wordpress开发复杂网站wordpress恢复数据库文件

最近遇到很多用户都在跟德迅云反馈自己网站遇到攻击问题,有的是反馈自己的网站用户反应打开网站很卡甚至打不开,有的用户自己的网站服务器都无法连接上了。通过德迅云安全对用户反馈的问题进行详细查看分析后,给用户提供了安全SCDN方案&#…

商业网站设计与制作论文景区类网站

看了重排话剧《哗变》的首演。是根据美国剧作家诺尔曼沃克的小说《凯恩号哗变记》改编。1988年北京人艺曾演出,由著名演员朱旭主演。而这次出演的演员除冯远征外大都为新面孔(至少对我来说是),导演为任鸣,朱旭则作为艺…

tinkphp5网站开发论坛网站在线生成

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 鲸鱼优化算法(WOA) 4.1.1 包围猎物 4.1.2 螺旋式搜索 4.1.3 更新策略 4.2 K近邻(KNN)分类器 4.3 基于WOA的KNN分类特征选择算法 5.完…

深圳建站服务公司有下划线的网址是什么网站

首先建立.net Core API - empty 这个就不说了然后创建新的Controller记得添加路由[Route("api/Users")]然后在Nuget Packages安装 所需安装包这里是用mysql所以下载如下的mysqlSugarCore(切记不要忘记安装Mysql.Data)创建实例化class文件DbText.cs用于连接数据库&…

广州网站建设中心WordPress 4.7漏洞

1. RAID系统使用多块磁盘改进性能或可靠性,其中构建RAID0至少需要()个磁盘;RAID5阵列至少需要()个磁盘。 答:2 3 2. 请描述一下磁盘存储空间管理方法:成组链接法的数据结构、盘块回…

新媒体代运营谷歌搜索优化seo

在 Cypress 中的测试都是在前端运行的, 一些后端的操作是不可以直接调用的, 例如 fs, 但是可以通过 task 作为桥梁进行调用. 1. 在 cypress.config.js 中配置 e2e: {setupNodeEvents(on, config) {plugins(on, config);},2. 在 plugins/index.js 中实现 const fs require(&q…

呼和浩特做网站的wordpress app怎么登录注册

腾讯云服务器价格计算器可以一键计算出云服务器的精准报价,包括CVM实例规格价格、CPU内存费用、公网带宽收费、存储系统盘和数据盘详细费用,腾讯云百科txybk.com分享腾讯云价格计算器链接入口、使用方法说明: 腾讯云服务器价格计算器 打开腾…

如何做网站发产品销售西安网站建设qq群号

1.wind:返回桌面 2.wine:打开计算机 3.winx:打开Windows移动中心 4.设置桌面:设置–》个性化–》背景 5.设置主题:设置–》个性化–》主题(锁屏) 6.设置开始菜单 7.winp:选择投影 8.winl:锁屏 9.winr:打开运行…

贺州网站制作如何搭建服务器做网站

编程笔记 Golang基础 018 常量与变量 一、常量常量的定义iota特性 二、变量变量定义变量作用域零值与初始化类型转换注意事项 三、重要性 常量,就是在程序编译阶段就确定下来的值,而程序在运行时则无法改变该值。变量是程序的基本组成单位,用…

网站如何调用手机淘宝做淘宝客镇江建设网站的公司

以下脚本由杨良伟同学一手编写,我只是为了其他文章方便转载才放进自己的文章,以下有附件可以下载,将txt改成sh,赋予执行位,即可执行自动安装,忘转载者标明出处,谢谢。 杨良伟同学blog链接: http…

网站建设与网站维护织梦网站还原

阿里云申请证书,有个专门的免费的申请方式与普通证书是平级的功能; 访问服务器,判断apache是不是开启ssl功能,如果没有安装就安装它 [rootcentos ~]# rpm -qa | grep mod_ssl //什么没显示说明没装 yum install mod_ssl openssl …

长宁怎么做网站优化好红桥集团网站建设

正题 题目链接:https://www.luogu.com.cn/problem/CF1066F 题目大意 平面上有nnn个点,每个点在max(x,y)max(x,y)max(x,y)层,走第kkk层的点之前一定要先走前面层的点,求走完所有点的最短路。 解题思路 对于每一层来说,我们可以将…

做网站堵怕犯法吗公司的网站建设服务费

存储过程无法编译和抛掉!!我在一个项目组中与同事一起开发存储过程,碰到过其他人在调试存储过程时,我无法编译同一个存储过程的问题。但是,现在我使用pl/sql dev将其他的进程都杀掉后--包括在调…

本地电脑静态网站建设哪个网址可以看免费的

一.条件变量 条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等待另…

做设计在哪个网站找图片宝安画册设计公司

本节书摘来自华章出版社《R的极客理想—工具篇》一 书中的第2章,作者:张丹,更多章节内容可以访问云栖社区“华章计算机”公众号查看。 第2章 时间序列基础包 本章主要介绍了时间序列数据处理的3个工具包,帮助读者掌握时间序列在R语…