• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

JavaScript Zuweisung

Jona$3006

Neues Mitglied
Ich habe ein Tetris Spiel mit Hilfe eines Tutorials gemacht. Jetzt würde ich gerne die Farben der einzelnen Formen durch Bilder ersetzen. Wäre es irgendwie möglich, dass man den einzelnen Zahlen in den Formen ein Bild zuweisen kann? Das Bild für 1 in Tetrominos 'I' lightBlueBlock.png


Code:
    const tetrominos = {
        'I': [
            [0,0,0,0],
            [1,1,1,1],
            [0,0,0,0],
            [0,0,0,0],
        ],


        'J': [
            [2,0,0],
            [2,2,2],
            [0,0,0],
        ],


        'L': [
            [0,0,3],
            [3,3,3],
            [0,0,0],
        ],


        'O': [
            [4,4],
            [4,4],
        ],


        'S': [
            [0,5,5],
            [5,5,0],
            [0,0,0],
        ],


        'Z': [
            [6,6,0],
            [0,6,6],
            [0,0,0],
        ],


        'T': [
            [0,7,0],
            [7,7,7],
            [0,0,0],
        ],
    };


    const colors = {
        'I': '#00eeef',
        'O': '#f3f106',
        'T': '#9e02ec',
        'S': '#00f300',
        'Z': '#f30005',
        'J': '#0103eb',
        'L': '#f0a003'
    };
 

Sempervivum

Senior HTML'ler
Das ist ganz sicher möglich aber dazu müsste man etwas genauer wissen, wie das Spiel realisiert ist. Wahrscheinlich hast Du schon das Bild, das Du gepostet hast und möchtest darin nur die Farbe ändern?
Poste am besten den Code von dem Spiel.
 

Jona$3006

Neues Mitglied
Code:
const toggleButton = document.getElementsByClassName('toggleButton')[0]
const navbarLinks = document.getElementsByClassName('navbarLinks')[0]

toggleButton.addEventListener('click', () => {
    navbarLinks.classList.toggle('active')
})

const audio = new Audio();           
audio.src = "js/music/tetrisMusic.mp3"
audio.loop = true;
audio.volume = 0.5

function volumeDown(){
    if (audio.volume >= 1) {
        audio.volume -= 0.1;
    }
    else {
        audio.volume -= 0.1;
    }
}

function volumeUp(){
    if (audio.volume <= 1) {
        audio.volume += 0.1;
    }
    else {
        audio.volume += 0.1;
    }
}

let int = document.getElementById('points');
let integer = 0;

let int2 = document.getElementById('points2')
let integer2 = 0;

function onePoint(){
    integer += 1;
    int.innerHTML = integer

    integer2 += 1;
    int2.innerHTML = integer2

}

function tenPoints(){
    integer += 10;
    int.innerHTML = integer

    integer2 += 10;
    int2.innerHTML = integer2
}
        
function fiftyPoints(){
    integer += 50;
    int.innerHTML = integer

    integer2 += 50;
    int2.innerHTML = integer2
}

const anzeige = document.getElementById("seconds");
const anzeige2 = document.getElementById("seconds2");

var gestoppteZeit = 0;
var pausiert = true;
var letzterDurchlauf = new Date();

function aktualisiereZeit() {
    if(pausiert === false) {
        gestoppteZeit += new Date() - letzterDurchlauf;
        aktualisiereAnzeige();
    }

    letzterDurchlauf = new Date();
    setTimeout(aktualisiereZeit, 1);
}

function aktualisiereAnzeige() {
    let sekunden = Math.floor(gestoppteZeit / 1000) % 60;
    let minuten = Math.floor(gestoppteZeit / 60000) % 60;
    let stunden = Math.floor(gestoppteZeit / 3600000);

    stunden = stunden < 10 ? "0" + stunden : stunden;
    minuten = minuten < 10 ? "0" + minuten : minuten;
    sekunden = sekunden < 10 ? "0" + sekunden : sekunden;

    anzeige.innerHTML = stunden + ":" + minuten + ":" + sekunden;
    anzeige2.innerHTML = stunden + ":" + minuten + ":" + sekunden;
}

aktualisiereZeit();

