Use vue, migrate emoji table to vue

This commit is contained in:
evanpelle
2024-10-11 17:47:35 -07:00
parent 0904125b69
commit d85370dc19
16 changed files with 234 additions and 207 deletions
+61 -8
View File
@@ -22,6 +22,7 @@
"googleapis": "^143.0.0", "googleapis": "^143.0.0",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"jimp": "^0.22.12", "jimp": "^0.22.12",
"lit": "^3.2.1",
"msgpack5": "^6.0.2", "msgpack5": "^6.0.2",
"node-addon-api": "^8.1.0", "node-addon-api": "^8.1.0",
"node-gyp": "^10.2.0", "node-gyp": "^10.2.0",
@@ -43,7 +44,7 @@
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/mocha": "^10.0.7", "@types/mocha": "^10.0.7",
"@types/node": "^22.5.2", "@types/node": "^22.7.5",
"@types/sinon": "^17.0.3", "@types/sinon": "^17.0.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/ws": "^8.5.11", "@types/ws": "^8.5.11",
@@ -69,7 +70,7 @@
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"tsx": "^4.17.0", "tsx": "^4.17.0",
"typescript": "^5.5.4", "typescript": "^5.6.3",
"webpack": "^5.91.0", "webpack": "^5.91.0",
"webpack-cli": "^5.1.4", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4" "webpack-dev-server": "^5.0.4"
@@ -3655,6 +3656,21 @@
"integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
"dev": true "dev": true
}, },
"node_modules/@lit-labs/ssr-dom-shim": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz",
"integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==",
"license": "BSD-3-Clause"
},
"node_modules/@lit/reactive-element": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz",
"integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==",
"license": "BSD-3-Clause",
"dependencies": {
"@lit-labs/ssr-dom-shim": "^1.2.0"
}
},
"node_modules/@npmcli/agent": { "node_modules/@npmcli/agent": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz",
@@ -4428,9 +4444,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.5.2", "version": "22.7.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
"integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==", "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@@ -4542,6 +4558,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
"node_modules/@types/uuid": { "node_modules/@types/uuid": {
"version": "10.0.0", "version": "10.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
@@ -9990,6 +10012,37 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/lit": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz",
"integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==",
"license": "BSD-3-Clause",
"dependencies": {
"@lit/reactive-element": "^2.0.4",
"lit-element": "^4.1.0",
"lit-html": "^3.2.0"
}
},
"node_modules/lit-element": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz",
"integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==",
"license": "BSD-3-Clause",
"dependencies": {
"@lit-labs/ssr-dom-shim": "^1.2.0",
"@lit/reactive-element": "^2.0.4",
"lit-html": "^3.2.0"
}
},
"node_modules/lit-html": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz",
"integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==",
"license": "BSD-3-Clause",
"dependencies": {
"@types/trusted-types": "^2.0.2"
}
},
"node_modules/load-bmfont": { "node_modules/load-bmfont": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz",
@@ -13470,9 +13523,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.5.4", "version": "5.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
+3 -2
View File
@@ -20,7 +20,7 @@
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/mocha": "^10.0.7", "@types/mocha": "^10.0.7",
"@types/node": "^22.5.2", "@types/node": "^22.7.5",
"@types/sinon": "^17.0.3", "@types/sinon": "^17.0.3",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/ws": "^8.5.11", "@types/ws": "^8.5.11",
@@ -46,7 +46,7 @@
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"tsx": "^4.17.0", "tsx": "^4.17.0",
"typescript": "^5.5.4", "typescript": "^5.6.3",
"webpack": "^5.91.0", "webpack": "^5.91.0",
"webpack-cli": "^5.1.4", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4" "webpack-dev-server": "^5.0.4"
@@ -68,6 +68,7 @@
"googleapis": "^143.0.0", "googleapis": "^143.0.0",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"jimp": "^0.22.12", "jimp": "^0.22.12",
"lit": "^3.2.1",
"msgpack5": "^6.0.2", "msgpack5": "^6.0.2",
"node-addon-api": "^8.1.0", "node-addon-api": "^8.1.0",
"node-gyp": "^10.2.0", "node-gyp": "^10.2.0",
+9 -4
View File
@@ -8,19 +8,24 @@ import {EventBus} from "../../core/EventBus";
import {TransformHandler} from "./TransformHandler"; import {TransformHandler} from "./TransformHandler";
import {Layer} from "./layers/Layer"; import {Layer} from "./layers/Layer";
import {EventsDisplay} from "./layers/EventsDisplay"; import {EventsDisplay} from "./layers/EventsDisplay";
import {RadialMenu} from "./layers/RadialMenu"; import {RadialMenu} from "./layers/radial/RadialMenu";
import {EmojiTable} from "./layers/radial/EmojiTable";
export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer { export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: EventBus, clientID: ClientID): GameRenderer {
const transformHandler = new TransformHandler(game, eventBus, canvas) const transformHandler = new TransformHandler(game, eventBus, canvas)
const emojiTable = document.querySelector('emoji-table') as EmojiTable;
if (!emojiTable || !(emojiTable instanceof EmojiTable)) {
console.error('EmojiTable element not found in the DOM');
}
const layers: Layer[] = [ const layers: Layer[] = [
new TerrainLayer(game), new TerrainLayer(game),
new TerritoryLayer(game, eventBus), new TerritoryLayer(game, eventBus),
new NameLayer(game, game.config().theme(), transformHandler, clientID), new NameLayer(game, game.config().theme(), transformHandler, clientID),
new UILayer(eventBus, game, clientID, transformHandler), new UILayer(eventBus, game, clientID, transformHandler),
new EventsDisplay(eventBus, game, clientID), new EventsDisplay(eventBus, game, clientID),
new RadialMenu(eventBus, game, transformHandler, clientID), new RadialMenu(eventBus, game, transformHandler, clientID, emojiTable as EmojiTable),
] ]
return new GameRenderer(game, eventBus, canvas, transformHandler, layers) return new GameRenderer(game, eventBus, canvas, transformHandler, layers)
@@ -65,7 +70,7 @@ export class GameRenderer {
this.layers.forEach(l => { this.layers.forEach(l => {
if (l.shouldTransform()) { if (l.shouldTransform()) {
l.render(this.context) l.renderLayer(this.context)
} }
}) })
@@ -73,7 +78,7 @@ export class GameRenderer {
this.layers.forEach(l => { this.layers.forEach(l => {
if (!l.shouldTransform()) { if (!l.shouldTransform()) {
l.render(this.context) l.renderLayer(this.context)
} }
}) })
+1 -1
View File
@@ -263,7 +263,7 @@ export class EventsDisplay implements Layer {
this.events[index] = event; this.events[index] = event;
} }
render(): void { } renderLayer(): void { }
renderTable(): void { renderTable(): void {
if (this.events.length === 0) { if (this.events.length === 0) {
+1 -1
View File
@@ -3,6 +3,6 @@ import {TransformHandler} from "../TransformHandler"
export interface Layer { export interface Layer {
init() init()
tick() tick()
render(context: CanvasRenderingContext2D) renderLayer(context: CanvasRenderingContext2D)
shouldTransform(): boolean shouldTransform(): boolean
} }
+1 -1
View File
@@ -100,7 +100,7 @@ export class NameLayer implements Layer {
} }
} }
public render(mainContex: CanvasRenderingContext2D) { public renderLayer(mainContex: CanvasRenderingContext2D) {
const [upperLeft, bottomRight] = this.transformHandler.screenBoundingRect() const [upperLeft, bottomRight] = this.transformHandler.screenBoundingRect()
for (const render of this.renders) { for (const render of this.renders) {
render.isVisible = this.isVisible(render, upperLeft, bottomRight) render.isVisible = this.isVisible(render, upperLeft, bottomRight)
+1 -1
View File
@@ -41,7 +41,7 @@ export class TerrainLayer implements Layer {
}) })
} }
render(context: CanvasRenderingContext2D) { renderLayer(context: CanvasRenderingContext2D) {
context.drawImage( context.drawImage(
this.canvas, this.canvas,
-this.game.width() / 2, -this.game.width() / 2,
+1 -1
View File
@@ -50,7 +50,7 @@ export class TerritoryLayer implements Layer {
}) })
} }
render(context: CanvasRenderingContext2D) { renderLayer(context: CanvasRenderingContext2D) {
this.renderTerritory() this.renderTerritory()
this.context.putImageData(this.imageData, 0, 0); this.context.putImageData(this.imageData, 0, 0);
context.drawImage( context.drawImage(
+1 -1
View File
@@ -30,7 +30,7 @@ export class UILayer implements Layer {
} }
render(context: CanvasRenderingContext2D) { renderLayer(context: CanvasRenderingContext2D) {
if (!this.game.inSpawnPhase()) { if (!this.game.inSpawnPhase()) {
return return
} }
@@ -0,0 +1,107 @@
import {LitElement, html, css} from 'lit';
import {customElement, state} from 'lit/decorators.js';
const emojiTable: string[][] = [
["😀", "😱", "🤩", "🎯", "🥺"],
["🪦", "👏", "🥉", "🥈", "🥇"],
["🤙", "🥰", "😇", "😊", "🔥"],
["💪", "🥳", "💀", "😭", "🤦‍♂️"],
["😎", "👎", "👍", "🥱", "💔"],
["❤️", "💰", "🤝", "🛡️", "💥"],
["🆘", "🕊️", "➡️", "⬅️", "↙️"],
["↖️", "↗️", "⬆️", "↘️", "⬇️"]
];
@customElement('emoji-table')
export class EmojiTable extends LitElement {
static styles = css`
:host {
display: block;
}
.emoji-table {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
background-color: #1E1E1E;
padding: 15px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
max-width: 95vw;
max-height: 95vh;
overflow-y: auto;
}
.emoji-row {
display: flex;
justify-content: center;
width: 100%;
}
.emoji-button {
font-size: 60px;
width: 80px;
height: 80px;
border: 1px solid #333;
background-color: #2C2C2C;
color: white;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
margin: 8px;
}
.emoji-button:hover {
background-color: #3A3A3A;
transform: scale(1.1);
}
.emoji-button:active {
background-color: #4A4A4A;
transform: scale(0.95);
}
.hidden {
display: none !important;
}
`;
@state()
private _hidden = true;
public onEmojiClicked: (emoji: string) => void = () => { }
render() {
return html`
<div class="emoji-table ${this._hidden ? 'hidden' : ''}">
${emojiTable.map(row => html`
<div class="emoji-row">
${row.map(emoji => html`
<button class="emoji-button" @click=${() => this.onEmojiClicked(emoji)}>
${emoji}
</button>
`)}
</div>
`)}
</div>
`;
}
hideTable() {
this._hidden = true;
this.requestUpdate();
}
showTable() {
this._hidden = false;
this.requestUpdate();
}
get isVisible() {
return !this._hidden;
}
}
@@ -1,21 +1,21 @@
import {EventBus} from "../../../core/EventBus"; import {EventBus} from "../../../../core/EventBus";
import {AllPlayers, Cell, Game, Player} from "../../../core/game/Game"; import {AllPlayers, Cell, Game, Player} from "../../../../core/game/Game";
import {ClientID} from "../../../core/Schemas"; import {ClientID} from "../../../../core/Schemas";
import {and, bfs, dist, manhattanDist, manhattanDistWrapped, sourceDstOceanShore} from "../../../core/Util"; import {and, bfs, dist, manhattanDist, manhattanDistWrapped, sourceDstOceanShore} from "../../../../core/Util";
import {ContextMenuEvent, MouseUpEvent} from "../../InputHandler"; import {ContextMenuEvent, MouseUpEvent} from "../../../InputHandler";
import {SendAllianceRequestIntentEvent, SendAttackIntentEvent, SendBoatAttackIntentEvent, SendBreakAllianceIntentEvent, SendDonateIntentEvent, SendEmojiIntentEvent, SendSpawnIntentEvent, SendTargetPlayerIntentEvent} from "../../Transport"; import {SendAllianceRequestIntentEvent, SendAttackIntentEvent, SendBoatAttackIntentEvent, SendBreakAllianceIntentEvent, SendDonateIntentEvent, SendEmojiIntentEvent, SendSpawnIntentEvent, SendTargetPlayerIntentEvent} from "../../../Transport";
import {TransformHandler} from "../TransformHandler"; import {TransformHandler} from "../../TransformHandler";
import {Layer} from "./Layer"; import {Layer} from "../Layer";
import * as d3 from 'd3'; import * as d3 from 'd3';
import traitorIcon from '../../../../resources/images/TraitorIconWhite.png'; import traitorIcon from '../../../../../resources/images/TraitorIconWhite.png';
import allianceIcon from '../../../../resources/images/AllianceIconWhite.png'; import allianceIcon from '../../../../../resources/images/AllianceIconWhite.png';
import boatIcon from '../../../../resources/images/BoatIconWhite.png'; import boatIcon from '../../../../../resources/images/BoatIconWhite.png';
import swordIcon from '../../../../resources/images/SwordIconWhite.png'; import swordIcon from '../../../../../resources/images/SwordIconWhite.png';
import targetIcon from '../../../../resources/images/TargetIconWhite.png'; import targetIcon from '../../../../../resources/images/TargetIconWhite.png';
import emojiIcon from '../../../../resources/images/EmojiIconWhite.png'; import emojiIcon from '../../../../../resources/images/EmojiIconWhite.png';
import disabledIcon from '../../../../resources/images/DisabledIcon.png'; import disabledIcon from '../../../../../resources/images/DisabledIcon.png';
import donateIcon from '../../../../resources/images/DonateIconWhite.png'; import donateIcon from '../../../../../resources/images/DonateIconWhite.png';
import {MessageType} from "./EventsDisplay"; import {EmojiTable} from "./EmojiTable";
enum Slot { enum Slot {
@@ -45,12 +45,12 @@ export class RadialMenu implements Layer {
private isCenterButtonEnabled = false private isCenterButtonEnabled = false
constructor( constructor(
private eventBus: EventBus, private eventBus: EventBus,
private game: Game, private game: Game,
private transformHandler: TransformHandler, private transformHandler: TransformHandler,
private clientID: ClientID, private clientID: ClientID,
private emojiTable: EmojiTable
) { } ) { }
init() { init() {
@@ -59,49 +59,6 @@ export class RadialMenu implements Layer {
this.createMenuElement(); this.createMenuElement();
} }
private hideEmojiTable(): void {
const emojiTable: HTMLTableElement | null = document.getElementById('uniqueEmojiTable') as HTMLTableElement | null;
if (emojiTable instanceof HTMLTableElement) {
if (!emojiTable.classList.contains('hidden')) {
emojiTable.classList.add('hidden');
}
} else {
console.error('Emoji table not found');
}
}
private showEmojiTable(recipient: Player | typeof AllPlayers): void {
const emojiTable: HTMLTableElement | null = document.getElementById('uniqueEmojiTable') as HTMLTableElement | null;
if (emojiTable instanceof HTMLTableElement) {
emojiTable.classList.remove('hidden');
} else {
console.error('Emoji table not found');
}
this.setupEmojiButtons(recipient)
}
private setupEmojiButtons(recipient: Player | typeof AllPlayers) {
let emojiTable = document.getElementById('uniqueEmojiTable');
if (emojiTable) {
// Remove existing listeners
emojiTable.replaceWith(emojiTable.cloneNode(true));
emojiTable = document.getElementById('uniqueEmojiTable');
emojiTable.addEventListener('click', (event) => {
const emojiElement = event.target as HTMLElement;
if (emojiElement.classList.contains('emoji-button')) {
const emoji = emojiElement.textContent;
this.hideEmojiTable()
this.eventBus.emit(new SendEmojiIntentEvent(recipient, emoji))
}
});
} else {
console.error('Emoji table not found');
}
}
private createMenuElement() { private createMenuElement() {
this.menuElement = d3.select(document.body) this.menuElement = d3.select(document.body)
.append('div') .append('div')
@@ -227,7 +184,7 @@ export class RadialMenu implements Layer {
// Update logic if needed // Update logic if needed
} }
render(context: CanvasRenderingContext2D) { renderLayer(context: CanvasRenderingContext2D) {
// No need to render anything on the canvas // No need to render anything on the canvas
} }
@@ -272,7 +229,11 @@ export class RadialMenu implements Layer {
const target = tile.owner() == myPlayer ? AllPlayers : (tile.owner() as Player) const target = tile.owner() == myPlayer ? AllPlayers : (tile.owner() as Player)
if (myPlayer.canSendEmoji(target)) { if (myPlayer.canSendEmoji(target)) {
this.activateMenuElement(Slot.Emoji, "#ebe250", emojiIcon, () => { this.activateMenuElement(Slot.Emoji, "#ebe250", emojiIcon, () => {
this.showEmojiTable(target) this.emojiTable.onEmojiClicked = (emoji: string) => {
this.emojiTable.hideTable()
this.eventBus.emit(new SendEmojiIntentEvent(target, emoji))
}
this.emojiTable.showTable()
}) })
} }
} }
@@ -387,7 +348,7 @@ export class RadialMenu implements Layer {
private onPointerUp(event: MouseUpEvent) { private onPointerUp(event: MouseUpEvent) {
this.hideRadialMenu() this.hideRadialMenu()
this.hideEmojiTable() this.emojiTable.hideTable()
} }
private showRadialMenu(x: number, y: number) { private showRadialMenu(x: number, y: number) {
+1 -58
View File
@@ -79,64 +79,7 @@
<div id="app"></div> <div id="app"></div>
<div id="radialMenu" class="radial-menu"></div> <div id="radialMenu" class="radial-menu"></div>
<table id="uniqueEmojiTable" class="emoji-table hidden"> <emoji-table></emoji-table>
<tr>
<td><button class="emoji-button">😀</button></td>
<td><button class="emoji-button">😱</button></td>
<td><button class="emoji-button">🤩</button></td>
<td><button class="emoji-button">🎯</button></td>
<td><button class="emoji-button">🥺</button></td>
</tr>
<tr>
<td><button class="emoji-button">🪦</button></td>
<td><button class="emoji-button">👏</button></td>
<td><button class="emoji-button">🥉</button></td>
<td><button class="emoji-button">🥈</button></td>
<td><button class="emoji-button">🥇</button></td>
</tr>
<tr>
<td><button class="emoji-button">🤙</button></td>
<td><button class="emoji-button">🥰</button></td>
<td><button class="emoji-button">😇</button></td>
<td><button class="emoji-button">😊</button></td>
<td><button class="emoji-button">🔥</button></td>
</tr>
<tr>
<td><button class="emoji-button">💪</button></td>
<td><button class="emoji-button">🥳</button></td>
<td><button class="emoji-button">💀</button></td>
<td><button class="emoji-button">😭</button></td>
<td><button class="emoji-button">🤦‍♂️</button></td>
</tr>
<tr>
<td><button class="emoji-button">😎</button></td>
<td><button class="emoji-button">👎</button></td>
<td><button class="emoji-button">👍</button></td>
<td><button class="emoji-button">🥱</button></td>
<td><button class="emoji-button">💔</button></td>
</tr>
<tr>
<td><button class="emoji-button">❤️</button></td>
<td><button class="emoji-button">💰</button></td>
<td><button class="emoji-button">🤝</button></td>
<td><button class="emoji-button">🛡️</button></td>
<td><button class="emoji-button">💥</button></td>
</tr>
<tr>
<td><button class="emoji-button">🆘</button></td>
<td><button class="emoji-button">🕊️</button></td>
<td><button class="emoji-button">➡️</button></td>
<td><button class="emoji-button">⬅️</button></td>
<td><button class="emoji-button">↙️</button></td>
</tr>
<tr>
<td><button class="emoji-button">↖️</button></td>
<td><button class="emoji-button">↗️</button></td>
<td><button class="emoji-button">⬆️</button></td>
<td><button class="emoji-button">↘️</button></td>
<td><button class="emoji-button">⬇️</button></td>
</tr>
</table>
<style> <style>
body { body {
+12
View File
@@ -0,0 +1,12 @@
import {LitElement, html, css} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('my-element')
export class MyElement extends LitElement {
@property()
name = 'World';
render() {
return html`<p>Hello, ${this.name}!</p>`;
}
}
-57
View File
@@ -406,64 +406,7 @@ h3 {
} }
/* EMOJI Table */ /* EMOJI Table */
.emoji-table {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
background-color: #1E1E1E;
padding: 15px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
max-width: 95vw;
max-height: 95vh;
overflow-y: auto;
}
.emoji-row {
display: flex;
justify-content: center;
width: 100%;
}
.emoji-button {
font-size: 60px;
/* Increased font size for larger emojis */
width: 80px;
/* Increased width */
height: 80px;
/* Increased height */
border: 1px solid #333;
background-color: #2C2C2C;
color: white;
border-radius: 12px;
/* Slightly increased border radius */
cursor: pointer;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
margin: 8px;
/* Increased margin */
}
.emoji-button:hover {
background-color: #3A3A3A;
transform: scale(1.1);
}
.emoji-button:active {
background-color: #4A4A4A;
transform: scale(0.95);
}
.emoji-table.hidden {
display: none;
}
@media (max-width: 600px) { @media (max-width: 600px) {
.emoji-button { .emoji-button {
+6 -6
View File
@@ -8,12 +8,12 @@ export const devConfig = new class extends DefaultConfig {
numSpawnPhaseTurns(): number { numSpawnPhaseTurns(): number {
return 40 return 40
} }
// gameCreationRate(): number { gameCreationRate(): number {
// return 2 * 1000 return 2 * 1000
// } }
// lobbyLifetime(): number { lobbyLifetime(): number {
// return 2 * 1000 return 2 * 1000
// } }
turnIntervalMs(): number { turnIntervalMs(): number {
return 100 return 100
} }
+3 -1
View File
@@ -6,7 +6,9 @@
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true, "sourceMap": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true "esModuleInterop": true,
"experimentalDecorators": true,
"useDefineForClassFields": false,
}, },
"include": [ "include": [
"src/**/*", "src/**/*",