카테고리 없음

슬롯게임 코딩 교육예제

장호박 2021. 3. 3. 03:08

 현재 Main.qml파일을 qml다음 구현

import Felgo 3.0
 import QtQuick 2.0

 GameWindow {
   id: gameWindow

   // You get free licenseKeys from https://felgo.com/licenseKey
   // With a licenseKey you can:
   //  * Publish your games & apps for the app stores
   //  * Remove the Felgo Splash Screen or set a custom one (available with the Pro Licenses)
   //  * Add plugins to monetize, analyze & improve your apps (available with the Pro Licenses)
   //licenseKey: "<generate one from https://felgo.com/licenseKey>"

   activeScene: scene

   // the size of the Window can be changed at runtime by pressing Ctrl (or Cmd on Mac) + the number keys 1-8
   // the content of the logical scene size (480x320 for landscape mode by default) gets scaled to the window size based on the scaleMode
   // you can set this size to any resolution you would like your project to start with, most of the times the one of your main target device
   // this resolution is for iPhone 4 & iPhone 4S
   width: 960
   height: 640

   Scene {
     id: scene

     // the "logical size" - the scene content is auto-scaled to match the GameWindow size
     width: 480
     height: 320

     // properties for the game
     property int betAmount: 4 // amount to bet per line
     property int creditAmount: 400 // player credit for gambling

     // fill game window with background
     Rectangle {
       anchors.fill: scene.gameWindowAnchorItem
       color: "#400000"
     }
   }
 }

 

상단 바 생성

상단 막대는 게임 로고 및 크레딧 금액과 같은 추가 항목을 포함하는 장면 

이러한 요소에 대해 별도의 QML 항목을 만드는 것이 좋습니다. 폴더에 새 파일 TopBar.qml을 qml만들고 다음 코드로 채 웁니다.

import Felgo 3.0
 import QtQuick 2.0

 Item {
   id: topBar
   height: 50

   // add background
   Image {
     anchors.fill: parent
     source: "../assets/BGTopBar.png"
   }

   // add logo
   Image {
     width: 241
     height: 46
     anchors.top: parent.top
     anchors.horizontalCenter: parent.horizontalCenter
     source: "../assets/Logo.png"
   }

   // add gold image (credits)
   Image {
     id: goldImage
     width: 36
     height: 30
     anchors.top: parent.top
     anchors.right: parent.right
     anchors.topMargin: 8
     anchors.rightMargin: 4
     source: "../assets/Coins.png"
   }

   // add gold amount (credit amount)
   Text {
     anchors.verticalCenter: goldImage.verticalCenter
     anchors.right: goldImage.left
     text: scene.creditAmount
     color: "white"
     font.pixelSize: 12
   }
 }

각 라인 이미지는 전체 슬롯 머신 높이를 포함합니다.

심볼의 동적 생성을 실현하기 위해 몇 가지 단계를 수행

  1. 라인의 모든 슬롯 위치를 확인하여 플레이어가 이겼는지 확인
  2. 이 점검 중에 승리를 담당하는 선의 위치와 기호를 기억해야함
  3. 기반으로 동적으로 선 심볼을 만들고 선 위에 배치

