吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5322|回复: 13
收起左侧

[Java 原创] 【web】纯JavaScript实现window经典纸牌游戏

[复制链接]
含笑阁 发表于 2019-3-20 23:59
本帖最后由 含笑阁 于 2019-3-21 10:53 编辑

JS
昨天刚好看到html5新功能中的拖放事件,于是心血来潮,想用这个功能做一个纸牌游戏。
目前有个小?Bug,不能同时拖动多张扑克;
测试地址:http://www.lingmx.com/poker/

接下来给大家说一下思路,以及实现的代码
先把最先单的CSS和HTML代码片段发出来吧,只有CSS和HTML的话,效果显示如下:
poker1.png
CSS代码片段:
[CSS] 纯文本查看 复制代码
                        body {
                                margin: 0;
                                padding: 0;
                                background: url(img/bg.png);
                        }

                        #main {
                                width: 100%;
                                height: 100%;
                        }

                        .nav {
                                width: 100%;
                                height: 200px;
                                display: flex;
                                justify-content: space-around;
                                align-items: center;
                        }

                        #allPoker,
                        #fourPokers {
                                display: flex;
                                justify-content: space-around;
                                align-items: center;
                        }

                        #fourPokers div,
                        #sevenPokers div,
                        #allPoker div {
                                width: 105px;
                                height: 150px;
                                margin: 0 20px;
                                box-sizing: border-box;
                                border: 2px solid rgba(255, 255, 255, 0.6);
                                border-radius: 5px;
                                cursor: pointer;
                                position: relative;
                        }

                        #fourPokers div img,
                        #sevenPokers div img,
                        #allPoker div img {
                                position: relative;
                                border-radius: 5px;
                        }

                        #allPoker div:nth-child(1).active:after {
                                content: "";
                                width: 105px;
                                height: 150px;
                                position: absolute;
                                left: 0;
                                top: 0;
                                background: url(img/01.png);
                        }

                        #sevenPokers {
                                display: flex;
                                justify-content: space-around;
                                align-items: center;
                        }

                        #fourPokers div img,
                        #sevenPokers div img,
                        #allPoker div img {
                                position: absolute;
                                left: 0;
                                top: 0;
                        }


HTML代码片段:
[HTML] 纯文本查看 复制代码
                <div id="main">
                        <!-- 顶部牌堆 -->
                        <div class="nav">
                                <!-- 左侧牌堆 -->
                                <div id="allPoker">
                                        <div class="active"></div>
                                        <div></div>
                                </div>
                                <!-- 右侧4个牌堆 -->
                                <div id="fourPokers">
                                        <div></div>
                                        <div></div>
                                        <div></div>
                                        <div></div>
                                </div>
                        </div>
                        <!-- 底部 7个牌堆-->
                        <div id="sevenPokers">
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>
                        </div>
                </div>


首先:说一下思路,网页整体分为三个关键位置
1.左上角主牌堆
2.右上角4个放置牌的区域
3.下方7个牌堆
我们需要床架一个随机生成没有重复的0~51的数保存到数组中【共52张扑克,没有大小王】,
然后把所有的图片对象保存到另一个数组中,通过第一个数组中保存的下标去取第二个数组中的图片,
这样就能保证每次取出的图片都是随机的


接下来就是按照游戏规则修改拖放事件和拖放释放事件