function play(){
    audio.play();
    rAF = requestAnimationFrame(loop);
    pausiert = false;
}

function pause() {
    audio.pause();
    cancelAnimationFrame(rAF);
    showPause();
    pausiert = true;
}

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);

    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function generateSequence() {
    const sequence = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'];

    while (sequence.length) {
        const rand = getRandomInt(0, sequence.length - 1);
        const name = sequence.splice(rand, 1)[0];
        tetrominoSequence.push(name);
    }
}

function getNextTetromino() {

    if (tetrominoSequence.length === 0) {
        generateSequence();
    }

    const name = tetrominoSequence.pop();
    const matrix = tetrominos[name];

    const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);

    const row = name === 'I' ? -1 : -2;

    return {
        name: name,     
        matrix: matrix, 
        row: row,       
        col: col,       
    };
}

function rotate(matrix) {
    const N = matrix.length - 1;
    const result = matrix.map((row, i) =>
      row.map((val, j) => matrix[N - j][i])
    );

    return result;
}

function isValidMove(matrix, cellRow, cellCol) {
    for (let row = 0; row < matrix.length; row++) {
        for (let col = 0; col < matrix[row].length; col++) {
            if (matrix[row][col] && (
                    
                    cellCol + col < 0 ||
                    cellCol + col >= playfield[0].length ||
                    cellRow + row >= playfield.length ||
                    
                    playfield[cellRow + row][cellCol + col])
                ) {
                return false;
            }
        }
    }
    return true;
}

function placeTetromino() {
    tenPoints();
    for (let row = 0; row < tetromino.matrix.length; row++) {
        for (let col = 0; col < tetromino.matrix[row].length; col++) {
            if (tetromino.matrix[row][col]) {

                if (tetromino.row + row < 0) {
                    return showGameOver();
                }

                playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;
            }
        }
    }

    for (let row = playfield.length - 1; row >= 0; ) {
        if (playfield[row].every(cell => !!cell)) {

            fiftyPoints();

            for (let r = row; r >= 0; r--) {
                for (let c = 0; c < playfield[r].length; c++) {
                    playfield[r][c] = playfield[r-1][c];
                }
            }
        }
        else {
            row--;
        }
    }

    tetromino = getNextTetromino();
}

const popupScreen = document.querySelector(".popupScreen");
const popupBox = document.querySelector(".popupBox");
const closeBtn = document.querySelector(".closeBtn");

function showGameOver() {
    audio.pause();
    pausiert = true;
    cancelAnimationFrame(rAF);
    gameOver = true;

    setTimeout(() => {
        popupScreen.classList.add("aktive");
    }, 0000);
    
    closeBtn.addEventListener("click", () => {
        location.reload();
    });
}

function showPause() {
    context.fillStyle = 'black';
    context.globalAlpha = 0.75;
    context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);
    context.globalAlpha = 1;
    context.fillStyle = 'white';
    context.font = '36px Open Sans, sans-serif';
    context.textAlign = 'center';
    context.textBaseline = 'middle';
    context.fillText('Pause', canvas.width / 2, canvas.height / 2);
}

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const grid = 32;
const tetrominoSequence = [];
const playfield = [];

for (let row = -2; row < 20; row++) {
    playfield[row] = [];

    for (let col = 0; col < 10; col++) {
        playfield[row][col] = 0;
    }
}

const tetrominos = {
    'I': [
        [0,0,0,0],
        [1,1,1,1],
        [0,0,0,0],
        [0,0,0,0],
    ],

    'J': [
        [2,0,0],
        [2,2,2],
        [0,0,0],
    ],

    'L': [
        [0,0,3],
        [3,3,3],
        [0,0,0],
    ],

    'O': [
        [4,4],
        [4,4],
    ],

    'S': [
        [0,5,5],
        [5,5,0],
        [0,0,0],
    ],

    'Z': [
        [6,6,0],
        [0,6,6],
        [0,0,0],
    ],

    'T': [
        [0,7,0],
        [7,7,7],
        [0,0,0],
    ],
};

const colors = {
    'I': '#00eeef',
    'O': '#f3f106',
    'T': '#9e02ec',
    'S': '#00f300',
    'Z': '#f30005',
    'J': '#0103eb',
    'L': '#f0a003'
};

