Super Smash Brothers Card Game

By Simon Ma

April 10/2021

Today we are going to build a Super Smash Brothers Card Game with React. This application will utilize all the basics such as components, props, maps, class names, import, exports, and syntax from JSX, JavaScript, and Cascading Style Sheets. This game logic is simple. Every time you push refresh, it will be a randomized 4 vs 4 card game where the team with the highest total attack wins. I chose 8 characters to make the game with, but it can be easily scalable if you choose to have more characters. The game will look something like this.  All images were found on Wikipedia after Googling Super Smash Bros character list.

Now before you start to code in React, there is prior knowledge you must know in order to make this game.

Programs Required: You would need Visual Studio Code and Node Package Manager to get started. Once everything is installed

Components: React is very object oriented. Components are known as Classes and are used to piece together the front end. You can use JavaScript, Cascading Style Sheets, and HTML-like code in these components.

Import and Export: Import and export is essentially how JavaScript files call React components from each other. When you make a component, you have to export it at the bottom in order for another JavaScript file to pick it up. 

Props: These are properties for short. They are used to pass information to the components. You can see like the parameters in Java. They are also immutable. Props can only be used to read data.

Arrays: You must understand how arrays work in JavaScript. To make this card game, it requires quite a bit of data especially if you want to scale it to all the Smash Brothers Characters ever known since Nintendo 64.

Divs in React: You must understand that if you want to code beyond a one line return in a component, you MUST put it in between Divs. It’s pretty much law of the land. This can be easily overlooked and cause trauma because you’re wondering where you went wrong.

The Card Game:

In this React application, there are 6 files in total. The App.js is already created for you in visual studio code when you type “Create-React-App smashbros” in the Visual Studio Code’s terminal. You just need to make minor modifications to it. You would also need to make a Characters.js file, a Characters.css file, a Smashcard.js file, a Smashcard.css file, and a Smashgame.js file. I also made some modifications to index.css.

Smashcard.js: Start off with Smashcard.js as this is simple piece and addresses the design of a single card. What you will notice is that this component has a lot of props. This is because there’s multiple characters so the name, from, and attack have to be able to print out differently to screen. I also numbered all my images like 1.png, 2.png etc, so that I can loop through the images easier when I give each character an ID in my array.

import React, {Component} from 'react';
import './Smashcard.css';
const SMASH_API = 'https://simonma.ca/wp-content/uploads/2021/04/';

class Smashcard extends Component {
    render(){
        let imgSrc = `${SMASH_API}${this.props.id}.png`
        return (
          <div className="Smashcard">
            <h1 className="Smashcard-title">{this.props.name}</h1>
            <div className="Smashcard-image">
            <img src ={imgSrc} height="60%" alt = {this.props.name}/> 
            </div>
            <div className ="Smashcard-data">From: {this.props.from}</div> 
            <div className ="Smashcard-data">Attack: {this.props.attack}</div> 
          </div>  
        );
    }
}

export default Smashcard;

Characters.js: The next file is to build the characters. The logic in this file prints the entire team onto the web page using a loop and the imported code from Smashcard.js. The loop shown in this code is an array loop method called “map” in React.

import React, {Component} from 'react';
import Smashcard from './Smashcard';
import './Characters.css';

class Characters extends Component {
    render(){
       return(
        <div className="">
            <h2>{this.props.team}</h2>
            <p><strong>Total Attack: {this.props.exp}</strong></p>
            <p><strong>{this.props.isWinner ? 'WINNER!' : 'LOSER!'}</strong></p>
            <div className="smashbros-cards">
            {this.props.smashbros.map((p) => (
                <Smashcard id={p.id} name={p.name} from={p.from} attack={p.attack} />
            ))}
        </div>
        </div>
       );
    }
}
export default Characters;

