diff options
| author | Amir Rajan <[email protected]> | 2020-09-22 06:27:46 -0500 |
|---|---|---|
| committer | Amir Rajan <[email protected]> | 2020-09-22 06:27:46 -0500 |
| commit | 20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5 (patch) | |
| tree | b4742e4f9acfd5400a04f314164812606a71df9f /docs/search_results.txt | |
| parent | 5b2311900072cfff9582bb0296140cfb354cb911 (diff) | |
| download | dragonruby-game-toolkit-contrib-20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5.tar.gz dragonruby-game-toolkit-contrib-20d5b4057b44ffcf92478b2a8e9476ace2fdc0f5.zip | |
synced with 1.22
Diffstat (limited to 'docs/search_results.txt')
| -rw-r--r-- | docs/search_results.txt | 665 |
1 files changed, 1 insertions, 664 deletions
diff --git a/docs/search_results.txt b/docs/search_results.txt index 39ac95e..ad996a7 100644 --- a/docs/search_results.txt +++ b/docs/search_results.txt @@ -1,664 +1 @@ -* Hello World - -Welcome to DragonRuby Game Toolkit. Take the steps below to get started. - -* Join the Discord and Subscribe to the News Letter - -Our Discord channel is [[http://discord.dragonruby.org]]. - -The News Letter will keep you in the loop with regards to current -DragonRuby Events: [[http://dragonrubydispatch.com]]. - -Those who use DragonRuby are called Dragon Riders. This identity is -incredibly important to us. When someone asks you: - -#+begin_quote -What game engine do you use? -#+end_quote - -Reply with: - -#+begin_quote -I am a Dragon Rider. -#+end_quote - -* Watch Some Intro Videos - -Each video is only 20 minutes and all of them will fit into a lunch -break. So please watch them: - -1. Beginner Introduction to DragonRuby Game Toolkit: [[https://youtu.be/ixw7TJhU08E]] -2. Intermediate Introduction to Ruby Syntax: [[https://youtu.be/HG-XRZ5Ppgc]] -3. Intermediate Introduction to Arrays in Ruby: [[https://youtu.be/N72sEYFRqfo]] - -The second and third videos are not required if you are proficient -with Ruby, but *definitely* watch the first one. - -You may also want to try this free course provided at -[[http://dragonruby.school]]. - -* Getting Started Tutorial - -This is a tutorial written by Ryan C Gordon (a Juggernaut in the -industry who has contracted to Valve, Epic, Activision, and -EA... check out his Wikipedia page: [[https://en.wikipedia.org/wiki/Ryan_C._Gordon]]). - -** Introduction - -Welcome! - -Here's just a little push to get you started if you're new to -programming or game development. - -If you want to write a game, it's no different than writing any other -program for any other framework: there are a few simple rules that -might be new to you, but more or less programming is programming no -matter what you are building. - -Did you not know that? Did you think you couldn't write a game because -you're a "web guy" or you're writing Java at a desk job? Stop letting -people tell you that you can't, because you already have everything -you need. - -Here, we're going to be programming in a language called "Ruby." In -the interest of full disclosure, I (Ryan Gordon) wrote the C parts of -this toolkit and Ruby looks a little strange to me (Amir Rajan wrote -the Ruby parts, discounting the parts I mangled), but I'm going to -walk you through the basics because we're all learning together, and -if you mostly think of yourself as someone that writes C (or C++, C#, -Objective-C), PHP, or Java, then you're only a step behind me right -now. - -** Prerequisites - -Here's the most important thing you should know: Ruby lets you do some -complicated things really easily, and you can learn that stuff -later. I'm going to show you one or two cool tricks, but that's all. - -Do you know what an if statement is? A for-loop? An array? That's all -you'll need to start. - -** The Game Loop - -Ok, here are few rules with regards to game development with GTK: - -- Your game is all going to happen under one function ... -- that runs 60 times a second ... -- and has to tell the computer what to draw each time. - -That's an entire video game in one run-on sentence. - -Here's that function. You're going to want to put this in -mygame/app/main.rb, because that's where we'll look for it by -default. Load it up in your favorite text editor. - -#+begin_src ruby - def tick args - args.outputs.labels << [580, 400, 'Hello World!'] - end -#+end_src - -Now run ~dragonruby~ ...did you get a window with "Hello World!" -written in it? Good, you're officially a game developer! - -** Breakdown Of The ~tick~ Method - -~mygame/app/main.rb~, is where the Ruby source code is located. This -looks a little strange, so I'll break it down line by line. In Ruby, a -'#' character starts a single-line comment, so I'll talk about this -inline. - -#+begin_src ruby - # This "def"ines a function, named "tick," which takes a single argument - # named "args". DragonRuby looks for this function and calls it every - # frame, 60 times a second. "args" is a magic structure with lots of - # information in it. You can set variables in there for your own game state, - # and every frame it will updated if keys are pressed, joysticks moved, - # mice clicked, etc. - def tick args - - # One of the things in "args" is the "outputs" object that your game uses - # to draw things. Afraid of rendering APIs? No problem. In DragonRuby, - # you use arrays to draw things and we figure out the details. - # If you want to draw text on the screen, you give it an array (the thing - # in the [ brackets ]), with an X and Y coordinate and the text to draw. - # The "<<" thing says "append this array onto the list of them at - # args.outputs.labels) - args.outputs.labels << [580, 400, 'Hello World!'] - end -#+end_src - -Once your ~tick~ function finishes, we look at all the arrays you made -and figure out how to draw it. You don't need to know about graphics -APIs. You're just setting up some arrays! DragonRuby clears out these -arrays every frame, so you just need to add what you need _right now_ -each time. - -** Rendering A Sprite - -Now let's spice this up a little. - -We're going to add some graphics. Each 2D image in DragonRuby is -called a "sprite," and to use them, you just make sure they exist in a -reasonable file format (png, jpg, gif, bmp, etc) and specify them by -filename. The first time you use one, DragonRuby will load it and keep -it in video memory for fast access in the future. If you use a -filename that doesn't exist, you get a fun checkerboard pattern! - -There's a "dragonruby.png" file included, just to get you -started. Let's have it draw every frame with our text: - -#+begin_src ruby - def tick args - args.outputs.labels << [580, 400, 'Hello World!'] - args.outputs.sprites << [576, 100, 128, 101, 'dragonruby.png'] - end -#+end_src - -(Pro Tip: you don't have to restart DragonRuby to test your changes; -when you save main.rb, DragonRuby will notice and reload your -program.) - -That ~.sprites~ line says "add a sprite to the list of sprites we're -drawing, and draw it at position (576, 100) at a size of 128x101 -pixels". You can find the image to draw at dragonruby.png. - -** Coordinate System and Virtual Canvas - -Quick note about coordinates: (0, 0) is the bottom left corner of the -screen, and positive numbers go up and to the right. This is more -"geometrically correct," even if it's not how you remember doing 2D -graphics, but we chose this for a simpler reason: when you're making -Super Mario Brothers and you want Mario to jump, you should be able to -add to Mario's y position as he goes up and subtract as he falls. It -makes things easier to understand. - -Also: your game screen is _always_ 1280x720 pixels. If you resize the -window, we will scale and letterbox everything appropriately, so you -never have to worry about different resolutions. - -Ok, now we have an image on the screen, let's animate it: - -#+begin_src ruby - def tick args - args.state.rotation ||= 0 - args.outputs.labels << [580, 400, 'Hello World!' ] - args.outputs.sprites << [576, 100, 128, 101, 'dragonruby.png', args.state.rotation] - args.state.rotation -= 1 - end -#+end_src - -Now you can see that this function is getting called a lot! - -** Game State - -Here's a fun Ruby thing: ~args.state.rotation ||= 0~ is shorthand for -"if args.state.rotation isn't initialized, set it to zero." It's a -nice way to embed your initialization code right next to where you -need the variable. - -~args.state~ is a place you can hang your own data and have it survive -past the life of the function call. In this case, the current rotation -of our sprite, which is happily spinning at 60 frames per second. If -you don't specify rotation (or alpha, or color modulation, or a source -rectangle, etc), DragonRuby picks a reasonable default, and the array -is ordered by the most likely things you need to tell us: position, -size, name. - -** There Is No Delta Time - -One thing we decided to do in DragonRuby is not make you worry about -delta time: your function runs at 60 frames per second (about 16 -milliseconds) and that's that. Having to worry about framerate is -something massive triple-AAA games do, but for fun little 2D games? -You'd have to work really hard to not hit 60fps. All your drawing is -happening on a GPU designed to run Fortnite quickly; it can definitely -handle this. - -Since we didn't make you worry about delta time, you can just move the -rotation by 1 every time and it works without you having to keep track -of time and math. Want it to move faster? Subtract 2. - -** Handling User Input - -Now, let's move that image around. - -#+begin_src ruby - def tick args - args.state.rotation ||= 0 - args.state.x ||= 576 - args.state.y ||= 100 - - if args.inputs.mouse.click - args.state.x = args.inputs.mouse.click.point.x - 64 - args.state.y = args.inputs.mouse.click.point.y - 50 - end - - args.outputs.labels << [580, 400, 'Hello World!'] - args.outputs.sprites << [args.state.x, - args.state.y, - 128, - 101, - 'dragonruby.png', - args.state.rotation] - - args.state.rotation -= 1 - end -#+end_src - -Everywhere you click your mouse, the image moves there. We set a -default location for it with ~args.state.x ||= 576~, and then we -change those variables when we see the mouse button in action. You can -get at the keyboard and game controllers in similar ways. - -** Coding On A Raspberry Pi - -We have only tested DragonRuby on a Raspberry Pi 3, Models B and B+, but we -believe it _should_ work on any model with comparable specs. - -If you're running DragonRuby Game Toolkit on a Raspberry Pi, or trying to run -a game made with the Toolkit on a Raspberry Pi, and it's really really slow-- -like one frame every few seconds--then there's likely a simple fix. - -You're probably running a desktop environment: menus, apps, web browsers, -etc. This is okay! Launch the terminal app and type: - -#+begin_src -sudo raspi-config -#+end_src - -It'll ask you for your password (if you don't know, try "raspberry"), and then -give you a menu of options. Find your way to "Advanced Options", then "GL -Driver", and change this to "GL (Full KMS)" ... not "fake KMS," which is -also listed there. Save and reboot. In theory, this should fix the problem. - -If you're _still_ having problems and have a Raspberry Pi 2 or better, go back -to raspi-config and head over to "Advanced Options", "Memory split," and give -the GPU 256 megabytes. You might be able to avoid this for simple games, as -this takes RAM away from the system and reserves it for graphics. You can -also try 128 megabytes as a gentler option. - -Note that you can also run DragonRuby without X11 at all: if you run it from -a virtual terminal it will render fullscreen and won't need the "Full KMS" -option. This might be attractive if you want to use it as a game console -sort of thing, or develop over ssh, or launch it from RetroPie, etc. - -** Conclusion - -There is a lot more you can do with DragonRuby, but now you've already -got just about everything you need to make a simple game. After all, -even the most fancy games are just creating objects and moving them -around. Experiment a little. Add a few more things and have them -interact in small ways. Want something to go away? Just don't add it -to ~args.output~ anymore. - -** IMPORTANT: Go Through All Of The Sample Apps! Study Them Thoroughly!! - -Now that you've completed the Hello World tutorial. Head over to the -`samples` directory. It is very very important that you study the -sample apps thoroughly! Go through them in order. Here is a short -description of each sample app. - -1. 00_beginner_ruby_primer: This is an interactive tutorial that shows how to render ~solid~s, animated ~sprite~s, ~label~s. -2. 00_intermediate_ruby_primer: This is a set of sample Ruby snippets that give you a high level introduction to the programming language. -3. 01_api_01_labels: Various ways to render ~label~s. -4. 01_api_02_lines: Various ways to render ~line~s. -5. 01_api_03_rects: Sample app shows various ways to render ~solid~s and ~border~s. -6. 01_api_04_sprites: Sample app shows various ways to render ~sprite~s. -7. 01_api_05_keyboard: Hows how to get keyboard input from the user. -8. 01_api_06_mouse: Hows how to get mouse mouse position. -9. 01_api_07_point_to_rect: How to get mouse input from the user and shows collision/hit detection. -10. 01_api_08_rect_to_rect: Hit detection/collision between two rectangles. -11. 01_api_10_controller: Interaction with a USB/Bluetooth controller. -12. 01_api_99_tech_demo: All the different render primitives along with using ~render_targets~. -13. 02_collision_01_simple: Collision detection with dynamically moving bodies. -14. 02_collision_02_moving_objects: Collision detection between many primitives, simple platformer physics, and keyboard input. -15. 02_collision_03_entities: Collision with entities and serves as a small introduction to ECS (entity component system). -16. 02_collision_04_ramp_with_debugging: How ramp trajectory can be calculated. -17. 02_collision_05_ramp_with_debugging_two: How ramp trajectory can be calculated. -18. 02_sprite_animation_and_keyboard_input: How to animate a sprite based off of keyboard input. -19. 03_mouse_click: How to determine what direction/vector a mouse was clicked relative to a player. -20. 04_sounds: How to play sounds and work with buttons. -21. 05_mouse_move: How to determine what direction/vector a mouse was clicked relative to a player. -22. 05_mouse_move_paint_app: Represents a simple paint app. -23. 05_mouse_move_tile_editor: A starting point for a tile editor. -24. 06_coordinate_systems: Shows the two origin systems within Game Toolkit where the origin is in the center and where the origin is at the bottom left. -25. 07_render_targets: Shows a powerful concept called ~render_target~s. You can use this to programatically create sprites (it's also useful for representing parts of a scene as if it was a view port/camera). -26. 07_render_targets_advanced: Advanced usage of ~render_target~s. -27. 08_platformer_collisions: Axis aligned collision along with platformer physics. -28. 08_platformer_collisions_metroidvania: How to save map data and place sprites live within a game. -29. 08_platformer_jumping_inertia: Jump physics and how inertia affects collision. -30. 09_controller_analog_usage_advanced_sprites: Extended properties of a ~sprite~ and how to change the rotation anchor point and render a subset/tile of a sprite. -31. 09_sprite_animation_using_tile_sheet: How to perform sprite animates using a tile sheet. -32. 10_save_load_game: Save and load game data. -33. 11_coersion_of_primitives: How primitives of one specific type can be rendered as another primitive type. -34. 11_hash_primitives: How primitives can be represented using a ~Hash~. -35. 12_controller_input_sprite_sheet_animations: How to leverage vectors to move a player around the screen. -36. 12_top_down_area: How to render a top down map and how to manage collision of a player. -37. 13_01_easing_functions: How to use lerping functions to define animations/movement. -38. 13_02_cubic_bezier: How to create a bezier curve using lines. -39. 13_03_easing_using_spline: How a collection of bezier curves can be used to define an animation. -40. 13_04_parametric_enemy_movement: How to define the movement of enemies and projectiles using lerping/parametric functions. -41. 14_sprite_limits: Upper limit for how many sprites can be rendered to the screen. -42. 14_sprite_limits_static_references: Upper limit for how many sprites can be rendered to the screen using ~static~ output collections (which are updated by reference as opposed to by value). -43. 15_collision_limits: How many collisions can be processed across many primitives. -44. 18_moddable_game: How you can make a game where content is authored by the player (modding support). -45. 19_lowrez_jam: How to use ~render_targets~ to create a low resolution game. -46. 20_roguelike_starting_point: A starting point for a roguelike and explores concepts such as line of sight. -47. 20_roguelike_starting_point_two: A starting point for a roguelike where sprites are provided from a tile map/tile sheet. -48. 21_mailbox_usage: How to do interprocess communication. -49. 22_trace_debugging: Debugging techniques and tracing execution through your game. -50. 22_trace_debugging_classes: Debugging techniques and tracing execution through your game. -51. 23_hexagonal_grid: How to make a tactical grid/map made of hexagons. -52. 23_isometric_grid: How to make a tactical grid/map made of isometric sprites. -53. 24_http_example: How to make http requests. -54. 25_3d_experiment_01_square: How to create 3D objects. -55. 26_jam_craft: Starting point for crafting game. It also shows how to customize the mouse cursor. -56. 99_sample_game_basic_gorillas: Reference implementation of a full game. Topics covered: physics, keyboard input, collision, sprite animation. -57. 99_sample_game_clepto_frog: Reference implementation of a full game. Topics covered: camera control, spring/rope physics, scene orchestration. -58. 99_sample_game_dueling_starships: Reference implementation that shows local multiplayer. Topics covered: vectors, particles, friction, inertia. -59. 99_sample_game_flappy_dragon: Reference implementation that is a clone of Flappy Bird. Topics covered: scene orchestration, collision, sound, sprite animations, lerping. -60. 99_sample_game_pong: Reference implementation of pong. -61. 99_sample_game_return_of_serenity: Reference implementation of low resolution story based game. -62. 99_sample_game_the_little_probe: Reference implementation of a full game. Topics covered: Arbitrary collision detection, loading map data, bounce/ball physics. -63. 99_sample_nddnug_workshop: Reference implementation of a full game. Topics covered: vectors, controller input, sound, trig functions. -64. 99_sample_snakemoji: Shows that Ruby supports coding with emojis. -65. 99_zz_gtk_unit_tests: A collection of unit tests that exercise parts of DragonRuby's API. - - -* How To Render A Sprite Using An Array - -All file paths should use the forward slash ~/~ *not* backslash -~~. Game Toolkit includes a number of sprites in the ~sprites~ -folder (everything about your game is located in the ~mygame~ directory). - -The following code renders a sprite with a ~width~ and ~height~ of -~100~ in the center of the screen. - -~args.outputs.sprites~ is used to render a sprite. - -#+begin_src ruby - def tick args - args.outputs.sprites << [ - 640 - 50, # X - 360 - 50, # Y - 100, # W - 100, # H - 'sprites/square-blue.png' # PATH - ] - end -#+end_src - -* More Sprite Properties As An Array - -Here are all the properties you can set on a sprite. - -#+begin_src ruby - def tick args - args.outputs.sprites << [ - 100, # X - 100, # Y - 32, # W - 64, # H - 'sprites/square-blue.png', # PATH - 0, # ANGLE - 255, # ALPHA - 0, # RED_SATURATION - 255, # GREEN_SATURATION - 0 # BLUE_SATURATION - ] - end -#+end_src - -* Different Sprite Representations - -Using ordinal positioning can get a little unruly given so many -properties you have control over. - -You can represent a sprite as a ~Hash~: - -#+begin_src ruby - def tick args - args.outputs.sprites << { - x: 640 - 50, - y: 360 - 50, - w: 100, - h: 100, - path: 'sprites/square-blue.png', - angle: 0, - a: 255, - r: 255, - g: 255, - b: 255, - source_x: 0, - source_y: 0, - source_w: -1, - source_h: -1, - flip_vertically: false, - flip_horizontally: false, - angle_anchor_x: 0.5, - angle_anchor_y: 1.0 - } - end -#+end_src - -You can represent a sprite as an ~object~: - -#+begin_src ruby - # Create type with ALL sprite properties AND primitive_marker - class Sprite - attr_accessor :x, :y, :w, :h, :path, :angle, :a, :r, :g, :b, - :source_x, :source_y, :source_w, :source_h, - :tile_x, :tile_y, :tile_w, :tile_h, - :flip_horizontally, :flip_vertically, - :angle_anchor_x, :angle_anchor_y - - def primitive_marker - :sprite - end - end - - class BlueSquare < Sprite - def initialize opts - @x = opts[:x] - @y = opts[:y] - @w = opts[:w] - @h = opts[:h] - @path = 'sprites/square-blue.png' - end - end - - def tick args - args.outputs.sprites << (BlueSquare.new x: 640 - 50, - y: 360 - 50, - w: 50, - h: 50) - end -#+end_src - -* Using ~args.state~ To Store Your Game State - -~args.state~ is a open data structure that allows you to define -properties that are arbitrarily nested. You don't need to define any kind of -~class~. - -To initialize your game state, use the ~||=~ operator. Any value on -the right side of ~||=~ will only be assigned _once_. - -To assign a value every frame, just use the ~=~ operator, but _make -sure_ you've initialized a default value. - -#+begin_src - def tick args - # initialize your game state ONCE - args.player.x ||= 0 - args.player.y ||= 0 - args.player.hp ||= 100 - - # increment the x position of the character by one every frame - args.player.x += 1 - - # Render a sprite with a label above the sprite - args.outputs.sprites << [ - args.player.x, - args.player.y, - 32, 32, - "player.png" - ] - - args.outputs.labels << [ - args.player.x, - args.player.y - 50, - args.player.hp - ] - end -#+end_src - -* DOCS: ~Array#map~ - -The function given a block returns a new ~Enumerable~ of values. - -Example of using ~Array#map~ in conjunction with ~args.state~ and -~args.outputs.sprites~ to render sprites to the screen. - -#+begin_src - def tick args - # define the colors of the rainbow in ~args.state~ - # as an ~Array~ of ~Hash~es with :order and :name. - # :order will be used to determine render location - # and :name will be used to determine sprite path. - args.state.rainbow_colors ||= [ - { order: 0, name: :red }, - { order: 1, name: :orange }, - { order: 2, name: :yellow }, - { order: 3, name: :green }, - { order: 4, name: :blue }, - { order: 5, name: :indigo }, - { order: 6, name: :violet }, - ] - - # render sprites diagonally to the screen - # with a width and height of 50. - args.outputs - .sprites << args.state - .rainbow_colors - .map do |color| # <-- ~Array#map~ usage - [ - color[:order] * 50, - color[:order] * 50, - 50, - 50, - "sprites/square-#{color[:name]}.png" - ] - end - end -#+end_src - - -* DOCS: ~Array#each~ - -The function, given a block, invokes the block for each item in the -~Array~. ~Array#each~ is synonymous to foreach constructs in other languages. - -Example of using ~Array#each~ in conjunction with ~args.state~ and -~args.outputs.sprites~ to render sprites to the screen: - -#+begin_src - def tick args - # define the colors of the rainbow in ~args.state~ - # as an ~Array~ of ~Hash~es with :order and :name. - # :order will be used to determine render location - # and :name will be used to determine sprite path. - args.state.rainbow_colors ||= [ - { order: 0, name: :red }, - { order: 1, name: :orange }, - { order: 2, name: :yellow }, - { order: 3, name: :green }, - { order: 4, name: :blue }, - { order: 5, name: :indigo }, - { order: 6, name: :violet }, - ] - - # render sprites diagonally to the screen - # with a width and height of 50. - args.state - .rainbow_colors - .map do |color| # <-- ~Array#each~ usage - args.outputs.sprites << [ - color[:order] * 50, - color[:order] * 50, - 50, - 50, - "sprites/square-#{color[:name]}.png" - ] - end - end -#+end_src - - -* DOCS: ~Numeric#frame_index~ - -This function is helpful for determining the index of frame-by-frame - sprite animation. The numeric value ~self~ represents the moment the - animation started. - -~frame_index~ takes three additional parameters: - -- How many frames exist in the sprite animation. -- How long to hold each animation for. -- Whether the animation should repeat. - -~frame_index~ will return ~nil~ if the time for the animation is out -of bounds of the parameter specification. - -Example using variables: - -#+begin_src ruby - def tick args - start_looping_at = 0 - number_of_sprites = 6 - number_of_frames_to_show_each_sprite = 4 - does_sprite_loop = true - - sprite_index = - start_looping_at.frame_index number_of_sprites, - number_of_frames_to_show_each_sprite, - does_sprite_loop - - sprite_index ||= 0 - - args.outputs.sprites << [ - 640 - 50, - 360 - 50, - 100, - 100, - "sprites/dragon-#{sprite_index}.png" - ] - end -#+end_src - -Example using named parameters: - -#+begin_src ruby - def tick args - start_looping_at = 0 - - sprite_index = - start_looping_at.frame_index count: 6, - hold_for: 4, - repeat: true, - tick_count_override: args.state.tick_count - - sprite_index ||= 0 - - args.outputs.sprites << [ - 640 - 50, - 360 - 50, - 100, - 100, - "sprites/dragon-#{sprite_index}.png" - ] - end -#+end_src - - +* DOCS: No results found.
\ No newline at end of file |
