Skip to content

Commit

Permalink
Copying over a bunch of the newer organization and perf work
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyLeland committed Jan 8, 2024
1 parent 7ee4342 commit 507104d
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 298 deletions.
347 changes: 216 additions & 131 deletions games/Frogger/editor.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion games/Frogger/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<title>Frogger v0.85</title>
<title>Frogger v0.9</title>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./ui.css">
Expand Down
2 changes: 1 addition & 1 deletion games/Frogger/levels/classic/road.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"cols":15,"rows":15,"tileInfoKeys":["Grass","Bush","Road"],"tiles":[0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"directions":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"entities":[{"type":"Froggy1","x":0,"y":3,"dir":0},{"type":"Froggy2","x":2,"y":1,"dir":0},{"type":"Froggy3","x":7,"y":2,"dir":1},{"type":"Froggy4","x":13,"y":10,"dir":1},{"type":"Froggy5","x":6,"y":12,"dir":1},{"type":"Froggy6","x":1,"y":12,"dir":1},{"type":"BlueCar","x":14,"y":6,"dir":2},{"type":"BlueCar","x":9,"y":6,"dir":2},{"type":"BlueCar","x":4,"y":6,"dir":2},{"type":"YellowCar","x":13,"y":7,"dir":4},{"type":"YellowCar","x":6,"y":7,"dir":4},{"type":"GreenCar","x":11,"y":8,"dir":2},{"type":"GreenCar","x":3,"y":8,"dir":2}],"spawn":{"x":14,"y":0,"dir":3},"time":18000}
{"cols":15,"rows":15,"tileInfoKeys":["Grass","Bush","Road"],"tiles":[0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"directions":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"entities":[{"type":"Froggy1","x":0,"y":3,"dir":0},{"type":"Froggy2","x":2,"y":1,"dir":0},{"type":"Froggy3","x":7,"y":2,"dir":1},{"type":"Froggy4","x":13,"y":10,"dir":1},{"type":"Froggy5","x":6,"y":12,"dir":1},{"type":"Froggy6","x":1,"y":12,"dir":1},{"type":"BlueCar","x":14,"y":6,"dir":2},{"type":"BlueCar","x":9,"y":6,"dir":2},{"type":"BlueCar","x":4,"y":6,"dir":2},{"type":"YellowCar","x":13,"y":7,"dir":4},{"type":"YellowCar","x":6,"y":7,"dir":4},{"type":"GreenCar","x":11,"y":8,"dir":2},{"type":"GreenCar","x":3,"y":8,"dir":2}],"spawn":{"x":0,"y":0,"dir":3},"time":18000}
1 change: 1 addition & 0 deletions games/Frogger/levels/new/bridge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"cols":15,"rows":15,"tileInfoKeys":["Grass","Water","Road","Bush","Lilypad"],"tiles":[1,1,0,0,0,0,3,0,3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,4,1,1,1,4,1,1,1,4,1,1,0,0,0,1,1,1,4,1,1,1,4,1,1,1,1,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,3,1,1,1,1,3,0,3,1,1,1,1,3,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,4,1,1,3,1,4,1,0,0,3,0,0,3,0,1,1,4,1,0,4,1,1,0,0,0,0,3,0,0,0,1,1,1,1,1,1,0,3,0,0,3,0,0,3,0,1,1,1,1],"directions":[0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,3,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,4,4,4,4,4,4,4,4,3,0,1,2,0,0,0,1,0,0,0,0,0,0,0,4,3,0,1,0,0,4,1,0,0,0,0,0,0,0,0,3,0,1,2,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0],"entities":[{"type":"BlueCar","x":3,"y":6},{"type":"BlueCar","x":9,"y":6},{"type":"Froggy1","x":3,"y":0,"dir":3},{"type":"Froggy2","x":10,"y":0,"dir":3},{"type":"Froggy3","x":0,"y":7,"dir":4},{"type":"Froggy4","x":14,"y":7,"dir":2},{"type":"Froggy5","x":4,"y":13,"dir":1},{"type":"RedCar","x":12,"y":5},{"type":"RedCar","x":6,"y":5},{"type":"RedCar","x":1,"y":5},{"type":"LogMiddle","x":2,"y":2},{"type":"LogStart","x":7,"y":2},{"type":"LogStart","x":1,"y":2},{"type":"LogEnd","x":3,"y":2},{"type":"LogEnd","x":8,"y":2},{"type":"Turtle","x":3,"y":10},{"type":"Turtle","x":7,"y":10},{"type":"Turtle","x":11,"y":10},{"type":"Turtle","x":3,"y":11},{"type":"Turtle","x":7,"y":11},{"type":"Turtle","x":10,"y":12},{"type":"GreenCar","x":12,"y":8},{"type":"GreenCar","x":8,"y":8},{"type":"GreenCar","x":3,"y":8},{"type":"YellowCar","x":10,"y":9},{"type":"YellowCar","x":5,"y":9},{"type":"YellowCar","x":0,"y":9},{"type":"Turtle","x":13,"y":12},{"type":"Turtle","x":0,"y":11},{"type":"LogEnd","x":14,"y":2},{"type":"LogMiddle","x":13,"y":2},{"type":"LogStart","x":12,"y":2},{"type":"Turtle","x":13,"y":1},{"type":"Turtle","x":9,"y":1},{"type":"Turtle","x":5,"y":1},{"type":"Turtle","x":1,"y":1},{"type":"Turtle","x":1,"y":13},{"type":"Froggy6","x":8,"y":14}],"spawn":{"x":7,"y":7,"dir":0},"time":15000}
10 changes: 6 additions & 4 deletions games/Frogger/src/Constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const NumFroggies = 6;
export const MaxLives = 4;