好了,接下来是正题
直接放出完整的代码吧:我在代码里加了详细?的注释应该可以看的明白
[JavaScript] 纯文本查看 复制代码
// 循环遍历将poker图片添加到数组中
                        var pokersList = [];
                        var flower = 0;
                        for (var i = 1; i <= 52; i++) {
                                var poker = new Image();
                                poker.src = "img/" + i + ".jpg"
                                poker.setAttribute("data-i",i-flower*13); //保存扑克的值
                                poker.setAttribute("data-flower",flower); //保存扑克的花色
                                pokersList.push(poker);
                                if(i%13==0){flower++}
                        }

                        console.log(pokersList);

                        //随机生成长度为52的数组 保存下标,0~51;
                        var pokerObjI = [];
                        for (var i = 0; pokerObjI.length < 52; i++) {
                                var num = Math.floor(Math.random() * 52);
                                var isRepeat = false;
                                for (var item of pokerObjI) {
                                        if (item == num) {
                                                isRepeat = true;
                                        }
                                }
                                if (!isRepeat) {
                                        pokerObjI.push(num);
                                }
                        }

                        // -----------------向所有牌堆中添加扑克-----------------
                        // 创建全局变量 pokerNum 来保存以添加过的最后一个下标
                        var pokerNum = 0;
                        // 获取牌堆对象
                        var allPoker = document.getElementById('allPoker').children[0];
                        // 向牌堆中插入24张扑克
                        for (var i = 0; i < 24; i++) {
                                allPoker.appendChild(pokersList[pokerObjI[i]]);
                                pokerNum++; //同时样poker的下标增加
                        }
                        // 向下方7个牌堆中分别保存 1,2,3,4,5,6,7张扑克(共28张)
                        // 获取7个牌堆对象
                        var sevenObj = document.getElementById('sevenPokers').children;
                        // console.log(sevenObj)
                        // 循环向牌堆中添加扑克
                        for (var i = 1; i <= 7; i++) {
                                for (var j = 1; j <= i; j++) {
                                        sevenObj[i - 1].appendChild(pokersList[pokerObjI[pokerNum]]);
                                        pokerNum++;
                                }
                        }

                        // ----------------为下方7个牌堆添加层叠样式-----------------
                        // 给除最后一张扑克外添加active样式
                        function addClass(){
                                for (var item of sevenObj) {
                                        var items = item.children;
                                        try{
                                                for(var j of items){
                                                        var src = j.getAttribute("data-src");
                                                        if(src !==null){j.src = src;j.removeAttribute("data-src")};
                                                }
                                        }catch(e){
                                                //TODO handle the exception
                                        }
                                        if (items.length > 1) {
                                                for (var i = items.length - 2; i >= 0; i--) {
                                                        items[i].setAttribute("data-src", items[i].src);
                                                        items[i].src = "img/01.png";
                                                }
                                        }
                                }        
                        }
                        
                        // 判断7个牌堆中如果有最后一个扑克均为背面,则让最后一个变为正面,
                        // 如果最后一个为正面,则什么都不改变
                        function changeClass(){
                                for (var item of sevenObj){
                                        var lastItem = item.children[item.children.length-1];
                                        var penultimate = item.children[item.children.length-2];
                                        if(item.children.length>0){
                                                if(penultimate==undefined){
                                                        if(lastItem.dataset.src!=null){
                                                                console.log(lastItem);
                                                                console.log(lastItem.src);
                                                                console.log(lastItem.dataset.src);
                                                                lastItem.src = lastItem.dataset.src;
                                                        }
                                                }else if(penultimate.src == lastItem.src){
                                                        // 如果倒数第二个扑克和倒数第一个扑克src相等,让最后一个变为正面
                                                        lastItem.src = lastItem.dataset.src;
                                                }
                                        }
                                }
                        }
                        
                        // 给扑克添加上外边距 让他们分开
                        function addMarginTop() {
                                for (var item of sevenObj) {
                                        var items = item.children;
                                        for(var i of items){
                                                i.removeAttribute("style");
                                        }
                                        if (items.length > 1) {
                                                for (var i = 1; i < items.length; i++) {
                                                        items[i].style.marginTop = i * 30 + "px";
                                                }
                                        }
                                }
                        }
                        
                        // 调用上方的函数
                        addClass();
                        addMarginTop();

                        // ----------在所有扑克分发结束后绑定事件----------

                        //为牌堆中poker绑定点击事件 [点击显示一张,全部显示完后再次点击让所有牌回到牌堆]
                        // 1.获取到所有牌堆中的扑克
                        var AllpokerObj = allPoker.getElementsByTagName('img');
                        // 2.获取牌堆展示的div
                        var AllpokerDiv = allPoker.nextElementSibling;
                        // 创建变量保存被拖动的扑克和展示区域当前已添加的扑克数
                        var thisPoker, pakerListNum;
                        // 创建变量保存当前被拖动扑克的花色和值
                        var thisI,thisFlower;
                        // 为牌堆添加点击事件
                        allPoker.onclick = function() {
                                // 将展示区域的所有扑克保存在list中
                                var pokerList = AllpokerDiv.getElementsByTagName('img');
                                // 创建变量保存展示区域扑克个数
                                pakerListNum = pokerList.length;
                                // console.log(pokerList);
                                if (AllpokerObj.length > 0) {
                                        AllpokerDiv.appendChild(AllpokerObj[AllpokerObj.length - 1]); //将最后一张扑克(最上方的),移动到展示区域
                                        if (AllpokerObj.length == 0) {
                                                allPoker.classList.remove('active')
                                        } //如果牌堆没有扑克了,去掉active样式(取消扑克背面样式)
                                } else {
                                        allPoker.classList.add('active') //为牌堆添加active样式
                                        for (var i = pakerListNum - 1; i >= 0; i--) {
                                                allPoker.appendChild(pokerList[i]); //循环遍历将展示区域扑克添加到牌堆中
                                        }
                                }
                                // console.log(pakerListNum);

                                // 为牌堆展示框中所有扑克绑定拖动事件  写在点击事件里,每次点击都更新
                                // 创建变量保存鼠标位置
                                var left, top;
                                for (item of pokerList) {

                                        item.ondragstart = function(e) {
                                                console.log("拖动开始")
                                                thisPoker = this;
                                                thisI = this.dataset.i;
                                                thisFlower = this.dataset.flower;
                                                //保存当前鼠标在扑克上的位置
                                                left = e.clientX - this.offsetLeft;
                                                top = e.clientY - this.offsetTop;
                                        }
                                        item.ondrag = function(e) {
                                                // console.log("拖动ing~")
                                                // 设置当前扑克的位置
                                                //this.style.position = "fixed"
                                                this.style.top = e.clientY - top + "px";
                                                this.style.left = e.clientX - left + "px";
                                        }
                                        item.ondragend = function() {
                                                console.log("拖动结束")
                                                // 移除之前添加的样式
                                                this.removeAttribute("style")
                                        }
                                }
                        }
                        // 为7个牌堆的最后一个扑克添加拖动事件
                        function addDrag(){
                                for (var item of sevenObj) {
                                        var list = item.children[item.children.length - 1];
                                        var left,op,style;
                                        if(list){
                                                list.ondragstart = function(e) {
                                                        console.log("拖动开始")
                                                        thisPoker = this;
                                                        thisI = this.dataset.i;
                                                        thisFlower = this.dataset.flower;
                                                        //保存当前鼠标在扑克上的位置
                                                }
                                                list.ondrag = function(e) {
                                                }
                                                list.ondragend = function() {
                                                        console.log("拖动结束")
                                                        // 移除之前添加的样式
                                                        //this.removeAttribute("style");
                                                        //this.setAttribute("style",style);
                                                }
                                        }
                                        
                                }                
                        }
                        addDrag();
                        // 为4个牌堆添加拖动释放事件
                        // 获取4个牌堆
                        var fourPokers = document.getElementById('fourPokers').children;
                        for (var item of fourPokers) {
                                item.ondragenter = function() {
                                        console.log("拖动进入")
                                }
                                item.ondragover = function(e) {
                                        e.preventDefault();
                                        console.log("拖动悬停")
                                }
                                item.ondragleave = function() {
                                        console.log("拖动离开")
                                }
                                item.ondrop = function() {
                                        console.log(this.children.length)
                                        // 当本牌堆里没有扑克时,只可放入A,即thisI为1的扑克
                                        if(this.children.length==0){
                                                // 判断当前拖动的扑克的值不等于1则停止运行 return
                                                if(thisI != 1){
                                                        console.log("只可放入A");
                                                        return;
                                                }
                                        }else{ // 当牌堆中有扑克时,先判断当前拖动扑克的值和花色,如果与牌堆中的花色不同and值不大于最后一个扑克1时,停止运行
                                                // 获取当前牌堆的data-i和data-flower
                                                var itemI = parseInt(this.dataset.i);
                                                var itemFlower = this.dataset.flower;
                                                if(thisFlower != itemFlower || (thisI - itemI) != 1){
                                                        console.log("仅可放入同花色且值仅能比当前值大1")
                                                        return;
                                                }
                                        }
                                        
                                        console.log("拖动释放")
                                        console.log(thisPoker);
                                        console.log(thisI);
                                        console.log(thisFlower);
                                        console.log(this);
                                        this.appendChild(thisPoker);
                                        this.setAttribute("data-i",thisI);
                                        this.setAttribute("data-flower",thisFlower);
                                        for(var i of this.children){
                                                i.removeAttribute("style");
                                        }
                                        addDrag();
                                        changeClass();
                                        // pakerListNum--;
                                }
                        }
                        
                        // 为下方7个牌堆添加拖动释放事件
                        for(var item of sevenObj){
                                item.ondragenter = function() {
                                        console.log("拖动进入")
                                }
                                item.ondragover = function(e) {
                                        e.preventDefault();
                                        console.log("拖动悬停")
                                }
                                item.ondragleave = function() {
                                        console.log("拖动离开")
                                }
                                item.ondrop = function() {
                                        console.log(this.children.length)
                                        if(this.children.length==0){
                                                // 当本牌堆里没有扑克时,只可放入K,即thisI为13的扑克
                                                // 判断当前拖动的扑克的值不等于1则停止运行 return
                                                if(thisI != 13){
                                                        console.log("只可放入K");
                                                        return;
                                                }
                                        }else{
                                                var thisItem = this.children[this.children.length-1];
                                                var itemI = parseInt(thisItem.dataset.i);
                                                var itemFlower = parseInt(thisItem.dataset.flower);
                                                if(thisFlower%2 == itemFlower%2 || itemI - thisI !=1){
                                                        console.log("只能放置不同的花色,并且值执行相差1")
                                                        return;
                                                }
                                        }
                                        console.log("拖动释放");
                                        this.appendChild(thisPoker)
                                        for(var i of this.children){
                                                i.removeAttribute("style");
                                        }
                                        addDrag();
                                        addMarginTop();
                                        changeClass();
                                        // pakerListNum--;
                                }
                        }


