diff options
| author | Amir Rajan <[email protected]> | 2019-09-06 15:33:10 -0500 |
|---|---|---|
| committer | Amir Rajan <[email protected]> | 2019-09-06 15:33:10 -0500 |
| commit | 220c3f0ed4a323d5d7e354c7f1b7ff1e8b16c4e9 (patch) | |
| tree | ea88e9c1425389a0fe4df8fb3d411a7c5fed1542 | |
| parent | 9c2ce126dba8a4c3ada82e5f4bd6637b1fa92ab0 (diff) | |
| download | dragonruby-game-toolkit-contrib-220c3f0ed4a323d5d7e354c7f1b7ff1e8b16c4e9.tar.gz dragonruby-game-toolkit-contrib-220c3f0ed4a323d5d7e354c7f1b7ff1e8b16c4e9.zip | |
Added deploy_template to contribe.
18 files changed, 1679 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..642c1d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*DS_Store*
\ No newline at end of file diff --git a/deploy_template/README-raspberrypi.txt b/deploy_template/README-raspberrypi.txt new file mode 100644 index 0000000..4f7b5ab --- /dev/null +++ b/deploy_template/README-raspberrypi.txt @@ -0,0 +1,33 @@ +We have only tested DragonRuby on a Raspberry Pi 3, Models B and B+, but we +believe it _should_ work on any model, including the Pi Zero. + +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 proabably running a desktop environment: menus, apps, web browsers, +etc. This is okay! Launch the terminal app and type: + + sudo raspi-config + +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. + +If you have questions or problems, please let us know! You can find us on +the forums at https://dragonruby.itch.io/dragonruby-gtk or our Discord channel +at https://discord.dragonruby.org/ ... + diff --git a/deploy_template/README.txt b/deploy_template/README.txt new file mode 100644 index 0000000..80050db --- /dev/null +++ b/deploy_template/README.txt @@ -0,0 +1,407 @@ +Join the Discord: http://discord.dragonruby.org +Community Forums: https://dragonruby.itch.io/dragonruby-gtk/community +Free Training Course: http://dragonruby.school + +Welcome! + +Here's just a little push to get you started. + +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 wrote the C parts of this toolkit and Ruby +looks a little strange to me, 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. + +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. + +If you don't know how to program, no worries! Watching these two videos will +help tremendously: + +- https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-primer.mp4 +- https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-intermediate.mp4 + +Did you watch the videos? Great! + +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. + + +def tick args + args.outputs.labels << [ 580, 400, 'Hello World!' ] +end + +Now run "dragonruby" ...did you get a window with "Hello World!" written in +it? Good, you're officially a game developer! + +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. + +# 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 + +# 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. + +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: + +def tick args + args.outputs.labels << [ 580, 400, 'Hello World!' ] + args.outputs.sprites << [ 576, 100, 128, 101, 'dragonruby.png' ] +end + +(ProTip: 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, and you can +find the image to draw at dragonruby.png. + +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: + +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 + +Now you can see that this function is getting called a lot! + +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. + +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. + +Now, let's move that image around. + +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 + +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. + +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. + +If you want to get a good idea of what's available to you, please check out +the "samples" directory: in there, the "tech_demo" directory is a good dumping +ground of features, and many of the others are little starter games. Just +go to the samples directory, find the sample you want to run, and double click +"dragonruby" within the sample folder. + +There is also a lot more you _can't_ do with DragonRuby, at least not yet. +We are excited about the potential of this, so we wanted to get it in your +hands right away. We intend to add a bunch of features and we would love +feedback on what needs work and what you want that isn't there. + +But now, it's time to show your friends and family that you're a real game +developer! Let's package up what we have and let them play it! + +Let's just give it a few bits of information. Point your text editor at +mygame/metadata/game_metadata.txt and make it look like this: + +devid=bob +devtitle=Bob The Game Developer +gameid=mygame +gametitle=My Game +version=0.1 + +(obviously you should change it if your name isn't Bob.) + +See that other program? dragonruby-publish? Let's use that to package up your +game. Run this from the command line: + +./dragonruby-publish --only-package mygame + +(if you're on Windows, don't put the "./" on the front. That's a Mac and +Linux thing.) + +This should spit out packaged versions of your game for Windows, Linux and +macOS that you can hand out to friends and family however you like. They +just have to download and double-click it! + +But if you want to get _really_ fancy: Set up a free account on +https://itch.io/, with the same login as you specified for "devid" in +game_metadata.txt, and a product with the gameid. Set a price for it. And +then run... + +./dragonruby-publish mygame + +...and DragonRuby will package _and publish_ your game to itch.io! Tell your +friends to go to your game's very own webpage and buy it! + +If you make changes to your game, just re-run dragonruby-publish and it'll +update the downloads for you. + +And that's all! We hope you find DragonRuby useful, and more importantly we +hope you have fun playing around with it. Please check out +https://dragonruby.itch.io/dragonruby-gtk as we add new features and improve +this toolkit based on your feedback! + +BORING LEGAL STUFF AND CREDIT WHERE CREDIT IS DUE: +(if you don't read software licenses, you're done with this README now. IT IS +STRONGLY RECOMMENDED THAT YOU GO THROUGH ALL THE SAMPLE APPS!!) + +DragonRuby uses the following open source libraries! + +- mRuby: https://mruby.org/ + +Copyright (c) 2019 mruby developers + +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. + + +- Simple Directmedia Layer: https://www.libsdl.org/ + +Simple DirectMedia Layer +Copyright (C) 1997-2019 Sam Lantinga <[email protected]> + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + +- stb_vorbis, stb_image, stb_truetype: https://github.com/nothings/stb/ + +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. + + +- lodepng: https://lodev.org/lodepng/ + +Copyright (c) 2005-2018 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + + +- miniz: https://github.com/richgel999/miniz + +Copyright 2013-2014 RAD Game Tools and Valve Software +Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + +All Rights Reserved. + +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. + + +- MojoAL: https://hg.icculus.org/icculus/mojoAL/ + + Copyright (c) 2018 Ryan C. Gordon and others. + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from + the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + Ryan C. Gordon <[email protected]> + + +- PhysicsFS: https://icculus.org/physfs/ + + Copyright (c) 2001-2019 Ryan C. Gordon and others. + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from + the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + Ryan C. Gordon <[email protected]> diff --git a/deploy_template/console-logo.png b/deploy_template/console-logo.png Binary files differnew file mode 100644 index 0000000..7486868 --- /dev/null +++ b/deploy_template/console-logo.png diff --git a/deploy_template/dragonruby-controller.png b/deploy_template/dragonruby-controller.png Binary files differnew file mode 100644 index 0000000..b7e941e --- /dev/null +++ b/deploy_template/dragonruby-controller.png diff --git a/deploy_template/dragonruby.png b/deploy_template/dragonruby.png Binary files differnew file mode 100644 index 0000000..57254fe --- /dev/null +++ b/deploy_template/dragonruby.png diff --git a/deploy_template/font.ttf b/deploy_template/font.ttf Binary files differnew file mode 100644 index 0000000..33dcfde --- /dev/null +++ b/deploy_template/font.ttf diff --git a/deploy_template/mygame/app/main.rb b/deploy_template/mygame/app/main.rb new file mode 100644 index 0000000..a7d9ad6 --- /dev/null +++ b/deploy_template/mygame/app/main.rb @@ -0,0 +1,6 @@ +def tick args + args.outputs.labels << [ 580, 500, 'Hello World!' ] + args.outputs.labels << [ 475, 150, '(Consider reading README.txt now.)' ] + args.outputs.sprites << [ 576, 310, 128, 101, 'dragonruby.png' ] +end + diff --git a/deploy_template/mygame/app/repl.rb b/deploy_template/mygame/app/repl.rb new file mode 100644 index 0000000..56390c1 --- /dev/null +++ b/deploy_template/mygame/app/repl.rb @@ -0,0 +1,307 @@ +# =============================================================== +# Welcome to repl.rb +# =============================================================== +# You can experiement with code within this file. Code in this +# file is only executed when you save (and only excecuted ONCE). +# =============================================================== + +# =============================================================== +# REMOVE the "x" from the word "xrepl" and save the file to RUN +# the code in between the do/end block delimiters. +# =============================================================== + +# =============================================================== +# ADD the "x" to the word "repl" (make it xrepl) and save the +# file to IGNORE the code in between the do/end block delimiters. +# =============================================================== + +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "The result of 1 + 2 is: #{1 + 2}" +end + +# ==================================================================================== +# Ruby Crash Course: +# Strings, Numeric, Booleans, Conditionals, Looping, Enumerables, Arrays +# ==================================================================================== + +# ==================================================================================== +# Strings +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + message = "Hello World" + puts "The value of message is: " + message + puts "Any value can be interpolated within a string using \#{}." + puts "Interpolated message: #{message}." + puts 'This #{message} is not interpolated because the string uses single quotes.' +end + +# ==================================================================================== +# Numerics +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + a = 10 + puts "The value of a is: #{a}" + puts "a + 1 is: #{a + 1}" + puts "a / 3 is: #{a / 3}" +end + +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + b = 10.12 + puts "The value of b is: #{b}" + puts "b + 1 is: #{b + 1}" + puts "b as an integer is: #{b.to_i}" + puts '' +end + +# ==================================================================================== +# Booleans +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + c = 30 + puts "The value of c is #{c}." + + if c + puts "This if statement ran because c is truthy." + end +end + +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + d = false + puts "The value of d is #{d}." + + if !d + puts "This if statement ran because d is falsey, using the not operator (!) makes d evaluate to true." + end + + e = nil + puts "Nil is also considered falsey. The value of e is: #{e}." + + if !e + puts "This if statement ran because e is nil (a falsey value)." + end +end + +# ==================================================================================== +# Conditionals +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + i_am_true = true + i_am_nil = nil + i_am_false = false + i_am_hi = "hi" + + puts "======== if statement" + i_am_one = 1 + if i_am_one + puts "This was printed because i_am_one is truthy." + end + + puts "======== if/else statement" + if i_am_false + puts "This will NOT get printed because i_am_false is false." + else + puts "This was printed because i_am_false is false." + end + + puts "======== if/elsif/else statement" + if i_am_false + puts "This will NOT get printed because i_am_false is false." + elsif i_am_true + puts "This was printed because i_am_true is true." + else + puts "This will NOT get printed i_am_true was true." + end + + puts "======== case statement " + i_am_one = 1 + case i_am_one + when 10 + puts "case equaled: 10" + when 9 + puts "case equaled: 9" + when 5 + puts "case equaled: 5" + when 1 + puts "case equaled: 1" + else + puts "Value wasn't cased." + end + + puts "======== different types of comparisons" + if 4 == 4 + puts "equal (4 == 4)" + end + + if 4 != 3 + puts "not equal (4 != 3)" + end + + if 3 < 4 + puts "less than (3 < 4)" + end + + if 4 > 3 + puts "greater than (4 > 3)" + end + + if ((4 > 3) || (3 < 4) || false) + puts "or statement ((4 > 3) || (3 < 4) || false)" + end + + if ((4 > 3) && (3 < 4)) + puts "and statement ((4 > 3) && (3 < 4))" + end +end + +# ==================================================================================== +# Looping +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "======== times block" + 3.times do |i| + puts i + end + puts "======== range block exclusive" + (0...3).each do |i| + puts i + end + puts "======== range block inclusive" + (0..3).each do |i| + puts i + end +end + +# ==================================================================================== +# Enumerables +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "======== array each" + colors = ["red", "blue", "yellow"] + colors.each do |color| + puts color + end + + puts '======== array each_with_index' + colors = ["red", "blue", "yellow"] + colors.each_with_index do |color, i| + puts "#{color} at index #{i}" + end +end + +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "======== single parameter function" + def add_one_to n + n + 5 + end + + puts add_one_to(3) + + puts "======== function with default value" + def function_with_default_value v = 10 + v * 10 + end + + puts "passing three: #{function_with_default_value(3)}" + puts "passing nil: #{function_with_default_value}" + + puts "======== Or Equal (||=) operator for nil values" + def function_with_nil_default_with_local a = nil + result = a + result ||= "or equal operator was exected and set a default value" + end + + puts "passing 'hi': #{function_with_nil_default_with_local 'hi'}" + puts "passing nil: #{function_with_nil_default_with_local}" +end + +# ==================================================================================== +# Arrays +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "======== Create an array with the numbers 1 to 10." + one_to_ten = (1..10).to_a + puts one_to_ten + + puts "======== Create a new array that only contains even numbers from the previous array." + one_to_ten = (1..10).to_a + evens = one_to_ten.find_all do |number| + number % 2 == 0 + end + puts evens + + puts "======== Create a new array that rejects odd numbers." + one_to_ten = (1..10).to_a + also_even = one_to_ten.reject do |number| + number % 2 != 0 + end + puts also_even + + puts "======== Create an array that doubles every number." + one_to_ten = (1..10).to_a + doubled = one_to_ten.map do |number| + number * 2 + end + puts doubled + + puts "======== Create an array that selects only odd numbers and then multiply those by 10." + one_to_ten = (1..10).to_a + odd_doubled = one_to_ten.find_all do |number| + number % 2 != 0 + end.map do |odd_number| + odd_number * 10 + end + puts odd_doubled + + puts "======== All combination of numbers 1 to 10." + one_to_ten = (1..10).to_a + all_combinations = one_to_ten.product(one_to_ten) + puts all_combinations + + puts "======== All uniq combinations of numbers. For example: [1, 2] is the same as [2, 1]." + one_to_ten = (1..10).to_a + uniq_combinations = + one_to_ten.product(one_to_ten) + .map do |unsorted_number| + unsorted_number.sort + end.uniq + puts uniq_combinations +end + +# ==================================================================================== +# Advanced Arrays +# ==================================================================================== +# Remove the x from xrepl to run the code. Add the x back to ignore to code. +xrepl do + puts "======== All unique Pythagorean Triples between 1 and 40 sorted by area of the triangle." + + one_to_hundred = (1..40).to_a + triples = + one_to_hundred.product(one_to_hundred).map do |width, height| + [width, height, Math.sqrt(width ** 2 + height ** 2)] + end.find_all do |_, _, hypotenuse| + hypotenuse.to_i == hypotenuse + end.map do |triangle| + triangle.map(&:to_i) + end.uniq do |triangle| + triangle.sort + end.map do |width, height, hypotenuse| + [width, height, hypotenuse, (width * height) / 2] + end.sort_by do |_, _, _, area| + area + end + + triples.each do |width, height, hypotenuse, area| + puts "(#{width}, #{height}, #{hypotenuse}) = #{area}" + end +end diff --git a/deploy_template/mygame/app/tests.rb b/deploy_template/mygame/app/tests.rb new file mode 100644 index 0000000..1dc452a --- /dev/null +++ b/deploy_template/mygame/app/tests.rb @@ -0,0 +1,24 @@ +# For advanced users: +# You can put some quick verification tests here, any method +# that starts with the `test_` will be run when you save this file. + +# here is an example test and game + +class MySuperHappyFunGame + gtk_args + + def tick + outputs.solids << [100, 100, 300, 300] + end +end + +def test_universe args, assert + game = MySuperHappyFunGame.new + game.args = args + game.tick + assert.true! args.outputs.solids.length == 1, "failure: a solid was not added after tick" + assert.false! 1 == 2, "failure: some how, 1 equals 2, the world is ending" + puts "test_universe completed successfully" +end + +$gtk.tests.start diff --git a/deploy_template/mygame/documentation/01-high-level.md b/deploy_template/mygame/documentation/01-high-level.md new file mode 100644 index 0000000..7206d8d --- /dev/null +++ b/deploy_template/mygame/documentation/01-high-level.md @@ -0,0 +1,31 @@ +# General Stuff + +- You have 1280x720 pixels to work with. The bottom left corner is 0, 0 + with X increasing going right, and Y increasing going up. +- The game is on a fixed 60 fps cycle (no delta time needed). +- Come to the Discord if you need help: http://discord.dragonruby.org +- Going through all the sample apps is a REALLY GOOD IDEA. Most sample apps + contain a recorded replay/demo. So just double click `watch-recording` to + see a full presentation of the sample. + +# Entry Point + +For all the examples in the other documentation files. It's assumed they +are being placed into the follow code block: + +``` +# Entry point placed in main.rb +def tick args + args.outputs.labels << [100, 100, 'hello world'] +end +``` + +# New to Ruby + +If you are a complete beginner and have never coded before: + +1. Run the 00_beginner_ruby_primer sample app and work through it. + Video walkthrough: https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-primer.mp4 +2. Read all the code in the 00_intermediate_ruby_primer sample app. + Video walkthrough: https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-intermediate.mp4 +3. There is also a free course you can sign up for at http://dragonruby.school diff --git a/deploy_template/mygame/documentation/02-labels.md b/deploy_template/mygame/documentation/02-labels.md new file mode 100644 index 0000000..a7a729c --- /dev/null +++ b/deploy_template/mygame/documentation/02-labels.md @@ -0,0 +1,132 @@ +# Labels + +Labels display text. + +## Sample Apps Related to Label Usage (ordered by size of codebase increasing) + +- 01_api_01_labels +- 01_api_99_tech_demo (includes recording) +- 10_save_load_game (includes recording) +- 18_moddable_game +- 19_lowrez_jam_01_hello_world +- 99_sample_game_return_of_serenity + +## Minimum Code + +Creates a label with black text at location 100, 100. + +```ruby +# X Y TEXT +args.outputs.labels << [100, 100, "Hello world"] +``` + +## Font Size + +The size can be a number between `-10` and `+10`. The default size is `0`. + +```ruby +# X Y TEXT SIZE +args.outputs.labels << [100, 100, "Hello world", 5] +``` + +## Alignment + +Alignment values are `0` (left, default), `1` (center), and `2` +(right). The value must come after the size. + +A label smack dab in the center of the screen, with a center alignment: + +```ruby +# X Y TEXT SIZE ALIGNMENT +args.outputs.labels << [640, 360, "Hello world", 0, 1] +``` + +## RGBA - Colors and Alpha + +Labels can have colors. The value for the color is an number between +`0` and `255`. + +A green label with 50% opacity. + +```ruby +# X Y TEXT RED GREEN BLUE ALPHA +args.outputs.labels << [640, 360, "Hello world", 0, 255, 0, 128] +``` + +A green label with size and alignment. + +```ruby +# X Y TEXT SIZE ALIGNMENT RED GREEN BLUE ALPHA +args.outputs.labels << [640, 360, "Hello world", 0, 1, 0, 255, 0, 128] +``` + +## Custom Font + +You can override the font for a label. The font needs to be under the +`mygame` directory. It's recommended that you create a `fonts` folder +to keep things organized. + +Here is how you create a label with a font named `coolfont.ttf` under a directory `mygame/fonts`. + +```ruby +# X Y TEXT SIZE ALIGNMENT RED GREEN BLUE ALPHA FONT FILE +args.outputs.labels << [640, 360, "Hello world", 0, 1, 0, 0, 0, 255, "fonts/coolfont.ttf"] +``` + +## Hashes (Advanced) + +If you want a more readable invocation. You can use the following hash to create a label. +Any parameters that are not specified will be given a default value. The keys of the hash can +be provided in any order. + +Here is how you create a green label with a font named `coolfont.ttf` under a directory `mygame/fonts` +using the helper method (providing all the parameters). + +```ruby +args.outputs.labels << { + x: 200, + y: 550, + text: "dragonruby", + size: 2, + alignment: 1, + r: 155, + g: 50, + b: 50, + a: 255, + font: "fonts/manaspc.ttf" +} +``` + +## Duck Typing (Advanced) + +You can also create a class with line properties and render it as a primitive. +ALL properties must on the class. ADDITIONALLY, a method called +`primitive_marker` must be defined on the class. + +Here is an example: + +```ruby +# Create type with ALL sprite properties AND primitive_marker +class Label + attr_accessor :x, :y, :text, :size, :alignment, :r, :g, :b, :a + + def primitive_marker + :label + end +end + +# Inherit from type +class TitleLabel < Label + + # constructor + def initialize x, y, text + self.x = x + self.y = y + self.text = text + end +end + +# render layer label + +args.outputs.label << TitleLabel.new(10, 10, "The Game") +``` diff --git a/deploy_template/mygame/documentation/03-solids-and-borders.md b/deploy_template/mygame/documentation/03-solids-and-borders.md new file mode 100644 index 0000000..0ed2fc9 --- /dev/null +++ b/deploy_template/mygame/documentation/03-solids-and-borders.md @@ -0,0 +1,126 @@ +# Solids and Borders + +Solids and Borders are great to use as place holders for sprites. + +## Sample Apps Releated to Solid/Borders Usage (ordered by size of codebase increasing) + +- 01_api_03_rects +- 01_api_99_tech_demo (includes recording) +- 02_collisions +- 12_top_down_area (includes recording) +- 99_sample_game_flappy_dragon (includes recording) +- 08_platformer_collisions +- 20_roguelike_starting_point +- 99_sample_game_pong (includes recording) + +## Minimum Code + +Creates a solid black rectangle located at 100, 100. 160 pixels +wide and 90 pixels tall. + +```ruby +# X Y WIDTH HEIGHT +args.outputs.solids << [100, 100, 160, 90] +``` + +Creates an unfilled black-bordered rectangle located at 100, 100. +160 pixels wide and 90 pixels tall. + +```ruby +# X Y WIDTH HEIGHT +args.outputs.borders << [100, 100, 160, 90] +``` + +## RGBA - Colors and Alpha + +The value for the color and alpha is an number between `0` and `255`. The +alpha property is optional and will be set to `255` if not specified. + +Creates a green solid rectangle with an opacity of 50%. + +```ruby +# X Y WIDTH HEIGHT RED GREEN BLUE ALPHA +args.outputs.solids << [100, 100, 160, 90, 0, 255, 0, 128] +``` + +Creates an unfilled green-bordered rectangle located at 100, 100. +160 pixels wide and 90 pixels tall and an opacity of 50%. + +```ruby +# X Y WIDTH HEIGHT RED GREEN BLUE ALPHA +args.outputs.borders << [100, 100, 160, 90, 0, 255, 0, 128] +``` + +Creates a solid gray rectangle that covers the entire scene. Like a background. +The opacity is excluded because it's 100% opaque (which has a value of 255). + +```ruby +# X Y WIDTH HEIGHT RED GREEN BLUE +args.outputs.solids << [ 0, 0, 1280, 720, 128, 128, 128] +``` + +## Hash (Advanced) + +If you want a more readable invocation. You can use the following hash to create a solid. +Any parameters that are not specified will be given a default value. The keys of the hash can +be provided in any order. + +```ruby +args.outputs.solids << { + x: 0, + y: 0, + w: 100, + h: 100, + r: 0, + g: 255, + b: 0, + a: 255 +} + + +args.outputs.borders << { + x: 0, + y: 0, + w: 100, + h: 100, + r: 0, + g: 255, + b: 0, + a: 255 +} +``` + +## Duck Typing (Advanced) + +You can also create a class with solid/border properties and render it as a primitive. +ALL properties must on the class. ADDITIONALLY, a method called `primitive_marker` +must be defined on the class. + +Here is an example: + +```ruby +# Create type with ALL solid/border properties AND primitive_marker +class Solid (or Border) + attr_accessor :x, :y, :w, :h, :r, :g, :b, :a_x + + def primitive_marker + :solid (or :border) + end +end + +# Inherit from type +class Square < Solid (or Border) + # constructor + def initialize x, y, size + self.x = x + self.y = y + self.w = size + self.h = size + end +end + +# render solid/border + +args.outputs.solids << Square.new(10, 10, 32) +args.outputs.borders << Square.new(10, 10, 32) +``` diff --git a/deploy_template/mygame/documentation/04-lines.md b/deploy_template/mygame/documentation/04-lines.md new file mode 100644 index 0000000..03c1abc --- /dev/null +++ b/deploy_template/mygame/documentation/04-lines.md @@ -0,0 +1,108 @@ +# Lines + +Lines are 1 pixel wide and can be diagonal. + +## Sample Apps Related to Line Usage (ordered by size of codebase increasing) + +- 01_api_02_lines +- 01_api_99_tech_demo (includes recording) +- 06_coordinate_systems (includes recording) +- 19_lowrez_jam_01_hello_world +- 99_sample_game_pong (includes recording) + +## Minimum Code + +Creates a black line from the bottom left corner to the top right corner. + +```ruby +# X1 Y1 X2 Y2 +args.outputs.lines << [ 0, 0, 1280, 720] +``` + +Creates a black vertical line through the center of the scene. + +```ruby +# X1 Y1 X2 Y2 +args.outputs.lines << [ 640, 0, 640, 720] +``` + +Creates a black horizontal line through the center of the scene. + +```ruby +# X1 Y1 X2 Y2 +args.outputs.lines << [ 0, 360, 1280, 360] +``` + +## RGBA - Colors and Alpha + +The value for the color and alpha is an number between `0` and `255`. The +alpha property is optional and will be set to `255` if not specified. + +Creates a green horizontal line through the center of the scene with an opacity of 50%. + +```ruby +# X1 Y1 X2 Y2 RED GREEN BLUE ALPHA +args.outputs.lines << [ 0, 360, 1280, 360, 0, 255, 0, 128] +``` + +Creates a green vertical line through the center of the scene. +The opacity is excluded because it's 100% opaque (which has a value of 255). + +```ruby +# X1 Y1 X2 Y2 RED GREEN BLUE +args.outputs.lines << [ 640, 0, 640, 720, 0, 255, 0] +``` + +## Hash (Advanced) + +If you want a more readable invocation. You can use the following hash to create a line. +Any parameters that are not specified will be given a default value. The keys of the hash can +be provided in any order. + +```ruby +args.outputs.lines << { + x: 0, + y: 0, + x2: 1280, + y2: 720, + r: 0, + g: 255, + b: 0, + a: 255 +} +``` + +## Duck Typing (Advanced) + +You can also create a class with line properties and render it as a primitive. +ALL properties must on the class. ADDITIONALLY, a method called `primitive_marker` +must be defined on the class. + +Here is an example: + +```ruby +# Create type with ALL line properties AND primitive_marker +class Line + attr_accessor :x, :y, :x2, :y2, :r, :g, :b, :a + + def primitive_marker + :line + end +end + +# Inherit from type +class VerticalLine < Line + + # constructor + def initialize x, y, h + self.x = x + self.y = y + self.x2 = x + self.y2 = y + h + end +end + +# render line + +args.outputs.lines << VerticalLine.new(10, 10, 100) +``` diff --git a/deploy_template/mygame/documentation/05-sprites.md b/deploy_template/mygame/documentation/05-sprites.md new file mode 100644 index 0000000..c80b46c --- /dev/null +++ b/deploy_template/mygame/documentation/05-sprites.md @@ -0,0 +1,239 @@ +# Sprites + +Sprites are the most important visual component of a game. + +## Sample Apps Related to Sprite Usage (ordered by size of codebase increasing) + +- 01_api_04_sprites +- 01_api_99_tech_demo (includes recording) +- 02_sprite_animation_and_keyboard_input (includes recording) +- 08_platformer_collisions_metroidvania +- 09_controller_analog_usage_advanced_sprites +- 99_sample_game_basic_gorillas (includes recording) +- 99_sample_game_dueling_starships (includes recording) +- 99_sample_game_flappy_dragon (includes recording) +- 99_sample_game_return_of_serenity + +## Minimum Code + +Sprites need to be under the `mygame` directory. It's recommended that you create a `sprites` folder +to keep things organized. All sprites must be `.png` files + +Here is how you create an sprite with located at 100, 100, that is 32 pixels wide and 64 pixels tall. +In this example the sprite name is `player.png` and is located under a directory `mygame/sprites`. + +```ruby +# X Y WIDTH HEIGHT PATH +args.outputs.sprites << [100, 100, 32, 64, "sprites/player.png"] +``` + +## Rotation / Angle + +Unlike `solids` and `borders`, sprites can be rotated. This is how you rotate a sprite 90 degress. + +Note: All angles in DragonRuby Game Toolkit are represented in degrees (not radians). + +```ruby +# X Y WIDTH HEIGHT PATH ANGLE +args.outputs.sprites << [100, 100, 32, 64, "sprites/player.png", 90] +``` + +## Alpha + +Sprites can also have a transparency associated with them. The transparency value must come after +the angle value and supports a number between 0 and 255. + +This is how you would define a sprite with no rotation, and a 50% transparency. + +```ruby +# X Y WIDTH HEIGHT PATH ANGLE ALPHA +args.outputs.sprites << [100, 100, 32, 64, "sprites/player.png", 0, 128] +``` + +## Color Saturations + +A Sprite's color levels can be changed. The color saturations must come after `angle` and +`alpha` values. + +This is a sprite with no rotation, fully opaque, and with a green tint. + +```ruby +args.outputs.sprites << [100, # X + 100, # Y + 32, # W + 64, # H + "sprites/player.png", # PATH + 0, # ANGLE + 255, # ALPHA + 0, # RED_SATURATION + 255, # GREEN_SATURATION + 0] # BLUE_SATURATION +``` + +## Sprite Sub Division / Tile + +You can render a portion of a sprite (a tile). The sub division of the sprite is denoted as a rectangle +directly related to the original size of the png. + +This is a sprite scaled to 100 pixels where the source "tile" is located at the bottom left corner +within a 32 pixel square. The angle, opacity, and color levels of the tile are unaltered. + +```ruby +args.outputs.sprites << [ 100, # X + 100, # Y + 32, # W + 64, # H + "sprites/player.png", # PATH + 0, # ANGLE + 255, # ALPHA + 0, # RED_SATURATION + 255, # GREEN_SATURATION + 0, # BLUE_SATURATION + 0, # TILE_X + 0, # TILE_Y + 32, # TILE_W + 32] # TILE_H +``` + +## Flipping a Sprite Horizontally and Vertically + +A sprite can be flipped horizontally and vertically. + +This is a sprite that has been flipped horizontally. The sprites's angle, alpha, color saturations, +and tile subdivision are unaltered. + +```ruby +args.outputs.sprites << [ 100, # X + 100, # Y + 32, # W + 64, # H + "sprites/player.png", # PATH + 0, # ANGLE + 255, # ALPHA + 0, # RED_SATURATION + 255, # GREEN_SATURATION + 0, # BLUE_SATURATION + 0, # TILE_X + 0, # TILE_Y + 32, # TILE_W + 32, # TILE_H + true, # FLIP_HORIZONTALLY + false] # FLIP_VERTICALLY +``` + +This is a sprite that has been flipped vertically. The sprites's angle, alpha, color saturations, +and tile subdivision are unaltered. + +```ruby +args.outputs.sprites << [ 100, # X + 100, # Y + 32, # W + 64, # H + "sprites/player.png", # PATH + 0, # ANGLE + 255, # ALPHA + 0, # RED_SATURATION + 255, # GREEN_SATURATION + 0, # BLUE_SATURATION + 0, # TILE_X + 0, # TILE_Y + 32, # TILE_W + 32, # TILE_H + false, # FLIP_HORIZONTALLY + true] # FLIP_VERTICALLY +``` + +## Rotation Center + +A sprites center of rotation can be altered. + +This is a sprite that has its rotation center set to the top-middle. The sprites's angle, alpha, color saturations, +tile subdivision, and projectsions are unaltered. + +```ruby +args.outputs.sprites << [ 100, # X + 100, # Y + 32, # W + 64, # H + "sprites/player.png", # PATH + 0, # ANGLE + 255, # ALPHA + 255, # RED_SATURATION + 255, # GREEN_SATURATION + 0, # BLUE_SATURATION + 0, # TILE_X + 0, # TILE_Y + -1, # TILE_W + -1, # TILE_H + false, # FLIP_HORIZONTALLY + false, # FLIP_VERTICALLY + 0.5, # ANGLE_ANCHOR_X + 1.0] # ANCHOR_Y +``` + +## Hash (Advanced) + +If you want a more readable invocation. You can use the following hash to create a sprite. +Any parameters that are not specified will be given a default value. The keys of the hash can +be provided in any order. + +```ruby +args.outputs.sprites << { + x: 100, + y: 100, + w: 100, + h: 100, + path: "sprites/player.png", + angle: 0, + a, 255 + r: 255, + g: 255, + b: 255, + tile_x: 0, + tile_y: 0, + tile_w: -1, + tile_h: -1, + flip_vertically: false, + flip_horizontally: false, + angle_anchor_x: 0.5, + angle_anchor_y: 1.0 +} +``` + +## Duck Typing (Advanced) + +You can also create a class with sprite properties and render it as a primitive. +ALL properties must on the class. ADDITIONALLY, a method called `primitive_marker` +must be defined on the class. + +Here is an example: + +```ruby +# Create type with ALL sprite properties AND primitive_marker +class Sprite + attr_accessor :x, :y, :w, :h, :path, :angle, :a, :r, :g, :b, :tile_x, + :tile_y, :tile_w, :tile_h, :flip_horizontally, + :flip_vertically, :angle_anchor_x, :angle_anchor_y + + def primitive_marker + :sprite + end +end + +# Inherit from type +class PlayerSprite < Sprite + + # constructor + def initialize x, y, w, h + self.x = x + self.y = y + self.w = w + self.h = h + self.path = 'sprites/player.png' + end +end + +#render player sprite + +args.outputs.sprites << PlayerSprite.new(10, 10, 32, 64) +``` diff --git a/deploy_template/mygame/documentation/06-keyboard.md b/deploy_template/mygame/documentation/06-keyboard.md new file mode 100644 index 0000000..33c9312 --- /dev/null +++ b/deploy_template/mygame/documentation/06-keyboard.md @@ -0,0 +1,150 @@ +# Keyboard + +Determining if a key was down: + +``` +if args.inputs.keyboard.key_down.a + puts 'The key was in the down state' +end +``` + +Determining if a key is being held: + +``` +if args.inputs.keyboard.key_held.a + puts 'The key is being held' +end +``` + +Determining if a key is in the down state or is being held: + +``` +if args.inputs.keyboard.a + puts 'The key is being held' +end +``` + +Determining if a key is released: + +``` +if args.inputs.keyboard.key_up.a + puts 'The key is being held' +end +``` + +# Truthy Keys + +You can access all triggered keys through `thruthy_keys` on `keyboard`, `controller_one`, and `controller_two`. + +This is how you would right all keys to a file. The game must be in the foreground and have focus for this data +to be recorded. + +``` +def tick args + [ + [args.inputs.keyboard, :keyboard], + [args.inputs.controller_one, :controller_one], + [args.inputs.controller_two, :controller_two] + ].each do |input, name| + if input.key_down.truthy_keys.length > 0 + args.gtk.write_file("mygame/app/#{name}_key_down_#{args.state.tick_count}", input.key_down.truthy_keys.to_s) + end + end +end +``` + +# List of keys: + +These are the character and associated properities that will +be set to true. + +For example `A => :a, :shift` means that `args.inputs.keyboard.a` +would be true and so would `args.inputs.keyboard.shift` +(if both keys were being held or in the down state). + +``` +A => :a, :shift +B => :b, :shift +C => :c, :shift +D => :d, :shift +E => :e, :shift +F => :f, :shift +G => :g, :shift +H => :h, :shift +I => :i, :shift +J => :j, :shift +K => :k, :shift +L => :l, :shift +M => :m, :shift +N => :n, :shift +O => :o, :shift +P => :p, :shift +Q => :q, :shift +R => :r, :shift +S => :s, :shift +T => :t, :shift +U => :u, :shift +V => :v, :shift +W => :w, :shift +X => :x, :shift +Y => :y, :shift +Z => :z, :shift +! => :exclamation_point +0 => :zero +1 => :one +2 => :two +3 => :three +4 => :four +5 => :five +6 => :six +7 => :seven +8 => :eight +9 => :nine +\b => :backspace +\e => :escape +\r => :enter +\t => :tab +( => :open_round_brace +) => :close_round_brace +{ => :open_curly_brace +} => :close_curly_brace +[ => :open_square_brace +] => :close_square_brace +: => :colon +; => :semicolon += => :equal_sign +- => :hyphen + => :space +$ => :dollar_sign +" => :double_quotation_mark +' => :single_quotation_mark +` => :backtick +~ => :tilde +. => :period +, => :comma +| => :pipe +_ => :underscore +# => :hash ++ => :plus +@ => :at +/ => :forward_slash +\ => :back_slash +* => :asterisk +< => :less_than +> => :greater_than +^ => :greater_than +& => :ampersand +² => :superscript_two +§ => :section_sign +? => :question_mark +% => :percent_sign +º => :ordinal_indicator +right arrow => :right +left arrow => :left +down arrow => :down +up arrow => :up +delete key => :delete +control key => :control +windows key/command key => :meta +alt key => :alt +``` diff --git a/deploy_template/mygame/documentation/07-mouse.md b/deploy_template/mygame/documentation/07-mouse.md new file mode 100644 index 0000000..cbace44 --- /dev/null +++ b/deploy_template/mygame/documentation/07-mouse.md @@ -0,0 +1,29 @@ +# Mouse + +Determining current position of mouse: + +``` +args.inputs.mouse.x +args.inputs.mouse.y +``` + +Determining if the mouse has been clicked, and it's position. Note: +`click` and `down` are aliases for each other. + +``` +if args.inputs.mouse.click + puts args.inputs.mouse.click + puts args.inputs.mouse.click.point.x + puts args.inputs.mouse.click.point.y +end +``` + +Determining if the mouse button has been released: + +``` +if args.inputs.mouse.up + puts args.inputs.mouse.up + puts args.inputs.mouse.up.point.x + puts args.inputs.mouse.up.point.y +end +``` diff --git a/deploy_template/mygame/documentation/08-controllers.md b/deploy_template/mygame/documentation/08-controllers.md new file mode 100644 index 0000000..6b8b9bd --- /dev/null +++ b/deploy_template/mygame/documentation/08-controllers.md @@ -0,0 +1,86 @@ +# Controllers + +There are two controllers you have access to: + +``` +args.inputs.controller_one +args.inputs.controller_two +``` + +Determining if a key was down: + +``` +if args.inputs.controller_one.key_down.a + puts 'The key was in the down state' +end +``` + +Determining if a key is being held: + +``` +if args.inputs.controller_one.key_held.a + puts 'The key is being held' +end +``` + +Determining if a key is released: + +``` +if args.inputs.controller_one.key_up.a + puts 'The key is being held' +end +``` + +# Truthy Keys + +You can access all triggered keys through `thruthy_keys` on `keyboard`, `controller_one`, and `controller_two`. + +This is how you would right all keys to a file. The game must be in the foreground and have focus for this data +to be recorded. + +``` +def tick args + [ + [args.inputs.keyboard, :keyboard], + [args.inputs.controller_one, :controller_one], + [args.inputs.controller_two, :controller_two] + ].each do |input, name| + if input.key_down.truthy_keys.length > 0 + args.gtk.write_file("mygame/app/#{name}_key_down_#{args.state.tick_count}", input.key_down.truthy_keys.to_s) + end + end +end +``` + +# List of keys: + +``` +args.inputs.controller_one.key_held.up +args.inputs.controller_one.key_held.down +args.inputs.controller_one.key_held.left +args.inputs.controller_one.key_held.right +args.inputs.controller_one.key_held.a +args.inputs.controller_one.key_held.b +args.inputs.controller_one.x +args.inputs.controller_one.y +args.inputs.controller_one.key_held.l1 +args.inputs.controller_one.key_held.r1 +args.inputs.controller_one.key_held.l2 +args.inputs.controller_one.key_held.r2 +args.inputs.controller_one.key_held.l3 +args.inputs.controller_one.key_held.r3 +args.inputs.controller_one.key_held.start +args.inputs.controller_one.key_held.select +args.inputs.controller_one.key_held.directional_up +args.inputs.controller_one.key_held.directional_down +args.inputs.controller_one.key_held.directional_left +args.inputs.controller_one.key_held.directional_right +args.inputs.controller_one.left_analog_x_raw, +args.inputs.controller_one.left_analog_y_raw, +args.inputs.controller_one.left_analog_x_perc, +args.inputs.controller_one.left_analog_y_perc, +args.inputs.controller_one.right_analog_x_raw, +args.inputs.controller_one.right_analog_y_raw, +args.inputs.controller_one.right_analog_x_perc, +args.inputs.controller_one.right_analog_y_perc +``` |
