'I (do not know React at all) made a Snake React Component (with OpenAI Codex) but my Snake is not showing
I wasn't sure if I should ask this here because it's a dumb question but I'm really struggling with this. After asking lots of friends and fixing some things it still doesn't show my Game Board and Snake.
It always just looks like this: Game Board does not show anything
React Component:
import React from "react";
import "./styles.css";
class Snake extends React.Component {
constructor(props) {
super(props);
this.state = {
snake: [],
food: [],
direction: "right",
score: 0,
gameOver: false,
gamePaused: false,
gameStarted: false,
gameSpeed: 100,
gameSpeedMultiplier: 1,
gameSpeedMultiplierMax: 5,
gameSpeedMultiplierMin: 1,
gameSpeedMultiplierStep: 0.1,
gameSpeedMultiplierSteps: [
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
0.9,
1,
1.1,
1.2,
1.3,
1.4,
1.5,
1.6,
1.7,
1.8,
1.9,
2
],
gameSpeedMultiplierStepIndex: 0,
gameSpeedMultiplierStepIndexMax: 19,
gameSpeedMultiplierStepIndexMin: 0,
gameSpeedMultiplierStepIndexStep: 1,
gameSpeedMultiplierStepIndexSteps: [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
]
};
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.handleGameSpeedMultiplierChange = this.handleGameSpeedMultiplierChange.bind(
this
);
this.handleGameSpeedMultiplierStepIndexChange = this.handleGameSpeedMultiplierStepIndexChange.bind(
this
);
this.handleGameSpeedChange = this.handleGameSpeedChange.bind(this);
this.handleGameStart = this.handleGameStart.bind(this);
this.handleGamePause = this.handleGamePause.bind(this);
this.handleGameReset = this.handleGameReset.bind(this);
this.handleGameOver = this.handleGameOver.bind(this);
this.handleGameSpeedMultiplierStepIndexChange = this.handleGameSpeedMultiplierStepIndexChange.bind(
this
);
}
handleKeyDown(event) {
if (event.keyCode === 37) {
this.setState({ direction: "left" });
} else if (event.keyCode === 38) {
this.setState({ direction: "up" });
} else if (event.keyCode === 39) {
this.setState({ direction: "right" });
} else if (event.keyCode === 40) {
this.setState({ direction: "down" });
}
}
handleKeyUp(event) {
if (
event.keyCode === 37 ||
event.keyCode === 38 ||
event.keyCode === 39 ||
event.keyCode === 40
) {
this.setState({ direction: "none" });
}
}
handleGameSpeedMultiplierChange(event) {
this.setState({ gameSpeedMultiplier: event.target.value });
}
handleGameSpeedMultiplierStepIndexChange(event) {
this.setState({ gameSpeedMultiplierStepIndex: event.target.value });
}
handleGameSpeedChange(event) {
this.setState({ gameSpeed: event.target.value });
}
handleGameStart() {
this.setState({ gameStarted: true });
}
handleGamePause() {
this.setState({ gamePaused: true });
}
handleGameReset() {
this.setState({
gameStarted: false,
gamePaused: false,
gameOver: false,
score: 0,
snake: [],
food: []
});
}
handleGameOver() {
this.setState({ gameOver: true });
}
componentDidMount() {
document.addEventListener("keydown", this.handleKeyDown);
document.addEventListener("keyup", this.handleKeyUp);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleKeyDown);
document.removeEventListener("keyup", this.handleKeyUp);
}
render() {
return (
<div className="snake">
<div className="snake__game">
<div className="snake__game__header">
<div className="snake__game__header__title">Snake</div>
<div className="snake__game__header__score">
Score: {this.state.score}
</div>
</div>
<div className="snake__game__body">
<div className="snake__game__body__grid">
{this.state.gameOver ? (
<div className="snake__game__body__grid__game-over">
Game Over
</div>
) : null}
{this.state.gamePaused ? (
<div className="snake__game__body__grid__game-paused">
Game Paused
</div>
) : null}
{this.state.gameStarted ? (
<div className="snake__game__body__grid__game-started">
Game Started
</div>
) : null}
{this.state.snake.map((snakePart, index) => {
return (
<div
key={index}
className="snake__game__body__grid__snake-part"
>
<div className="snake__game__body__grid__snake-part__snake-part-body"></div>
</div>
);
})}
{this.state.food.map((foodPart, index) => {
return (
<div
key={index}
className="snake__game__body__grid__food-part"
>
<div className="snake__game__body__grid__food-part__food-part-body"></div>
</div>
);
})}
</div>
</div>
<div className="snake__game__controls">
<div className="snake__game__controls__game-speed">
<div className="snake__game__controls__game-speed__title">
Game Speed
</div>
<div className="snake__game__controls__game-speed__value">
{this.state.gameSpeed}
</div>
<input
className="snake__game__controls__game-speed__input"
type="range"
min="100"
max="1000"
step="10"
value={this.state.gameSpeed}
onChange={this.handleGameSpeedChange}
/>
</div>
<div className="snake__game__controls__game-speed-multiplier">
<div className="snake__game__controls__game-speed-multiplier__title">
Game Speed Multiplier
</div>
<div className="snake__game__controls__game-speed-multiplier__value">
{this.state.gameSpeedMultiplier}
</div>
<input
className="snake__game__controls__game-speed-multiplier__input"
type="range"
min={this.state.gameSpeedMultiplierMin}
max={this.state.gameSpeedMultiplierMax}
step={this.state.gameSpeedMultiplierStep}
value={this.state.gameSpeedMultiplier}
onChange={this.handleGameSpeedMultiplierChange}
/>
</div>
<div className="snake__game__controls__game-speed-multiplier-step-index">
<div className="snake__game__controls__game-speed-multiplier-step-index__title">
Game Speed Multiplier Step Index
</div>
<div className="snake__game__controls__game-speed-multiplier-step-index__value">
{this.state.gameSpeedMultiplierStepIndex}
</div>
<input
className="snake__game__controls__game-speed-multiplier-step-index__input"
type="range"
min={this.state.gameSpeedMultiplierStepIndexMin}
max={this.state.gameSpeedMultiplierStepIndexMax}
step={this.state.gameSpeedMultiplierStepIndexStep}
value={this.state.gameSpeedMultiplierStepIndex}
onChange={this.handleGameSpeedMultiplierStepIndexChange}
/>
</div>
<div className="snake__game__controls__game-start">
<div className="snake__game__controls__game-start__title">
Game Start
</div>
<div className="snake__game__controls__game-start__value">
{this.state.gameStarted ? "Game Started" : "Game Not Started"}
</div>
<button
className="snake__game__controls__game-start__button"
onClick={this.handleGameStart}
>
Start
</button>
</div>
<div className="snake__game__controls__game-pause">
<div className="snake__game__controls__game-pause__title">
Game Pause
</div>
<div className="snake__game__controls__game-pause__value">
{this.state.gamePaused ? "Game Paused" : "Game Not Paused"}
</div>
<button
className="snake__game__controls__game-pause__button"
onClick={this.handleGamePause}
>
Pause
</button>
</div>
<div className="snake__game__controls__game-reset">
<div className="snake__game__controls__game-reset__title">
Game Reset
</div>
<div className="snake__game__controls__game-reset__value">
{this.state.gameStarted ? "Game Reset" : "Game Not Reset"}
</div>
<button
className="snake__game__controls__game-reset__button"
onClick={this.handleGameReset}
>
Reset
</button>
</div>
<div className="snake__game__controls__game-over">
<div className="snake__game__controls__game-over__title">
Game Over
</div>
<div className="snake__game__controls__game-over__value">
{this.state.gameOver ? "Game Over" : "Game Not Over"}
</div>
<button
className="snake__game__controls__game-over__button"
onClick={this.handleGameOver}
>
Over
</button>
</div>
</div>
</div>
</div>
);
}
}
export default Snake;
Even though my Gameboard is black and the Snake is white, it still doesn't show up. What have I messed up in the React code?
styles.css:
.snake {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
background-color: #000;
}
.snake__game {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 10%;
width: 100%;
background-color: #000;
}
.snake__game__header__title {
font-size: 2em;
color: #fff;
}
.snake__game__header__score {
font-size: 1.5em;
color: #fff;
}
.snake__game__body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 90%;
width: 100%;
background-color: #000;
}
.snake__game__body__grid {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__body__grid__game-over {
font-size: 2em;
color: #fff;
}
.snake__game__body__grid__game-paused {
font-size: 2em;
color: #fff;
}
.snake__game__body__grid__game-started {
font-size: 2em;
color: #fff;
}
.snake__game__body__grid__snake-part {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 10%;
width: 10%;
background-color: #fff;
}
.snake__game__body__grid__snake-part__snake-part-body {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
.snake__game__body__grid__food-part {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 10%;
width: 10%;
background-color: #fff;
}
.snake__game__body__grid__food-part__food-part-body {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
.snake__game__controls {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 10%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed__input {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed-multiplier {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed-multiplier__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed-multiplier__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed-multiplier__input {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed-multiplier-step-index {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-speed-multiplier-step-index__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed-multiplier-step-index__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-speed-multiplier-step-index__input {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-start {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-start__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-start__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-start__button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
.snake__game__controls__game-pause {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-pause__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-pause__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-pause__button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
.snake__game__controls__game-reset {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-reset__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-reset__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-reset__button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
.snake__game__controls__game-over {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
background-color: #000;
}
.snake__game__controls__game-over__title {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-over__value {
font-size: 1.5em;
color: #fff;
}
.snake__game__controls__game-over__button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff;
}
Solution 1:[1]
It looks like you're instantiating your snake state variable as an empty array. When you're calling map on it in the middle of your JSX, it's mapping over an empty array and therefore returning nothing.
This is also way too much code for one component to hold. It's very difficult to debug in huge codebases that aren't properly scoped, so I'd suggest trying to divvy this up into 2-3 files and just prop drilling if you need.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Willey Ohana |