打包下载:https://www.lanzouj.com/i3hz4ih
puke.rar (746.98 KB, 下载次数: 47)

免费评分

参与人数 1热心值 +1 收起 理由
hohov + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

随风浅忆 发表于 2019-5-22 20:17
本帖最后由 随风浅忆 于 2019-5-22 20:19 编辑

我在楼主的基础上进行了部分修改
  • 结构分离:将css和js从HTML里分离为单个文件
  • 去除了左上角牌堆的背景图
  • 牌组数组的img预设为背面,在显示时将其翻面
  • 删除addClass()函数,在向下方七个牌堆添加牌时判断是否为最下一张,并将其翻为正面
  • 修改了牌堆点击事件内的牌堆翻面和恢复
  • 添加新变量thisList(Array),保存在下方牌堆拖动牌时的拖拽牌下方的牌
  • 在下方牌堆ondrop事件下判断thisList是否为空,若不为空则将其中的牌同时移动到目标牌堆

puke.rar

747.4 KB, 下载次数: 93, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
含笑阁 + 2 + 1 厉害了这个层主~

查看全部评分

yzy9952 发表于 2019-3-21 00:05
kamui 发表于 2019-3-21 00:12
有意思,js能干的是多,不过node.js性能不好啊……
caipubao 发表于 2019-3-21 00:12
感谢楼主分享
wzq0391 发表于 2019-3-21 00:18
xiexiegnexiang
dongtian123sss 发表于 2019-3-21 00:20
支持一下
头像被屏蔽
zero0226 发表于 2019-3-21 00:54
提示: 作者被禁止或删除 内容自动屏蔽
yangaiday 发表于 2019-3-21 01:36
大佬,厉害&#128077;
喂黑涩会的小姐 发表于 2019-3-21 07:27
没看明白,学习中,不太玩游戏
IceWind 发表于 2019-3-21 07:39
厉害了,竟然能用HTML5作出这游戏,膜拜……
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 10:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表