改变动画中的反应本机动画值

发布于 2025-01-17 21:07:43 字数 1797 浏览 0 评论 0原文

我构建了类似于流行游戏 Flappy Bird 的东西 - 一个物体掉落,用户单击一个按钮导致该物体跳跃,目的是确保它不会撞到屏幕底部。

我最初是通过对状态进行多次更新来构建此效果的,即通过将对象的位置移动几个像素并重新渲染来实现下落对象和“跳跃”效果。例如这样:

//falling effect
gameTimerId = setInterval(()=>{
          setObjectHeight(objectHeight => objectHeight - 5)
       }, 30)

    return ()=>{
      clearInterval(gameTimerId)
      }

//jump effect (struggling to replicate this below)
const jump = () => {
    if(!isGameOver && (objectHeight < screenHeight)){
      setObjectHeight(objectHeight => objectHeight +50)
      console.log("jumped!")
    }
  }

这显然是一种非常低效的做事方式,所以我一直在尝试使用 React Animated API 来重新设计它,它将使用 UI 线程来制作动画。

我可以实现坠落效果,但在坠落效果处于活动状态时很难使对象跳跃。当用户单击“跳跃”时,对象应该再次开始下落,但高度略高于当前位置。我已阅读文档并尝试了多种选项,但似乎都不起作用。这是我到目前为止所得到的:

export default App = () => {
  
  // animated value for height of square on screen
  const squareHeight = useRef(new Animated.Value(Dimensions.get('screen').height / 2)).current;

  //gravity animation
  const gravity =  Animated.timing(squareHeight, {
      toValue: 0,
      duration: 2000,
      useNativeDriver: true,
    })

  //start falling effect on component loading
  useEffect(() => {
   gravity.start()
  }, []); 

 
//PROBLEM - this should restart falling effect from square's current location + 10px
  const jump = () => {
    //squareHeight.setValue(squareHeight + 10) 
    gravity.start()
  }

  return (
    <>
    <Animated.View
      style={[
        {
          position: 'absolute',
          backgroundColor: 'blue',
          width: 50,
          height: 60,
          bottom: squareHeight,
        },
      ]}/>

  <Button title="Jump!" onPress={jump}> </Button>
  </>
  );
};

我是反应原生动画的新手,非常感谢您提供有关如何实现这一目标的帮助!谢谢。

I have built something similar to the popular game Flappy Bird - an object falls, and the user clicks a button causing that object to jump with the aim of making sure it doesn't hit the bottom of the screen.

I originally built this through many updates to state, ie the falling object and 'jump' effect was achieved by moving the position of the object a few pixels and re-rendering. Like this for example:

//falling effect
gameTimerId = setInterval(()=>{
          setObjectHeight(objectHeight => objectHeight - 5)
       }, 30)

    return ()=>{
      clearInterval(gameTimerId)
      }

//jump effect (struggling to replicate this below)
const jump = () => {
    if(!isGameOver && (objectHeight < screenHeight)){
      setObjectHeight(objectHeight => objectHeight +50)
      console.log("jumped!")
    }
  }

This is obviously a very inefficient way of doing things, so I have been trying to rework this using the react Animated API, which would animate using the UI thread.

I can achieve the falling effect, but am struggling to make the object jump while the falling effect is active. When the user clicks 'jump' the object should begin falling again but from a height slightly above where it currently is. I have read the docs and tried numerous options, none of which seem to work. Here is what I have so far:

export default App = () => {
  
  // animated value for height of square on screen
  const squareHeight = useRef(new Animated.Value(Dimensions.get('screen').height / 2)).current;

  //gravity animation
  const gravity =  Animated.timing(squareHeight, {
      toValue: 0,
      duration: 2000,
      useNativeDriver: true,
    })

  //start falling effect on component loading
  useEffect(() => {
   gravity.start()
  }, []); 

 
//PROBLEM - this should restart falling effect from square's current location + 10px
  const jump = () => {
    //squareHeight.setValue(squareHeight + 10) 
    gravity.start()
  }

  return (
    <>
    <Animated.View
      style={[
        {
          position: 'absolute',
          backgroundColor: 'blue',
          width: 50,
          height: 60,
          bottom: squareHeight,
        },
      ]}/>

  <Button title="Jump!" onPress={jump}> </Button>
  </>
  );
};

I'm new to react native animated so grateful for help as to how to achieve this! Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦屿孤独相伴 2025-01-24 21:07:43

将您的跳跃函数更改为:

const jump = () => {
  //squareHeight.setValue(squareHeight + 10)
  squareHeight._startingValue = squareHeight._value+10; // new starting value
  gravity.reset();
  gravity.start();
}

说明:

  1. 首先更改动画的起始值。
  2. 然后重置动画以便可以再次开始。
  3. 然后开始动画。

Change your jump function to this:

const jump = () => {
  //squareHeight.setValue(squareHeight + 10)
  squareHeight._startingValue = squareHeight._value+10; // new starting value
  gravity.reset();
  gravity.start();
}

Explanation:

  1. First change your starting value of animation.
  2. Then reset the animation so it can be started again.
  3. Then start the animation.
风柔一江水 2025-01-24 21:07:43

好吧,您还可以每次开始动画时都会改变持续时间来保持速度。更改的持续时间可以写成原始绘制/原始Squareheight Times NewsQuareheight。

Well you can also maintain speed by just changing the duration everytime you start your animation. Changed duration can be written as originalDuration/originalSquareHeight times newSquareHeight.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文