likes
comments
collection
share

react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

作者站长头像
站长
· 阅读数 27

小游戏练习

react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

源码地址:https://github.com/Eleven11ya...

游戏主要分成两个:gameA和gameB

react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

整个过程主要分为三部分

首页:

主要内容:游戏难度分成三个等级,改变变量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) => ())}

难度第二级react入门练习2-对react基础知识的综合应用-实现两个动画小游戏难度第三级react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

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,达到整体刷新的结果。难度第二级react入门练习2-对react基础知识的综合应用-实现两个动画小游戏难度第三级react入门练习2-对react基础知识的综合应用-实现两个动画小游戏

页面布局:

首先在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.在搭建页面时注意变量初始化,锻炼统筹思想,在进行方法详细编写之前,把所需要的变量,函数,常量等参数准备好,后续直接使用,不要出现边写边增加变量的现象,在结尾整理时,容易出现变量或者函数之间互相影响,产生预料之外的变化和错误。