let count = 0;
let tetromino = getNextTetromino();
let rAF = null;
let gameOver = false;

function loop() {
    rAF = requestAnimationFrame(loop);
    context.clearRect(0,0,canvas.width,canvas.height);

    for (let row = 0; row < 20; row++) {
        for (let col = 0; col < 10; col++) {
            if (playfield[row][col]) {
                const name = playfield[row][col];
                context.fillStyle = colors[name];

                context.fillRect(col * grid, row * grid, grid-1, grid-1);
            }
        }
    }

    if (tetromino) {

        if (++count > 35) {
            tetromino.row++;
            count = 0;
 
            if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {
                tetromino.row--;
                placeTetromino();
            }
        }
        context.fillStyle = colors[tetromino.name];

        for (let row = 0; row < tetromino.matrix.length; row++) {
            for (let col = 0; col < tetromino.matrix[row].length; col++) {
                if (tetromino.matrix[row][col]) {

                    context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);
                }
            }
        }
    }
}

document.addEventListener('keydown', function(e) {                         
    if (gameOver) return;       

    if (e.which === 65 || e.which === 68) {
        const col = e.which === 65
        ? tetromino.col - 1
        : tetromino.col + 1;

        if (isValidMove(tetromino.matrix, tetromino.row, col)) {
            tetromino.col = col;
        }
    }

    if (e.which === 87) {
        const matrix = rotate(tetromino.matrix);
        if (isValidMove(matrix, tetromino.row, tetromino.col)) {
            tetromino.matrix = matrix;
        }
    }

    if(e.which === 83) {
        const row = tetromino.row + 1;

        if (!isValidMove(tetromino.matrix, row, tetromino.col)) {
            tetromino.row = row - 1;

            placeTetromino();
            return;
        }
        tetromino.row = row;
    }
});
 

Sempervivum

Senior HTML'ler
Das ist dann nicht besonders schwer. Zunächst stellen wir die einzelnen Bilder bereit:
Code:
        const colors = {
            'I': '#00eeef',
            'O': '#f3f106',
            'T': '#9e02ec',
            'S': '#00f300',
            'Z': '#f30005',
            'J': '#0103eb',
            'L': '#f0a003'
        };

        // Die Pfade der einzelnen Bilder bereit stellen:
        const imagesSrc = {
            'I': 'images/lightBlueBlock.png',
            'O': 'images/lightBlueBlock.png',
            'T': 'images/lightBlueBlock.png',
            'S': 'images/lightBlueBlock.png',
            'Z': 'images/lightBlueBlock.png',
            'J': 'images/lightBlueBlock.png',
            'L': 'images/lightBlueBlock.png'
        };

        // Bildobjekte vorbereiten:
        let images = {};
        // Schleife über die Pfade:
        for (let name in imagesSrc) {
            // Bildobjekt erzeugen:
            const img = new Image();
            // Pfad als src-Attribut zuweisen:
            img.src = imagesSrc[name];
            // Bildobjekt in das Objekt mit den Bildern eintragen:
            images[name] = img;
        }
Und beim Zeichnen auf das Canvas zeichnen wir dann statt eines einfarbigen Rechtecks das betr. Bild:
Code:
        function loop() {
            rAF = requestAnimationFrame(loop);
            context.clearRect(0, 0, canvas.width, canvas.height);

            for (let row = 0; row < 20; row++) {
                for (let col = 0; col < 10; col++) {
                    if (playfield[row][col]) {
                        const name = playfield[row][col];
                        // Bild, das zu dem Namen gehört, aus dem Objekt bereit stellen:
                        const image = images[name];

                        // Anstatt das Rechteck einfarbig zu füllen
                        // zeichnen wir jetzt das Bild:
                        // context.fillStyle = colors[name];
                        // context.fillRect(col * grid, row * grid, grid - 1, grid - 1);
                        context.drawImage(image, col * grid, row * grid);
                    }
                }
            }

            if (tetromino) {

                if (++count > 35) {
                    tetromino.row++;
                    count = 0;

                    if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {
                        tetromino.row--;
                        placeTetromino();
                    }
                }
                // context.fillStyle = colors[tetromino.name];
                // Bild, das zu dem Namen gehört, aus dem Objekt bereit stellen:
                const image = images[tetromino.name];

                for (let row = 0; row < tetromino.matrix.length; row++) {
                    for (let col = 0; col < tetromino.matrix[row].length; col++) {
                        if (tetromino.matrix[row][col]) {

                            // Anstatt das Rechteck einfarbig zu füllen
                            // zeichnen wir jetzt das Bild:
                            // context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid - 1, grid - 1);
                            context.drawImage(image, (tetromino.col + col) * grid, (tetromino.row + row) * grid);
                        }
                    }
                }
            }
        }
