溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何用JavaScript制作大轉(zhuǎn)盤游戲

發(fā)布時(shí)間:2023-02-03 09:10:37 來(lái)源:億速云 閱讀:133 作者:iii 欄目:開(kāi)發(fā)技術(shù)

今天小編給大家分享一下如何用JavaScript制作大轉(zhuǎn)盤游戲的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

一、開(kāi)始前的準(zhǔn)備

首先就是確定產(chǎn)品需求,仔細(xì)一看,emmm,就是正常的一個(gè)大轉(zhuǎn)盤該有的東西,也沒(méi)啥特殊要求,唯一需要注意的是大轉(zhuǎn)盤的轉(zhuǎn)盤個(gè)數(shù)需要?jiǎng)討B(tài)變化,即用戶設(shè)置多少獎(jiǎng)品我就需要顯示多少塊區(qū)域。

既然要做大轉(zhuǎn)盤,不外乎三個(gè)步驟:

  • 畫出大轉(zhuǎn)盤

  • 把獎(jiǎng)勵(lì)放上去

  • 讓大轉(zhuǎn)盤滾起來(lái)

二、畫出大轉(zhuǎn)盤

畫出大轉(zhuǎn)盤底圖部分就不必多說(shuō)了,最難的部分在于把一個(gè)圓動(dòng)態(tài)平均分成N份,并讓其在底圖上正常顯示。

我采用的方法是:用戶選擇了多少獎(jiǎng)品(除2個(gè)獎(jiǎng)品以外)我就在底圖上生成多少個(gè)寬高為底圖50%的div,目的是使每個(gè)div的右下角正好與底圖的中心點(diǎn)重合(這里有個(gè)坑,看下去就知道了),接著計(jì)算出對(duì)應(yīng)的圓心角 angle = 360 / n ,然后將其形變后以右下角為圓心旋轉(zhuǎn)對(duì)應(yīng)的角度拼成一個(gè)圓形。其中,形變和旋轉(zhuǎn)分別采用skew與rotate進(jìn)行實(shí)現(xiàn)。

注:

  • skew形變的角度為(90 - angle)deg

  • 如果要給每一塊加上漸變色的話,由于使用了skew形變,所以要顯示從左到右的漸變的效果,就需要從原先正方形的底邊變到右邊,即:background: linear-gradient('45deg', color1, color2)

// 以下為N為8時(shí),用純JS寫的一個(gè)測(cè)試demo
const n = 8; // 獎(jiǎng)品數(shù)量
const circle = document.getElementById('circle');
for(let i = 0; i < n ; i++) {
    let item = document.createElement('div');
    item.className = `circle-item  circle-item-${n}`;
  	// n為2時(shí),旋轉(zhuǎn)原點(diǎn)不在右下角改為底部中點(diǎn),不需要skew形變,并且寬度不是50%而是100%
    if(n !== 2) {
      item.style=
        `transform: rotate(${i * angle}deg) skew(${90 - angle}deg);
         transform-origin: bottom right;
         background-color: ${colorList[i % colorList.length]}; //設(shè)置了每個(gè)格子的背景色,可以不設(shè)置
        `
    } else {
      item.style=
        `transform: rotate(${i * angle}deg);
         transform-origin: bottom;
         background-color: ${colorList[i % colorList.length]};
        `
    }
    circle.appendChild(item);
  }

如何用JavaScript制作大轉(zhuǎn)盤游戲

本以為算解決了一個(gè)難題,直到我開(kāi)始測(cè)試時(shí),發(fā)現(xiàn) n == 3時(shí)出現(xiàn)了奇怪的現(xiàn)象:

如何用JavaScript制作大轉(zhuǎn)盤游戲

好嘛,當(dāng) n == 3時(shí),只設(shè)置50%的寬高顯然并不能填充滿整個(gè)背景圖。于是更改了當(dāng) n != 2時(shí)的樣式,改為寬高的60%,并設(shè)置其初始位置往左和上各平移10%。

.circle-item {
    border: 1px solid;
    height: 60%;
    width: 60%;
    position: absolute;
    left: -10%;
    top: -10%;
}

如何用JavaScript制作大轉(zhuǎn)盤游戲

這樣乍一看是實(shí)現(xiàn)了平均分的問(wèn)題,但仔細(xì)一想還有一個(gè)問(wèn)題,那便是如果加上指針,指針永遠(yuǎn)是向上的,這樣看起來(lái)就怪怪的了,所以還需要將整個(gè)圖像進(jìn)行一個(gè)旋轉(zhuǎn),使初始指針默認(rèn)指向第一塊的中心位置。

旋轉(zhuǎn)角度為: (180 - angle) / 2。

如何用JavaScript制作大轉(zhuǎn)盤游戲

三、把獎(jiǎng)勵(lì)放上去

把獎(jiǎng)勵(lì)放上去我想到兩種方法:

1、給每個(gè)獎(jiǎng)勵(lì)生成一個(gè)與底部背景圖寬高一樣的正方形,然后將其對(duì)著中心點(diǎn)旋轉(zhuǎn)對(duì)應(yīng)的角度,將其一層層的放在底部背景圖上,即可完成。如下圖1所示,每一個(gè)正方形的大小都是與底部的背景圖的寬高是一樣的,只是將其進(jìn)行一個(gè)旋轉(zhuǎn)即可。(當(dāng)時(shí)以為不好顯示用戶抽中的扇形的部分,就沒(méi)采用這種方法,現(xiàn)在總結(jié)了才發(fā)現(xiàn)只需要將顏色填充在每個(gè)扇形中即可,不用填充在獎(jiǎng)勵(lì)背景上,如下圖2所示,應(yīng)該也是能實(shí)現(xiàn)的)

