Create a 2048 Game using React-Native
Last Updated :
02 Aug, 2024
In this article, we are going to implement a 2048 Game using React Native. The 2048 game is a popular sliding puzzle game that involves combining tiles with the same number to reach the tile with the number 2048. Players can move the tiles in four directions: up, down, left, or right.
Prerequisite
Preview of final output: Let us have a look at how the final output will look like.
Preview of the appApproach
In this app basically we added a 4x4 board and also added all functionalities required in the 2048 game.
Functionalities and logic of the app
- The Game2048 component initializes the game board as a state variable using the useState hook.
- The initializeGame function sets up the initial state of the board with two randomly placed tiles containing either the number 2 or 4.
- The PanGestureHandler is used to detect swipe gestures on the game board.
- The onSwipeEvent function is triggered when a swipe gesture ends (State.END). It determines the direction of the swipe based on the horizontal and vertical translations and calls the handleSwipe function accordingly.
- The handleSwipe function triggers the appropriate movement function (moveUp, moveDown, moveLeft, or moveRight) based on the detected swipe direction.
- The movement functions iterate through the board to move and merge tiles in the specified direction. The merging logic follows the rules of the 2048 game.
- If any movement occurs, a new tile is added to the board using the addNewTile function.
- The isGameOver function checks if there are any possible moves left on the board. If not, it triggers a game over alert with an option to restart the game.
Steps to Create React Native Application
Step 1: Create a react native application by using this command in the command prompt
React-native init Game2048
Step 2: After initiating the project, install the react-native-gesture-handler package because Gesture handlers are components that handle touch interactions and gestures, such as tapping, swiping, pinching, and rotating on the screen.
npm i react-native-gesture-handle
Project Structure:

