Conveyor.qml 5.1 KB

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