Wie Du siehst, habe ich zunächst für alle Blöcke das selbe Bild genommen. Um unterschiedliche Farben zu erzeugen, gibt es mehrere Wege:
  • Wenn Du mit der Bildbearbeitung vertraut bist, kannst Du für jedes Tetromino ein eigenes Bild herstellen.
  • Man kann jedoch auch mit Canvas den Farbton ändern und aus dem blauen Block welche in anderen Farben erzeugen.
  • Oder jeden Block direkt mit Canvas zeichnen ohne den Umweg über eine Bilddatei.
 

Jona$3006

Neues Mitglied
Das mit den Bildern hat geklappt. Die Bilder werden beim "fallen" der Blöcke aber nicht angezeigt. Sie werden erst angezeigt, wenn die Blöcke am Boden sind. Könnten Sie mir vlt dabei helfen, den Fehler zu beheben? (Das Script beinhaltet über 1000 Zeichen, daher hänge ich eine .txt an)
 

Anhänge

  • tetris-javascript.txt
    12,4 KB · Aufrufe: 3

Sempervivum

Senior HTML'ler
Du hast noch nicht richtig verstanden, wie das mit den Objekten oder assoziativen Arrays funktioniert. Ich versuche, es ein wenig zu erklären.
Du hast ja die die Adressen der Bilder so definiert:
Code:
const imagesSrc = {
    'I': 'js/img/games/tetris/lightBlueBlock.png',
    'J': 'js/img/games/tetris/blueBlock.png',
    'L': 'js/img/games/tetris/orangeBlock.png',
    'O': 'js/img/games/tetris/yellowBlock.png',
    'S': 'js/img/games/tetris/redBlock.png',
    'Z': 'js/img/games/tetris/greenBlock.png',
    'T': 'js/img/games/tetris/purpleBlock.png',
};
console.log(imagesSrc['O']);
Füge mal das console.log ein und sieh dir die Ausgabe in der Console an. Wenn Du so imagesSrc['O'] auf das Objekt zugreifst, bekommst Du die Adresse des Bildes, das zu diesem Namen bzw. Buchstaben gehört.
Ändere den Buchstabe und Du wirst sehen, dass Du immer die richtige Adresse erhältst.


Nach der Definition der Adressen hatte ich diese Schleife vorgeschlagen:
Code:
        // Bildobjekte vorbereiten:
        let images = {};
        // Schleife über alle Adressen in imagesSrc:
        for (let name in imagesSrc) {
            // Bei jedem Schleifendurchlauf steht in "name" der betr. Buchstabe,
            // z. B. 'L' oder 'S'.
            // Bildobjekt erzeugen:
            const img = new Image();
            // Pfad als src-Attribut zuweisen:
            img.src = imagesSrc[name];
            // Bildobjekt in das Objekt mit den Bildern eintragen:
            images[name] = img;
            // Später können wir mit z. B. images['L'] oder images['S']
            // wieder auf das gespeicherte Objekt zugreifen.
        }
        // Jetzt stehen die Bildobjekte für alle Namen bzw. Buchstaben
        // in "images" bereit:
        console.log(images);
Sieh dir an, was das letzte console.log ausgibt.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: NCM

Jona$3006

Neues Mitglied
Ich habe mir das Script nochmal in ruhe angeguckt ( Bin JS Anfänger), habe das Script überarbeitet und habe "console.log(images);" in die Console eingegeben und jetzt wird eine Art "Dateienpfad" angezeigt.

Es hat geklappt. Alles läuft einwandfrei. Die Bilder werden angezeigt.
Vielen, Vielen Dank für die Hilfe
 
Werbung:
Oben