403Webshell
Server IP : 172.67.187.206  /  Your IP : 172.71.28.156
Web Server : Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30
System : Windows NT WIN-ECQAAA40806 6.2 build 9200 (Windows Server 2012 Standard Edition) i586
User : SYSTEM ( 0)
PHP Version : 5.6.30
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /Inetpub/www/game/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /Inetpub/www/game/train.html
<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>เกมสร้างรถไฟ</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            font-family: 'Arial', sans-serif;
            background-color: #f0f8ff; /* Light blue */
            display: flex;
            flex-direction: column;
            height: 100vh;
            touch-action: manipulation; /* Prevent default touch actions */
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        #palette {
            background-color: #e0e0e0;
            padding: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 15px; /* Adjust gap for more items */
            border-bottom: 2px solid #ccc;
            min-height: 120px;
            overflow-x: auto; /* Allow scrolling on palette if too many items */
            white-space: nowrap;
        }

        .train-part-selection {
            width: 90px; /* Slightly smaller for more items */
            height: 70px;
            background-color: #f9f9f9;
            border: 2px solid #333;
            border-radius: 8px;
            cursor: grab; /* Indicate draggable */
            display: inline-flex; /* Use inline-flex for horizontal scroll */
            flex-direction: column;
            justify-content: center;
            align-items: center;
            font-size: 11px; /* Smaller font */
            font-weight: bold;
            color: #555;
            transition: transform 0.2s, box-shadow 0.2s;
            overflow: hidden;
            flex-shrink: 0; /* Prevent shrinking */
            position: relative; /* For draggable styling */
        }

        .train-part-selection:hover {
            transform: translateY(-3px); /* Smaller hover effect */
            box-shadow: 0 4px 12px rgba(0,0,0,0.2); /* Smaller shadow */
        }
        
        .train-part-selection img {
            max-width: 80%; /* Smaller image */
            max-height: 80%;
            object-fit: contain;
            margin-bottom: 3px;
        }
        
        /* Dragging feedback */
        .dragging {
            opacity: 0.7;
            border-style: dashed;
            box-shadow: 0 0 15px rgba(0, 0, 255, 0.5);
            z-index: 1000; /* Ensure it's on top */
        }

        #game-options {
            background-color: #f0f0f0;
            padding: 10px;
            border-bottom: 1px solid #ddd;
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;
            font-size: 0.9em;
            color: #333;
        }

        #game-options select, #game-options input[type="number"] {
            padding: 5px 10px;
            border-radius: 5px;
            border: 1px solid #ccc;
            font-size: 0.9em;
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
        }
        #game-options label {
            white-space: nowrap;
        }

        #building-area-container {
            flex-grow: 1;
            overflow: hidden;
            position: relative;
            background-color: #c8e6c9; /* Light green (grass) */
            border-top: 5px dashed #8bc34a; /* Top rail */
            border-bottom: 5px dashed #8bc34a; /* Bottom rail */
            
            /* Parallax Background */
            background-image: url('https://www.transparenttextures.com/patterns/clean-textile.png'), url('https://picsum.photos/800/600?random=1'); /* Example textures/image */
            background-repeat: repeat, no-repeat;
            background-size: auto, cover; /* Tile texture, cover image */
            background-position: 0 0, center center;
        }

        #building-area {
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            white-space: nowrap;
            display: flex;
            align-items: flex-end;
            height: 100%;
        }

        .train-part {
            display: inline-block;
            width: 100px;
            height: 80px;
            background-color: #b3e5fc;
            border: 2px solid #333;
            border-left: none;
            position: relative;
            box-sizing: border-box;
            display: flex;
            flex-direction: column; /* For delete button */
            justify-content: center;
            align-items: center;
            font-size: 12px;
            color: #333;
            flex-shrink: 0;
            touch-action: none; /* Disable default touch actions like scroll/zoom for parts */
        }
        .train-part:first-child {
             border-left: 2px solid #333;
        }
        .train-part img {
            max-width: 90%;
            max-height: 90%;
            object-fit: contain;
        }
        /* Wheels */
        .train-part::before, .train-part::after {
            content: '';
            position: absolute;
            bottom: -15px;
            width: 20px;
            height: 20px;
            background-color: #555;
            border-radius: 50%;
            border: 2px solid #222;
        }
        .train-part::before { left: 10px; }
        .train-part::after { right: 10px; }

        .locomotive { background-color: #ef9a9a; }
        .carriage { background-color: #b2dfdb; }
        .cargo { background-color: #ffcc80; }
        .passenger-blue { background-color: #81d4fa; } /* New color */
        .boxcar { background-color: #bcaaa4; } /* New color */

        /* Delete Button on Train Part */
        .delete-part-btn {
            position: absolute;
            top: -5px; /* Adjust as needed */
            right: -5px; /* Adjust as needed */
            background-color: #f44336;
            color: white;
            border-radius: 50%;
            width: 20px;
            height: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 14px;
            font-weight: bold;
            cursor: pointer;
            z-index: 10;
            line-height: 1;
            padding: 0;
            border: 1px solid #a00;
            opacity: 0.8;
            display: none; /* Hide by default, show when editing */
        }
        .delete-part-btn:hover {
            opacity: 1;
            transform: scale(1.1);
        }
        .editable .delete-part-btn {
            display: flex; /* Show delete button when in editable mode */
        }


        #controls {
            background-color: #e0e0e0;
            padding: 15px;
            display: flex;
            justify-content: center;
            gap: 20px;
            border-top: 2px solid #ccc;
        }

        .control-btn {
            padding: 10px 25px;
            font-size: 1.2em;
            font-weight: bold;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            transition: background-color 0.2s, transform 0.2s;
        }

        #run-btn { background-color: #4CAF50; color: white; }
        #run-btn:hover { background-color: #45a049; transform: translateY(-2px); }

        #stop-btn { background-color: #FFC107; color: #333; }
        #stop-btn:hover { background-color: #ffb300; transform: translateY(-2px); }

        #clear-btn { background-color: #F44336; color: white; }
        #clear-btn:hover { background-color: #da190b; transform: translateY(-2px); }

    </style>
</head>
<body>
    <div id="palette">
        <div class="train-part-selection" data-type="locomotive" data-img="https://www.flaticon.com/svg/static/icons/svg/3081/3081977.svg">
            <img src="https://www.flaticon.com/svg/static/icons/svg/3081/3081977.svg" alt="หัวรถจักร"> หัวรถจักร
        </div>
        <div class="train-part-selection" data-type="carriage" data-img="https://www.flaticon.com/svg/static/icons/svg/3081/3081978.svg">
            <img src="https://www.flaticon.com/svg/static/icons/svg/3081/3081978.svg" alt="ตู้โดยสาร"> ตู้โดยสาร
        </div>
        <div class="train-part-selection" data-type="cargo" data-img="https://www.flaticon.com/svg/static/icons/svg/3081/3081979.svg">
            <img src="https://www.flaticon.com/svg/static/icons/svg/3081/3081979.svg" alt="ตู้สินค้า"> ตู้สินค้า
        </div>
        <div class="train-part-selection" data-type="passenger-blue" data-img="https://www.flaticon.com/svg/static/icons/svg/3081/3081980.svg">
            <img src="https://www.flaticon.com/svg/static/icons/svg/3081/3081980.svg" alt="ตู้โดยสารสีฟ้า"> ตู้โดยสารฟ้า
        </div>
         <div class="train-part-selection" data-type="boxcar" data-img="https://www.flaticon.com/svg/static/icons/svg/3081/3081981.svg">
            <img src="https://www.flaticon.com/svg/static/icons/svg/3081/3081981.svg" alt="ตู้บรรทุก"> ตู้บรรทุก
        </div>
    </div>

    <div id="game-options">
        <label for="train-speed-select">ความเร็วรถไฟ:</label>
        <select id="train-speed-select">
            <option value="1">ช้า</option>
            <option value="2" selected>ปานกลาง</option>
            <option value="4">เร็ว</option>
            <option value="8">เร็วมาก</option>
        </select>
        <label for="bg-speed-input">ความเร็วฉากหลัง:</label>
        <input type="number" id="bg-speed-input" value="1" min="0.1" step="0.1">
    </div>

    <div id="building-area-container">
        <div id="building-area">
            </div>
    </div>

    <div id="controls">
        <button id="run-btn" class="control-btn">วิ่ง!</button>
        <button id="stop-btn" class="control-btn">หยุด/แก้ไข</button>
        <button id="clear-btn" class="control-btn">ล้างรถไฟ</button>
    </div>

    <audio id="add-sound" src="https://www.soundjay.com/buttons/beep-07.wav" preload="auto"></audio>
    <audio id="delete-sound" src="https://www.soundjay.com/buttons/beep-06.wav" preload="auto"></audio>
    <audio id="train-run-sound" src="https://www.soundjay.com/transport/train-crossing-bell-01.wav" loop preload="auto"></audio>
    <script>
        const palette = document.getElementById('palette');
        const buildingArea = document.getElementById('building-area');
        const runBtn = document.getElementById('run-btn');
        const stopBtn = document.getElementById('stop-btn');
        const clearBtn = document.getElementById('clear-btn');
        const trainSpeedSelect = document.getElementById('train-speed-select'); // New speed select
        const bgSpeedInput = document.getElementById('bg-speed-input'); // New background speed input

        // Audio elements
        const addSound = document.getElementById('add-sound');
        const deleteSound = document.getElementById('delete-sound');
        const trainRunSound = document.getElementById('train-run-sound');

        let isRunning = false;
        let animationFrameId;
        let trainSpeed = parseFloat(trainSpeedSelect.value); // Initial train speed from select
        let backgroundScrollPos = 0;
        let backgroundSpeed = parseFloat(bgSpeedInput.value); // Initial background speed

        let currentDraggedPart = null; // For drag and drop

        // --- Event Listeners for Game Options ---
        trainSpeedSelect.addEventListener('change', (event) => {
            trainSpeed = parseFloat(event.target.value);
        });

        bgSpeedInput.addEventListener('change', (event) => {
            backgroundSpeed = parseFloat(event.target.value);
        });

        // --- เพิ่มชิ้นส่วนรถไฟเมื่อคลิก/Drag & Drop ---

        // Drag start for palette items
        palette.addEventListener('pointerdown', (e) => {
            if (e.target.closest('.train-part-selection') && !isRunning) {
                e.preventDefault(); // Prevent default browser drag behavior
                currentDraggedPart = e.target.closest('.train-part-selection').cloneNode(true);
                currentDraggedPart.classList.add('dragging');
                currentDraggedPart.style.position = 'absolute';
                currentDraggedPart.style.zIndex = '1000';
                currentDraggedPart.style.pointerEvents = 'none'; // Don't block mouse events
                document.body.appendChild(currentDraggedPart);

                const initialX = e.clientX;
                const initialY = e.clientY;
                const offsetX = e.clientX - e.target.closest('.train-part-selection').getBoundingClientRect().left;
                const offsetY = e.clientY - e.target.closest('.train-part-selection').getBoundingClientRect().top;

                const moveAt = (pageX, pageY) => {
                    currentDraggedPart.style.left = (pageX - offsetX) + 'px';
                    currentDraggedPart.style.top = (pageY - offsetY) + 'px';
                };

                moveAt(e.pageX, e.pageY);

                const onMouseMove = (event) => {
                    moveAt(event.pageX, event.pageY);
                };

                document.addEventListener('pointermove', onMouseMove);

                currentDraggedPart.onpointerup = () => {
                    document.removeEventListener('pointermove', onMouseMove);
                    currentDraggedPart.onpointerup = null;

                    // Check if dropped over building area
                    const buildingAreaRect = buildingArea.getBoundingClientRect();
                    const draggedRect = currentDraggedPart.getBoundingClientRect();

                    if (
                        draggedRect.right > buildingAreaRect.left &&
                        draggedRect.left < buildingAreaRect.right &&
                        draggedRect.bottom > buildingAreaRect.top &&
                        draggedRect.top < buildingAreaRect.bottom
                    ) {
                        // Determine where to add the part (always at the end for simplicity)
                        const partType = currentDraggedPart.dataset.type;
                        addTrainPart(partType, currentDraggedPart.dataset.img);
                    }
                    currentDraggedPart.remove();
                    currentDraggedPart = null;
                };
            }
        });

// Fallback for click (if not dragging) or direct click
palette.addEventListener('click', (event) => {
    if (isRunning || currentDraggedPart) return; // Don't add if running or dragging

    const target = event.target.closest('.train-part-selection');
    if (!target) return;

    const partType = target.dataset.type;
    const partImg = target.dataset.img;
    addTrainPart(partType, partImg);
});

        function addTrainPart(type, img_src) {
            if (isRunning) return; // Double check

            const part = document.createElement('div');
            part.classList.add('train-part', type);
            part.dataset.type = type;

            const img = document.createElement('img');
            img.src = img_src;
            img.alt = type;
            part.appendChild(img);

            // Delete button
            const deleteBtn = document.createElement('button');
            deleteBtn.classList.add('delete-part-btn');
            deleteBtn.textContent = 'X';
            deleteBtn.addEventListener('click', (e) => {
                e.stopPropagation(); // Prevent event from bubbling to parent train-part
                if (!isRunning) {
                    part.remove();
                    deleteSound.play();
                    adjustBuildingAreaPosition(); // Adjust position after deletion
                }
            });
            part.appendChild(deleteBtn);

            // Validation rules
            if (type === 'locomotive') {
                if (buildingArea.querySelector('.locomotive')) {
                    alert('มีหัวรถจักรอยู่แล้ว! รถไฟมีหัวเดียวก็พอจ้า');
                    return;
                }
                // If adding locomotive and there are other parts, move them after locomotive
                if (buildingArea.children.length > 0) {
                     // Find the first non-locomotive part and insert before it
                     const firstNonLocomotive = buildingArea.querySelector('.train-part:not(.locomotive)');
                     if (firstNonLocomotive) {
                         buildingArea.insertBefore(part, firstNonLocomotive);
                     } else {
                         buildingArea.appendChild(part);
                     }
                } else {
                    buildingArea.appendChild(part);
                }
            } else {
                if (!buildingArea.querySelector('.locomotive')) {
                     alert('ต้องมีหัวรถจักรก่อนนะจ๊ะ!');
                     return;
                }
                buildingArea.appendChild(part);
            }
            
            addSound.play();
            adjustBuildingAreaPosition();
        }

        // Adjust building area position to keep train visible
        function adjustBuildingAreaPosition() {
            const trainWidth = buildingArea.scrollWidth;
            const containerWidth = buildingArea.parentElement.offsetWidth;
            let currentLeft = parseFloat(buildingArea.style.left || 0);

            // If the train is too long and goes off the right, pull it left
            if (currentLeft + trainWidth < containerWidth) {
                buildingArea.style.left = (containerWidth - trainWidth) + 'px';
            }
            // If it's too short and too far left, bring it back to 0
            if (currentLeft > 0) {
                 buildingArea.style.left = '0px';
            }
            // Ensure it doesn't go too far left if not running
            if (!isRunning && currentLeft < -(trainWidth - containerWidth) && trainWidth > containerWidth) {
                buildingArea.style.left = -(trainWidth - containerWidth) + 'px';
            }
        }


        // --- การเคลื่อนที่ของรถไฟและฉากหลัง ---
        function animateTrainAndBackground() {
            if (isRunning) {
                let currentLeft = parseFloat(buildingArea.style.left || 0);
                buildingArea.style.left = (currentLeft - trainSpeed) + 'px';

                // Loop the train if it goes off screen
                if (currentLeft < -buildingArea.scrollWidth) {
                    buildingArea.style.left = window.innerWidth + 'px'; // Reset to right of screen
                }

                // Animate background
                backgroundScrollPos -= backgroundSpeed;
                if (backgroundScrollPos <= -buildingArea.parentElement.offsetWidth) {
                    backgroundScrollPos = 0; // Reset background position
                }
                buildingArea.parentElement.style.backgroundPosition = `${backgroundScrollPos}px 0, center center`;
                
                animationFrameId = requestAnimationFrame(animateTrainAndBackground);
            }
        }

        function runTrain() {
            if (buildingArea.children.length === 0) {
                alert('ยังไม่มีรถไฟเลย! สร้างก่อนนะ');
                return;
            }
            if (!buildingArea.querySelector('.locomotive')) {
                alert('รถไฟต้องมีหัวรถจักรนะจ๊ะ!');
                return;
            }

            isRunning = true;
            runBtn.disabled = true;
            stopBtn.disabled = false;
            clearBtn.disabled = true;
            palette.style.pointerEvents = 'none'; // Disable palette interaction
            trainRunSound.play(); // Play train sound

            // Hide delete buttons
            document.querySelectorAll('.train-part').forEach(part => part.classList.remove('editable'));

            // Ensure train starts from a reasonable position if already off-screen
            const currentLeft = parseFloat(buildingArea.style.left || 0);
            if (currentLeft + buildingArea.scrollWidth < 0) { 
                 buildingArea.style.left = window.innerWidth + 'px';
            }
            
            animateTrainAndBackground();
        }

        function stopTrain() {
            isRunning = false;
            runBtn.disabled = false;
            stopBtn.disabled = true;
            clearBtn.disabled = false;
            palette.style.pointerEvents = 'auto'; // Enable palette interaction
            trainRunSound.pause(); // Pause train sound
            trainRunSound.currentTime = 0; // Reset sound

            // Show delete buttons
            document.querySelectorAll('.train-part').forEach(part => part.classList.add('editable'));
            
            cancelAnimationFrame(animationFrameId);
        }

        // --- ปุ่ม "ล้างรถไฟ" ---
        clearBtn.addEventListener('click', () => {
            if (confirm('คุณต้องการล้างรถไฟทั้งหมดใช่หรือไม่?')) {
                buildingArea.innerHTML = ''; // Remove all parts
                buildingArea.style.left = '0px'; // Reset position
                stopTrain(); // Ensure stopped
            }
        });


        // --- Event Listeners for Control Buttons ---
        runBtn.addEventListener('click', runTrain);
        stopBtn.addEventListener('click', stopTrain);

        // Initial setup
        document.addEventListener('DOMContentLoaded', () => {
            stopTrain(); // Start in stopped/editable mode
            buildingArea.style.left = '0px'; // Initial position
        });
    </script>
</body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit