Gravity.qml 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import QtQuick 2.5
  2. import Box2D 2.0
  3. Item {
  4. id: root
  5. signal togglePause
  6. signal toggleChaos
  7. signal next
  8. property var pictureDelegate: Qt.createComponent("HorizontalArtDelegate.qml")
  9. anchors.fill: parent
  10. QtObject {
  11. id: d
  12. property double pace: settings.pace/60.0
  13. property int itemCount: 0
  14. property int itemTravel: settings.itemTravel
  15. property int primedColumns: 0
  16. property int columnCount: settings.columnCount
  17. property bool running: primedColumns >= columnCount
  18. property bool globalWorld: settings.globalWorld
  19. function reset() {
  20. itemCount = 0
  21. primedColumns = 0
  22. }
  23. onColumnCountChanged: reset()
  24. }
  25. World {
  26. id: bullshitWorld
  27. timeStep: d.pace
  28. running: d.running
  29. }
  30. World {
  31. id: commonWorld
  32. timeStep: d.pace
  33. running: d.globalWorld && d.running
  34. }
  35. Component {
  36. id: columnComponent
  37. Item {
  38. id: column
  39. property int stackHeight: 0
  40. property bool full: false
  41. property int xOffset: width * index
  42. onStackHeightChanged: {
  43. if (!column.full && (stackHeight > root.height)) {
  44. d.primedColumns += 1
  45. column.full = true
  46. }
  47. }
  48. function considerImage() {
  49. if (stackHeight < (1.3 + 1/d.columnCount)*root.height) {
  50. addImage()
  51. }
  52. }
  53. function addImage() {
  54. var item = pictureDelegate.createObject(column, { x: -1000, y: -1000 })
  55. item.beyondThePale.connect(removeImage)
  56. stackHeight += (item.height + d.itemTravel)
  57. item.world = d.globalWorld ? commonWorld : columnWorld
  58. item.x = xOffset
  59. item.y = floor.y - stackHeight
  60. d.itemCount++
  61. pictureArray.push(item)
  62. }
  63. function removeImage(image) {
  64. stackHeight -= (image.height + d.itemTravel)
  65. image.destroy()
  66. d.itemCount--
  67. }
  68. width: parent.width/d.columnCount
  69. anchors { top: parent.top; bottom: parent.bottom }
  70. property var pictureArray: []
  71. property bool fixedRotation: true
  72. World {
  73. id: columnWorld
  74. timeStep: d.pace
  75. running: !d.globalWorld && d.running
  76. }
  77. RectangleBoxBody {
  78. id: floor
  79. world: columnWorld
  80. height: 0
  81. width: parent.width
  82. x: xOffset
  83. anchors {
  84. top: parent.bottom
  85. }
  86. friction: 1
  87. }
  88. Timer {
  89. id: pumpTimer
  90. interval: Math.random()*500 + 500
  91. repeat: true
  92. running: true
  93. onTriggered: considerImage()
  94. }
  95. Timer {
  96. id: deathTimer
  97. running: d.running
  98. repeat: true
  99. interval: 1000*(settings.interval > 60 ? 60*(settings.interval-60) : settings.interval)*(Math.random()+1)
  100. onTriggered: {
  101. if (pictureArray.length > 0) {
  102. var image = pictureArray.shift()
  103. image.world = bullshitWorld
  104. addImage()
  105. }
  106. }
  107. }
  108. Connections {
  109. target: root
  110. onTogglePause: deathTimer.running = !deathTimer.running
  111. onNext: deathTimer.triggered()
  112. onToggleChaos: fixedRotation = !fixedRotation
  113. }
  114. Timer {
  115. id: settleTimer
  116. running: false
  117. interval: 200
  118. onTriggered: deathTimer.triggered()
  119. }
  120. }
  121. }
  122. // floor
  123. RectangleBoxBody {
  124. id: globalFloor
  125. world: commonWorld
  126. height: 0
  127. anchors {
  128. left: parent.left
  129. right: parent.right
  130. top: parent.bottom
  131. }
  132. friction: 1
  133. }
  134. DebugDraw {
  135. id: debugDraw
  136. enabled: false
  137. z: 1
  138. world: commonWorld
  139. anchors.fill: parent
  140. opacity: 0.75
  141. visible: enabled
  142. }
  143. Repeater {
  144. model: d.columnCount
  145. delegate: columnComponent
  146. }
  147. // TODO: The boot (Monty Python foot) of death to be applied to the stacks
  148. RectangleBoxBody {
  149. id: rect
  150. enabled: false
  151. visible: false
  152. friction: 1.0
  153. density: 1000
  154. color: "red"
  155. width: 50; height: 50
  156. bullet: true
  157. SequentialAnimation {
  158. id: murderAnimation
  159. //loops: Animation.Infinite
  160. //running: true
  161. ScriptAction { script: { root.togglePause() } }
  162. ScriptAction { script: { rect.world = worldArray.pop() } }
  163. PropertyAction { target: rect; property: "x"; value: -rect.width }
  164. PropertyAction { target: rect; property: "y"; value: root.height }
  165. ParallelAnimation {
  166. NumberAnimation { target: rect; property: "x"; to: 2560; duration: 1000 }
  167. NumberAnimation { target: rect; property: "y"; to: 0; duration: 1000 }
  168. }
  169. }
  170. }
  171. Rectangle {
  172. visible: settings.viewItemCount
  173. z: 1
  174. color: "black"
  175. anchors { right: parent.right; top: parent.top }
  176. width: itemCountLabel.width
  177. height: itemCountLabel.height
  178. Text {
  179. id: itemCountLabel
  180. font.pixelSize: 100
  181. text: d.itemCount
  182. color: "white"
  183. }
  184. }
  185. Keys.onUpPressed: root.togglePause()
  186. Keys.onDownPressed: root.toggleChaos() //root.next()
  187. }