export const TileSize = 48;
export const Constants = {
NumFroggies: 6,
MaxLives: 4,
SpawnDelay: 500,
TileSize: 48,
};
21 changes: 20 additions & 1 deletion games/Frogger/src/Entity.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { Entities } from './Entities.js';

export const Direction = {
None: 0, Up: 1, Left: 2, Down: 3, Right: 4
};

// TODO: Rename DirInfo, put in a better named file?
export const Dir = [
/* none */ { x: 0, y: 0, angle: 0 , dist: ( x, y ) => 0 },
/*Up:*/ { x: 0, y: -1, angle: -Math.PI / 2, dist: ( x, y ) => y - Math.ceil( y - 1 ) },
/*Left:*/ { x: -1, y: 0, angle: Math.PI , dist: ( x, y ) => x - Math.ceil( x - 1 ) },
/*Down:*/ { x: 0, y: 1, angle: Math.PI / 2, dist: ( x, y ) => Math.floor( y + 1 ) - y },
/*Right:*/ { x: 1, y: 0, angle: 0 , dist: ( x, y ) => Math.floor( x + 1 ) - x },
];
];

export class Entity {
static draw( entity, ctx, { dir, action, time } = {} ) {
ctx.save();
ctx.translate( entity.x, entity.y );
ctx.rotate( Dir[ ( dir > 0 ? dir : null ) ?? entity.dir ]?.angle ?? 0 );
// ctx.scale( entity.size, entity.size ); // nothing changes size for now

ctx.strokeStyle = 'black';
ctx.lineWidth = 0.02;

Entities[ entity.type ].draw( ctx, action ?? entity.animationAction, time ?? entity.animationTime ?? 0 );

ctx.restore();
}
}
32 changes: 16 additions & 16 deletions games/Frogger/src/Frog.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,52 +60,52 @@ export class Frog {

const footOffset = -0.1 * Math.sin( animationTime * Math.PI );

const feet = new Path2D();
ctx.beginPath();

[ -1, 1 ].forEach( dir => {
[ -1, 1 ].forEach( side => {
const x = dir * ( FOOT_OFFSET_X + ( animationAction == Frog.Status.SquishedHorizontal ? 0.1 : 0 ) ) + FOOT_SHIFT + footOffset;
const y = side * ( FOOT_OFFSET_Y + ( animationAction == Frog.Status.SquishedVertical ? 0.1 : 0 ) );

feet.moveTo( x, y - FOOT_SIZE / 2 );
feet.lineTo( x + FOOT_SIZE, y - FOOT_SIZE );
feet.quadraticCurveTo(
ctx.moveTo( x, y - FOOT_SIZE / 2 );
ctx.lineTo( x + FOOT_SIZE, y - FOOT_SIZE );
ctx.quadraticCurveTo(
x + FOOT_SIZE + TOE_LENGTH, y,
x + FOOT_SIZE, y + FOOT_SIZE
);
feet.lineTo( x, y + FOOT_SIZE / 2 );
feet.lineTo( x, y - FOOT_SIZE / 2 );
ctx.lineTo( x, y + FOOT_SIZE / 2 );
ctx.lineTo( x, y - FOOT_SIZE / 2 );
} );
} );

ctx.fill( feet );
ctx.stroke( feet );
ctx.fill();
ctx.stroke();

const legs = new Path2D();
ctx.beginPath();

[ -1, 1 ].forEach( dir => {
[ -1, 1 ].forEach( side => {
const footX = dir * ( FOOT_OFFSET_X + ( animationAction == Frog.Status.SquishedHorizontal ? 0.1 : 0 ) ) + FOOT_SHIFT + footOffset;
const footY = FOOT_OFFSET_Y + ( animationAction == Frog.Status.SquishedVertical ? 0.1 : 0 );

// TODO: Change magic numbers to named constants
legs.moveTo( 0, side * ( footY - 0.2 ) );
legs.quadraticCurveTo(
ctx.moveTo( 0, side * ( footY - 0.2 ) );
ctx.quadraticCurveTo(
0, side * footY,
footX, side * ( footY + FOOT_SIZE / 2 ),
);
legs.lineTo( footX, side * ( footY - FOOT_SIZE / 2 ) );
legs.quadraticCurveTo(
ctx.lineTo( footX, side * ( footY - FOOT_SIZE / 2 ) );
ctx.quadraticCurveTo(
dir * 0.1, side * ( footY - 0.1 ),
dir * 0.2, side * ( footY - 0.2 ),
);
} );
} );

legs.closePath();
ctx.closePath();

ctx.fill( legs );
ctx.stroke( legs );
ctx.fill();
ctx.stroke();

if ( animationAction == Frog.Status.SquishedHorizontal ) {
ctx.fill( bodySquishHoriz );
Expand Down
6 changes: 4 additions & 2 deletions games/Frogger/src/FroggerCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const KeyDir = {
export class FroggerCanvas extends AnimatedCanvas {
showUI = true;
scale = 1;

world;

constructor( canvas ) {
super( 100, 100, canvas );
Expand Down Expand Up @@ -56,13 +58,13 @@ export class FroggerCanvas extends AnimatedCanvas {
}

update( dt ) {
this.world.update( dt );
this.world?.update( dt );
}

draw( ctx ) {
ctx.save();
ctx.scale( this.scale, this.scale );

this.world.draw( ctx, this.showUI );
this.world?.draw( ctx, this.showUI );
}
}
81 changes: 18 additions & 63 deletions games/Frogger/src/Level.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
const BASE_W = 0.05, HEAD_W = 0.2, NECK = 0, LEN = 0.2;
const arrow = new Path2D();
arrow.moveTo( -LEN, -BASE_W );
arrow.lineTo( NECK, -BASE_W );
arrow.lineTo( NECK, -HEAD_W );
arrow.lineTo( LEN, 0 );
arrow.lineTo( NECK, HEAD_W );
arrow.lineTo( NECK, BASE_W );
arrow.lineTo( -LEN, BASE_W );
arrow.closePath();

const ARROW_COLOR = '#ff05';
const TILE_BORDER = 1 / 64;

import { Dir } from './Entity.js';
import { Tiles } from './Tiles.js';
import { Props } from './Props.js';
import { TileMap } from './TileMap.js';
Expand Down Expand Up @@ -42,7 +27,6 @@ export class Level
this.directions = Array.from( this.tiles );
}

// TODO: Make this take col,row instead, and have caller do Math.round()?
getTileInfo( x, y ) {
const col = Math.round( x );
const row = Math.round( y );
Expand All @@ -53,42 +37,35 @@ export class Level
}
}

//
// TODO -- make all these use 1D arrays instead of 2D
//
setTileInfo( col, row, tileInfoKey ) {
let tileKeyIndex = this.tileInfoKeys.indexOf( tileInfoKey );
if ( tileKeyIndex < 0 ) {
tileKeyIndex = this.tileInfoKeys.length;
this.tileInfoKeys.push( tileInfoKey );
}

setDirection( dir, col, row ) {
this.tiles[ col ][ row ].dir = dir;
this.tiles[ col + row * this.cols ] = tileKeyIndex;
this.#tileMap = null;
}

let affected = this.entities.find( e => e.x == col && e.y == row );
setDirection( col, row, dir ) {
this.directions[ col + row * this.cols ] = dir;

if ( affected ) {
affected.dir = dir;
}
else if ( this.player.x == col && this.player.y == row ) {
this.player.dir = dir;
}
// May need new tilemap, e.g. this might've affected road lines
this.#tileMap = null;
}

addEntity( type, col, row ) {
this.removeEntity( col, row );

this.entities.push(
new Entity(
Entities[ type ],
{
x: col,
y: row,
// dir: this.tiles[ col ]?.[ row ]?.dir ?? Direction.Right,
}
)
);
addEntity( col, row, type ) {
this.entities.push( { type: type, x: col, y: row } );
}

removeEntity( col, row ) {
this.entities = this.entities.filter( e => e.x != col || e.y != row );
}

//
// TODO: Make all these work for 1D arrays
//
addColumn( col ) {
this.tiles.splice( col, 0,
Array.from( this.tiles[ col ], e => ( { tileInfoKey: e.tileInfoKey, dir: e.dir } ) )
Expand Down Expand Up @@ -156,28 +133,6 @@ export class Level
Props[ 'Bullseye' ].draw( ctx );
}

if ( Level.DebugGrid ) {
ctx.fillStyle = ctx.strokeStyle = ARROW_COLOR;
ctx.lineWidth = TILE_BORDER;
ctx.textAlign = 'center';
ctx.font = '10px Arial'; // work around https://bugzilla.mozilla.org/show_bug.cgi?id=1845828

ctx.strokeRect( -0.5, -0.5, 1, 1 );

const dir = this.directions[ col + row * this.cols ];
if ( dir > 0 ) {
ctx.save();
ctx.rotate( Dir[ dir ].angle );
ctx.fill( arrow );
ctx.restore();
}

ctx.save();
ctx.scale( 0.02, 0.02 ); // work around https://bugzilla.mozilla.org/show_bug.cgi?id=1845828
ctx.fillText( `(${ col },${ row })`, 0, 20 );
ctx.restore();
}

ctx.translate( 1, 0 );
}

Expand Down
Loading

0 comments on commit 507104d

Please sign in to comment.