Smashgame.js: This is where all the game logic lives. You start off with an array. This is where you store all the character’s data for the application to access. I gave each character an ID which would make it easier to access all the images as the image file names are all numbers as well. You may notice something called default props in the code. This just means that if data is not passed to one of the props, it does not display undefined on the page but rather one of the characters info.

import React, { Component } from 'react';
import Characters from './Characters';

class Smashgame extends Component {
    static defaultProps = {
        smashBros : [
            {id: 1, name: 'Link', from: 'Zelda', attack: 72},
            {id: 2, name: 'Samus', from: 'Metroid', attack: 73},
            {id: 3, name: 'Bowser', from: 'Super Mario', attack: 72},
            {id: 4, name: 'Captain Falcon', from: 'F-Zero', attack: 178},
            {id: 5, name: 'Luigi', from: 'Super Mario', attack: 112},
            {id: 6, name: 'Marth', from: 'Fire Emblem', attack: 105},
            {id: 7, name: 'Ness', from: 'EarthBound', attack: 225},
            {id: 8, name: 'Pit', from: 'Kid Icarus', attack: 85}
        ]
    };
    render(){
        let hand1 = [];
        let hand2 =[...this.props.smashBros];
        while (hand1.length < hand2.length){
            let randIdx = Math.floor(Math.random() * hand2.length);
            let randSmash = hand2.splice(randIdx, 1)[0];
            hand1.push(randSmash);
        }
        let att1 = hand1.reduce((att, smashBros) => att + smashBros.attack, 0);
        let att2 = hand2.reduce((att, smashBros) => att + smashBros.attack, 0);

        return(
            <div>
    <Characters team= 'Team 1' smashbros={hand1} exp={att1} isWinner ={att1 > att2}/>
    <Characters team= 'Team 2' smashbros={hand2} exp={att2} isWinner ={att2 > att1}/>
            </div>
        );
    }
}

export default Smashgame;

Smashcard.css: This is where I style the cards. I decided to use flexbox just because I didn’t want to wrestle with the space for the images.

.Smashcard {
    
    width: 230px;
    padding: 10px;
    margin: 1rem;
    box-shadow: 7px 10px 12px -5px rgba(0,0,0,0.56);
    text-align: center;
    background-color: white;
}

.Smashcard-data{
    font-size: 15px;
    font-weight: bold;
}

.Smashcard-image{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 175px;
    background-color: rgb(211, 211, 211);
    border-radius: 3px;
}

Characters.css: I used flexbox to space the cards evenly across the screen.

.smashbros-cards {
    display : flex;
    justify-content: space-evenly;
    flex-wrap: wrap;
}

Index.css: I added one line of code to the body portion. It’s just to change the background color of the page.

background-color: #f5f5f5;

App.js: The important part of App.js is that it calls on all the logic of the application. Think of it as the main method in Java.

import React, { Component } from "react";
import Smashgame from './Smashgame';
import './App.css';

class App extends Component {
  render() {
    return (
    <div className="App">
     <Smashgame />
    </div>
    );
  }
}

export default App;

The Struggles:

I am not going to lie, React seemed so confusing at first. I think my problem was that I didn’t remember too much of JavaScript from second semester. I believed those that programmed in JavaScript for a long time can pickup React quite easily because it is a very elegant way to organize all the html, JavaScript, and Cascading Style Sheets into one area making big level productions way easier. The hardest part believe it or not, was wresting with my IDE. For whatever reason, Visual Studio Code does not like it when I rename a JavaScript file. It just breaks it even though it asked me do I want to update all the code that have paths leading to that file. Nor can I delete a JavaScript file. Same problem. I just fixed it by creating a new project and copying over the files. Also, apparently I couldn’t put my images on a local hard drive and get the images off that. Somehow a local host does not exactly see the local hard drive when I use relative or absolute path. Stack overflow was confusing. I was like whatever. I’m sure there’s an easy solution like in Java where you were just missing a curly brace somewhere, therefore it didn’t compile. I just went around the problem and hosted the images on my GoDaddy.