Rubble Trouble!

Rubble Trouble! preview image

1 collaborator

Turtlezero2-white-048 James Steiner (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.3.0 • Viewed 208 times • Downloaded 45 times • Run 0 times
Download the 'Rubble Trouble!' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

; extensions [ sound ]

globals
[
  pixel
  keypress
  the-ship
  the-reticule
  click
  num-rocks
  active-reticule
  score
  credits
  reset-pressed
  rock-color
  setup-finished
  rock-info
]

patches-own
[ rr gg bb
]

breed [ rocks rock ]
breed [ ships ship ]
breed [ bullets bullet ]
breed [ fragments fragment ]
breed [ messengers messenger ]
breed [ reticules reticule ]
breed [ letters letter ]
breed [ clocks clock ]
breed [ HS-effects hs-effect ]

clocks-own
[ current-time
  elapsed-time
  start-time
  cumulative-time
  pause-until
  clock-on
]

letters-own
[ base-size
  base-color
  base-xcor
  base-heading
]

reticules-own
[
  timeout
]

hs-effects-own
[ effect-direction ]

ships-own
[
  vx vy vv
  ax ay av
  gun-temp
  gun-limit
  gun-cooldown
  max-temp
  bullet-speed;
  bullet-burnout
  max-burnout
]

rocks-own
[
  rock-type
  vx vy vv
  av
  exploding
]

bullets-own
[
  vx vy vv
  bullet-burnout
  bullet-speed
  max-burnout
  seeker?
  target-rock
]

fragments-own
[ vv vx vy av burnout max-burnout kind ]

messengers-own
[
  text ;; the message to ;display
  caret ;; position within the text
  cursor ;; patch offset of the caret
  window ;; the set of patches under the message
  window# ;; the line on which to ;display the message
  show-cursor? ;; show the simulated blinking curtor
]

to ? [ thing ]
  (
    ifelse
    ( is-list? thing )
    [
      output-print " [ "
      foreach thing [ ?? -> ? ?? ] output-print " ] "
    ]
    [
      output-print thing
    ]
  )
end 

to-report plus-or-minus [ value ]
  report value * ( random 2 * 2 - 1 )
end 

to x_set-line-thickness [ width ]
  ;; __set-line-thickness width
end 

to setup-rock
  let rock-start-size 1.5 ^ 5
  let rock-start-av .1 + random-float 0.75
  let rock-start-v .1 + random-float .1
  set rock-info
  [
    [ "rock-1" 0 1 22 ]
    [ "rock-2" 0 1 22 ]
    [ "rock-3" 0 1 22 ]
    [ "rock-4" 0 1 22 ]
    [ "rock-5" 1 2 12 ]
  ]

  create-rocks 1
  [
    home
    x_set-line-thickness pixel * 2
    let side plus-or-minus 1
    let startx side * ( max-pxcor - random ( world-width / 4 ) )
    let starty random-ycor
    setxy startx starty
    let endx side * ( max-pxcor - random ( world-width / 4 ) )
    set heading towardsxy endx plus-or-minus max-pycor
    set vx dx * rock-start-v
    set vy dy * rock-start-v
    set av rock-start-av
    set color white
    set rock-type item ( roulette rock-info 3 ) rock-info
    set shape item 0 rock-type
    set size rock-start-size / item 2 rock-type
  ]
end 

to-report roulette [ $layout $bias-index ]
  ;; the layout are the values being selected from
  ;; the canoes are widths of each pocket the tendency of each value to be selected
  let canoes map [ $bias -> item $bias-index $bias ] $layout
  let total sum canoes
  let fall random-float total
  let pocket 0
  ;; intial value of canoe = inside the first pocket
  let canoe item pocket canoes
  while [ fall > canoe ]
  [ set pocket pocket + 1
    set canoe canoe + item pocket canoes
  ]
  report pocket
end 

to rock-explode
  ;; sound:play-note-later delay instrument keynumber velocity duration
  sfx "explode-rock" size

  set heading atan vx vy
  set vv sqrt ( vx * vx + vy * vy )
  if ( size > 4 )
  [
    set size size * 2 / 3
    if vv < .9 [ set vv vv * 1.1 ]

    let a -1
    repeat (1 + random 2)
    [
      hatch 1
      [
        rt 90 * a
        set a a + 2
        set vx dx * vv
        set vy dy * vv
        jump size / 2
        set shape one-of [ "rock-1" "rock-2" "rock-2" ]
        x_set-line-thickness pixel * 2
      ]
    ]
  ]
  fragment-setup white 0 size
  die
end 

to fragment-setup [ hue direction radius ]
  let xx xcor
  let yy ycor
  let $extra max list 0 (count fragments - 100)
  ask n-of $extra fragments [ die ]
  hatch-fragments ifelse-value ( direction = 0 ) [ 5 ] [ 1 ]
  [ set color hue
    set heading random 360
    x_set-line-thickness pixel * 2
    set vv .1 + random-float .2
    set vx dx * vv
    set vy dy * vv
    set max-burnout 40
    ifelse direction != 0
    [ jump 2
      rt 180
      set size 2
      set av 0
    ]
    [
      jump ( .5 * random-float radius )
      rt 90
      set size ( size + random-float 2 )
      set av 20 * ( random 2 * 2 - 1 )
    ]
  ]
end 

to game-clear
  ;; setup a game
  clear-drawing
  clear-patches
  clear-turtles
  clear-links
  set num-rocks 0
end 

to ship-setup
  create-ships 1
  [ set color magenta + 2
    set heading 0
    set shape "_ship-000"
    x_set-line-thickness pixel * 2
    set size 2
    set bullet-speed 1
    set bullet-burnout max-pxcor / bullet-speed
    set max-burnout bullet-burnout
    set gun-limit 5
    set gun-temp 0
    set max-temp 4 / bullet-speed
    ;; floor ( 30 / 2 / pixel )
    set the-ship self
  ]
  inspect the-ship
end 

to reticule-setup
  ask patch min-pxcor min-pycor
  [ sprout-reticules 1
    [ hide-turtle
      setxy max-pxcor max-pycor
      set heading 0
      set shape "reticule"
      set color red
      x_set-line-thickness pixel * 3
      set size 2
      set active-reticule self
      set timeout 0
    ]
  ]
end 

to reticules-go
  if self != active-reticule
  [ if timeout = 0 [ set timeout timer + 2 ]
    ifelse timer < timeout
    [ set color scale-color red ( timeout - timer ) -3 8 ]
    [ die ]
  ]
end 

to ship-explode
  sfx "ship-explode" 0
  die
end 

to-report ship-fire
  ;; SETUP-bullet
  let fire! false
  ask the-ship
  [
    if gun-temp <= 0 and count bullets < gun-limit
    [
      sfx "pew" 0
      hatch-bullets 1
      [
        x_set-line-thickness pixel * 4
        set size max list .5 ( pixel * 3 )
        set color white
        set vx dx * ( bullet-speed )
        set vy dy * ( bullet-speed )
        jump .5
        set fire! true
        set seeker? false
        let vary random 100
        ( ifelse
          ( vary > 90 )
          ;; hunter missle
          [
            set seeker? true
            set size .5
            set shape "missle"
            set target-rock one-of rocks
            set color yellow
            set bullet-burnout 200
          ]
          ( vary > 80 )
          ;; triple shot
          [ hatch 1 [ rt 90 jump .5 lt 90 ]
            hatch 1 [ lt 90 jump .5 rt 90 ]
          ]
          ( vary > 70 )
          ;; to left, right, and center
          [ hatch 1 [ rt 90 ]
            hatch 1 [ lt 90 ]
          ]
          ( vary > 60 )
          ;; four-way shot
          [ hatch 1 [ rt 90 ]
            hatch 1 [ lt 90 ]
            hatch 1 [ rt 180 jump 1 ]
          ]
          ( vary > 55 )
          ;; circle of pebbles
          [ let a heading
            setxy [ xcor ] of myself [ ycor ] of myself
            repeat ( 360 / 5 )
            [ hatch 1 [ rt a jump .5 ]
              set a a + 5
            ] jump .5
          ]
          ;; no specialization
          [ ]
        )
      ]
      set gun-temp max-temp
    ]
  ]
  report fire!
end 

to rock-go

  ;  if count rocks < 5 and any? ships
  ;  [
  ;    let hh towards one-of ships
  ;    set vx .5 * sin hh
  ;    set vy .5 * cos hh
  ;  ]
  set vv ( vx * vx + vy * vy )
  ifelse ( vv > 1 )
  [
    rock-explode
  ]
  [
    let trail-color red + 10 * int min list 120 ( 10 * size )
    setxy ( xcor + vx ) ( ycor + vy )
    rt av
    ask patches in-radius (round (.3 * size)) [set pcolor trail-color ]
    set color rock-color
    if ( any? ships in-radius ( size / 2 + .5 ) )
    [
      ask ships [ ship-explode ]
    ]
    if ( true )
    [ let close min-one-of ( other rocks ) [ distance myself ]
      let overlap -1 * boundary-distance close
      if
      ( overlap > 2 * pixel )
      [
        if ( overlap > 4 * pixel )
        [ ;; too close! force them away
          face close rt 180 jump overlap / 2
          ask close [ face myself rt 180 jump overlap / 2 ]
        ]
        collide-with close
      ]
    ]
  ]
end 

to collide-with [ other-particle ] ;; particle procedure
  let recovery .99
  ;;; PHASE 1: initial setup

  ;; for convenience, grab some quantities from other-particle

  let h ifelse-value ( vx != 0 or vy != 0 ) [ atan vx vy ] [ 0 ]
  let mass size ^ 3
  let speed sqrt ( vx * vx + vy * vy )
  let mass2 [ size ^ 3 ] of other-particle
  let speed2 [ sqrt ( vx * vx + vy * vy ) ] of other-particle
  let h2 [ ifelse-value ( vx != 0 or vy != 0 ) [ atan vx vy ] [ 0 ] ] of other-particle

  ;;modified so that theta is heading toward other particle
  let theta towards other-particle

  ;;; PHASE 2: convert velocities to theta-based vector representation

  ;; now convert my velocity from speed/heading representation to components
  ;; along theta and perpendicular to theta
  let v1t ( speed * cos ( theta - h ) )
  let v1l ( speed * sin ( theta - h ) )

  ;; do the same for other-particle
  let v2t ( speed2 * cos ( theta - h2 ) )
  let v2l ( speed2 * sin ( theta - h2 ) )

  ;;; PHASE 3: manipulate vectors to implement collision

  ;; compute the velocity of the system's center of mass along theta
  let vcm ( ( ( mass * v1t ) + ( mass2 * v2t ) ) / ( mass + mass2 ) )

  ;; now compute the new velocity for each particle along direction theta.
  ;; velocity perpendicular to theta is unaffected by a collision along theta,
  ;; so the next two lines actually implement the collision itself, in the
  ;; sense that the effects of the collision are exactly the following changes
  ;; in particle velocity.
  set v1t ( 2 * vcm - v1t )
  set v2t ( 2 * vcm - v2t )

  let d distance other-particle - ( size + [ size ] of other-particle ) / 2
  ;;; PHASE 4: convert back to normal speed/heading

  ;; now convert my velocity vector into my new speed and heading
  set speed recovery * sqrt ( ( v1t * v1t ) + ( v1l * v1l ) )
  ;; if the magnitude of the velocity vector is 0, atan is undefined. but
  ;; speed will be 0, so heading is irrelevant anyway. therefore, in that
  ;; case we'll just leave it unmodified.
  if v1l != 0 or v1t != 0
  [ let new-h ( theta - ( atan v1l v1t ) )
    set vx sin new-h * speed
    set vy cos new-h * speed
    setxy xcor + vx ycor + vy
  ]

  ;; and do the same for other-particle
  set speed2 recovery * sqrt ( ( v2t ^ 2 ) + ( v2l ^ 2 ) )
  if v2l != 0 or v2t != 0
  [ let new-h ( theta - ( atan v2l v2t ) )
    ask other-particle [
      set vx sin new-h * speed2
      set vy cos new-h * speed2
      setxy xcor + vx ycor + vy
    ]
  ]
end 

to fragment-go
  setxy xcor + vx ycor + vy
  rt av
  if random 10 = 1
  [
    set av av * 2
    set size size / 2
    set burnout burnout * 1.5
    rt 90
    hatch 1 [ rt 180 ]
  ]
  set max-burnout max-burnout - 1

  ifelse max-burnout > 0
  [ if max-burnout < 10
    [ set color max-burnout ]
  ]
  [ die ]
end 

to-report boundary-distance [ obj ]
  if not is-turtle? obj [ report world-width ]
  report ( distance obj - ( size / 2 ) - [ size / 2 ] of obj )
end 

to ship-go
  set xcor xcor + vx
  set ycor ycor + vy
  ;; ask patches in-radius size [ set pcolor 9.9 ]
  if gun-temp > 0
  [ set gun-temp gun-temp - 1 ]
  let crowd rocks in-radius 20
  if any? crowd
  [ let close min-one-of crowd [ boundary-distance myself ]
    let dc abs boundary-distance close
    if dc <= 2 and dc >= 1
    [ fragment-setup turquoise 1 1 ]
    if ( dc < .5 ) [ ship-teleport ]
  ]
end 

to bullet-go
  if seeker? and is-rock? target-rock
  [ lt .05 * subtract-headings heading towards target-rock ]
  jump bullet-speed
  let hits rocks with [ distance myself < size / 2 ]
  if any? hits [
    ask hits [ rock-explode ]
    set bullet-burnout -1

  ]
  set bullet-burnout bullet-burnout - 1
  if bullet-burnout <= 0 [ die ]
end 

to ship-spin-ws
  ask the-ship [ set shape "_ship-001" lt 15 ]
end 

to ship-spin-cw
  ask the-ship [ set shape "_ship-100" rt 15 ]
end 

to ship-thrust
  ask the-ship
  [
    ;; get components of thrust vector
    let am pixel / 2
    set ax am * sin heading
    set ay am * cos heading

    ;; add to current velocity vector components
    let nvx vx + ax
    let nvy vy + ay

    ;; calculate new velocity magnitude
    let maxvm 1.00
    let nvm sqrt ( nvx * nvx + nvy * nvy )
    let svm ifelse-value ( nvm <= maxvm ) [ 1 ] [ nvm / maxvm ]

    set vx nvx / svm
    set vy nvy / svm

    ;; output-print " xcor ycor heading ax ay am vx vy vm"
    ;; foreach ( list xcor ycor heading ax ay am vx vy vm ) [ n -> output-type fixed n output-type " " ] output-print ""
    set shape "_ship-010"
  ]
end 

to-report fixed [ n ]
  let m ifelse-value n < 0 [ "-" ] [ " " ]

  let ns ( word " " ( int n ) "." int ( 100 * ( ( abs n ) - ( abs int n ) ) ) "0" )
  set ns reverse substring reverse ns 0 7
  report ns
end 

to ship-nothing
  ask the-ship
  [ set shape "_ship-000" ]
end 

to message-go
  ;; draw character, if appropriate
  ;; at end of message, die
  let font-size 36
  let pix 1 / patch-size
  let char-width ceiling (font-size / patch-size / 1.5)
  let char-height font-size / patch-size * 2
  ifelse ( caret >= length text )
  [ die ]
  [
    let new-x pxcor
    if ( pxcor >= cursor )
    [
      let c item caret text
      if c = "W" or c = "m" or c = "M"
      [
        set new-x new-x + 1
        if new-x > max-pxcor - 1 [ set new-x min-pxcor ]
        set xcor new-x
        set cursor new-x
      ]
      if c = "i" or c = "l"
      [ set new-x new-x - 1
        set xcor new-x
        set cursor new-x
      ]
      set plabel c
      set caret caret + 1
      set cursor cursor + char-width
    ]
    ;; advance cursor
    set new-x new-x + 1
    if new-x > max-pxcor - 1 [ set new-x min-pxcor ]
    set xcor new-x
  ]
end 

to message-setup [ $window# $text ]
  let this nobody
  let font-size 36
  let pix 1 / patch-size
  let char-width ceiling (font-size / patch-size / 1.5)
  let line-height ceiling(font-size / patch-size * 1.4)
  ;; get or create the indicated message line
  ifelse ( any? messengers with [ window# = $window# ] )
  [ ;; use existing messenger
    set this one-of messengers with [ window# = $window# ]
  ]
  [ ;; make a new messenger
    ;; since we can't be sure what is making the message,
    ;; ask a patch to do it, so we can use SPROUT with certainty.
    ask patch min-pxcor min-pycor
    [ sprout-messengers 1
      [ set this self ]
    ]
  ]
  ;; now work with the messenger
  ask this
  [
    set shape "cursor"
    set size 8
    set color black
    set text $text
    set window# $window#
    set show-cursor? false
    setxy ( min-pxcor + ceiling (char-width / 2) ) ( max-pycor - line-height * window# )
    let min-py pycor - ( line-height / 2 ) + 1
    let max-py pycor + ( line-height / 2 ) - 1
    set window patches with [ pycor >= min-py and pycor <= max-py ]
    ask window [ set plabel "" set pcolor white set plabel-color black ]
    set caret 0
    set cursor pxcor
    set hidden? true ;; not show-cursor?
  ]
end 

to write-message
  let expiration timer + 10
  while [ any? messengers and timer < expiration ]
  [ repeat 5 [ ask messengers
    [ message-go
    ]]
    tick
  ]
  ask messengers [ die ]
end 

to mouse-mode
  if ( mouse-inside? )
  [
    let diff [ -1 * subtract-headings towardsxy mouse-xcor mouse-ycor heading ] of the-ship
    let turn 0
    (
      ifelse
      ( diff > 0 )
      [ set turn 1 ]
      ( diff < 0 )
      [ set turn -1 ]
      ;; otherwise
      [ set turn 0 ]
    )
    ask the-ship [ lt diff / 2 ]
  ]
  ifelse ( mouse-down? )
  [ ifelse click = 0
    [ let void ship-fire
      set click 1
    ]
    [ ship-thrust

    ]
  ] [ set click 0 ]
end 

to auto-pilot
  ask the-ship
  [ let diff 0
    let close rocks in-radius 20
    ifelse ( any? close )
    [
      set close min-one-of close [ distance myself ]
      ;if ( not member? close link-neighbors )
      ; [ ask my-links [ die ]
      ; create-link-with close
      ; ]
      let dd [ distance myself ] of close
      let rockspeed [ sqrt ( vx * vx + vy * vy ) ] of close
      let bullspeed bullet-speed
      let bx dx * bullspeed
      let by dy * bullspeed
      let frx [ xcor + vx * dd / bullspeed ] of close
      let fry [ ycor + vy * dd / bullspeed ] of close
      let frh towardsxy frx fry
      let fdist distancexy frx fry

      let fhdiff subtract-headings frh heading
      ;; let dist boundary-distance close

      ifelse ( abs fhdiff > 2 )
      [
        ifelse ( fhdiff < 0 )
        [ lt 5 ]
        [ rt 5 ]
      ]
      [
        ifelse ( fdist > 2 * ( bullet-speed * bullet-burnout ) )
        [ ship-thrust ]
        [
          if ship-fire
          [ if not any? reticules
            [ reticule-setup
            ]
            ask active-reticule
            [ set timeout timer + 2
              setxy frx fry
              show-turtle
              ; create-link-with close
              ; [ set thickness 2 * pixel
              ; set color violet
              ; ]

              hatch 1
              [ hide-turtle
                set active-reticule self
                set timeout 0
              ]
            ]
          ]
        ]
      ]
    ]
    [ let rnd random 100
      ( ifelse
        ( rnd < 5 ) [ ship-spin-ws ]
        ( rnd >= 40 and rnd < 55 ) [ ship-thrust ]
        ( rnd >= 90 and rnd < 95 ) [ ship-spin-cw ]
        [ let void ship-fire ]
      )
    ]
  ]
end 

to GET-input
  if ( any? ships )
  [ ship-nothing
    ifelse ( full-auto? )
    [
      auto-pilot

    ]
    [
      if ( mouse-mode? )
      [
        mouse-mode
      ]
      ( ifelse
        ( keypress = "fire" ) [ let void ship-fire ]
        ( keypress = "ws" ) [ ship-spin-ws ]
        ( keypress = "cw" ) [ ship-spin-cw ]
        ( keypress = "t" ) [ ship-thrust ]
        [ ship-nothing ]
      )
      set keypress ""
    ]
  ]
end 

to shapes-setup
  set-default-shape ships "_ship-000"
  set-default-shape rocks "rock-1"
  set-default-shape bullets "bullet"
  set-default-shape fragments "fragment"
  set-default-shape messengers "cursor"
end 

to startup
  clear-all
  reset-ticks
  message-setup 1 "Please press RUN"
  write-message
  tick
end 

to globals-setup
  set pixel 1 / patch-size
  set active-reticule nobody
end 

to rocks-setup
  if num-rocks = false or num-rocks < 5 [ set num-rocks 5 ]
  repeat num-rocks [ setup-rock ]
  let retry-limit 50
  let too-many-rocks true
  while [ too-many-rocks and retry-limit > 0 ]
  [
    set too-many-rocks false
    ASK ROCKS
    [ LET too-close OTHER ROCKS IN-RADIUS (SIZE * 2)
      LET is-too-close? ANY? too-close
      SET too-many-rocks too-many-rocks OR is-too-close?
      IF is-too-close?
      [
        RT RANDOM 360
        JUMP 1
      ]

      SET retry-limit retry-limit - 1
    ]
  ]
end 

to ship-teleport
  let max-jumps 100
  let crowd rocks in-radius 20
  hatch-HS-effects 1
  [ set size 3
    set color violet
    set effect-direction 1
    set shape "circle"
  ]
  while
  [
    max-jumps > 0
    and
    any? crowd with [ boundary-distance myself < 2 ]
  ]
  [
    fragment-setup green 0 1
    setxy random-xcor random-ycor
    set vx 0
    set vy 0
    set crowd rocks in-radius 10
    set max-jumps max-jumps - 1
    ;display
  ]
  hatch-HS-effects 1
  [ set color red
    set size 20
    set effect-direction -1
    set shape "circle"
  ]
  fragment-setup lime 1 2
end 

to clock-setup
  create-clocks 1
  [ set shape "clock"
    set start-time 0
    set current-time 0
    set elapsed-time 0
    set cumulative-time 0
    set pause-until 0
    set clock-on false
    set size 3
    setxy 0 max-pycor - size / 2 - pixel
  ]
end 

to game-setup
  set score 0
  globals-setup
  shapes-setup
  game-clear
  rocks-setup
  logo-display
  directions-display
  write-message
  clock-setup
  stop-inspecting-dead-agents
  set setup-finished true
  reset-ticks
end 

to new-game
  set score 0
  game-clear
  rocks-setup
  ship-setup
  set setup-finished true
end 

to directions-display
  message-setup 5 "THE MISSION:"
  write-message
  message-setup 6 "DESTROY RUBBLE."
  write-message
  message-setup 7 "-PRESS START-"
end 

to game-go
  ifelse ( setup-finished = 0 ) [ game-setup ]
  [ get-input
    ask ships [ ship-go ]
    ask bullets [ bullet-go ]
    set rock-color white
    ;; ifelse-value ( random 100 < 10 ) [ 1 + random-float 1 + 2.9 * random 2 ] [ white ]
    ask rocks [ rock-go ]
    ask fragments [ fragment-go ]
    ask messengers [ message-go ]
    ask reticules [ reticules-go ]
    ask HS-effects
    [
      ifelse ( size < 3 or size > 20 )
      [ die ]
      [ set size size + effect-direction ]
    ]
    ;; ask aliens [ GO-alien ]
    ;; if ( not ( any? ships or any? messengers ) ) [ messenger-setup 1 "PRESS PLAY" ]
    if ( not ( any? rocks ) )
    [ set num-rocks num-rocks * 1.25 rocks-setup
      ask ships [ home set vx 0 set vy 0 ]
    ]
    ask patches
    [ let hue ifelse-value (is-list? pcolor) [pcolor ][ extract-rgb pcolor ]
      set rr item 0 hue ^ 2 * .95
      set gg item 1 hue ^ 2 * .95
      set bb item 2 hue ^ 2 * .95
    ]
    diffuse rr .2
    diffuse gg .2
    diffuse bb .2
    ask patches
    [ set pcolor rgb sqrt rr sqrt gg sqrt bb
    ]
  ]
  tick
end 

to logo-display
  clear-patches
  ask letters [ die ]
  tick
  ;; ask patches with [ ( pxcor + pycor ) mod 2 = 0 ] [ set pcolor ( 2.5 + black ) ]
  let logo0 "RUBBLE"
  let logo1 "TROUBLE"
  logo-animate logo0 0
  logo-animate logo1 1
  ;display
end 

to logo-animate [ logo line ]
  let len length logo
  let letter-size ( world-width ) / ( len )
  let start-x min-pxcor + ( world-width - 1 ) / 2 - ( ( len * letter-size ) / 2 ) + .5 * letter-size
  let line-height 1.5
  let these-letters no-turtles
  foreach range len
  [
    [ t ] ->
    create-letters 1
    [
      let c item t logo
      let pos-x letter-size * t
      setxy ( start-x + pos-x ) max-pxcor - letter-size * line * line-height
      if ( c = " " ) [ set c "space" ]
      set shape word "logo-" c
      set size letter-size
      set color base-color
      set heading 0
      set base-xcor xcor
      set base-size size
      set base-color white
      set color base-color
      set base-heading heading
      setxy 0 min-pycor
      set size 0
      set these-letters ( turtle-set these-letters self )
    ]
  ]
  let top-y ( world-height - 1 ) - ( .5 * letter-size ) - line * letter-size * line-height
  (
    foreach ( range 0 1.0 ( 2 / 30 ) )
    [
      [ ratio ] ->
      let y min-pycor + top-y * ratio
      let m2 ratio * letter-size
      ask these-letters
      [
        set size m2
        set ycor y
        set xcor base-xcor * ratio
      ]
      tick
      wait 1 / 30
    ]
  )
  set pixel 1 / patch-size
  let thick PIXEL * 16
  let lcolor lime - 3.5
  ask letters
  [ let mythick thick
    LET MYCOLOR LCOLOR
    repeat 4
    [ hatch 1
      [ set color MYCOLOR
        x_set-line-thickness mythick
        set mythick mythick / 2
        SET MYCOLOR MYCOLOR + 2
      ]
    ]
    DIE
  ]
  ;
end 

to play-note [ $inst $key $vel $dur ]
  ;; sound:play-note $inst $key $vel $dur
end 

to play-note-later [ $delay $inst $key $vel $dur ]
  ;; sound:play-note-later $delay $inst $key $vel $dur
end 

to play-drum [ $inst $vel ]
  ;; sound:play-drum $inst $vel
end 

to stop-music
  ;; sound:stop-music
end 

to sfx [ fx option ]

  (
    ifelse
    ( fx = "explode-rock" )
    [
      play-drum "CRASH CYMBAL 2" 12
      play-note-later .10 "timpani" ( 45 - option * 4 ) 64 + option .3
      play-note "timpani"
      ( 42 - option * 2 ) 64 + option .1
    ]
    ( fx = "ship-explode" )
    [
      play-drum "CRASH CYMBAL 2" 127
      play-note-later .20 "timpani" 42 100 .1
      play-note-later .10 "timpani" 42 100 .1
      play-note "timpani" 40 64 .1
    ]
    ( fx = "pew" )
    [
      let fxarppegio-steps 5
      let fxkeys map [ r -> 42 - r * 3 ] ( range fxarppegio-steps )
      let fxvelocity 48
      let fxduration .02 * fxarppegio-steps
      let fxdelay-step fxduration / fxarppegio-steps
      foreach ( range fxarppegio-steps )
      [ [ i ] ->
        play-note-later ( i * fxdelay-step ) "SYNTH BRASS 1" ( item i fxkeys ) fxvelocity fxdelay-step
      ]
    ]
    [
      stop-music
    ]
  )
end 

;; The following code was publsihed by and released to the Public Domain by Uri Wilensky,
;; and was obtained from the NetLogo v 6.3 Model Library.
;; note that the 6.2.2 version used TAN 90, which is mathematically undefined, but
;; netlogo used to incorrectly report as a value

;; reports a two-item list of x and y coordinates, or an empty
;; list if no intersection is found

to-report intersection [ t1 t2 ]
  let is-t1-vertical? ( [ heading ] of t1 = 0 or [ heading ] of t1 = 180 )
  let is-t2-vertical? ( [ heading ] of t2 = 0 or [ heading ] of t2 = 180 )

  ;; is t1 vertical? if so, swap the two turtles, and run again.
  ;; ( unless both are vertical, i.e. they are parallel--report an empty list )
  ifelse ( is-t1-vertical? )
  [
    ifelse ( is-t2-vertical? )
    [ report [ ]
    ]
    [ report intersection t2 t1
    ]
    ;; report ends the procedure immediately
  ]
  [
    let m1 [ tan ( 90 - heading ) ] of t1

    ;; is t2 vertical? if so, handle specially
    ifelse ( is-t2-vertical? )
    [
      ;; represent t1 line in slope-intercept form ( y=mx+c )
      let c1 [ ycor - xcor * m1 ] of t1
      ;; t2 is vertical so we know x already
      let x [ xcor ] of t2
      ;; solve for y
      let y m1 * x + c1
      ;; check if intersection point lies on both segments
      ifelse [ not x-within? x ] of t1 or [ not y-within? y ] of t2
      [
        report [ ]
      ]
      [
        report list x y
      ]
    ]
    [
      let m2 [ tan ( 90 - heading ) ] of t2

      ;; treat parallel/collinear lines as non-intersecting
      ifelse m1 = m2
      [
        report [ ]
      ]
      [

        ;; now handle the normal case where neither turtle is vertical;
        ;; start by representing lines in slope-intercept form ( y=mx+c )
        let c1 [ ycor - xcor * m1 ] of t1
        let c2 [ ycor - xcor * m2 ] of t2
        ;; now solve for x
        let x ( c2 - c1 ) / ( m1 - m2 )
        ;; check if intersection point lies on both segments
        ifelse [ not x-within? x ] of t1 or [ not x-within? x ] of t2
        [
          report [ ]
        ]
        [
          report list x ( m1 * x + c1 ) ]
      ]
    ]
  ]
end 

to-report x-within? [ x ] ;; turtle procedure
  report abs ( xcor - x ) <= abs ( size / 2 * dx )
end 

to-report y-within? [ y ] ;; turtle procedure
  report abs ( ycor - y ) <= abs ( size / 2 * dy )
end 

;; below only for when generating a new thumbnail image for the commons
;to setup
; clear-all
; startup
; new-game
; set num-rocks 15
; rocks-setup
;end
;to go
; repeat 15 [ game-go wait 1 / 30 ]
;end

There are 8 versions of this model.

Uploaded by When Description Download
James Steiner about 1 year ago big fixes, messages, color trails Download this version
James Steiner over 1 year ago added inelastic collisions of rocks, more rock types, better explosion debris Download this version
James Steiner over 1 year ago reconfigured added variant projectile patterns Download this version
James Steiner over 1 year ago changed aspect ratio other tweaks Download this version
James Steiner over 1 year ago Removed Display/NoDisplay Download this version
James Steiner over 1 year ago Removed set line thickness Download this version
James Steiner over 1 year ago Removed Sounds Download this version
James Steiner over 1 year ago Initial upload Download this version

Attached files

File Type Description Last updated
Rubble Trouble!.png preview Preview for 'Rubble Trouble!' over 1 year ago, by James Steiner Download

This model does not have any ancestors.

This model does not have any descendants.