0

I am trying to implement a simple circle tapping game with react native for learning purposes.

What I am trying to do is render some circles with random locations on screen with small radius then increase it up to a value, after decrease it and finally remove the circle from screen - just like in this game: http://mouseaccuracy.com/

import React, { Component } from "react";
import {
  AppRegistry,
  StyleSheet,
  Dimensions,
  View,
  ToastAndroid
} from "react-native";

const { width: WIDTH, height: HEIGHT } = Dimensions.get("window");

export default class BestGameEver extends Component {
  constructor() {
    super();
    this.state = {
      circles: []
    };
  }

  componentWillMount() {
    setInterval(this.spawner, 1000);
    setInterval(this.updateCircle, 16);
  }

  updateCircle = () => {
    this.state.circles.map((circle, i) => {
      if (
        circle.width < 50 &&
        circle.height < 50 &&
        circle.borderRadius < 50 &&
        circle.increase == true
      ) {
        circle.width = circle.width + 1;
        circle.height = circle.height + 1;
        circle.borderRadius = circle.borderRadius + 1;

        var array = this.state.circles;
        array.splice(i, 1);
        array.push(circle);
        this.setState({ circles: array });
      } else if (
        circle.width == 50 &&
        circle.height == 50 &&
        circle.borderRadius == 50
      ) {
        circle.increase = false;
      }
      if (circle.increase == false) {
        circle.width = circle.width - 1;
        circle.height = circle.height - 1;
        circle.borderRadius = circle.borderRadius - 1;

        var array = this.state.circles;
        array.splice(i, 1);
        array.push(circle);
        this.setState({ circles: array });
      }

      if (circle.width == 0 && circle.height == 0 && circle.borderRadius == 0) {
        ToastAndroid.show("removing", ToastAndroid.SHORT);
        var array = this.state.circles;
        array.splice(i, 1);
        this.setState({ circles: array });
      }
    });
  };
  spawner = () => {
    var randomX = Math.floor(Math.random() * (WIDTH - 0 + 1) + 0);
    var randomY = Math.floor(Math.random() * (HEIGHT - 0 + 1) + 0);

    var circle = {
      increase: true,
      x: randomX,
      y: randomY,
      width: 5,
      height: 5,
      borderRadius: 5
    };
    this.setState({ circles: [...this.state.circles, circle] });
  };
  renderCircles = () => {
    if (this.state.circles.length != 0) {
      return this.state.circles.map((circle, i) => {
        return (
          <View
            style={{
              position: "absolute",
              backgroundColor: "blue",
              width: circle.width,
              height: circle.height,
              borderRadius: circle.borderRadius,
              left: circle.x,
              top: circle.y
            }}
          />
        );
      });
    }
  };

  render() {
    return <View style={styles.container}>{this.renderCircles()}</View>;
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#FFF"
  }
});

Currently I can spawn circles on screen every 5 second then increase their size up to 50 with the updateCircle function.

How do i then decrease the size of circle once it has reached up to 50?

thanks

edit: I updated my question now i can decrease but its lagging for some reason ?

2 Answers 2

0

You may add a new variable to track whether it is in increasing mode or decreasing mode. If it's increasing mode initially, run current logic. If it's in decreasing mode, add new block of code to reduce circle size down to 0 or whatever.

2
  • hello i edited my question now i can decrease but its lagging ?
    – l0veisreal
    Commented Sep 21, 2018 at 19:56
  • You should optimize your logic somewhere else. The answer is strictly related to your specific question.
    – obvdso
    Commented Sep 21, 2018 at 20:18
0

You should look into the Animated API. An Animated.Value() can be bound to a style property in an Animated.View. Then you can change that Animated.Value and the style change will be reflected automatically for the view.

You'd use <Animated.View> components for the circles, then use a single Animated.Value() for each circle to style its width, height, and borderRadius (you'll probably need Animated.divide() for the border radius). Then you could use Animated.timing() and Animated.sequence() to tween that circle's value up, then down. All of that could be set immediately after each circle was created.

You'll get much better performance, since the instructions can be sent to the native code once per circle, instead of once per circle per frame of animation.

Not the answer you're looking for? Browse other questions tagged or ask your own question.