# blockenberg/2.0.11/blocks/2048-game/index.js

Blockenberg — 600+ Advanced Gutenberg Blocks &amp; AI Agent for WordPress Block Editor, version 2.0.11. 187 lines.

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.11/code/blocks/2048-game/index.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.11/raw/blocks/2048-game/index.js
- Modified: 2026-07-22T02:13:48+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/blockenberg/2.0.11/code/blocks/2048-game/index.js#L10-L20`.

```javascript
( function () {
    var el = wp.element.createElement;
    var Fragment = wp.element.Fragment;
    var registerBlockType = wp.blocks.registerBlockType;
    var __ = wp.i18n.__;
    var InspectorControls = wp.blockEditor.InspectorControls;
    var PanelColorSettings = wp.blockEditor.PanelColorSettings;
    var useBlockProps = wp.blockEditor.useBlockProps;
    var RichText = wp.blockEditor.RichText;
    var PanelBody = wp.components.PanelBody;
    var RangeControl = wp.components.RangeControl;
    var ToggleControl = wp.components.ToggleControl;

    /* ── lazy typography helpers ── */
    function _tc() { return window.bkbgTypographyControl || null; }
    Object.defineProperty(window, '__bkG48_tvf', { get: function () { delete window.__bkG48_tvf; return (window.__bkG48_tvf = window.bkbgTypoCssVars || function () { return {}; }); } });
    function getTypoCssVars(a) {
        var o = {};
        Object.assign(o, window.__bkG48_tvf(a.titleTypo || {}, '--bkg48-tt-'));
        Object.assign(o, window.__bkG48_tvf(a.subtitleTypo || {}, '--bkg48-st-'));
        return o;
    }

    var TILE_COLORS = {
        0:    { bg: '#cdc1b4', text: '#776e65' },
        2:    { bg: '#eee4da', text: '#776e65' },
        4:    { bg: '#ede0c8', text: '#776e65' },
        8:    { bg: '#f2b179', text: '#f9f6f2' },
        16:   { bg: '#f59563', text: '#f9f6f2' },
        32:   { bg: '#f67c5f', text: '#f9f6f2' },
        64:   { bg: '#f65e3b', text: '#f9f6f2' },
        128:  { bg: '#edcf72', text: '#f9f6f2' },
        256:  { bg: '#edcc61', text: '#f9f6f2' },
        512:  { bg: '#edc850', text: '#f9f6f2' },
        1024: { bg: '#edc53f', text: '#f9f6f2' },
        2048: { bg: '#edc22e', text: '#f9f6f2' }
    };

    var DEMO = [
        [2,    4,    8,    16   ],
        [32,   64,   128,  256  ],
        [0,    0,    512,  1024 ],
        [0,    0,    0,    2048 ]
    ];

    function TileGrid(props) {
        var a = props;
        var sz    = a.boardSize || 380;
        var gap   = a.gridGap  || 10;
        var rad   = a.tileRadius || 8;
        var cells = [];

        for (var r = 0; r < 4; r++) {
            for (var c = 0; c < 4; c++) {
                var val = DEMO[r][c];
                var tc  = TILE_COLORS[val] || { bg: '#3c3a32', text: '#f9f6f2' };
                var fs  = val < 100 ? 36 : val < 1000 ? 26 : val < 10000 ? 20 : 16;
                cells.push(el('div', {
                    key: r + '_' + c,
                    style: {
                        background: tc.bg,
                        color: tc.text,
                        borderRadius: rad,
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                        fontSize: fs, fontWeight: 700,
                        fontFamily: "'Helvetica Neue', Arial, sans-serif"
                    }
                }, val > 0 ? val : null));
            }
        }

        return el('div', { style: {
            display: 'grid',
            gridTemplateColumns: 'repeat(4,1fr)',
            gap: gap,
            background: a.gridBg || '#bbada0',
            padding: gap,
            borderRadius: rad + gap,
            width: sz, height: sz, boxSizing: 'border-box',
            userSelect: 'none'
        } }, cells);
    }

    function ScoreBox(label, value, bg) {
        return el('div', { style: { background: bg || '#bbada0', borderRadius: 6, padding: '6px 14px', textAlign: 'center', minWidth: 70 } },
            el('div', { style: { fontSize: 11, fontWeight: 700, color: '#eee4da', letterSpacing: 1, textTransform: 'uppercase' } }, label),
            el('div', { style: { fontSize: 22, fontWeight: 700, color: '#fff' } }, value)
        );
    }

    function EditorPreview(props) {
        var a = props.attributes;
        var setAttributes = props.setAttributes;
        var blockProps = useBlockProps((function () {
            var s = getTypoCssVars(a);
            s.background = a.sectionBg || '#fef9ee';
            s.padding = '28px 20px';
            return { style: s };
        })());

        return el(Fragment, null,
            el(InspectorControls, null,
                el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
                    ),
                el(PanelBody, { title: __('Board Settings', 'blockenberg'), initialOpen: false },
                    el(RangeControl, {
                        label: __('Board Size (px)', 'blockenberg'), value: a.boardSize, min: 260, max: 560,
                        onChange: function (v) { setAttributes({ boardSize: v }); }
                    }),
                    el(RangeControl, {
                        label: __('Tile Radius (px)', 'blockenberg'), value: a.tileRadius, min: 0, max: 24,
                        onChange: function (v) { setAttributes({ tileRadius: v }); }
                    }),
                    el(RangeControl, {
                        label: __('Grid Gap (px)', 'blockenberg'), value: a.gridGap, min: 4, max: 20,
                        onChange: function (v) { setAttributes({ gridGap: v }); }
                    }),
                    el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Score', 'blockenberg'), checked: a.showScore, onChange: function (v) { setAttributes({ showScore: v }); } }),
                    el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Best Score', 'blockenberg'), checked: a.showBestScore, onChange: function (v) { setAttributes({ showBestScore: v }); } }),
                    el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Animate Tiles', 'blockenberg'), checked: a.animateTiles, onChange: function (v) { setAttributes({ animateTiles: v }); } })
                ),
                
                el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
                    _tc() && el(_tc(), { label: __('Title', 'blockenberg'), value: a.titleTypo || {}, onChange: function (v) { setAttributes({ titleTypo: v }); } }),
                    _tc() && el(_tc(), { label: __('Subtitle', 'blockenberg'), value: a.subtitleTypo || {}, onChange: function (v) { setAttributes({ subtitleTypo: v }); } })
                ),
el(PanelColorSettings, {
                    title: __('Colors', 'blockenberg'), initialOpen: false,
                    colorSettings: [
                        { label: __('Grid Background', 'blockenberg'),    value: a.gridBg,       onChange: function (v) { setAttributes({ gridBg: v || '#bbada0' }); } },
                        { label: __('Empty Tile', 'blockenberg'),         value: a.tileBg,       onChange: function (v) { setAttributes({ tileBg: v || '#cdc1b4' }); } },
                        { label: __('Section Background', 'blockenberg'), value: a.sectionBg,    onChange: function (v) { setAttributes({ sectionBg: v || '#fef9ee' }); } },
                        { label: __('Title / Text', 'blockenberg'),       value: a.titleColor,   onChange: function (v) { setAttributes({ titleColor: v || '#776e65' }); } },
                        { label: __('Score Header', 'blockenberg'),       value: a.scoreHeaderBg,onChange: function (v) { setAttributes({ scoreHeaderBg: v || '#bbada0' }); } },
                        { label: __('New Game Button', 'blockenberg'),    value: a.newGameBg,    onChange: function (v) { setAttributes({ newGameBg: v || '#8f7a66' }); } }
                    ]
                })
            ),
            el('div', blockProps,
                // Header row
                el('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12, flexWrap: 'wrap', gap: 8 } },
                    el('div', null,
                        el(RichText, {
                            tagName: 'h2', className: 'bkbg-g48-title', value: a.title,
                            onChange: function (v) { setAttributes({ title: v }); },
                            placeholder: '2048',
                            style: { color: a.titleColor, margin: 0 }
                        }),
                        el(RichText, {
                            tagName: 'p', className: 'bkbg-g48-subtitle', value: a.subtitle,
                            onChange: function (v) { setAttributes({ subtitle: v }); },
                            placeholder: 'Combine tiles to reach 2048!',
                            style: { color: a.titleColor, margin: '2px 0 0', opacity: 0.75 }
                        })
                    ),
                    el('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' } },
                        a.showScore     && ScoreBox('Score', '0', a.scoreHeaderBg),
                        a.showBestScore && ScoreBox('Best', '0', a.scoreHeaderBg),
                        el('button', { style: { background: a.newGameBg, color: '#fff', border: 'none', borderRadius: 6, padding: '8px 14px', fontWeight: 700, fontSize: 14, cursor: 'pointer' } }, 'New Game')
                    )
                ),
                // Board preview
                el('div', { style: { display: 'flex', justifyContent: 'center' } },
                    el(TileGrid, a)
                ),
                el('p', { style: { textAlign: 'center', fontSize: 13, color: a.titleColor, opacity: 0.6, marginTop: 10 } },
                    '← → ↑ ↓ arrow keys or swipe to play'
                )
            )
        );
    }

    registerBlockType('blockenberg/game-2048', {
        edit: EditorPreview,
        save: function (props) {
            var a = props.attributes;
            var sv = getTypoCssVars(a);
            return el('div', useBlockProps.save(),
                el('div', { className: 'bkbg-g48-app', 'data-opts': JSON.stringify(a), style: sv },
                    el(RichText.Content, { tagName: 'h2', className: 'bkbg-g48-title', value: a.title }),
                    el(RichText.Content, { tagName: 'p', className: 'bkbg-g48-subtitle', value: a.subtitle })
                )
            );
        }
    });
}() );

```
