Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions .github/workflows/deploy.yml

This file was deleted.

25 changes: 6 additions & 19 deletions step5/App.js → App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export default function App() {
const BALL_WIDTH = 20;
const TARGET_WIDTH = BALL_WIDTH * 2;
const TARGET_BORDER_WIDTH = 2;
const UPDATE_INTERVAL = 16 // 16ms is equivalent to 60fps

const Game = () => {
const { width, height } = useSafeAreaFrame();
Expand All @@ -48,16 +47,14 @@ const Game = () => {
// Start with a score of 0
const [score, setScore] = React.useState(0);

// START: STEP 5 ADDITION
// Start with the ball in the center of the playable screen area
const ballAnimation = useSharedValue(getCenterPosition());
// END: STEP 5 ADDITION

// Create the ball styles based on the current ballAnimation value
const ballPosition = useAnimatedStyle(() => ({
transform: [
{ translateX: withTiming(ballAnimation.value.x, { duration: UPDATE_INTERVAL, easing: Easing.linear }) },
{ translateY: withTiming(ballAnimation.value.y, { duration: UPDATE_INTERVAL, easing: Easing.linear }) },
{ translateX: ballAnimation.value.x },
{ translateY: ballAnimation.value.y },
],
}));

Expand All @@ -67,21 +64,17 @@ const Game = () => {
// Create the target styles based on the current ballAnimation value
const targetPosition = useAnimatedStyle(() => ({
transform: [
{ translateX: withTiming(targetAnimation.value.x, { duration: 350 }) },
{ translateY: withTiming(targetAnimation.value.y, { duration: 350 }) },
{ translateX: targetAnimation.value.x },
{ translateY: targetAnimation.value.y },
],
}));

// Setup the device motion sensor listner
React.useEffect(() => {
DeviceMotion.setUpdateInterval(UPDATE_INTERVAL);
// Set the update interval to 16ms (60fps)
DeviceMotion.setUpdateInterval(16);

const subscription = DeviceMotion.addListener((deviceMotionMeasurment) => {
// Don't do anthing if the expected `rotation` data is missing
if (!deviceMotionMeasurment.rotation) {
return;
}

// Update the ball position based on the device motion sensor.
ballAnimation.value = {
// Change the value of the ball's x position by the device motion sensor's gamma value
Expand Down Expand Up @@ -109,7 +102,6 @@ const Game = () => {
// And vibrate
Haptics.notificationAsync();

// START: STEP 5 ADDITION
// And update the score by 1
setScore((score) => {
const newScore = score + 1;
Expand All @@ -119,7 +111,6 @@ const Game = () => {

return newScore;
});
// END: STEP 5 ADDITION
}
});

Expand All @@ -131,7 +122,6 @@ const Game = () => {
<Reanimated.View style={[styles.target, targetPosition]} />
<Reanimated.View style={[styles.ball, ballPosition]} />

{/* START: STEP 5 ADDITION */}
<View style={styles.scoreContainer}>
<Text style={styles.scoreText}>Score: {score}</Text>

Expand All @@ -144,7 +134,6 @@ const Game = () => {
<Text style={styles.resetText}>Reset</Text>
</Pressable>
</View>
{/* END: STEP 5 ADDITION */}
</View>
);
};
Expand All @@ -169,7 +158,6 @@ const styles = StyleSheet.create({
borderWidth: TARGET_BORDER_WIDTH,
borderColor: "blue",
},
// START: STEP 5 ADDITION
scoreContainer: { position: "absolute", bottom: 20, left: 20 },
scoreText: {
fontSize: 40,
Expand All @@ -178,5 +166,4 @@ const styles = StyleSheet.create({
resetText: {
fontSize: 20,
},
// END: STEP 5 ADDITION
});
77 changes: 1 addition & 76 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1 @@
# React Native Workshop

## From Zero to React Native

This workshop will help you learn the basics of React Native including how to create, develop, and build an application. The workshop assumes you have some experience with JavaScript and some knowledge of React. While it is aimed at those who are new to React Native but can be used be engineers of any experience level.

## Prerequisites

Before running this workshop you will need to have the following installed:

- [NodeJS](https://nodejs.org/): While there is no specific version required we recommend getting the latest LTS version.
- [Git](https://git-scm.com/)
- [Watchman](https://facebook.github.io/watchman/docs/install#buildinstall) for Linux and Mac users

It is also recommended that you install [Expo Go](https://expo.dev/client) on your device in order to run the application.

## ▶️▶️▶️ Start Here ◀️◀️◀️

Open and follow the slide deck here:

👉 **[https://nearform.github.io/react-native-workshop/](https://nearform.github.io/react-native-workshop/)** 👈

☝️☝️☝️ Start there ☝️☝️☝️

---

## About this workshop

By the end of the above ☝️ workshop, you'll have a working tilt-game app looking something like this:

![Animated gif of a simple ball-rolling game](https://github.com/nearform/react-native-workshop/blob/main/slides/images/step5.gif)

The workshop splits app creation into the following five steps, each of which has a folder in this repo containing working code for the app at that point:

0. [Step 0](/step0)

> **Objectives**:
> - Set up an Expo app
> - Make it run

1. [Step 1](/step1)

> **Objectives**:
> - Add all dependencies
> - Add the game math using a pre-build hook
> - Setup the game area and a static ball

2. [Step 2](/step2)

> **Objectives**:
> - Detect device tilts by the user
> - Control the ball by tilting the device

3. [Step 3](/step3)

> **Objectives**:
> - Add a target circle
> - Place it at a random position
> - (No collision detection yet)

4. [Step 4](/step4)

> **Objectives**:
> - Detect collisions between the ball and the target
> - Trigger haptic feedback

5. [Step 5](/step5)

> **Objectives**:
> - Keep track of the score
> - Speak the score out loud
> - Allow the score to be reset

6. Bonus steps

If you complete all the above and want to do more, visit the [./step6-bonus](https://github.com/nearform/react-native-workshop/tree/bonus-step/step6-bonus) directory in the [bonus-step PR branch](https://github.com/nearform/react-native-workshop/pull/22).
# Step 1
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 0 additions & 3 deletions slides/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion slides/images/discord-mark-white.svg

This file was deleted.

Binary file removed slides/images/expo.png
Binary file not shown.
1 change: 0 additions & 1 deletion slides/images/meta-logo.svg

This file was deleted.

Binary file removed slides/images/microsoft-logo.png
Binary file not shown.
100 changes: 0 additions & 100 deletions slides/images/nearform.svg

This file was deleted.

Binary file removed slides/images/qrcode_expo.dev.png
Binary file not shown.
1 change: 0 additions & 1 deletion slides/images/react-native.svg

This file was deleted.

Loading