如何用JavaScript制作大轉(zhuǎn)盤游戲

圖1 每一層獎(jiǎng)勵(lì)的范圍

如何用JavaScript制作大轉(zhuǎn)盤游戲

圖2 總結(jié)時(shí)想到的實(shí)現(xiàn)方法

2、將獎(jiǎng)勵(lì)直接放在每一個(gè)扇形區(qū)域里面,這樣我就直接修改每個(gè)扇形的背景色即可。看上去很簡(jiǎn)單,但實(shí)際開(kāi)始操作了就發(fā)現(xiàn)了兩個(gè)問(wèn)題:

  • 由于每一塊方格是skew形變出來(lái)的,獎(jiǎng)勵(lì)直接放上去也會(huì)產(chǎn)生形變,需要將形變消除;

  • 獎(jiǎng)勵(lì)居中顯示很麻煩,到現(xiàn)在我也沒(méi)有找到可以套用的公式;

第一點(diǎn)解決起來(lái)較為簡(jiǎn)單,只需要將獎(jiǎng)勵(lì)進(jìn)行一個(gè)反向的skew變形,旋轉(zhuǎn)角度為:-(90 &ndash; (angle / 2))deg。 第二點(diǎn)我到現(xiàn)在也沒(méi)有找到可以套用的公式,是每一種給他寫了一個(gè)樣式居中的。(還好產(chǎn)品只要求2-6的獎(jiǎng)勵(lì)數(shù)量,不然可能就沒(méi)有這篇文章了,如果大家有好的方法也可以教教我)

兩種方法各有優(yōu)點(diǎn): 方法一的優(yōu)點(diǎn)是不需要將獎(jiǎng)勵(lì)進(jìn)行反向形變,怎么放上去就是怎么顯示; 方法二的優(yōu)點(diǎn)是獎(jiǎng)勵(lì)與扇形不分離,我不需要額外的添加太多的div來(lái)實(shí)現(xiàn)獎(jiǎng)勵(lì)正確顯示。

四、讓大轉(zhuǎn)盤滾起來(lái)

大轉(zhuǎn)盤到現(xiàn)在已經(jīng)完成了七七八八了,現(xiàn)在就差最后一步,讓其滾起來(lái),點(diǎn)擊一次后滾動(dòng)到對(duì)應(yīng)的位置然后停下。

采用的方法是給大轉(zhuǎn)盤添加一個(gè)旋轉(zhuǎn)的動(dòng)畫,突然想起來(lái) transform 中有 ease-in-out 這個(gè)過(guò)渡方法,即慢-快-慢的過(guò)渡效果,正好滿足我抽獎(jiǎng)所需,于是直接采用了這種方法。

這里有個(gè)小細(xì)節(jié),由于大轉(zhuǎn)盤上本來(lái)就設(shè)置了transform的動(dòng)畫效果,如果不想現(xiàn)在的旋轉(zhuǎn)動(dòng)畫覆蓋掉之前的動(dòng)畫,就需要單獨(dú)給動(dòng)畫加上一層div,放在大轉(zhuǎn)盤底圖的外邊一層。

const circle = 8; // 旋轉(zhuǎn)圈數(shù)
let circleAdd = 0; // 抽獎(jiǎng)次數(shù),每次抽完自增
let rotateAngle = 0; // 旋轉(zhuǎn)角度
let getPrizeIndex = 0; // 抽到的獎(jiǎng)品的index

在定義完上面的內(nèi)容之后計(jì)算需要旋轉(zhuǎn)的角度: rotateAngle = circle * 360 * circleAdd - angle * getPrizeIndex,將這個(gè)rotateAngle放入需要旋轉(zhuǎn)的style中即可完成旋轉(zhuǎn)。

這里走了兩次彎路,一次是沒(méi)有加上circleAdd,然后就發(fā)現(xiàn)第一次大轉(zhuǎn)盤會(huì)正常旋轉(zhuǎn),第二次開(kāi)始就不動(dòng)或者只往前滾不到360&deg;甚至往回滾!原因是因?yàn)槊恳淮谓ostyle賦新值的時(shí)候,由于已經(jīng)有旋轉(zhuǎn)的角度了,他會(huì)在你設(shè)置新的旋轉(zhuǎn)角度的時(shí)候從上一個(gè)旋轉(zhuǎn)角度開(kāi)始執(zhí)行動(dòng)畫。

第二次是我在寫計(jì)算公式的時(shí)候,想當(dāng)然的把上面的“-”寫成了“+”,想的是我先旋轉(zhuǎn)了circle * circleAdd圈,然后還要滾 getPrizeIndex 個(gè)獎(jiǎng)勵(lì)就是我需要顯示的獎(jiǎng)勵(lì),然后發(fā)現(xiàn)指針指向的獎(jiǎng)勵(lì)與我需要選擇的 getPrizeIndex 并不相符。仔細(xì)檢查了才發(fā)現(xiàn)雖然大轉(zhuǎn)盤旋轉(zhuǎn)是順時(shí)針?lè)较虻?,但是?jiǎng)勵(lì)的讀取方向應(yīng)該是逆向的,所以應(yīng)該是“-”而不是“+”。

以上就是“如何用JavaScript制作大轉(zhuǎn)盤游戲”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI