-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from devshareacademy/connect-four
Connect four game prototype
- Loading branch information
Showing
14 changed files
with
1,452 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/dist | ||
/node_modules | ||
yarn-error.log | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"eslint.format.enable": true, | ||
"eslint.options": { | ||
"overrideConfigFile": "config/.eslintrc" | ||
}, | ||
"editor.defaultFormatter": "dbaeumer.vscode-eslint", | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll.eslint": "explicit" | ||
}, | ||
"cSpell.words": [ | ||
"devshareacademy" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Phaser 3 TypeScript - Connect Four | ||
|
||
A basic Phaser 3 TypeScript prototype of the game Connect Four. | ||
|
||
You can see a live demo of the example here: [Phaser 3 Connect Four](https://devshareacademy.github.io/phaser-3-typescript-games-and-examples/games/connect-four/index.html) | ||
|
||
## Local Development | ||
|
||
### Requirements | ||
|
||
[Node.js](https://nodejs.org) and [Yarn](https://yarnpkg.com/) are required to install dependencies and run scripts via `yarn`. | ||
|
||
[Vite](https://vitejs.dev/) is required to bundle and serve the web application. This is included as part of the projects dev dependencies. | ||
|
||
### Available Commands | ||
|
||
| Command | Description | | ||
|---------|-------------| | ||
| `yarn install --frozen-lockfile` | Install project dependencies | | ||
| `yarn start` | Build project and open web server running project | | ||
| `yarn build` | Builds code bundle for production | | ||
| `yarn lint` | Uses ESLint to lint code | | ||
|
||
### Writing Code | ||
|
||
After cloning the repo, run `yarn install --frozen-lockfile` from your project directory. Then, you can start the local development | ||
server by running `yarn start`. | ||
|
||
After starting the development server with `yarn start`, you can edit any files in the `src` folder | ||
and parcel will automatically recompile and reload your server (available at `http://localhost:8080` | ||
by default). | ||
|
||
### Deploying Code | ||
|
||
After you run the `yarn build` command, your code will be built into a single bundle located at | ||
`dist/*` along with any other assets you project depended. | ||
|
||
If you put the contents of the `dist` folder in a publicly-accessible location (say something like `http://myserver.com`), | ||
you should be able to open `http://myserver.com/index.html` and play your game. | ||
|
||
### Static Assets | ||
|
||
Any static assets like images or audio files should be placed in the `public` folder. It'll then be served at `http://localhost:8080/path-to-file-your-file/file-name.file-type`. | ||
|
||
## Ideas for improvement | ||
|
||
* add support for mobile | ||
* add title & game over screens | ||
* add cpu | ||
* add animations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"root": true, | ||
"extends": "@devshareacademy/eslint-config", | ||
"parserOptions": { | ||
"project": "./tsconfig.json" | ||
}, | ||
"rules": {}, | ||
"ignorePatterns": ["node_modules", "dist"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { defineConfig } from 'vite'; | ||
|
||
export default defineConfig({ | ||
base: "./", | ||
build: { | ||
rollupOptions: { | ||
output: { | ||
entryFileNames: 'assets/js/[name]-[hash].js', | ||
}, | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Basic Phaser 3 Example Template</title> | ||
<style> | ||
html, | ||
body, | ||
.container { | ||
margin: 0px; | ||
height: 100vh; | ||
width: 100vw; | ||
overflow: hidden; | ||
background: #d7d7d7; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container" id="game-container"> | ||
<h1>Phaser 3 - Connect Four</h1> | ||
</div> | ||
<script type="module" src="/src/main.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "@devshareacademy/phaser-3-typescript-game-template", | ||
"version": "1.0.0", | ||
"description": "A basic Phaser 3 Typescript project template that uses Vite.", | ||
"scripts": { | ||
"start": "vite --config config/vite.config.js", | ||
"build": "tsc && vite build --config config/vite.config.js", | ||
"serve": "vite preview --config config/vite.config.js", | ||
"lint": "eslint ./src --ext .ts,.tsx --config ./config/.eslintrc" | ||
}, | ||
"author": "scottwestover", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/devshareacademy/phaser-3-typescript-games-and-examples.git" | ||
}, | ||
"homepage": "https://github.com/devshareacademy/phaser-3-typescript-games-and-examples", | ||
"devDependencies": { | ||
"@devshareacademy/eslint-config": "0.0.16", | ||
"@devshareacademy/prettier-config": "0.0.4", | ||
"@devshareacademy/tsconfig": "0.0.3", | ||
"@typescript-eslint/eslint-plugin": "5.22.0", | ||
"@typescript-eslint/parser": "5.22.0", | ||
"eslint": "8.14.0", | ||
"eslint-config-prettier": "8.5.0", | ||
"eslint-plugin-prettier": "4.0.0", | ||
"prettier": "2.6.2", | ||
"typescript": "4.6.4", | ||
"vite": "2.9.13" | ||
}, | ||
"dependencies": { | ||
"@devshareacademy/connect-four": "0.0.5", | ||
"phaser": "3.55.2" | ||
}, | ||
"resolutions": {}, | ||
"prettier": "@devshareacademy/prettier-config", | ||
"volta": { | ||
"node": "16.15.0", | ||
"yarn": "1.22.11" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
☐ download project assets | ||
☐ update game config | ||
☐ install connect four npm package | ||
☐ load in assets | ||
☐ create board layout | ||
☐ handle player input | ||
☐ update text in ui | ||
☐ handle hover events | ||
☐ handle click events | ||
☐ add game piece | ||
☐ handle game over | ||
☐ draw winner message box | ||
☐ update text in ui | ||
☐ reset game |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import * as Phaser from 'phaser'; | ||
import { ConnectFour } from '@devshareacademy/connect-four'; | ||
import { Player } from '@devshareacademy/connect-four/dist/types'; | ||
|
||
const ASSET_KEY = 'spritesheet'; | ||
const SCALE_SIZE = 2; | ||
const FRAME_SIZE = 32; | ||
const SCALED_FRAME_SIZE = SCALE_SIZE * FRAME_SIZE; | ||
const GAME_HEIGHT = SCALED_FRAME_SIZE * 6; | ||
const GAME_WIDTH = SCALED_FRAME_SIZE * 7; | ||
|
||
class Game extends Phaser.Scene { | ||
private connectFour!: ConnectFour; | ||
|
||
constructor() { | ||
super({ key: 'Game' }); | ||
} | ||
|
||
public init(): void { | ||
this.connectFour = new ConnectFour(); | ||
} | ||
|
||
public preload(): void { | ||
// load in data | ||
this.load.spritesheet(ASSET_KEY, 'assets/images/connect-four.png', { | ||
frameWidth: 32, | ||
frameHeight: 32, | ||
}); | ||
} | ||
|
||
public create(): void { | ||
// Create game objects | ||
this.createBoard(); | ||
this.createInputColumns(); | ||
} | ||
|
||
private createBoard(): void { | ||
for (let i = 0; i < this.connectFour.board[0].length; i++) { | ||
for (let j = 0; j < this.connectFour.board.length; j++) { | ||
const x = i * SCALED_FRAME_SIZE; | ||
const y = j * SCALED_FRAME_SIZE; | ||
this.add.image(x, y, ASSET_KEY, 2).setOrigin(0).setScale(SCALE_SIZE).setDepth(2); | ||
} | ||
} | ||
} | ||
|
||
private createInputColumns(): void { | ||
const columnIndexKey = 'columnIndex'; | ||
|
||
// create the columns for the game and make them interactive | ||
for (let i = 0; i < this.connectFour.board[0].length; i++) { | ||
const x = i * SCALED_FRAME_SIZE; | ||
const rect = this.add.rectangle(x, 0, SCALED_FRAME_SIZE, GAME_HEIGHT, 0xffff00).setOrigin(0).setInteractive(); | ||
rect.setAlpha(0.01); | ||
rect.setData(columnIndexKey, i); | ||
rect.on(Phaser.Input.Events.POINTER_OVER as string, () => { | ||
if (this.connectFour.isGameOver) { | ||
return; | ||
} | ||
rect.setAlpha(0.2); | ||
}); | ||
rect.on(Phaser.Input.Events.POINTER_OUT as string, () => { | ||
rect.setAlpha(0.01); | ||
}); | ||
rect.on(Phaser.Input.Events.POINTER_DOWN as string, () => { | ||
if (this.connectFour.isGameOver) { | ||
return; | ||
} | ||
|
||
const currentPlayer = this.connectFour.playersTurn; | ||
const coordinate = this.connectFour.makeMove(rect.getData(columnIndexKey) as number); | ||
this.addGamePiece(coordinate.row, coordinate.col, currentPlayer); | ||
}); | ||
} | ||
} | ||
|
||
private addGamePiece(row: number, col: number, player: string): void { | ||
const gamePieceFrame = player === Player.ONE ? 0 : 1; | ||
const x = col * SCALED_FRAME_SIZE; | ||
const y = row * SCALED_FRAME_SIZE; | ||
this.add.image(x, y, ASSET_KEY, gamePieceFrame).setOrigin(0).setScale(SCALE_SIZE).setDepth(1); | ||
this.checkForGameOver(); | ||
} | ||
|
||
private checkForGameOver(): void { | ||
if (!this.connectFour.isGameOver) { | ||
return; | ||
} | ||
|
||
this.add | ||
.rectangle(20, GAME_HEIGHT / 3, GAME_WIDTH - 40, GAME_HEIGHT / 4, 0x000000) | ||
.setOrigin(0) | ||
.setDepth(4) | ||
.setInteractive() | ||
.once(Phaser.Input.Events.POINTER_DOWN as string, () => { | ||
this.scene.restart(); | ||
}); | ||
|
||
let winText = 'Draw'; | ||
if (this.connectFour.gameWinner) { | ||
winText = `Player ${this.connectFour.gameWinner} Wins!`; | ||
} | ||
|
||
this.add | ||
.text(GAME_WIDTH / 2, GAME_HEIGHT / 3 + 30, winText, { fontSize: '32px' }) | ||
.setOrigin(0.5) | ||
.setDepth(5); | ||
this.add | ||
.text(GAME_WIDTH / 2, GAME_HEIGHT / 2 + 15, 'Click here to play again!') | ||
.setOrigin(0.5) | ||
.setDepth(5); | ||
} | ||
} | ||
|
||
const gameConfig: Phaser.Types.Core.GameConfig = { | ||
type: Phaser.CANVAS, | ||
pixelArt: true, | ||
scale: { | ||
parent: 'game-container', | ||
width: GAME_WIDTH, | ||
height: GAME_HEIGHT, | ||
}, | ||
backgroundColor: '#5c5b5b', | ||
scene: [Game], | ||
}; | ||
|
||
const game = new Phaser.Game(gameConfig); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"extends": "@devshareacademy/tsconfig/tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "dist", | ||
"typeRoots": [ | ||
"node_modules/@types" | ||
] | ||
}, | ||
"include": [ | ||
"**/*.ts" | ||
], | ||
"ts-node": { | ||
"compilerOptions": { | ||
"module": "commonjs" | ||
} | ||
} | ||
} |
Oops, something went wrong.