Conveyor.qml 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import QtQuick 2.7
  2. import Box2D 2.0
  3. import Qt.labs.settings 1.0
  4. import PictureModel 1.0
  5. import ".."
  6. Item {
  7. id: root
  8. anchors.fill: parent
  9. property var pictureArray: []
  10. property var nextImage
  11. ImageBoxBody {
  12. id: foot
  13. world: theWorld
  14. density: 20000
  15. bodyType: Body.Dynamic
  16. x: -width
  17. anchors.verticalCenter: viewport.verticalCenter
  18. rotation: -90
  19. mirror: true
  20. fixedRotation: true
  21. z: 10
  22. source: "qrc:/Monty_python_foot.png"
  23. sourceSize.height: viewport.height
  24. sourceSize.width: viewport.height/foot.implicitHeight*foot.implicitWidth
  25. Behavior on x { SmoothedAnimation{ duration: conveyorSettings.footAnimationTime } }
  26. Component.onCompleted: {
  27. foot.body.gravityScale = 0
  28. }
  29. }
  30. SequentialAnimation {
  31. id: stomp
  32. running: false
  33. ScriptAction { script: foot.x = pictureArray[pictureArray.length-1].x*1.1 }
  34. NumberAnimation { duration: conveyorSettings.footAnimationTime }
  35. // linger
  36. NumberAnimation { duration: 2*conveyorSettings.footAnimationTime }
  37. ScriptAction { script: foot.x = -foot.width - 10 }
  38. NumberAnimation { duration: conveyorSettings.footAnimationTime }
  39. }
  40. function spawnImage() {
  41. if (stomp.running)
  42. return
  43. if (!nextImage) {
  44. nextImage = imageDelegate.createObject(viewport, { y: -10000 });
  45. }
  46. if (pictureArray.length > 0 && pictureArray[pictureArray.length-1].x < nextImage.width) {
  47. var body = pictureArray[pictureArray.length-1].body
  48. if (body.linearVelocity.y < 0.001) {
  49. stomp.start()
  50. }
  51. } else {
  52. nextImage.murder.connect(removeImage)
  53. nextImage.y = -nextImage.height
  54. nextImage.world = theWorld
  55. pictureArray.push(nextImage)
  56. nextImage = null
  57. }
  58. }
  59. function removeImage(image)
  60. {
  61. pictureArray.splice(pictureArray.indexOf(image),1)
  62. image.destroy()
  63. }
  64. Settings {
  65. id: conveyorSettings
  66. category: "Conveyor"
  67. property int rowCount: 6
  68. property int footAnimationTime: 500
  69. }
  70. Component {
  71. id: imageDelegate
  72. ArtBoxBody {
  73. signal murder(var item)
  74. density: 1
  75. height: root.height/conveyorSettings.rowCount
  76. width: height*imageModel.data(modelIndex, PictureModel.RatioRole)
  77. bodyType: Body.Dynamic
  78. fixedRotation: true
  79. onXChanged: {
  80. if (x < 0) {
  81. murder(this)
  82. } else if (x + width > floor.width) {
  83. fixedRotation = false
  84. }
  85. }
  86. onYChanged: {
  87. if (y > viewport.height) {
  88. murder(this)
  89. }
  90. }
  91. }
  92. }
  93. Item {
  94. id: viewport
  95. width: root.width*conveyorSettings.rowCount
  96. height: root.height/conveyorSettings.rowCount
  97. World {
  98. id: theWorld
  99. running: true
  100. timeStep: 1/20
  101. }
  102. DebugDraw {
  103. world: theWorld
  104. anchors.fill: parent
  105. visible: false
  106. enabled: visible
  107. }
  108. RectangleBoxBody {
  109. id: floor
  110. world: theWorld
  111. height: 0
  112. width: parent.width - 400
  113. anchors {
  114. top: parent.bottom
  115. }
  116. friction: 0
  117. }
  118. }
  119. Timer {
  120. id: feedTimer
  121. repeat: true
  122. running: true
  123. interval: 100
  124. onTriggered: {
  125. spawnImage()
  126. }
  127. }
  128. ShaderEffectSource {
  129. id: viewportTexture
  130. sourceItem: viewport
  131. width: viewport.width
  132. height: viewport.height
  133. }
  134. ShaderEffect {
  135. anchors.fill: parent
  136. property real rowCount: conveyorSettings.rowCount
  137. property variant source: viewportTexture
  138. fragmentShader: "
  139. varying highp vec2 qt_TexCoord0;
  140. uniform sampler2D source;
  141. uniform lowp float qt_Opacity;
  142. uniform lowp float rowCount;
  143. void main() {
  144. highp vec2 tc;
  145. lowp float row = floor(qt_TexCoord0.t * rowCount);
  146. tc.s = qt_TexCoord0.s / rowCount + row / rowCount;
  147. tc.t = mod(qt_TexCoord0.t, 1.0 / rowCount) * rowCount;
  148. lowp vec4 tex = texture2D(source, tc);
  149. gl_FragColor = vec4(tex.rgb, 1.0);
  150. }
  151. "
  152. }
  153. }