Рубрики
Без рубрики

Создайте игру для двух игроков с Python и Vue

Вам понадобится Python 3+, Virtualenv и Flask, установленные на вашем компьютере. Появление ПК и … Теги с Python, толкатель, Vue, в реальном времени.

Вам понадобится Python 3+, Virtualenv и Flask, установленные на вашем компьютере.

Приключение ПК и Интернета переоборудовало термин «развлечения» и средства, с помощью которых он может быть получен. В то время как консоль или некоторые специальные аппаратные средства были бы обязаны играть в игры в прошлом, игры находятся всего лишь клик в современном мире технологий.

В этом уроке мы создадим игру Realtime Tic-Tac-Tac-Tac-Toe, используя каналы Python и Pusher. Вот демо того, как игра будет выглядеть и ведет себя при создании:

Эта многопользовательская игра позволит игроку подключаться к использованию их предпочтительного имени пользователя (или генерировать случайное имя пользователя, где игрок не подключается с именем пользователя) и выбрать поиграть с другим игроком из списка других онлайн-игроков.

Сама игра следует обычным принципам популярных Tic-Tac-Toe игра. Функция «Интернет-плеер (ы)» работает на Толкатель присутствия каналов И обновления в реальном времени движения игрока по нескольким окнам питаются от Pusher Частные каналы. Исходный код для этого учебника доступен здесь Github Отказ

Давайте начнем.

Предварительные условия

Следует следовать, базовые знания Python, Flask, JavaScript (Syntax ES6) и Vue требуется. Вам также понадобится следующее, установленное на вашем компьютере:

  1. Python (v3.x)
  2. Виртуаль
  3. Колбы

Virtualenv отлично подходит для создания изолированных средов Python, поэтому мы можем установить зависимости в изолированной среде без загрязнения наших глобальных пакетов.

Настройка среды приложения

Мы создадим папку Project и активируйте виртуальную среду в нем:

    $ mkdir python-pusher-mutiplayer-game
    $ cd python-pusher-mutiplayer-game
    $ virtualenv .venv
    $ source .venv/bin/activate # Linux based systems
    $ \path\to\env\Scripts\activate # Windows users

Мы установим Колбу Используя эту команду:

    $ pip install flask

Настройка толкателя

Чтобы интегрировать точку в многопользовательскую игру, нам нужно создать приложение Pusher-каналов с помощью панели Dashboard. Если у вас нет учетной записи толкателя, отправляйтесь на Сайт Pusher и создать один.

После создания учетной записи создайте новые каналы приложения и включите клиентские события с помощью приборной панели приложения. Чтобы включить события клиента, нажмите на Настройки приложения и прокрутите до нижней части страницы, затем выберите параметр, который говорит, что Включить клиентские события, и обновить Настройки приложения.

Строительство Backeng Server

Вернуться в каталог проекта, давайте установим Библиотека Python Pusher С помощью этой команды:

    $ pip install pusher

Мы создадим новый файл и вызовите это приложение Здесь мы напишем весь код для сервера Backend Flask. Мы также создадим папку и называем это шаблоны Эта папка удерживает файлы разметки для этого приложения.

Давайте напишем какой-нибудь код для регистрации конечных точек для игры и обслуживать, открыть app.py Файл и вставьте следующий код:

    // File: ./app.py
    from flask import Flask, render_template, request, jsonify, make_response, json
    from pusher import pusher

    app = Flask(__name__)

    pusher = pusher_client = pusher.Pusher(
      app_id='PUSHER_APP_ID',
      key='PUSHER_APP_KEY',
      secret='PUSHER_APP_SECRET',
      cluster='PUSHER_APP_CLUSTER',
      ssl=True
    )

    name = ''

    @app.route('/')
    def index():
      return render_template('index.html')

    @app.route('/play')
    def play():
      global name
      name = request.args.get('username')
      return render_template('play.html')

    @app.route("/pusher/auth", methods=['POST'])
    def pusher_authentication():
      auth = pusher.authenticate(
        channel=request.form['channel_name'],
        socket_id=request.form['socket_id'],
        custom_data={
          u'user_id': name,
          u'user_info': {
            u'role': u'player'
          }
        }
      )
      return json.dumps(auth)

    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=True)

    name = ''

Заменить Pusher_app_ * Клавиши со значениями на приборной панели толкателя.

В указанном выше коде мы определили три конечных точка, вот что они делают:

  • / – Оказывает переднюю страницу, которая просит игроку подключиться с именем пользователя.
  • /играть в – Оказывает вид на игру.
  • /pusher/auth – Аутентифицирует присутствие Толшки и частные каналы для подключенных игроков.

