“I am participating in the nuggets Community Game Creativity Submission Contest. For details, please see: Game Creativity Submission Contest.”

App development framework: React Runtime platform: browser, mobile terminal gitee Address: Yain/Spell-game (gitee.com) Welcome to experience

preface

XDM, last time was years ago, sure enough, there are rewards to have productivity 😂, this time the idea comes from ZType, it is a great word shooting game, have never played can experience, with the game engine Impack, by comparison, this is very low, used to use Vue, now the new team only react, Let’s just get acquainted this time. May write water, interested big guy can CR give advice.

Game ideas

1. Initial configuration and customizable configuration of the game 2. Dom selection (changing the style of each frame) or Canvas (drawing each frame) 3. Logic change style and determination of various boundary cases

Particle background

Use the React-TSPArticles library to configure data.

import Particles from "react-tsparticles"; import options from '.. /assets/configData' <Particles id="tsparticles" options={options} />Copy the code

Menu configuration and data model

The menu

<div className='menuClass' style={{display:fix? 'the flex' : 'none'}} > < span onClick = {() = > palyAudio ()} > voice: {isPaly? '✅':'❎'}</span> <span> <input type='number' min="0.1" Max ="5" step="0.1" defaultValue={_target_config. speed} onBlur={(e)=>{ SetItem ('speed',e.target.value)}}> </input> </span> <span> Number(e.target.value)>=0.3&& localstorage.setitem ('speed',e.target.value)}}> <input type='number' min="1" max="6" step="1" defaultValue={_MAX_TARGET} onBlur={(e)=>{ Number(e.target.value)>=1&&Number(e.target.value<=6&&localStorage.setItem('_MAX_TARGET',e.target.value) }}> </input> </span> <span> <input type=' placeholder 'placeholder=' placeholder' onBlur={(e)=>{localStorage.setItem('_DICTIONARY',e.target.value)}}> </input> </span> < span > record: {localStorage. The getItem (' _HIGHEST_RECORD ') | | 0} < / span > < span > Tips: out-of-focus submit < / span > < / div > duplicate codeCopy the code

data

Initial global data: target quantity, falling speed, thesaurus

//assest/word // STR = link search word: https://blog.csdn.net/a1809032425/article/details/83961550 let wordArr = str.replace(/\W+/g,',') wordArr = [...new Set(wordArr.split(','))] wordArr = wordArr.filter(item=>item.length>1) export {wordArr} import {wordArr} from '.. /assets/word' const getItem = (key) => Number(localStorage.getItem(key)) const _MAX_TARGET = getItem('_MAX_TARGET')||3; / / picture a up to target in the const _TARGET_CONFIG = {speed: the getItem (' speed ') | | 1,}; // Drop speed const wordsPool = localstorage.getitem ('_DICTIONARY')? .split(','); Const _DICTIONARY = wordspool. length>1? 'wordsPool':wordArr;Copy the code

Page initial target data

  • Left: Each different index is generated randomly in different intervals so that there is as little overlap between words as possible
  • Top: To make the height of each word separate at the beginning, so that each word is generated at different heights, the number 3 is between [-120,60]
Const wordsPool = _dictionary.concat ([]).sort(()=>0.5- math.random ())// unsorted //text word left left offset top top offset let targetArr = wordsPool.splice(0,_MAX_TARGET).map((item,index)=>{ return{ txt:item, left:Math.floor((Math.random()+index)*340/_MAX_TARGET), top:Math.floor((Math.random() - 1)*_MAX_TARGET +1)*60, TargetArr = targetarr.map ((item,index)=>({... item, direction:item.left<175? 1:-1})) const [state,setState] = useState({targetArr, score: 0,// score: 0,// score: 0, False, color:['Blue','Pink','Aqua','FloralWhite','Chartreuse','BlueViolet']}) copy codeCopy the code

Change each frame style

The DOM used for implementation (changing the style of each frame), canvas is not selected mainly because it basically uses canvas-related API to draw, and all kinds of save and restore can be written with native. Dom should be familiar with writing React.

Loop rendering for each target word

  1. Change the value of left top direction in each frame
  2. Determine if you’re at the bottom, clear the loop, and update the GameOver value
  3. Update target array and score
const down = ()=>{ let newArr = [...state.targetArr] let timer = setInterval(()=>{ //1 newArr = newArr.map(item=>{ let newDire = item.direction if(item.left<0||item.left>350) newDire = item.direction*-1 return{ ... item, top:item.top+_TARGET_CONFIG.speed, left:item.left+newDire, direction:newDire } }) //2 let isBottom = newArr.find(item=>item.top>=600-60) if(isBottom){ clearInterval(timer) setState((state)=>{ return { ... state, gameOver:true } }) } //3 setState((state)=>{ state.score>localStorage.getItem('_HIGHEST_RECORD')&& localStorage.setItem('_HIGHEST_RECORD',state.score) return { ... State, targetArr:newArr}})},17)} Copy codeCopy the code

Target word lock and input box letters one by one display matching letters

  1. Start by defining the lock target word index
  2. When typing the first letter, look for a matching initial letter on the screen, update it and render the input value back into the input field
  3. If there is already a lock word, check whether the input word matches the target word. If yes, update the input value. If no, no operation is performed
  4. When the values of the input box are all equal to the value of the target word, the target word is put back into the thesaurus, and the original target word is randomly replaced with a new value
  5. Update scores and clear input values and locked target word indexes (restore defaults)
/ / the current lock words in the target array index let [currentIndex setCurrentIndex] = useState (1) const inputChange = (e) = > {the if (currentIndex = = = 1) { // Search for an array of words that start with the same letter and find the index with the highest value and assign it let matchObj = state.targetArr.filter(item=>item.txt[0]===e.target.value&&item.top>0) if(matchObj.length){ matchObj = matchObj.reduce((pre,cur)=>{ return cur.top>pre.top? cur:pre }) let tempIndex = state.targetArr.indexOf(matchObj) console.log(tempIndex); setCurrentIndex(tempIndex) setInput(e.target.value) }else{ return } }else if( new RegExp(e.target.value).test(state.targetarr [currentIndex].txt)){setInput clears the target and adds the next word when the word is the same as the word in the input box setInput(e.target.value) e.target.value===state.targetArr[currentIndex].txt &&clearAddTarget(currentIndex) } } / / remove spelling out goal back word library And random added a new const clearAddTarget = (index) = > {let {targetArr wordsPool, score} = state wordsPool.push(targetArr[index].txt) targetArr[index] = { txt:wordsPool[Math.floor(Math.random()*(wordsPool.length-1))], Left: Math. Floor (Math. The random () * 340), the top: Math. The floor (Math) random () * 1), direction: Math. The random () > 0.5? 1:-1} // score++ setState({... State, wordsPool, targetArr, score}) // Word index input box clears setCurrentIndex(-1) setInput(" ")} copy codeCopy the code

Target word and letter styles are rendered one by one

  1. Map renders each word, adding specific styles when the locked word index is equal to the word index
  2. Split each word into an array and map each letter
  3. If the letter index is smaller than the length of the input box and the word is locked, determine whether each letter matches the value of the input box and change the color
<div style={{width:'100%',height:'600px',position:'absolute',overflow:'hidden'}}> {state.targetArr.map((item,index)=>( <div key={index} className={`target ${currentIndex===index? 'aim':''}`} style={{left:item.left+'px',top:item.top+'px',color:state.color[index]}}> <div style={{marginTop:'40px',minWidth:'40px',textAlign:'center'}}>{item.txt.split('').map((key,i)=>( <span style={{color:currentIndex===index&&key===input[i]? 'yellow' : ' '}} key = {I} > {key}} < / span >)) < / div > < / div >)} < / div > duplicate codeCopy the code

insufficient

  • The overall style is not satisfactory
  • – No shooting effect (bullet moves to locked target per frame)
  • There should be bugs and other issues.

Who is the king of typing

I come first

The initial speed is 0.3, the speed will gradually increase, and there will be a speed plus score display at the end

Who is the fastest and most hot individual, who can get my respect 😄, please big guys screenshot comments

If there are more than 10 players in the game screenshots, choose the highest score in the reward (specified number 3 and the initial thesaurus)

The last

It is not easy to make, please like 🙃