小游戏练习
游戏次要分成两个:gameA 和 gameB
整个过程次要分为三局部:
首页:
次要内容 :游戏难度分成三个等级,扭转变量 level 的具体数值,传给 gameA 和 gameB 两个页面。
重点:
1. 在 src 文件夹中创立一个新的文件夹 models,应用 useModel,创立一个全局变量 level,所有页面均能够应用。
2. 按钮点击款式的批改,应用:hover,对于点击的按钮有色彩的浮动变动。
gameA:
次要内容 :在挪动对象中增加图片,对指标图片进行计数。
重点:
1. 应用 useEffect 对指标函数进行监听,能够针对不同函数做出相应操作。留神监听的指标和程序,当程序不适合的时候,会产生死循环。
useEffect(() => {console.log(forRun.animationTime);
if (forRun.styleVar && forRun.styleVar.transition) {setForRun({ ...forRun, playState: true});
setTimeout(() => {askUser();
setForRun({...forRun, playState: false, styleVar: { ...defaultStyle} });
}, forRun.animationTime * 1000 + 1000);
}
}, [forRun.styleVar]);
2. 利用 transform 和 transition,使对象进行挪动并固定挪动工夫。
styleVar: {
height: '100px',
transition: `all ${forRun.animationTime}s linear`,
transform: `translateX(${-1 * imageParamListItemWidth * imageParamList.length}px )`,
},
3. 应用 window.prompt(),能够在弹窗中输出数据。
const alertInput = window.prompt('请输出看到的白底成年女性头像数量!');
4. 取固定范畴的随机数
const randomNum = (max: number, min: number) => {const num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
};
5. 对数组内元素进行渲染
{item.map((status, index) => ())}
难度第二级
难度第三级
gameB:
次要内容 :在固定范畴内,截取图片。
重点:
1. 对图片进行重现达到截图的成果
2. 计算图片运行间隔:
const endTime = new Date().valueOf();
const runTime = endTime - startTime;
const currentLength =
((areaWidth + pictureListItemWidth) / forRun.animationTime / 1000) * runTime;
let isOk: boolean;
if (level === 1) {isOk = currentLength >= 550 && currentLength <= 700;} else if (level === 2) {isOk = currentLength >= 575 && currentLength <= 675;} else {isOk = currentLength >= 600 && currentLength <= 650;}
forRun.pictureState = isOk;
forRun.runLength = currentLength;
console.log(forRun.runLength, forRun.pictureState);
startTime = 0;
对图片在新的区域挪动雷同间隔:
transform: `translateX(${1200 - forRun.runLength}px )`,
3. 监听文档的 enter 事件,当此组件销毁时,enter 事件删除
useEffect(() => {
document.addEventListener('keypress', handleEnterKey);
return () => {document.removeEventListener('keypress', handleEnterKey);
};
}, [handleEnterKey]);
4. 监听键盘事件,按下 enter,判断以后是否接管回车按键(a && b), 记录按键工夫, 对数据进行解决, 阻止本次播放过程中再次按键。同时为了防止在图片挪动时不必要的更新,使 useCallback:
const handleEnterKey = useCallback((e: KeyboardEvent) => {if (e.code === 'Enter' && startTime != 0) {}
else{startTakePictures()}}
5. 初始款式的类型设为:
styleVar: Record<string, string>;
pictureStyle: Record<string, string>;
6. 对 state 进行 setState 的机会要判断分明,不是 state 有变动了就马上进行 set, 依据当前情况,如果后续还有其余变动,不须要立刻进行 setState,还可能产生关联的 state 始终在扭转的状况,就容易呈现死循环,能够在确定没有多于变动的机会,在进行一次 set,达到整体刷新的后果。
难度第二级
难度第三级
页面布局:
首先在 config.ts 文件中,将 layout 勾销应用,那么我的项目本来的布局就不再应用。
export default defineConfig({
hash: true,
antd: {},
dva: {hmr: true,},
layout: false,
在 src 文件夹中创立一个新的文件夹 layouts,在路由文件中,应用新的布局文件。
创立 BasicLayout 文件:
const {children} = props;
return (
<>
<Header />
<div className={styles.mainContent}>{children}</div>
<div className={styles.mainFooter}>
<Footer />
</div>
</>
);
优化:
1. 鉴于 gameB 图片运行速度过快,将 start 按钮勾销,换成由 enter 管制开始和完结。依据 code 和图片开始工夫的有无进行判断。
2. 具备雷同状态的变量归纳到同一个变量中进行管制。
3.css 文件的优化,具备雷同款式的进行合并。
总结
1. 对 useState,useEffect,useModel,table 中 item 的元素渲染等印象粗浅,熟练度进步,对代码程序的谨严进步器重,避免死循环呈现。
2. 页面布局:灵便应用模板自带的布局,能够套用加以批改。留神 route 的实际意义,在绝对应的 route 页面增加或批改,不要在 config 页面做多于批改。
3. 进步对 JavaScript 的意识和了解,熟记常见语法,常见函数。
4. 减少对各类款式的相熟度,针对不同款式需要,能够有多种形式实现。
5. 在搭建页面时留神变量初始化,锤炼兼顾思维,在进行办法具体编写之前,把所须要的变量,函数,常量等参数筹备好,后续间接应用,不要呈现边写边减少变量的景象,在结尾整顿时,容易呈现变量或者函数之间相互影响,产生意料之外的变动和谬误。