지금은 유효성 검사 단계를 건너 뛰고 3 단계에 집중하겠습니다. 라인을 올바르게 표시하기위한 기본 QML 구조를 생성하기 위해 폴더에 새 파일 WinningLine.qml을 추가 qml/slotmachine합니다.

 Item {
   id: winningLine

   // line fills up the area of its parent, the container for all lines has to match the slot machine height
   anchors.fill: parent

   // we want to set a different line image from the outside for each line
   property alias image: lineImage

   // the color of the winning line is used to draw symbols on the line in the correct color
   property string color

   // a line is represented as an array of slot positions
   property var positions: [] // each position has to be an object { reel: <reelNr>, row: <rowNr> }

   // property to hold amount of win
   property int winAmount

   // field that will hold positions that won after validation
   property var __winningPositions: []

   // field to hold symbol type of positions that won
   property var __winningTypes: []

   // field to hold dynamically created line symbols that form a line
   property var __lineSymbols: []

   // show the image of the line
   Image {
     id: lineImage
     anchors.fill: parent
   }

   // area that will hold dynamically created line-symbols
   Item {
     id: symbolArea
     anchors.horizontalCenter: parent.horizontalCenter
     anchors.verticalCenter: parent.verticalCenter

     // display win amount
     Text {
       id: winText
       x: 15
       color: "black"
       text: winAmount
       font.pixelSize: 10
       z: 2
     }

     // add background area around win text
     Rectangle {
       width: winText.width + 20
       height: winText.height + 4
       anchors.centerIn: winText
       color: winningLine.color
       z: 1
     }
   }

   // draw symbols on winning line, parameter machine holds a reference to the slot machine
   function drawLineSymbols(machine) {
     // remove old symbols
     removeLineSymbols()

     // set size of symbol container to match slot machine
     // this is needed to be able to position the symbols on the line relatively to
     // the slot machine instead of the winning line area (winning line is wider than the slot machine)
     symbolArea.width = machine.width
     symbolArea.height = machine.height
     // define y-offset for each line symbol, this is required because the symbol size of the slot machine items includes a top margin of 5px
     var yOffset = 5

     // create all line symbols for winning positions
     for(var i = 0; i < winningLine.__winningPositions.length; i++) {
       // set properties for line symbol
       var properties = {
         // the symbol background and border should be colored in the line color
         color: winningLine.color,
         // set correct position and height
         x: Math.round((machine.defaultReelWidth * winningLine.__winningPositions[i].reel)),
         y: Math.round((machine.defaultItemHeight * winningLine.__winningPositions[i].row) + yOffset),
         width: machine.defaultReelWidth,
         height: machine.defaultItemHeight - 10,
         // set symbol type
         type: winningLine.__winningTypes[i]
       }

       // dynamically create line symbol and add it symbol area
       var component = Qt.createComponent(Qt.resolvedUrl("LineSymbol.qml"))
       var symbol = component.createObject(symbolArea, properties)

       // memorize all symbol objects that are created
       winningLine.__lineSymbols.push(symbol)
     }

     // set y position of win text (different for each line)
     if(__winningPositions[0].row === 0) {
       // on the first row: write win text below first symbol of the line
       winText.y = winningLine.__lineSymbols[0].y + winningLine.__lineSymbols[0].height
      }
     else {
       // on other rows: write win text above first symbol of the line
       winText.y = winningLine.__lineSymbols[0].y - winText.height
     }
   }

   // remove symbols from winning line
   function removeLineSymbols() {
     // destroy all line symbols
     for(var i = 0; i < winningLine.__lineSymbols.length; i++) {
       winningLine.__lineSymbols[i].destroy()
     }

     // delete memory
     winningLine.__lineSymbols = []
   }
 }

함수는 다음 작업을 처리

  •  validate()기능은 모든 라인의 유효성을 검사하고 플레이어가 이기면 라인을 기억하고 라인의 승리 금액으로 총 승리 금액을 증가 그런 다음 실제 플레이어 크레딧을 총 승리 금액만큼 늘리고 true플레이어가 적어도 한 줄에서 이기면 반환
  •  reset()함수는 새 슬롯 머신 스핀을 위해 유효성 검사기를 준비 유효성 검사기의 경우 모든 라인을 숨기고 라인 을 표시하는 타이머  중지하는 것으로 충분
  •  showWinningLines()함수는 첫 번째 승리 라인 을 표시하고 Timer를 시작합니다.  기능은 일정 시간이 지난 후 다른 라인을 표시
  • showLine함수 ()에 기초하여 원 광고 표시 index파라미터. 또한 현재 보이는 라인의 인덱스를 기억
  •  hideAllLines()함수는 단순히 visible모든 행  속성을로 설정합니다 false.

요약하자면, 우리는 우승 한 모든 라인의 표시를 번갈아 표시 할 수있는 Timer와 두 개의 속성을 추가했습니다. 

이를 위해 우리는 라인의 유효성을 검사 할 때이긴 라인을 기억합니다. 

 showWinningLines()함수를 사용 하여 유효성 검사 단계 후 라인 표시를 시작할 수 있습니다 . 

그리고새 게임을 시작할 때이 reset()기능을 통해 모든 것을 다시 숨길 수 있습니다. 이제 남은 것은 씬에 유효성 검사기를 추가하고 올바른 위치에서 이러한 함수를 호출하는 것입니다.

qml/Main.qml:

GameWindow {
   id: gameWindow

   // ...

   Scene {

     // ...

     // add slot machine
     FlaskOfRumMachine {
                 // ...
     }

     // validator to check if player has won
     WinValidator {
       id: winValidator
       height: slotMachine.height // height is the same as slotmachine height
       width: Math.round(height /  240 * 408) // width/height ratio should remain constant
       anchors.centerIn: scene.gameWindowAnchorItem
     }

     // ...

     // start slot machine
     function startSlotMachine() {
       if(!slotMachine.spinning && scene.creditAmount >= scene.betAmount) {
         bottomBar.startActive = true

         // reduce player credits
         scene.creditAmount -= scene.betAmount

         // start machine
         winValidator.reset()
         var stopInterval = utils.generateRandomValueBetween(500, 1000) // between 500 and 1000 ms
         slotMachine.spin(stopInterval)
       }
     }

     // when spin is finished -> validate result
     function spinEnded() {
       bottomBar.startActive = false
       var won = winValidator.validate(slotMachine)
       if(won)
         winValidator.showWinningLines()
       else if(bottomBar.autoActive)
         startSlotMachine()
     }
   }
 }

 

완성된 슬롯 화면