Строительство Frontend

В Шаблоны Папка, мы создадим два файла:

  1. index.html.
  2. Play.html.

index.html Файл будет отображать страницу подключения, поэтому откройте Шаблоны/index.html Файл и вставьте следующий код:



    
        
        
        
        
        TIC-TAC-TOE
        
        
      
      
        

Когда игрок посещает страницу соединения и помещает имя пользователя и адрес электронной почты, окно браузера будет перенаправлено на вид игры.

Давайте напишем на разметку для игры в игре. Открыть Play.html Файл и вставьте следующий код:




  
  
  
  TIC-TAC-TOE


  

{{ username }}

{{ players }} online player(s)


  • {{ member }}
  • {{ status }}

    Вышеуказанный код определяет макет игры игры, но не содержит никаких интерактивных функций или функций в реальном времени. В разделе скриптов до закрытия Тело TAG, мы включили библиотеки Vue и Pusher, потому что они требуются для игры для работы.

    Давайте включаем код JavaScript, который будет вести весь процесс игры и определить свою логику.

    В том же файле добавьте код ниже между скрипт Тег, который просто перед закрытием тело тег:

    var app = new Vue({
      el: '#app',
    
      data: {
        username: '',
        players: 0,
        connectedPlayers: [],
        status: '',
        pusher: new Pusher('PUSHER_APP_KEY', {
          authEndpoint: '/pusher/auth',
          cluster: 'PUSHER_APP_CLUSTER',
          encrypted: true
        }),
        otherPlayerName: '',
        mychannel: {},
        otherPlayerChannel: {},
        firstPlayer: 0,
        turn: 0,
        boxes: [0, 0, 0, 0, 0, 0, 0, 0, 0]
      },
    
      created () {
        let url = new URL(window.location.href);
        let name = url.searchParams.get("username");
    
        if (name) {
          this.username = name
          this.subscribe();
          this.listeners();
        } else {
          this.username = this.generateRandomName();
          location.assign(this.username);
        }
      },
    
      methods: {
        // We will add methods here
      }
    });
    

    Заменить Pusher_app_ * Клавиши с ключами на вашей панели приборной панели.

    Выше мы создаем новый экземпляр Vue, и мы нацелены на #app селектор. Мы определяем все значения по умолчанию в данные объект, а затем в Создать () Функция, которая называется автоматически, когда создается Vue Component, мы проверяем пользователя и назначаем пользователю имя пользователя, если он поставил.

    Мы также делаем звонки на Подписаться и слушатели методы. Давайте определим их внутри Методы объект. Внутри Методы Объект, вставьте следующие функции:

    // [...]
    
    subscribe: function () {
      let channel = this.pusher.subscribe('presence-channel');
      this.myChannel = this.pusher.subscribe('private-' + this.username)
    
      channel.bind('pusher:subscription_succeeded', (player) => {
        this.players = player.count - 1
        player.each((player) => {
          if (player.id != this.username)
            this.connectedPlayers.push(player.id)
        });
      });
    
      channel.bind('pusher:member_added', (player) => {
        this.players++;
        this.connectedPlayers.push(player.id)
      });
    
      channel.bind('pusher:member_removed', (player) => {
        this.players--;
        var index = this.connectedPlayers.indexOf(player.id);
        if (index > -1) {
          this.connectedPlayers.splice(index, 1)
        }
      });
    },
    
    listeners: function () {
      this.pusher.bind('client-' + this.username, (message) => {
        if (confirm('Do you want to start a game of Tic Tac Toe with ' + message)) {
          this.otherPlayerName = message
          this.otherPlayerChannel = this.pusher.subscribe('private-' + this.otherPlayerName)
          this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {
            this.otherPlayerChannel.trigger('client-game-started', this.username)
          })
          this.startGame(message)
        } else {
          this.otherPlayerChannel = this.pusher.subscribe('private-' + message)
          this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {
            this.otherPlayerChannel.trigger('client-game-declined', "")
          })
          this.gameDeclined()
        }
      }),
    
      this.myChannel.bind('client-game-started', (message) => {
        this.status = "Game started with " + message
        this.$refs.gameboard.classList.remove('invisible');
        this.firstPlayer = 1;
        this.turn = 1;
      })
    
      this.myChannel.bind('client-game-declined', () => {
        this.status = "Game declined"
      })
    
      this.myChannel.bind('client-new-move', (position) => {
        this.$refs[position].innerText = this.firstPlayer ? 'O' : 'X'
      })
    
      this.myChannel.bind('client-your-turn', () => {
        this.turn = 1;
      })
    
      this.myChannel.bind('client-box-update', (update) => {
        this.boxes = update;
      })
    
      this.myChannel.bind('client-you-lost', () => {
        this.gameLost();
      })
    },
    
    // [...]
    

    В Подписаться Метод, мы подписываемся на наш канал присутствия на толкатель, а затем подписаться на частный канал для текущего пользователя. В слушатели Метод Мы регистрируем слушателей для всех событий, которые мы ожидаем, что будут срабатываться на частном канале, на который мы подписались.

    Далее мы добавим другие методы помощника в наших методов класса. Внутри класса методов добавьте следующие функции на дно после слушатели Метод:

    // Generates a random string we use as a name for a guest user
    generateRandomName: function () {
      let text = '';
      let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      for (var i = 0; i < 6; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
      }
      return text;
    },
    
    // Lets you choose a player to play as.
    choosePlayer: function (e) {
      this.otherPlayerName = e.target.innerText
      this.otherPlayerChannel = this.pusher.subscribe('private-' + this.otherPlayerName)
      this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {
        this.otherPlayerChannel.trigger('client-' + this.otherPlayerName, this.username)
      });
    },
    
    // Begins the game
    startGame: function (name) {
      this.status = "Game started with " + name
      this.$refs.gameboard.classList.remove('invisible');
    },
    
    // User declined to play
    gameDeclined: function () {
      this.status = "Game declined"
    },
    
    // Game has ended with current user winning
    gameWon: function () {
      this.status = "You WON!"
      this.$refs.gameboard.classList.add('invisible');
      this.restartGame()
    },
    
    // Game has ended with current user losing
    gameLost: function () {
      this.turn = 1;
      this.boxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]
      this.status = "You LOST!"
      this.$refs.gameboard.classList.add('invisible');
      this.restartGame()
    },
    
    // Restarts a game
    restartGame: function () {
      for (i = 1; i < 10; i++) {
        this.$refs[i].innerText = ""
      }
      this.$refs.gameboard.classList.remove('invisible');
    },
    
    // Checks tiles to see if the tiles passed are a match
    compare: function () {
      for (var i = 1; i < arguments.length; i++) {
        if (arguments[i] === 0 || arguments[i] !== arguments[i - 1]) {
          return false
        }
      }
    
      return true;
    },
    
    // Checks the tiles and returns true if theres a winning play
    theresAMatch: function () {
      return this.compare(this.boxes[0], this.boxes[1], this.boxes[2]) ||
        this.compare(this.boxes[3], this.boxes[4], this.boxes[5]) ||
        this.compare(this.boxes[6], this.boxes[7], this.boxes[8]) ||
        this.compare(this.boxes[0], this.boxes[3], this.boxes[6]) ||
        this.compare(this.boxes[1], this.boxes[4], this.boxes[7]) ||
        this.compare(this.boxes[2], this.boxes[5], this.boxes[8]) ||
        this.compare(this.boxes[2], this.boxes[4], this.boxes[6]) ||
        this.compare(this.boxes[0], this.boxes[4], this.boxes[8])
    },
    
    // Checks to see if the play was a winning play
    playerAction: function (e) {
      let index = e.target.dataset.id - 1
      let tile = this.firstPlayer ? 'X' : 'O'
    
      if (this.turn && this.boxes[index] == 0) {
        this.turn = 0
        this.boxes[index] = tile
        e.target.innerText = tile
    
        this.otherPlayerChannel.trigger('client-your-turn', "")
        this.otherPlayerChannel.trigger('client-box-update', this.boxes)
        this.otherPlayerChannel.trigger('client-new-move', e.target.dataset.id)
    
        if (this.theresAMatch()) {
          this.gameWon()
          this.boxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]
          this.otherPlayerChannel.trigger('client-you-lost', '')
        }
      }
    },
    

    Выше мы добавили несколько методов помощника, которые игра нужно правильно функционировать и перед каждым методом, мы добавили комментарий, чтобы показать, что делает метод.

    Давайте проверим игру сейчас.

    Тестирование игры

    Мы можем проверить игру, запустив эту команду:

    $ flask run
    

    Теперь, если мы посетим localhost: 5000 Мы должны увидеть страницу подключения и тестировать игру:

    Вывод

    В этом руководстве мы узнали, как использовать Pusher SDK в создании онлайн-многопользовательской игры, питающейся сервером Backend Python.

    Исходный код для этого учебника доступен на Гадость

    Этот пост впервые появился на Pusher Blog Отказ

    Оригинал: “https://dev.to/neo/create-a-two-player-game-with-python-and-vue-4c3j”