The updated dependencies in package.json file will look like:
"dependencies": {
"@expo/vector-icons": "^13.0.0",
"react-native-elements": "0.18.5",
"react-native-gesture-handler": "~2.9.0"
}
Example: Write the below source code into the file.
JavaScript
//App.js
import React from 'react';
import GameLogic from './GameLogic';
import GameStyle from './GameStyle';
const Game2048 = () => {
const { board, initializeGame, handleSwipe } = GameLogic();
return (
<GameStyle board={board}
handleSwipe={handleSwipe}
initializeGame={initializeGame} />
);
};
export default Game2048;
JavaScript
//GameLogic.js
import React, { useState, useEffect } from 'react';
import { Alert } from 'react-native';
const BOARD_SIZE = 4;
const GameLogic = () => {
const [board, setBoard] = useState(Array.from({ length: BOARD_SIZE },
() => Array(BOARD_SIZE).fill(0)));
const initializeGame = () => {
const newBoard = Array.from({ length: BOARD_SIZE },
() => Array(BOARD_SIZE).fill(0));
addNewTile(newBoard);
addNewTile(newBoard);
setBoard(newBoard);
};
const addNewTile = (newBoard) => {
const emptyTiles = [];
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (newBoard[i][j] === 0) {
emptyTiles.push({ row: i, col: j });
}
}
}
if (emptyTiles.length > 0) {
const { row, col } = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
newBoard[row][col] = Math.random() < 0.9 ? 2 : 4;
}
};
const handleSwipe = (direction) => {
const newBoard = [...board];
let moved = false;
switch (direction) {
case 'UP':
moved = moveUp(newBoard);
break;
case 'DOWN':
moved = moveDown(newBoard);
break;
case 'LEFT':
moved = moveLeft(newBoard);
break;
case 'RIGHT':
moved = moveRight(newBoard);
break;
}
if (moved) {
addNewTile(newBoard);
setBoard(newBoard);
}
if (isGameOver(newBoard)) {
Alert.alert('Game Over', 'No more moves left!',
[{ text: 'Restart', onPress: initializeGame }]);
}
};
const moveUp = (newBoard) => {
let moved = false;
for (let col = 0; col < BOARD_SIZE; col++) {
for (let row = 1; row < BOARD_SIZE; row++) {
if (newBoard[row][col] !== 0) {
let currentRow = row;
while (currentRow > 0 && newBoard[currentRow - 1][col] === 0) {
newBoard[currentRow - 1][col] = newBoard[currentRow][col];
newBoard[currentRow][col] = 0;
currentRow--;
moved = true;
}
if (
currentRow > 0 &&
newBoard[currentRow - 1][col] === newBoard[currentRow][col]
) {
newBoard[currentRow - 1][col] *= 2;
newBoard[currentRow][col] = 0;
moved = true;
}
}
}
}
return moved;
};
const moveDown = (newBoard) => {
let moved = false;
for (let col = 0; col < BOARD_SIZE; col++) {
for (let row = BOARD_SIZE - 2; row >= 0; row--) {
if (newBoard[row][col] !== 0) {
let currentRow = row;
while(currentRow < BOARD_SIZE - 1 && newBoard[currentRow + 1][col]===0)
{
newBoard[currentRow + 1][col] = newBoard[currentRow][col];
newBoard[currentRow][col] = 0;
currentRow++;
moved = true;
}
if (
currentRow < BOARD_SIZE - 1 &&
newBoard[currentRow + 1][col] === newBoard[currentRow][col]
) {
newBoard[currentRow + 1][col] *= 2;
newBoard[currentRow][col] = 0;
moved = true;
}
}
}
}
return moved;
};
const moveLeft = (newBoard) => {
let moved = false;
for (let row = 0; row < BOARD_SIZE; row++) {
for (let col = 1; col < BOARD_SIZE; col++) {
if (newBoard[row][col] !== 0) {
let currentCol = col;
while (currentCol > 0 && newBoard[row][currentCol - 1] === 0) {
newBoard[row][currentCol - 1] = newBoard[row][currentCol];
newBoard[row][currentCol] = 0;
currentCol--;
moved = true;
}
if (
currentCol > 0 &&
newBoard[row][currentCol - 1] === newBoard[row][currentCol]
) {
newBoard[row][currentCol - 1] *= 2;
newBoard[row][currentCol] = 0;
moved = true;
}
}
}
}
return moved;
};
const moveRight = (newBoard) => {
let moved = false;
for (let row = 0; row < BOARD_SIZE; row++) {
for (let col = BOARD_SIZE - 2; col >= 0; col--) {
if (newBoard[row][col] !== 0) {
let currentCol = col;
while(currentCol < BOARD_SIZE - 1 && newBoard[row][currentCol + 1]===0)
{
newBoard[row][currentCol + 1] = newBoard[row][currentCol];
newBoard[row][currentCol] = 0;
currentCol++;
moved = true;
}
if (
currentCol < BOARD_SIZE - 1 &&
newBoard[row][currentCol + 1] === newBoard[row][currentCol]
) {
newBoard[row][currentCol + 1] *= 2;
newBoard[row][currentCol] = 0;
moved = true;
}
}
}
}
return moved;
};
const isGameOver = (newBoard) => {
for (let row = 0; row < BOARD_SIZE; row++) {
for (let col = 0; col < BOARD_SIZE; col++) {
if (
newBoard[row][col] === 0 ||
(row > 0 && newBoard[row][col] === newBoard[row - 1][col]) ||
(row < BOARD_SIZE - 1 && newBoard[row][col] === newBoard[row + 1][col]) ||
(col > 0 && newBoard[row][col] === newBoard[row][col - 1]) ||
(col < BOARD_SIZE - 1 && newBoard[row][col] === newBoard[row][col + 1])
) {
return false;
}
}
}
return true;
};
useEffect(() => {
initializeGame();
}, []);
return {
board,
initializeGame,
handleSwipe,
};
};
export default GameLogic;
JavaScript
//GameStyle.js
import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
import { PanGestureHandler, State } from 'react-native-gesture-handler';
const BOARD_SIZE = 4;
const GameStyle = ({ board, handleSwipe, initializeGame }) => {
const getTileColor = (value) => {
switch (value) {
case 2:
return '#EEE4DA';
case 4:
return '#EDE0C8';
case 8:
return '#F2B179';
case 16:
return '#F59563';
case 32:
return '#F67C5F';
case 64:
return '#F65E3B';
case 128:
return '#EDCF72';
case 256:
return '#EDCC61';
case 512:
return '#EDC850';
case 1024:
return '#EDC53F';
case 2048:
return '#EDC22E';
default:
return '#BBF99A';
}
};
const onSwipeEvent = (event) => {
if (event.nativeEvent.state === State.END) {
const { translationX, translationY } = event.nativeEvent;
const dx = Math.abs(translationX);
const dy = Math.abs(translationY);
if (dx > dy) {
if (translationX > 0) {
handleSwipe('RIGHT');
} else {
handleSwipe('LEFT');
}
} else {
if (translationY > 0) {
handleSwipe('DOWN');
} else {
handleSwipe('UP');
}
}
}
};
return (
<View style={styles.container}>
<View style={styles.Heading}>
<Text style={{ fontSize: 50, fontWeight: 'bold', color: 'green' }}>
GeekforGeeks
</Text>
<Text style={{
; paddingLeft: 70,
fontSize: 30,
fontWeight: 'bold',
color: 'black'
}}>
2048 Game
</Text>
</View >
<PanGestureHandler onGestureEvent={onSwipeEvent}>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((tile, colIndex) => (
<View key={colIndex}
style={[styles.tile, {
backgroundColor: getTileColor(tile)
}]}>
<Text style={styles.tileText}>
{tile !== 0 ? tile : ''}
</Text>
</View>
))}
</View>
))}
</View>
</PanGestureHandler>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
Heading: {
marginBottom: 30,
marginTop: -30,
},
board: {
flexDirection: 'column',
},
row: {
flexDirection: 'row',
},
tile: {
width: Dimensions.get('window').width / BOARD_SIZE - 10,
height: Dimensions.get('window').width / BOARD_SIZE - 10,
margin: 5,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
},
tileText: {
fontSize: 20,
fontWeight: 'bold',
color: '#776E65',
},
});
export default GameStyle;
Step to run the Project:
Step 1: Depending on your operating system, type the following command in terminal
React-native run-android
React-native run-ios
Output:
Similar Reads
Create a Memory Pair Game using React-Native
In this article, we will build the interactive Memory Pair Game using the React Native language. We are displaying the 12 boxes to the user, in the user has to click on each box, and when the user clicks on the box the random icon will be shown. Users have to guess or find its match by clicking on t
5 min read
Create Memes Generator App using React-Native
The MeÂme Generator App is a mobile application that allows users to effortlessly create memes. With its useÂr-friendly interface, useÂrs can choose from a wide collection of popular meÂme templates and add their own customized text to the top and bottom. In this article, we will see how we can bui
4 min read
Create a GPA Calculator using React Native
A GPA calculator proves to be a useful tool for students who want to monitor their academic progress. In this article, we will build a GPA calculator using React Native, a popular framework for building mobile applications. Preview Image PrerequisitesIntroduction to React NativeReact Native Componen
5 min read
Create an Image Carousal using React-Native
In this article, we will build the Image Carousal using React Native language. In this interactive application, we have taken some sample GFG course images which are automatically and manually scrolled. When the user clicks on the image, the additional information about that course is shown in a mod
5 min read
Create a Dashboard App using React-Native
A dashboard app using react native is a software application designed to provide a consolidated and visual representation of important information, data, or features in a single, easily accessible interface. Dashboards are commonly used in various industries to help users monitor, analyze, and manag
6 min read
Create a Blog App using React-Native
This article shows how to create a basic blog app using react native. This app contains functionalities such as adding a blog and a delete button to remove the blogs using react native. The user can enter content with a title and then click on 'Add New Post' to create a new blog post Preview of fina
4 min read
Create a Task Manager App using React-Native
In this article, we'll walk you through the process of building a basic Task Manager app using React Native. The application enables users to effortlessly create, edit, complete/incomplete, and delete tasks, providing an uncomplicated yet impactful introduction to ReÂact Native's mobile app develop
7 min read
Create Jokes Generator App using React-Native
In this article, we are going to build a jokes generator app using react native. React Native enables you to master the designing an elegant and dynamic useÂr interface while eÂffortlessly retrieving jokeÂs from external APIs. Let's take a look at how our completed project will look Prerequisites /
3 min read
Create Job Board App using React-Native
In this article, we are going to Create a Job Board App using React Native. The Job Board App is a simple application that is a collection of job openings in any field. It helps the students and the people who are searching for jobs in the market. It helps to find jobs and provides in-depth informat
6 min read
Create a Spin the Bottle game using React-Native
React-Native is an open-source framework used to develop cross-platform applications i.e., you can write code in React-Native and publish it as an Android or IOS app. In this article, we will build a basic Spin the Bottle game in React-Native. This is a multi-player game. Usually, people sit in a ro
3 min read