Select level JS (początkujący programista)

0

Witam, jestem początkującym programistom i potrzebuję zrobić dwa poziomy gry w JS. W pliku html mam:

<select id="selectLevel">	
<option disabled selected>--Select Level--</option>	
<option value="2">Easy</option>      
<option value="4">Hard</option>
</select>
<button id="startBtn" type="button" onclick="game">Start</button>

W pliku JS mam pobieranie tablicy z ikonami:

const prepareIconList = ["fas fa-volume-down", "fas fa-volume-down", "fas fa-bicycle", "fas fa-bicycle", "far fa-calendar-check", "far fa-calendar-check", "fas fa-wifi", "fas fa-wifi", "fas fa-camera", "fas fa-camera", "fas fa-laptop", "fas fa-laptop", "fas fa-mobile-alt", "fas fa-mobile-alt", "fab fa-android", "fab fa-android"],

potrzebuję przekazać value, aby przy wyborze poziomu easy i po kliknięciu w button rysowało mi 8 kafli, a przy wyborze poziomu hard i kliknięciu w button rysowało mi 16 kafli.

Myślałem, że coś takiego, ale co mi jeszcze brakuje w poniższym kodzie?:

function startGame() {
var level = getValue(); 
var numberOfTiles = level === 'easy' ? 8 : 16;
createGameBoard(numberOFTiles)
}

Albo co robię źle?

1

Zamień:

var level = getValue(); 

Na

let level = document.querySelector("#selectLevel"); 

I teraz możesz albo zrobić to tak:

let numberOfTiles = level.value == 2 ? 8 : 16; 

aby porównywać po wartości opcji w select lub:

let numberOfTiles = level.options[level.selectedIndex].text == 'Easy' ? 8 : 16;

aby porównywać po wartości tekstu w danej opcji

2
Greg_gb napisał(a):

Myślałem, że coś takiego, ale co mi jeszcze brakuje w poniższym kodzie?:

function startGame() {
var level = getValue(); 
var numberOfTiles = level === 'easy' ? 8 : 16;
createGameBoard(numberOFTiles)
}

Albo co robię źle?

Nie napisałeś, czy coś Ci nie działa. Na tej podstawie trudno stwierdzić, czy czegoś Ci jeszcze brakuje w kodzie, lub czy coś robisz źle.

var level = getValue();


Nie ma funkcji `getValue` w implementacjach JavaScriptu w przeglądarkach, przynajmniej ja o takiej nie wiem. Czy ta funkcja jest u Ciebie gdzieś zdefiniowana? Jeśli tak, jak wygląda jej kod?
0

Mam taki kod js. Muszę z

const prepareIconList

pobrać dane, aby w poziomie easy po kliknięciu w button rysowało mi 8 kafli i można było grać i później to samo tylko w poziome hard, ale już 16 kafli.

let matchedCards = [],
    currentOpenedCards = [],
    moves = 0,
    rateHTML = "",
    rateStep = 6,
    firstClick = true,
    hours, minutes, seconds,
    totalTime = 0,
    incrementer;

const prepareIconList = ["fas fa-volume-down", "fas fa-volume-down", "fas fa-bicycle", "fas fa-bicycle", "far fa-calendar-check", "far fa-calendar-check", "fas fa-wifi", "fas fa-wifi", "fas fa-camera", "fas fa-camera", "fas fa-laptop", "fas fa-laptop", "fas fa-mobile-alt", "fas fa-mobile-alt", "fab fa-android", "fab fa-android"],
    cardsList = document.querySelector(".cards"),
    cards = cardsList.children,
    movesContainer = document.querySelector(".moves"),
    modal = document.querySelector(".modal"),
    repeatBtn = document.querySelector(".features .play-again");
    repeatBtnFromModal = document.querySelector(".modal .play-again"),
    rateContainer = document.querySelector("#total_rate"),
    exactMoves = prepareIconList.length / 2,
    maxStars = exactMoves + rateStep,
    minStars = exactMoves + ( 2 * rateStep),
    stars = document.querySelectorAll(".star"),
    secondsContainer = document.querySelector("#seconds"),
    minutesContainer = document.querySelector("#minutes"),
    hoursContainer = document.querySelector("#hours");

