Creating a Car Game in React, Part 4: Score

DZone 's Guide to

Creating a Car Game in React, Part 4: Score

We contine our series on building a browser-based game using React by implementing a score keeping mechanism with our JavaScript.

· Web Dev Zone ·
Free Resource

This is the fourth part of a series (that began here). So far, we have a game where you can whizz around the screen avoiding trees. This effectively encompasses most aspects of a game of this type; that is, you can move, and there is a something preventing you.

The next step is to introduce something for the player to try to do, and give a score based on that. In our case, our player is going to try and collect cups — as per the original game. The asset I've created for the cup is here. For anyone following this series, you may have noticed that my artwork is a little... crap.

The source for this post is here.


The first thing that we've done here is we added some code to place a few cups around the screen; the code for this was essentially the same as build obstacles:

placeCups() {
    let cups = [];
    const cupCount = 1;
    for (let i = 1; i <= cupCount; i++) {
        const centreX = Math.floor(Math.random() * this.state.windowWidth) + 1;
        const centreY = Math.floor(Math.random() * this.state.windowHeight) + 1; 
        cups.push(<GameItem key={i} image={cupImg} centreX={centreX} centreY={centreY} width={this.spriteWidth} height={this.spriteHeight} itemType={2} />);
    return cups;

In a later post, I hope to do a full refactor, but for now, we have a separate function. This is rendered in the same way as the obstacles:

render() { 
    return <div onKeyDown={this.onKeyDown} tabIndex="0">
        <GameStatus Lives={this.state.playerLives} Message={this.state.message} Score={this.state.score} />

        <Background backgroundImage={backgroundImg}
        windowWidth={this.state.windowWidth} windowHeight={this.state.windowHeight} /> 

        <Car carImage={this.state.playerCrashed ? brokenCarImg : carImg} 
        centreX={this.state.playerX} centreY={this.state.playerY} 
        width={this.spriteWidth} height={this.spriteHeight} 
        rotation={this.state.playerRotation} /> 



Collecting Cups

In order to collect something, the player must collide with it. We need to change the collision code slightly to make it a little more re-usable:

detectAnyCollision(rect1) { 
    // Have we crashed or left the screen
    if (this.detectOutScreen(rect1)) {
        return true;
    let collided = this.detectGameItemCollision(this.halfWidth, this.halfHeight, rect1, this.obstacles);
    if (collided !== undefined) {
        return true;
    return false;

detectGameItemCollision(halfWidth, halfHeight, rect1, gameItemList) {
    const collided = gameItemList.find(a => {
        var rect2 = {
            x: a.props.centreX - halfWidth, y: a.props.centreY - halfHeight,
            width: this.spriteWidth, height: this.spriteHeight
        return (this.detectCollision(rect1, rect2));
    return collided;

As you can see, we now have a function that returns the item that we collided with, rather than a simple boolean. We then use this at the end of the game loop to determine whether we collided with a cup:

// Check for collected cup
const item = this.detectGameItemCollision(this.halfWidth, this.halfHeight, rect1, this.cups);
if (item !== undefined) {

There's little point in zooming around collecting cups, if there's no permanent record, so we need to add a score. Let's start with a state variable in game.jsx:

this.state = {
    playerX: 100,
    playerY: 100,
    windowWidth: 1500,
    windowHeight: 1500,
    playerMomentum: 0,
    playerRotation: 0,
    playerVelocityX: 0,
    playerVelocityY: 0,
    playerLives: 3,
    playerCrashed: false,
    gameLoopActive: false,
    message: "",
    score: 0

And here's the collectedCup function we mentioned a second ago:

collectedCup(key) {
    this.setState({ score: this.state.score + 1 });
    this.cups = this.cups.filter(cup => cup.key != key);
    this.updateMessage("Collected cup");

All we're doing here is simply updating the score and then removing that cup from the list.

The final part is to display the score on the screen; let's have a look at our updated GameStatus.jsx:

function GameStatus(props) {
    const flexStyle = {
        display: 'flex',
        position: 'absolute',
        zIndex: 1,
        margin: 20,
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%'
    const labelStyle = { 
        zIndex: 1,
        margin: 50
    return ( 
        <div className="flex-container" style={flexStyle}>
            <label style={labelStyle}>
                Lives Remaining: {props.Lives}
            <label style={labelStyle}>
                Score: {props.Score}
            <label style={labelStyle}>

As you can see, we're just displaying the score as part of the status.

In the next post, we'll have a look at the concept of levels, and introduce a time limit.


If you enjoyed this article and want to learn more about React, check out this collection of tutorials and articles on all things React.

web dev ,react ,react.js tutorials ,front-end development

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}