summaryrefslogtreecommitdiffhomepage
path: root/samples/05_mouse/03_mouse_move_paint_app
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2020-09-22 06:27:46 -0500
committerAmir Rajan <[email protected]>2020-09-22 06:27:46 -0500
commit20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5 (patch)
treeb4742e4f9acfd5400a04f314164812606a71df9f /samples/05_mouse/03_mouse_move_paint_app
parent5b2311900072cfff9582bb0296140cfb354cb911 (diff)
downloaddragonruby-game-toolkit-contrib-20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5.tar.gz
dragonruby-game-toolkit-contrib-20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5.zip
synced with 1.22
Diffstat (limited to 'samples/05_mouse/03_mouse_move_paint_app')
-rw-r--r--samples/05_mouse/03_mouse_move_paint_app/app/main.rb240
-rw-r--r--samples/05_mouse/03_mouse_move_paint_app/license-for-sample.txt21
-rw-r--r--samples/05_mouse/03_mouse_move_paint_app/replay.txt238
3 files changed, 499 insertions, 0 deletions
diff --git a/samples/05_mouse/03_mouse_move_paint_app/app/main.rb b/samples/05_mouse/03_mouse_move_paint_app/app/main.rb
new file mode 100644
index 0000000..9303949
--- /dev/null
+++ b/samples/05_mouse/03_mouse_move_paint_app/app/main.rb
@@ -0,0 +1,240 @@
+=begin
+
+ APIs listing that haven't been encountered in previous sample apps:
+
+ - Floor: Method that returns an integer number smaller than or equal to the original with no decimal.
+
+ For example, if we have a variable, a = 13.7, and we called floor on it, it would look like this...
+ puts a.floor()
+ which would print out 13.
+ (There is also a ceil method, which returns an integer number greater than or equal to the original
+ with no decimal. If we had called ceil on the variable a, the result would have been 14.)
+
+ Reminders:
+
+ - Hashes: Collection of unique keys and their corresponding values. The value can be found
+ using their keys.
+
+ For example, if we have a "numbers" hash that stores numbers in English as the
+ key and numbers in Spanish as the value, we'd have a hash that looks like this...
+ numbers = { "one" => "uno", "two" => "dos", "three" => "tres" }
+ and on it goes.
+
+ Now if we wanted to find the corresponding value of the "one" key, we could say
+ puts numbers["one"]
+ which would print "uno" to the console.
+
+ - args.state.new_entity: Used when we want to create a new object, like a sprite or button.
+ In this sample app, new_entity is used to create a new button that clears the grid.
+ (Remember, you can use state to define ANY property and it will be retained across frames.)
+
+ - args.inputs.mouse.click.point.(x|y): The x and y location of the mouse.
+
+ - args.inputs.mouse.click.point.created_at: The frame the mouse click occurred in.
+
+ - args.outputs.labels: An array. The values in the array generate a label.
+ The parameters are [X, Y, TEXT, SIZE, ALIGN, RED, GREEN, BLUE, ALPHA, FONT STYLE]
+ For more information about labels, go to mygame/documentation/02-labels.md.
+
+ - ARRAY#inside_rect?: Returns true or false depending on if the point is inside the rect.
+
+=end
+
+# This sample app shows an empty grid that the user can paint on.
+# To paint, the user must keep their mouse presssed and drag it around the grid.
+# The "clear" button allows users to clear the grid so they can start over.
+
+class PaintApp
+ attr_accessor :inputs, :state, :outputs, :grid, :args
+
+ # Runs methods necessary for the game to function properly.
+ def tick
+ print_title
+ add_grid
+ check_click
+ draw_buttons
+ end
+
+ # Prints the title onto the screen by using a label.
+ # Also separates the title from the grid with a line as a horizontal separator.
+ def print_title
+ args.outputs.labels << [ 640, 700, 'Paint!', 0, 1 ]
+ outputs.lines << horizontal_separator(660, 0, 1280)
+ end
+
+ # Sets the starting position, ending position, and color for the horizontal separator.
+ # The starting and ending positions have the same y values.
+ def horizontal_separator y, x, x2
+ [x, y, x2, y, 150, 150, 150]
+ end
+
+ # Sets the starting position, ending position, and color for the vertical separator.
+ # The starting and ending positions have the same x values.
+ def vertical_separator x, y, y2
+ [x, y, x, y2, 150, 150, 150]
+ end
+
+ # Outputs a border and a grid containing empty squares onto the screen.
+ def add_grid
+
+ # Sets the x, y, height, and width of the grid.
+ # There are 31 horizontal lines and 31 vertical lines in the grid.
+ # Feel free to count them yourself before continuing!
+ x, y, h, w = 640 - 500/2, 640 - 500, 500, 500 # calculations done so the grid appears in screen's center
+ lines_h = 31
+ lines_v = 31
+
+ # Sets values for the grid's border, grid lines, and filled squares.
+ # The filled_squares variable is initially set to an empty array.
+ state.grid_border ||= [ x, y, h, w ] # definition of grid's outer border
+ state.grid_lines ||= draw_grid(x, y, h, w, lines_h, lines_v) # calls draw_grid method
+ state.filled_squares ||= [] # there are no filled squares until the user fills them in
+
+ # Outputs the grid lines, border, and filled squares onto the screen.
+ outputs.lines.concat state.grid_lines
+ outputs.borders << state.grid_border
+ outputs.solids << state.filled_squares
+ end
+
+ # Draws the grid by adding in vertical and horizontal separators.
+ def draw_grid x, y, h, w, lines_h, lines_v
+
+ # The grid starts off empty.
+ grid = []
+
+ # Calculates the placement and adds horizontal lines or separators into the grid.
+ curr_y = y # start at the bottom of the box
+ dist_y = h / (lines_h + 1) # finds distance to place horizontal lines evenly throughout 500 height of grid
+ lines_h.times do
+ curr_y += dist_y # increment curr_y by the distance between the horizontal lines
+ grid << horizontal_separator(curr_y, x, x + w - 1) # add a separator into the grid
+ end
+
+ # Calculates the placement and adds vertical lines or separators into the grid.
+ curr_x = x # now start at the left of the box
+ dist_x = w / (lines_v + 1) # finds distance to place vertical lines evenly throughout 500 width of grid
+ lines_v.times do
+ curr_x += dist_x # increment curr_x by the distance between the vertical lines
+ grid << vertical_separator(curr_x, y + 1, y + h) # add separator
+ end
+
+ # paint_grid uses a hash to assign values to keys.
+ state.paint_grid ||= {"x" => x, "y" => y, "h" => h, "w" => w, "lines_h" => lines_h,
+ "lines_v" => lines_v, "dist_x" => dist_x,
+ "dist_y" => dist_y }
+
+ return grid
+ end
+
+ # Checks if the user is keeping the mouse pressed down and sets the mouse_hold variable accordingly using boolean values.
+ # If the mouse is up, the user cannot drag the mouse.
+ def check_click
+ if inputs.mouse.down #is mouse up or down?
+ state.mouse_held = true # mouse is being held down
+ elsif inputs.mouse.up # if mouse is up
+ state.mouse_held = false # mouse is not being held down or dragged
+ state.mouse_dragging = false
+ end
+
+ if state.mouse_held && # mouse needs to be down
+ !inputs.mouse.click && # must not be first click
+ ((inputs.mouse.previous_click.point.x - inputs.mouse.position.x).abs > 15) # Need to move 15 pixels before "drag"
+ state.mouse_dragging = true
+ end
+
+ # If the user clicks their mouse inside the grid, the search_lines method is called with a click input type.
+ if ((inputs.mouse.click) && (inputs.mouse.click.point.inside_rect? state.grid_border))
+ search_lines(inputs.mouse.click.point, :click)
+
+ # If the user drags their mouse inside the grid, the search_lines method is called with a drag input type.
+ elsif ((state.mouse_dragging) && (inputs.mouse.position.inside_rect? state.grid_border))
+ search_lines(inputs.mouse.position, :drag)
+ end
+ end
+
+ # Sets the definition of a grid box and handles user input to fill in or clear grid boxes.
+ def search_lines (point, input_type)
+ point.x -= state.paint_grid["x"] # subtracts the value assigned to the "x" key in the paint_grid hash
+ point.y -= state.paint_grid["y"] # subtracts the value assigned to the "y" key in the paint_grid hash
+
+ # Remove code following the .floor and see what happens when you try to fill in grid squares
+ point.x = (point.x / state.paint_grid["dist_x"]).floor * state.paint_grid["dist_x"]
+ point.y = (point.y / state.paint_grid["dist_y"]).floor * state.paint_grid["dist_y"]
+
+ point.x += state.paint_grid["x"]
+ point.y += state.paint_grid["y"]
+
+ # Sets definition of a grid box, meaning its x, y, width, and height.
+ # Floor is called on the point.x and point.y variables.
+ # Ceil method is called on values of the distance hash keys, setting the width and height of a box.
+ grid_box = [ point.x.floor, point.y.floor, state.paint_grid["dist_x"].ceil, state.paint_grid["dist_y"].ceil ]
+
+ if input_type == :click # if user clicks their mouse
+ if state.filled_squares.include? grid_box # if grid box is already filled in
+ state.filled_squares.delete grid_box # box is cleared and removed from filled_squares
+ else
+ state.filled_squares << grid_box # otherwise, box is filled in and added to filled_squares
+ end
+ elsif input_type == :drag # if user drags mouse
+ unless state.filled_squares.include? grid_box # unless the grid box dragged over is already filled in
+ state.filled_squares << grid_box # the box is filled in and added to filled_squares
+ end
+ end
+ end
+
+ # Creates and outputs a "Clear" button on the screen using a label and a border.
+ # If the button is clicked, the filled squares are cleared, making the filled_squares collection empty.
+ def draw_buttons
+ x, y, w, h = 390, 50, 240, 50
+ state.clear_button ||= state.new_entity(:button_with_fade)
+
+ # The x and y positions are set to display the label in the center of the button.
+ # Try changing the first two parameters to simply x, y and see what happens to the text placement!
+ state.clear_button.label ||= [x + w.half, y + h.half + 10, "Clear", 0, 1] # placed in center of border
+ state.clear_button.border ||= [x, y, w, h]
+
+ # If the mouse is clicked inside the borders of the clear button,
+ # the filled_squares collection is emptied and the squares are cleared.
+ if inputs.mouse.click && inputs.mouse.click.point.inside_rect?(state.clear_button.border)
+ state.clear_button.clicked_at = inputs.mouse.click.created_at # time (frame) the click occurred
+ state.filled_squares.clear
+ inputs.mouse.previous_click = nil
+ end
+
+ outputs.labels << state.clear_button.label
+ outputs.borders << state.clear_button.border
+
+ # When the clear button is clicked, the color of the button changes
+ # and the transparency changes, as well. If you change the time from
+ # 0.25.seconds to 1.25.seconds or more, the change will last longer.
+ if state.clear_button.clicked_at
+ outputs.solids << [x, y, w, h, 0, 180, 80, 255 * state.clear_button.clicked_at.ease(0.25.seconds, :flip)]
+ end
+ end
+end
+
+$paint_app = PaintApp.new
+
+def tick args
+ $paint_app.inputs = args.inputs
+ $paint_app.state = args.state
+ $paint_app.grid = args.grid
+ $paint_app.args = args
+ $paint_app.outputs = args.outputs
+ $paint_app.tick
+ tick_instructions args, "How to create a simple paint app. CLICK and HOLD to draw."
+end
+
+def tick_instructions args, text, y = 715
+ return if args.state.key_event_occurred
+ if args.inputs.mouse.click ||
+ args.inputs.keyboard.directional_vector ||
+ args.inputs.keyboard.key_down.enter ||
+ args.inputs.keyboard.key_down.escape
+ args.state.key_event_occurred = true
+ end
+
+ args.outputs.debug << [0, y - 50, 1280, 60].solid
+ args.outputs.debug << [640, y, text, 1, 1, 255, 255, 255].label
+ args.outputs.debug << [640, y - 25, "(click to dismiss instructions)" , -2, 1, 255, 255, 255].label
+end
diff --git a/samples/05_mouse/03_mouse_move_paint_app/license-for-sample.txt b/samples/05_mouse/03_mouse_move_paint_app/license-for-sample.txt
new file mode 100644
index 0000000..5c0563d
--- /dev/null
+++ b/samples/05_mouse/03_mouse_move_paint_app/license-for-sample.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 DragonRuby LLC, Ananth Vivekanand, Sahil Jain
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/samples/05_mouse/03_mouse_move_paint_app/replay.txt b/samples/05_mouse/03_mouse_move_paint_app/replay.txt
new file mode 100644
index 0000000..2f4753c
--- /dev/null
+++ b/samples/05_mouse/03_mouse_move_paint_app/replay.txt
@@ -0,0 +1,238 @@
+replay_version 2.0
+stopped_at 629
+seed 100
+recorded_at Sun Sep 29 22:17:52 2019
+[:mouse_move, 539, 647, 2, 1, 151]
+[:mouse_move, 545, 636, 2, 2, 152]
+[:mouse_move, 552, 618, 2, 3, 153]
+[:mouse_move, 556, 607, 2, 4, 154]
+[:mouse_move, 572, 557, 2, 5, 155]
+[:mouse_move, 576, 542, 2, 6, 156]
+[:mouse_move, 593, 468, 2, 7, 157]
+[:mouse_move, 594, 454, 2, 8, 158]
+[:mouse_move, 600, 410, 2, 9, 159]
+[:mouse_move, 602, 354, 2, 10, 160]
+[:mouse_move, 603, 327, 2, 11, 161]
+[:mouse_move, 605, 290, 2, 12, 162]
+[:mouse_move, 605, 281, 2, 13, 163]
+[:mouse_move, 606, 265, 2, 14, 164]
+[:mouse_move, 606, 256, 2, 15, 165]
+[:mouse_move, 606, 246, 2, 16, 166]
+[:mouse_move, 606, 242, 2, 17, 167]
+[:mouse_move, 606, 240, 2, 18, 168]
+[:mouse_move, 606, 239, 2, 19, 171]
+[:mouse_move, 606, 238, 2, 20, 174]
+[:mouse_move, 606, 239, 2, 21, 191]
+[:mouse_move, 606, 241, 2, 22, 199]
+[:mouse_move, 606, 243, 2, 23, 200]
+[:mouse_move, 606, 249, 2, 24, 201]
+[:mouse_move, 605, 253, 2, 25, 203]
+[:mouse_move, 603, 254, 2, 26, 204]
+[:mouse_move, 601, 257, 2, 27, 205]
+[:mouse_move, 599, 258, 2, 28, 206]
+[:mouse_move, 595, 259, 2, 29, 207]
+[:mouse_move, 594, 260, 2, 30, 208]
+[:mouse_move, 589, 260, 2, 31, 209]
+[:mouse_move, 587, 260, 2, 32, 210]
+[:mouse_move, 580, 259, 2, 33, 211]
+[:mouse_move, 579, 258, 2, 34, 212]
+[:mouse_move, 576, 257, 2, 35, 214]
+[:mouse_move, 575, 257, 2, 36, 215]
+[:mouse_move, 574, 257, 2, 37, 216]
+[:mouse_move, 573, 257, 2, 38, 217]
+[:mouse_move, 570, 257, 2, 39, 218]
+[:mouse_move, 566, 257, 2, 40, 219]
+[:mouse_move, 562, 258, 2, 41, 220]
+[:mouse_move, 558, 259, 2, 42, 222]
+[:mouse_move, 557, 259, 2, 43, 223]
+[:mouse_move, 554, 260, 2, 44, 224]
+[:mouse_move, 553, 260, 2, 45, 226]
+[:mouse_move, 552, 260, 2, 46, 228]
+[:mouse_move, 551, 260, 2, 47, 229]
+[:mouse_move, 550, 260, 2, 48, 230]
+[:mouse_move, 548, 259, 2, 49, 232]
+[:mouse_move, 547, 259, 2, 50, 234]
+[:mouse_move, 546, 259, 2, 51, 235]
+[:mouse_move, 545, 259, 2, 52, 239]
+[:mouse_move, 544, 259, 2, 53, 242]
+[:mouse_move, 542, 259, 2, 54, 243]
+[:mouse_move, 540, 259, 2, 55, 245]
+[:mouse_move, 539, 259, 2, 56, 246]
+[:mouse_move, 537, 259, 2, 57, 247]
+[:mouse_move, 536, 259, 2, 58, 248]
+[:mouse_move, 535, 259, 2, 59, 249]
+[:mouse_move, 534, 259, 2, 60, 250]
+[:mouse_move, 533, 259, 2, 61, 251]
+[:mouse_button_pressed, 1, 0, 1, 62, 257]
+[:mouse_button_up, 1, 0, 1, 63, 265]
+[:mouse_move, 535, 261, 2, 64, 278]
+[:mouse_move, 544, 266, 2, 65, 279]
+[:mouse_move, 550, 270, 2, 66, 280]
+[:mouse_move, 559, 274, 2, 67, 281]
+[:mouse_move, 581, 280, 2, 68, 282]
+[:mouse_move, 606, 287, 2, 69, 283]
+[:mouse_move, 635, 291, 2, 70, 284]
+[:mouse_move, 654, 293, 2, 71, 285]
+[:mouse_move, 677, 293, 2, 72, 286]
+[:mouse_move, 691, 293, 2, 73, 287]
+[:mouse_move, 721, 290, 2, 74, 288]
+[:mouse_move, 734, 286, 2, 75, 290]
+[:mouse_move, 740, 283, 2, 76, 291]
+[:mouse_move, 746, 279, 2, 77, 292]
+[:mouse_move, 748, 277, 2, 78, 293]
+[:mouse_move, 752, 273, 2, 79, 294]
+[:mouse_move, 753, 271, 2, 80, 295]
+[:mouse_move, 754, 268, 2, 81, 296]
+[:mouse_move, 755, 265, 2, 82, 297]
+[:mouse_move, 756, 265, 2, 83, 298]
+[:mouse_move, 756, 263, 2, 84, 299]
+[:mouse_move, 757, 262, 2, 85, 300]
+[:mouse_move, 757, 261, 2, 86, 302]
+[:mouse_move, 756, 260, 2, 87, 311]
+[:mouse_move, 755, 260, 2, 88, 312]
+[:mouse_move, 752, 259, 2, 89, 313]
+[:mouse_move, 751, 258, 2, 90, 314]
+[:mouse_move, 748, 258, 2, 91, 315]
+[:mouse_move, 747, 258, 2, 92, 316]
+[:mouse_move, 746, 257, 2, 93, 317]
+[:mouse_move, 745, 257, 2, 94, 318]
+[:mouse_move, 743, 257, 2, 95, 330]
+[:mouse_move, 742, 258, 2, 96, 331]
+[:mouse_move, 738, 259, 2, 97, 332]
+[:mouse_move, 736, 260, 2, 98, 334]
+[:mouse_move, 735, 260, 2, 99, 335]
+[:mouse_move, 734, 260, 2, 100, 336]
+[:mouse_move, 733, 260, 2, 101, 338]
+[:mouse_move, 732, 260, 2, 102, 340]
+[:mouse_move, 731, 260, 2, 103, 341]
+[:mouse_move, 730, 260, 2, 104, 343]
+[:mouse_move, 729, 260, 2, 105, 347]
+[:mouse_move, 727, 260, 2, 106, 349]
+[:mouse_move, 723, 260, 2, 107, 351]
+[:mouse_move, 721, 260, 2, 108, 353]
+[:mouse_move, 720, 260, 2, 109, 354]
+[:mouse_button_pressed, 1, 0, 1, 110, 363]
+[:mouse_button_up, 1, 0, 1, 111, 368]
+[:mouse_move, 720, 271, 2, 112, 382]
+[:mouse_move, 720, 279, 2, 113, 383]
+[:mouse_move, 714, 297, 2, 114, 384]
+[:mouse_move, 710, 307, 2, 115, 385]
+[:mouse_move, 687, 346, 2, 116, 386]
+[:mouse_move, 670, 365, 2, 117, 387]
+[:mouse_move, 632, 399, 2, 118, 388]
+[:mouse_move, 612, 411, 2, 119, 389]
+[:mouse_move, 584, 420, 2, 120, 390]
+[:mouse_move, 577, 420, 2, 121, 391]
+[:mouse_move, 548, 422, 2, 122, 392]
+[:mouse_move, 537, 416, 2, 123, 394]
+[:mouse_move, 533, 411, 2, 124, 395]
+[:mouse_move, 526, 401, 2, 125, 396]
+[:mouse_move, 524, 396, 2, 126, 397]
+[:mouse_move, 520, 386, 2, 127, 398]
+[:mouse_move, 518, 381, 2, 128, 399]
+[:mouse_move, 514, 371, 2, 129, 400]
+[:mouse_move, 513, 370, 2, 130, 401]
+[:mouse_move, 510, 366, 2, 131, 402]
+[:mouse_move, 509, 364, 2, 132, 403]
+[:mouse_move, 507, 362, 2, 133, 404]
+[:mouse_move, 501, 362, 2, 134, 405]
+[:mouse_move, 496, 362, 2, 135, 406]
+[:mouse_move, 487, 362, 2, 136, 407]
+[:mouse_move, 482, 362, 2, 137, 408]
+[:mouse_move, 475, 362, 2, 138, 409]
+[:mouse_move, 472, 362, 2, 139, 410]
+[:mouse_move, 468, 363, 2, 140, 411]
+[:mouse_move, 467, 363, 2, 141, 412]
+[:mouse_move, 466, 363, 2, 142, 413]
+[:mouse_move, 470, 363, 2, 143, 442]
+[:mouse_move, 473, 363, 2, 144, 443]
+[:mouse_move, 474, 362, 2, 145, 444]
+[:mouse_move, 474, 361, 2, 146, 445]
+[:mouse_move, 476, 360, 2, 147, 446]
+[:mouse_move, 477, 358, 2, 148, 447]
+[:mouse_move, 478, 355, 2, 149, 448]
+[:mouse_move, 479, 354, 2, 150, 449]
+[:mouse_move, 480, 351, 2, 151, 450]
+[:mouse_move, 481, 350, 2, 152, 452]
+[:mouse_move, 481, 349, 2, 153, 453]
+[:mouse_button_pressed, 1, 0, 1, 154, 474]
+[:mouse_move, 481, 350, 2, 155, 474]
+[:mouse_move, 483, 354, 2, 156, 475]
+[:mouse_move, 484, 359, 2, 157, 476]
+[:mouse_move, 491, 374, 2, 158, 477]
+[:mouse_move, 495, 383, 2, 159, 479]
+[:mouse_move, 497, 388, 2, 160, 480]
+[:mouse_move, 499, 391, 2, 161, 481]
+[:mouse_move, 503, 398, 2, 162, 482]
+[:mouse_move, 509, 408, 2, 163, 483]
+[:mouse_move, 511, 411, 2, 164, 485]
+[:mouse_move, 515, 417, 2, 165, 486]
+[:mouse_move, 517, 421, 2, 166, 487]
+[:mouse_move, 521, 425, 2, 167, 488]
+[:mouse_move, 523, 428, 2, 168, 489]
+[:mouse_move, 526, 431, 2, 169, 490]
+[:mouse_move, 528, 433, 2, 170, 491]
+[:mouse_move, 533, 437, 2, 171, 492]
+[:mouse_move, 536, 440, 2, 172, 493]
+[:mouse_move, 546, 447, 2, 173, 494]
+[:mouse_move, 551, 451, 2, 174, 495]
+[:mouse_move, 566, 461, 2, 175, 496]
+[:mouse_move, 582, 470, 2, 176, 497]
+[:mouse_move, 590, 473, 2, 177, 498]
+[:mouse_move, 597, 476, 2, 178, 499]
+[:mouse_move, 611, 482, 2, 179, 500]
+[:mouse_move, 622, 486, 2, 180, 501]
+[:mouse_move, 628, 488, 2, 181, 502]
+[:mouse_move, 632, 489, 2, 182, 503]
+[:mouse_move, 638, 491, 2, 183, 504]
+[:mouse_move, 644, 491, 2, 184, 505]
+[:mouse_move, 651, 492, 2, 185, 506]
+[:mouse_move, 660, 492, 2, 186, 507]
+[:mouse_move, 665, 492, 2, 187, 508]
+[:mouse_move, 669, 491, 2, 188, 509]
+[:mouse_move, 681, 489, 2, 189, 510]
+[:mouse_move, 685, 489, 2, 190, 512]
+[:mouse_move, 692, 487, 2, 191, 513]
+[:mouse_move, 697, 485, 2, 192, 514]
+[:mouse_move, 705, 482, 2, 193, 515]
+[:mouse_move, 709, 480, 2, 194, 516]
+[:mouse_move, 717, 475, 2, 195, 517]
+[:mouse_move, 721, 473, 2, 196, 518]
+[:mouse_move, 730, 467, 2, 197, 519]
+[:mouse_move, 733, 464, 2, 198, 520]
+[:mouse_move, 741, 458, 2, 199, 521]
+[:mouse_move, 746, 455, 2, 200, 522]
+[:mouse_move, 753, 448, 2, 201, 523]
+[:mouse_move, 761, 440, 2, 202, 524]
+[:mouse_move, 763, 438, 2, 203, 525]
+[:mouse_move, 767, 434, 2, 204, 526]
+[:mouse_move, 772, 426, 2, 205, 527]
+[:mouse_move, 774, 423, 2, 206, 528]
+[:mouse_move, 778, 415, 2, 207, 529]
+[:mouse_move, 782, 407, 2, 208, 530]
+[:mouse_move, 783, 402, 2, 209, 531]
+[:mouse_move, 785, 396, 2, 210, 532]
+[:mouse_move, 789, 385, 2, 211, 533]
+[:mouse_move, 791, 377, 2, 212, 534]
+[:mouse_move, 791, 373, 2, 213, 535]
+[:mouse_move, 792, 369, 2, 214, 536]
+[:mouse_move, 793, 357, 2, 215, 537]
+[:mouse_move, 794, 354, 2, 216, 539]
+[:mouse_move, 795, 348, 2, 217, 540]
+[:mouse_move, 795, 346, 2, 218, 541]
+[:mouse_move, 796, 342, 2, 219, 542]
+[:mouse_move, 796, 341, 2, 220, 543]
+[:mouse_move, 796, 340, 2, 221, 544]
+[:mouse_move, 796, 339, 2, 222, 545]
+[:mouse_move, 797, 339, 2, 223, 546]
+[:mouse_move, 797, 338, 2, 224, 547]
+[:mouse_button_up, 1, 0, 1, 225, 564]
+[:mouse_move, 807, 344, 2, 226, 564]
+[:mouse_move, 834, 357, 2, 227, 566]
+[:mouse_move, 858, 367, 2, 228, 567]
+[:mouse_move, 870, 370, 2, 229, 568]
+[:mouse_move, 912, 379, 2, 230, 569]
+[:mouse_move, 929, 380, 2, 231, 570]
+[:key_down_raw, 1073742051, 1024, 2, 232, 627]
+[:key_down_raw, 113, 1024, 2, 233, 628]
+[:key_up_raw, 113, 1024, 2, 234, 628]