/* Shuffle */
function shuffle(array) {
    let counter = array.length;

    while (counter > 0) {
        let index = Math.floor(Math.random() * counter);
        counter--;

        let temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

/* Initialize Game */
function init() {
    const icons = shuffle(prepareIconList);
    const cardsFragment = document.createDocumentFragment();
    
    for (let i = 0; i < icons.length; i++) {
        const card = document.createElement("li");
        card.innerHTML = "<i class='" + icons[i] + "'></i>";
        cardsFragment.appendChild(card);
    }
    cardsList.appendChild(cardsFragment);
}



/* Start Game */
function start() {
	init()	
    cardClick();
}

/* Click */
function cardClick() {
    for (let i = 0; i < cards.length; i++) {
        
        // Add a click event to each card
        cards[i].addEventListener("click", function () {

            const currentCard = this;
            const previousCard = currentOpenedCards[0];
            
            if(firstClick) {
                startTimer();
                firstClick = false;
            }
            if (currentOpenedCards.length === 1) {

                currentCard.className = "show disabled animated flipInY";

                currentOpenedCards.push(currentCard);

                isMatched(currentCard, previousCard);

                currentOpenedCards = [];

                addMove();

                rating();
            } 	else {
					currentCard.className = "show disabled animated flipInY";
					currentOpenedCards.push(currentCard);
				}
        });
    }
}
0
Greg_gb napisał(a):

Mam taki kod js. Muszę z

const prepareIconList

Ale przecież nie pobierasz danych z preprareIconList, tylko z interfejsu użytkownika. Chyba że chodziło Ci o inne pobieranie danych, ale wtedy nie wiem, o jakie.

W ogólności, jeśli chcesz pobierać dane z interfejsu użytkownika, możesz zrobić na przykład tak, jak napisał @Yukiteru Gromadzki wyżej:

let dane = document.querySelector("#identyfikatorTwojejKontrolkiZDanymi");

Myślę, że można nawet dać const zamiast let w tym przypadku, ponieważ oczekiwałbym (przynajmniej ja), że wartość zmiennej z pobranymi danymi nie zmieni się. Jeśli powinna się zmieniać, to oczywiście niech zostanie let.

  1. W tym ostatnim podanym przez Ciebie kodzie nie występuje wywołanie funkcji startGame (którą pokazałeś w pierwszym poście). Pokaż kod, gdzie ją wywołujesz. Chyba że jeszcze nie jesteś pewien, gdzie ją umieścić?

  2. W tym kodzie nie występuje też żadna inna zmienna ani funkcja z kodu podanego w pierwszym poście. Nie wiem, jak te fragmenty powiązać ze sobą.

  3. Co do tego fragmentu:

<button id="startBtn" type="button" onclick="game">Start</button>

Nie jestem pewien, czy będzie działać. Nie znam wszystkich dziwactw JavaScriptu, ale w mojej ocenie powinieneś zamienić game na wywołanie jakiejś funkcji. Może być np. game() – ale tylko, jeśli game jest u Ciebie funkcją. W sprawie szczegółów zobacz (1) https://www.w3schools.com/js/js_htmldom_events.asp oraz (2) https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers

  1. Dalej nie napisałeś, z czym dokładnie masz problem:
    5.1. Czy masz problem z wyborem miejsca w kodzie, w którym umieścić pobieranie danych z interfejsu użytkownika? Można to zrobić zarówno w pliku HTML, jak i w pliku JS. Jeśli to ta kwestia, pokaż również kod HTML, wtedy będzie można lepiej coś poradzić.
    5.2. Czy masz problem z budową funkcji, która pobiera dane z interfejsu użytkownika? Częściowo już zostało rozwiązane przez @Yukiteru Gromadzki.
    5.3. Czy masz problem z jakimś błędem, który pojawia się zamiast layoutu na stronie lub w konsoli w narzędziach deweloperskich w przeglądarce?
0

Mam problem, że nie wiem gdzie umieścić dokładnie ten kod i jak to dokładnie zrobić. Ja tylko podałem mój kod jaki i mam i chciałem zapytać jaki kod napisać, aby to zadziałało. Podaję mój kod html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">	
	<title>Memory Game</title>	
	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
	<link href="https://fonts.googleapis.com/css?family=Lato:400,700&amp;subset=latin-ext" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
    <link rel="stylesheet" href="css/app.css">
</head>

<body>
    <section class="game-container">
        <h1>Memory Game</h1>		
        <div class="features">
            <div class="moves-count">
                Moves: <span class="moves">--</span>
            </div>
            <div class="stars-rating">
                <i class="star fas fa-star"></i>
                <i class="star fas fa-star"></i>
                <i class="star fas fa-star"></i>
            </div>
            <div class="repeat">Restart:
                <i class="play-again fas fa-redo-alt"></i>
            </div>
            <div class="timer-container">
                <i class="far fa-clock"></i> <span id="hours">00</span>:<span id="minutes">00</span>:<span id="seconds">00</span>
            </div>
        </div>
        <div class="modal">
            <div class="inner">
                <h2>Congratulations!</h2>
                <p>In <span id="totalHours"></span> Hours, <span id="totalMinutes"></span> Minutes and <span id="totalSeconds"></span> Seconds</p>
                <p>It tooks you:
                    <span id="total_moves"></span> moves to complete it!<br>
                    Your rating is: <span id="total_rate"></span>
                </p>
                <button class="play-again">Play Again?</button>
            </div>
        </div>
		<select id="selectLevel">
			<option disabled selected>--Select Level--</option>
			<option value="2">&nbsp;&nbsp;Easy</option>
            <option value="4">&nbsp;&nbsp;Hard</option>
        </select>
        <button id="startBtn" type="button" onclick="game">Start</button>
		
        <ul class="cards">
		
        </ul>
    </section>

    <script src="js/app.js"></script>
	
</body>
</html>
0

Tak to jest cały kod html

0

OK.

1
  1. Zamień w HTML-u
onclick="game"

na

onclick="start();"

(wygląda, jakbyś zmienił nazwę funkcji z game na start, ale o tym zapomniał; mnie to się czasem zdarza).

  1. Zamień w HTML-u
<option value="2">  Easy</option>
<option value="4">  Hard</option>

na

<option value="easy">  Easy</option>
<option value="hard">  Hard</option>
  1. Dodaj na samym początku funkcji init kod:
  const selectLevelElement = document.querySelector("#selectLevel");
  const levelValue = selectLevelElement.options[selectLevelElement.selectedIndex].value;
  let numberOfTiles;
  if (levelValue === 'easy') {
    numberOfTiles = 8;
  } else if (levelValue === 'hard') {
    numberOfTiles = 16;
  } else {
    // tutaj obsłużenie sytuacji, że levelValue nie ma żadnej z tych wartości
  }

(Tak, wcześniej zapomniałem o tym # w wywołaniu querySelector).

W tym kodzie do zmiennej selectLevelElement pobierasz element HTML <select>. Następnie, do zmiennej levelValue pobierasz wartość opcji wybranej przez użytkownika (u Ciebie: wartość atrybutu HTML "value").

Należy jeszcze obsłużyć tutaj taką sytuację, że użytkownik może żadnej opcji nie wybrać (np. przez przypadek) – wtedy w zmiennej levelValue będzie ciąg znaków --Select Level--, no, a to nie jest wartość prawidłowa dla poziomu. Możesz ją obsłużyć np. tam, gdzie dałem komentarz. Jednak oprócz tego miejsca powinieneś albo ustawić domyślną wartość, która będzie dalej przetwarzana, albo uniemożliwić wykonywanie dalszego kodu w tej funkcji. Myślę, że obie sytuacje są równie dobre – zależy, jak wolisz mieć w swojej grze.

  1. Nie jestem jednak pewien, jak wykorzystać w Twoim kodzie zmienną numberOfTiles. Czy chcesz np. zamienić i < icons.length w pętli for poniżej na i < numberOfTiles?
0

Szczerze to nie mam pojęcia bo, na moim początkującym poziomie ciężko mi powiedzieć. Zdaję się na Twoją poradę

0

Na początek najważniejsze, by działało. Potem to możesz zawsze ulepszyć. Zawsze efektywniej (nie zawsze lepiej) poprawiać działające, niż pisać od początku.

Chodzi mi też o to, że w kodzie masz np. zmienną cards, a mówisz o "kaflach". Nie wiem, czy mówisz o tej samej, czy o dwóch różnych rzeczach. Jakkolwiek na planszy gry te dwie koncepcje mogą wyglądać tak samo, to jednak różnią się logicznie.

Tak na szybko patrząc, to właśnie w pętli for w funkcji init wypada zrobić taką zamianę. Sprawdź, jak działa, i napisz.


UPDATE:

Będąc po review codu, do którego link przysłałeś mi na priv (https://codepen.io/anon/pen/arEPvz?editors=0010):

Trochę nienajlepiej to zrobiłeś. Tak powinna wygląda funkcja init u Ciebie:

function init() {
  console.log("into init()");
  const selectLevelElement = document.querySelector("#selectLevel");
  const levelValue = selectLevelElement.options[selectLevelElement.selectedIndex].value;
  
  let numberOfTiles;
  if (levelValue === "easy") {
    numberOfTiles = 8;
  } else if (levelValue === "hard") {
    numberOfTiles = 16;
  }

  const icons = shuffle(prepareIconList);
  const cardsFragment = document.createDocumentFragment();

  for (let i = 0; i < numberOfTiles; i++) {
    const card = document.createElement("li");
    card.innerHTML = "<i class='" + icons[i] + "'></i>";
    cardsFragment.appendChild(card);
  }
  cardsList.appendChild(cardsFragment);
  console.log("out of init()");
}

I teraz działa. Nawet fajna gra (choć sam nie lubię w to grać zbyt długo naraz). Jest kilka problemów, co prawda – na przykład to, że jak się znajdzie jedną parę (i podświetli się ona na zielono), to już kafelki przestają znikać po odkryciu. Oraz to, że jak się nie wybierze żadnego poziomu, to użytkownik nie ma żadnego komunikatu, co poszło źle.


UPDATE: Oraz to jest problemem, że jak się naciśnie ponownie "Start", to kafelki dodają się nowe na samym dole, a nie zastępują te już obecne. Spróbuj sam rozwiązać. :) Ewentualnie – twórz nowe wątki na forum z konkretnymi pytaniami.

1 użytkowników online, w tym zalogowanych: 0, gości: 1