Skip to content

Commit

Permalink
Levels 3 to 5 (#5)
Browse files Browse the repository at this point in the history
* Add social/sharing data

* Update README with links to play online

* Add hints for level 2

* Update hints for levels 1 and 2

* Add Level 3. Vases are now transparent

* Level 4 WIP

* WIP level 4

* Update victory screen text with score

* Update level 4

* Add level 5

* Swap levels 4 and 5
  • Loading branch information
shaunanoordin authored Jan 30, 2022
1 parent bd5b5eb commit d809892
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 22 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
This is a Chinese New Year greeting card and mini video game for the Year of the
Tiger. Gong Xi Fa Cai, everyone!

Original code was based on [AvO Adventure Mk3](https://github.com/shaunanoordin/avo-adventure-mk3).
Play it online at [shaunanoordin.github.io/cny2022](https://shaunanoordin.github.io/cny2022/)
or [shaunanoordin.com/cny2022](https://shaunanoordin.com/cny2022/)

Created by [Shaun A. Noordin](https://shaunanoordin.com).
Created by [Shaun A. Noordin](https://shaunanoordin.com). Original code based on
[AvO Adventure Mk3](https://github.com/shaunanoordin/avo-adventure-mk3).

## How to Use

Expand Down
2 changes: 1 addition & 1 deletion app/main.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions app/main.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
<meta property="og:title" content="Chinese New Year 2022 - Year of the Tiger">
<meta property="og:description" content="Chinese New Year greeting card and mini video game for the Year of the Tiger. Gong Xi Fa Cai!">
<meta property="og:type" content="website">
<meta property="og:url" content="">
<meta property="og:image" content="">
<meta property="og:url" content="https://shaunanoordin.github.io/cny2022/">
<meta property="og:image" content="https://shaunanoordin.github.io/cny2022/assets/cny2022.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="0">
<meta property="og:image:height" content="0">
<meta property="og:image:width" content="1280">
<meta property="og:image:height" content="640">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@darke_shard">
<meta name="twitter:creator" content="@darke_shard">
<meta name="twitter:title" content="Chinese New Year 2022 - Year of the Tiger">
<meta name="twitter:description" content="Chinese New Year greeting card and mini video game for the Year of the Tiger. Gong Xi Fa Cai!">
<meta name="twitter:image" content="">
<meta name="twitter:image" content="https://shaunanoordin.github.io/cny2022/assets/cny2022.png">
</head>
<body>
<div id="app">
Expand Down
1 change: 1 addition & 0 deletions src/avo/atom/types/cny2022/vase.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default class Vase extends Atom {
this.colour = 'rgba(32, 32, 64, 0.5)'
this.solid = true
this.movable = true
this.transparent = true
this.x = col * TILE_SIZE + TILE_SIZE / 2
this.y = row * TILE_SIZE + TILE_SIZE / 2

Expand Down
42 changes: 42 additions & 0 deletions src/avo/atom/types/text-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Atom from '@avo/atom'
import { TILE_SIZE } from '@avo/constants'

/*
The TextMessage displays (non-interactable) text on the canvas.
Useful for having in-game instructions.
*/
export default class TextMessage extends Atom {
constructor (app, text, col = 0, row = 0, layer = 0) {
super(app)
this._type = 'text-message'

this.x = col * TILE_SIZE + TILE_SIZE / 2
this.y = row * TILE_SIZE + TILE_SIZE / 2
this.text = text
this.layer = layer

this.colour = 'rgba(0, 0, 0, 0.5)'
this.font = '3em sans-serif'
this.textBaseline = 'middle'
this.textAlign = 'center'

this.solid = false
this.movable = false
}

paint (layer = 0) {
// super.paint(layer)

const c2d = this._app.canvas2d
const camera = this._app.camera

if (layer === this.layer) {
c2d.font = this.font
c2d.textBaseline = this.textBaseline
c2d.textAlign = this.textAlign
c2d.fillStyle = this.colour

c2d.fillText(this.text, this.x, this.y)
}
}
}
188 changes: 183 additions & 5 deletions src/avo/levels.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Hero from '@avo/atom/types/hero'
import Wall from '@avo/atom/types/wall'
import Ball from '@avo/atom/types/ball'
import Enemy from '@avo/atom/types/enemy'
import TextMessage from '@avo/atom/types/text-message'

import Cat from '@avo/atom/types/cny2022/cat'
import LaserPointer from '@avo/atom/types/cny2022/laser-pointer'
Expand All @@ -28,6 +29,9 @@ export default class Levels {
this.cny2022LevelGenerators = [
this.generate_cny2022_level_1.bind(this),
this.generate_cny2022_level_2.bind(this),
this.generate_cny2022_level_3.bind(this),
this.generate_cny2022_level_4.bind(this),
this.generate_cny2022_level_5.bind(this),
]
this.cny2022HighScores = this.cny2022LevelGenerators.map(() => undefined)

Expand Down Expand Up @@ -154,6 +158,14 @@ export default class Levels {
app.atoms.push(new Coin(app, 15 + i * 3, 17))
}

// Hints
const hint1 = new TextMessage(app, '👆 Tap or click to aim laser', 19.5, 9, 0)
const hint2 = new TextMessage(app, 'Get tiger to goal 🐅⬇️', 37.5, 7.5, 0)
hint2.textAlign = 'right'
const hint3 = new TextMessage(app, 'Coins add to score ➡️', 2, 16, 0)
hint3.textAlign = 'left'
app.atoms.push(hint1, hint2, hint3)

this.createOuterWalls()
}

Expand Down Expand Up @@ -188,15 +200,181 @@ export default class Levels {
app.atoms.push(new Coin(app, 6.5, 17.5))

// Vases
app.atoms.push(new Vase(app, 13.5, 9.5))
app.atoms.push(new Vase(app, 16.5, 9.5))
app.atoms.push(new Vase(app, 19.5, 9.5))
app.atoms.push(new Vase(app, 22.5, 9.5))
app.atoms.push(new Vase(app, 25.5, 9.5))
for (let i = 0 ; i < 5 ; i ++ ) {
app.atoms.push(new Vase(app, 13.5 + i * 3, 8.5))
}
for (let i = 0 ; i < 3 ; i ++ ) {
app.atoms.push(new Vase(app, 16.5 + i * 3, 11.5))
}

// Hints
const hint1 = new TextMessage(app, '⬆️ Don\'t break vases!', 19.5, 13.5, 0)
const hint2 = new TextMessage(app, 'Walls block lasers', 19.5, 6, 2)
hint2.colour = 'rgba(255, 255, 255, 0.8)'
app.atoms.push(hint1, hint2)

this.createOuterWalls()
}

generate_cny2022_level_3 () {
const app = this._app

const cat = new Cat(app, 3, (CNY2022_ROWS - 1) / 2)
const laserPointer = new LaserPointer(app, (CNY2022_COLS - 1) / 2, 6.5)
app.atoms.push(cat)
app.atoms.push(laserPointer)
app.addRule(new CNY2022Controls(app, cat, laserPointer))
app.addRule(new CNY2022Victory(app))

// Layout
this.createOuterWalls()
app.atoms.push(new Wall(app, 1, 1, 3, 3, 'se')) // North triangle
app.atoms.push(new Wall(app, 36, 1, 3, 3, 'sw')) // North triangle
app.atoms.push(new Wall(app, 5, 5, 30, 1)) // North wall

app.atoms.push(new GlassWall(app, 17, 6, 1, 2)) // Glass cage
app.atoms.push(new GlassWall(app, 22, 6, 1, 2)) // Glass cage
app.atoms.push(new GlassWall(app, 17, 8, 6, 1)) // Glass cage

app.atoms.push(new Wall(app, 10, 14, 8, 1)) // South wall
app.atoms.push(new Wall(app, 22, 14, 8, 1)) // South wall
app.atoms.push(new Wall(app, 18, 12, 4, 1)) // South wall
app.atoms.push(new Wall(app, 17, 12, 1, 2)) // South wall
app.atoms.push(new Wall(app, 22, 12, 1, 2)) // South wall
app.atoms.push(new Wall(app, 5, 14, 5, 5, 'nw'))
app.atoms.push(new Goal(app, 19.5, 13.5))

// Coins
for (let i = 0 ; i < 6 ; i ++ ) {
app.atoms.push(new Coin(app, 9.5 + i * 4, 2.5))
}
app.atoms.push(new Coin(app, 2.5, 16.5))
app.atoms.push(new Coin(app, 11.5, 16.5))
app.atoms.push(new Coin(app, 27.5, 16.5))
app.atoms.push(new Coin(app, 36.5, 16.5))

// Vases
app.atoms.push(new Vase(app, 8, 9))
app.atoms.push(new Vase(app, 12, 9))
app.atoms.push(new Vase(app, 27, 9))
app.atoms.push(new Vase(app, 31, 9))
app.atoms.push(new Vase(app, 10, 12))
app.atoms.push(new Vase(app, 29, 12))
}

generate_cny2022_level_4 () {
const app = this._app

const cat = new Cat(app, 19.5, 4.5)
const laserPointer = new LaserPointer(app, 19.5, 9.5)
app.atoms.push(cat)
app.atoms.push(laserPointer)
app.addRule(new CNY2022Controls(app, cat, laserPointer))
app.addRule(new CNY2022Victory(app))
this.createOuterWalls()

app.atoms.push(new Goal(app, 19.5, 2))

// Central cage
app.atoms.push(new GlassWall(app, 18, 7, 4, 1))
app.atoms.push(new GlassWall(app, 18, 12, 4, 1))
app.atoms.push(new GlassWall(app, 17, 8, 1, 4))
app.atoms.push(new GlassWall(app, 22, 8, 1, 4))
app.atoms.push(new Wall(app, 18, 9.5, 0.5, 1))
app.atoms.push(new Wall(app, 21.5, 9.5, 0.5, 1))
app.atoms.push(new Wall(app, 19.5, 8, 1, 0.5))
app.atoms.push(new Wall(app, 19.5, 11.5, 1, 0.5))
app.atoms.push(new Vase(app, 19.5, 6))
app.atoms.push(new Vase(app, 19.5, 13))
app.atoms.push(new Vase(app, 16, 9.5))
app.atoms.push(new Vase(app, 23, 9.5))

// Left Side
app.atoms.push(new Coin(app, 4, 3))
app.atoms.push(new Coin(app, 4, 16))
app.atoms.push(new Coin(app, 12, 6))
app.atoms.push(new Coin(app, 12, 13))

app.atoms.push(new Vase(app, 2, 5))
app.atoms.push(new Vase(app, 2, 14))
app.atoms.push(new Vase(app, 7, 7))
app.atoms.push(new Vase(app, 7, 12))
app.atoms.push(new Vase(app, 9, 16))

app.atoms.push(new Wall(app, 2, 7, 1, 6))
app.atoms.push(new Wall(app, 6, 9, 5, 1, 'ne'))
app.atoms.push(new Wall(app, 6, 10, 5, 1, 'se'))

// Middle
app.atoms.push(new Coin(app, 19.5, 15))
app.atoms.push(new Coin(app, 19.5, 17))

// Right Side
app.atoms.push(new Coin(app, 35, 3))
app.atoms.push(new Coin(app, 35, 16))
app.atoms.push(new Coin(app, 27, 6))
app.atoms.push(new Coin(app, 27, 13))

app.atoms.push(new Vase(app, 37, 5))
app.atoms.push(new Vase(app, 37, 14))
app.atoms.push(new Vase(app, 32, 7))
app.atoms.push(new Vase(app, 32, 12))
app.atoms.push(new Vase(app, 30, 16))

app.atoms.push(new Wall(app, 37, 7, 1, 6))
app.atoms.push(new Wall(app, 29, 9, 5, 1, 'nw'))
app.atoms.push(new Wall(app, 29, 10, 5, 1, 'sw'))
}

generate_cny2022_level_5 () {
const app = this._app

const cat = new Cat(app, 19.5, 17)
const laserPointer = new LaserPointer(app, 19.5, 1.5)
// const laserPointer = new LaserPointer(app, 37.5, 1.5)
app.atoms.push(cat)
app.atoms.push(laserPointer)
app.addRule(new CNY2022Controls(app, cat, laserPointer))
app.addRule(new CNY2022Victory(app))
this.createOuterWalls()

// North Wall
app.atoms.push(new GlassWall(app, 4, 3, 35, 1))

// West Wall
app.atoms.push(new GlassWall(app, 4, 7, 1, 9))
app.atoms.push(new Coin(app, 2, 11))

// Eastern Maze
app.atoms.push(new Wall(app, 32, 4, 1, 9)) // East wall
app.atoms.push(new GlassWall(app, 32, 16, 1, 3)) // East wall
app.atoms.push(new GlassWall(app, 33, 6, 4, 1)) // East maze 1
app.atoms.push(new GlassWall(app, 35, 9, 4, 1)) // East maze 2
app.atoms.push(new GlassWall(app, 33, 12, 4, 1)) // East maze 3
app.atoms.push(new Goal(app, 35.5, 17))
app.atoms.push(new Coin(app, 35.5, 4.5))
app.atoms.push(new Coin(app, 35.5, 7.5))
app.atoms.push(new Coin(app, 35.5, 10.5))

// Middle maze
app.atoms.push(new GlassWall(app, 8, 7, 9, 1))
app.atoms.push(new GlassWall(app, 8, 11, 9, 1))
app.atoms.push(new GlassWall(app, 8, 15, 9, 1))
app.atoms.push(new GlassWall(app, 23, 9, 5, 1))
app.atoms.push(new GlassWall(app, 23, 13, 5, 1))
app.atoms.push(new Vase(app, 18, 7))
app.atoms.push(new Vase(app, 18, 11))
app.atoms.push(new Vase(app, 18, 15))
app.atoms.push(new Vase(app, 21, 9))
app.atoms.push(new Vase(app, 21, 13))
app.atoms.push(new Coin(app, 12, 5))
app.atoms.push(new Coin(app, 12, 9))
app.atoms.push(new Coin(app, 12, 13))
app.atoms.push(new Coin(app, 25, 7))
app.atoms.push(new Coin(app, 25, 11))
app.atoms.push(new Coin(app, 25, 15))
}

createOuterWalls () {
const app = this._app
app.atoms.push(new Wall(app, 0, 0, CNY2022_COLS, 1)) // North Wall
Expand Down
19 changes: 14 additions & 5 deletions src/avo/rule/types/cny2022-victory.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class CNY2022Victory extends Rule {
this.returnedToHomeMenu = false // bool: has the home menu been opened?

this.score = 0
this.victoryScore = 0
}

play (timeStep) {
Expand Down Expand Up @@ -71,9 +72,11 @@ export default class CNY2022Victory extends Rule {

// Victory message
if (this.victory) {
const VICTORY_TEXT = 'YOU DID IT!'
const VICTORY_TEXT = `YOU DID IT!`
const SCORE_TEXT = `${this.victoryScore} point${(this.victoryScore === 1)? '' : 's'}`
const VICTORY_X = app.canvasWidth / 2
const VICTORY_Y = app.canvasHeight / 2
const VICTORY_Y = app.canvasHeight / 2 - TILE_SIZE * 0.5
const SCORE_Y = app.canvasHeight / 2 + TILE_SIZE * 0.5
const VICTORY_SIZE_START = 5
const VICTORY_SIZE_END = 10

Expand All @@ -86,14 +89,19 @@ export default class CNY2022Victory extends Rule {
c2d.fillStyle = `rgba(128, 128, 128, ${blockOpacity})`
c2d.fillRect(0, 0, app.canvasWidth, app.canvasHeight)

c2d.font = `${textSize}em Source Code Pro`
c2d.font = `${textSize}em sans-serif`
c2d.textAlign = 'center'
c2d.textBaseline = 'middle'
c2d.lineWidth = 8
c2d.strokeStyle = '#eee'
c2d.strokeText(VICTORY_TEXT, VICTORY_X, VICTORY_Y)
c2d.fillStyle = '#c44'

c2d.textBaseline = 'bottom'
c2d.strokeText(VICTORY_TEXT, VICTORY_X, VICTORY_Y)
c2d.fillText(VICTORY_TEXT, VICTORY_X, VICTORY_Y)

c2d.textBaseline = 'top'
c2d.strokeText(SCORE_TEXT, VICTORY_X, SCORE_Y)
c2d.fillText(SCORE_TEXT, VICTORY_X, SCORE_Y)
}

// Score
Expand All @@ -119,5 +127,6 @@ export default class CNY2022Victory extends Rule {

this._app.levels.registerCNY2022Score(this.score)
this.victory = true
this.victoryScore = this.score
}
}
2 changes: 1 addition & 1 deletion src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ table {
#banner {
#card {
display: block;
max-width: 50%;
max-width: 60%;
margin: 0 auto;
}
}
Expand Down

0 comments on commit d809892

Please sign in to comment.