0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

wikipediaのAPIを使ってゲーム作ってみた#3

Last updated at Posted at 2023-07-05

はじめに

こんにちは!前回は、文中のリンク化したいワードをリンク化することができたので、今回は実際に、そのワードをクリックしたら、そのワードのページが閲覧できるようにしたいと思います。

前回の記事はこちらです↓

作業開始

1.クリックしたワードをviewsファイルへ送る

まず、spanタグが付いているワードをクリックしたらそのワードをviewsファイルに送るコードを書きます。

main.js
// クリックイベントの処理
function handleClick() {
    // クリックされたワードを取得する
    var clickedWord = event.target.textContent;

    //FormDataオブジェクトを作成し、appendメソッドを使用してワードを追加
    var form = new FormData();
    form.append('word', clickedWord);

    //fetch関数を使用して、POSTリクエストを送信
    fetch('/maingame/', {
        method: 'POST',
        body: form,
    })
}

解説していきます!!

まず、クリックされたワードを取得します。
VScodeだと、eventの部分が非推奨となっているんですが、一応動きます。逆に無いとエラーが起きます。
(これ何ですかね?ご存じの方、教えていただけるとありがたいです。)

var clickedWord =  event.target.textContent;

続いて、データを送るためにformにwordとしてクリックされたワードを入れます。

var form = new FormData();
form.append('word', clickedWord);

fetch関数なるものを作成し、POSTリクエストをviewsファイルのmainに送信しています。

fetch('/maingame/', {
    method: 'POST',
    body: form,
    }

これでクリックしたワードを、viewsファイルに送ることができました。

2.受け取ったワードのページを取得する

それでは、受け取ったワードのページを取得し、再度htmlとして出力させるようにしたいと思います。

views.py
#単語クリック用
if 'word' in request.POST:
    clicked_word = request.POST.get("word", "")
    #wikipediaapiで受け取ったデータを変数にそれぞれ入れる
    page_title,page_text,res = wikipediaapi(clicked_word)

    #javascriptへデータを返す
    return JsonResponse({
    'page_text': page_text, 
    'page_title': page_title,
    'res': res,
    })

まず、受け取ったワードを前回作ったwikipediaapi()に投げ、そこで処理をし、データを受け取ります。

if 'word' in request.POST:
    clicked_word = request.POST.get("word", "")
    #wikipediaapiで受け取ったデータを変数にそれぞれ入れる
    page_title,page_text,res = wikipediaapi(clicked_word)

受け取ったデータをJSON形式で先ほどのjavascriptに返します。

return JsonResponse({
        'page_text': page_text, 
        'page_title': page_title,
        'res': res,
        })

3.HTMLに反映させる

続いて、javascriptの方でデータを受け取った後の処理を書いていきます。

main.js
//レスポンスをJSON形式で解析
.then(response => response.json())
.then(data => {
    // 受け取ったデータを使用してHTMLを再構築する
    let html = '';
    html += `
        <h1>${data.page_title}</h1>
        <p>${data.res}</p>
        `;
     document.getElementById('main-text').innerHTML = html;
})
//エラーが発生した場合はコンソールにエラーメッセージを表示
.catch(error => {
    console.error('Error:', error);
});

まず、受け取ったレスポンスをJSON形式で解析します。

.then(response => response.json())

そのデータをもとにHTMLを再構築します。

.then(data => {
    // 受け取ったデータを使用してHTMLを再構築する
    let html = '';
    html += `
        <h1>${data.page_title}</h1>
        <p>${data.res}</p>
        `;
     document.getElementById('main-text').innerHTML = html;
})

これで、クリックしたワードに基づいてページが更新されるようになりました!

ただ、このシステムには問題があります。
実はこれ、単一のページで情報の入れ替えを行っており、厳密にはページ遷移をしているわけではないので前のページに戻ったり、ページを更新したりすると初期のページに戻ってしまいます。
つまり、一個前のページを見ることが現状できません。

ゲーム的に、一個戻るは使えないっていうのもありかな~と思って放置しているのですが、いつかここら辺も何とかしたいですね。

今回も下に最終的なコードを貼っておきます。

views.py
#メインの画面
def main(request):
    print("main entered")    
         
    #ワードクリック用
    if 'word' in request.POST:
        clicked_word = request.POST.get("word", "")
        #wikipediaapiで受け取ったデータを変数にそれぞれ入れる
        page_title,page_text,res = wikipediaapi(clicked_word)
        #javascriptへデータを返す
        return JsonResponse({
        'page_text': page_text, 
        'page_title': page_title,
        'res': res,
        })
    else:
        #初期の文字を受け取る
        selected_word = "ここに初期のページのワードを書き込む"
        #wikipediaapiで受け取ったデータを変数にそれぞれ入れる
        page_title,page_text,res = wikipediaapi(selected_word)

    #main.htmlに情報を返す
    return render(request, 'main/main.html', {
        'page_text': page_text, 
        'page_title': page_title,
        'res': res,
        })
main.js
// クリックイベントの処理
function handleClick() {
    // クリックされた言葉を取得する
    var clickedWord =  event.target.textContent;

    //FormDataオブジェクトを作成し、appendメソッドを使用してワードを追加
    var form = new FormData();
    form.append('word', clickedWord);

    //fetch関数を使用して、POSTリクエストを送信
    fetch('/maingame/', {
        method: 'POST',
        body: form,
    })
        //レスポンスをJSON形式で解析
        .then(response => response.json())
        .then(data => {
            // 受け取ったデータを使用してHTMLを再構築する
            let html = '';
            html += `
                    <h1>${data.page_title}</h1>
                    <p>${data.res}</p>
                `;
            document.getElementById('main-text').innerHTML = html;
        })
        //エラーが発生した場合はコンソールにエラーメッセージを表示
        .catch(error => {
            console.error('Error:', error);
        });
}

おわりに

以上で、特定のワードをクリックしたら、そのワードのページが閲覧できるようになりました!
これでほぼほぼwikipediaみたいな挙動になったかと思います!

さて、次回からはいよいよゲーム性を追加していきます。
まず最初に、「スタートとなるワード」と「ゴールとなるワード」を取得し、ゴールのページにたどり着いた時に何かアクションを起こせるようにしていきたいと思います。

今回の実装でもっと良い方法があったり、記事についてもっとこうするべき等があれば、是非教えてください!

Github:https://github.com/ITTON2001/WikiWord

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?