reight 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/release-gem.yml +62 -0
- data/.github/workflows/tag.yml +35 -0
- data/.github/workflows/test.yml +37 -0
- data/.github/workflows/utils.rb +56 -0
- data/.gitignore +1 -0
- data/ChangeLog.md +23 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +62 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/bin/r8 +35 -0
- data/lib/reight/all.rb +59 -0
- data/lib/reight/app/map/brush.rb +27 -0
- data/lib/reight/app/map/brush_base.rb +54 -0
- data/lib/reight/app/map/canvas.rb +150 -0
- data/lib/reight/app/map/chips.rb +84 -0
- data/lib/reight/app/map/editor.rb +117 -0
- data/lib/reight/app/map/line.rb +35 -0
- data/lib/reight/app/map/rect.rb +29 -0
- data/lib/reight/app/map/tool.rb +32 -0
- data/lib/reight/app/map.rb +8 -0
- data/lib/reight/app/music/editor.rb +25 -0
- data/lib/reight/app/music.rb +1 -0
- data/lib/reight/app/navigator.rb +172 -0
- data/lib/reight/app/runner.rb +275 -0
- data/lib/reight/app/sound/editor.rb +25 -0
- data/lib/reight/app/sound.rb +1 -0
- data/lib/reight/app/sprite/brush.rb +43 -0
- data/lib/reight/app/sprite/canvas.rb +254 -0
- data/lib/reight/app/sprite/chips.rb +92 -0
- data/lib/reight/app/sprite/color.rb +30 -0
- data/lib/reight/app/sprite/editor.rb +272 -0
- data/lib/reight/app/sprite/fill.rb +45 -0
- data/lib/reight/app/sprite/line.rb +37 -0
- data/lib/reight/app/sprite/select.rb +58 -0
- data/lib/reight/app/sprite/shape.rb +43 -0
- data/lib/reight/app/sprite/tool.rb +27 -0
- data/lib/reight/app/sprite.rb +10 -0
- data/lib/reight/app.rb +123 -0
- data/lib/reight/button.rb +93 -0
- data/lib/reight/chip.rb +150 -0
- data/lib/reight/extension.rb +24 -0
- data/lib/reight/helpers.rb +69 -0
- data/lib/reight/history.rb +135 -0
- data/lib/reight/map.rb +264 -0
- data/lib/reight/project.rb +115 -0
- data/lib/reight/reight.rb +83 -0
- data/lib/reight.rb +18 -0
- data/reight.gemspec +40 -0
- data/res/icons.png +0 -0
- data/test/helper.rb +15 -0
- data/test/test_chip.rb +108 -0
- data/test/test_chip_list.rb +68 -0
- data/test/test_map.rb +232 -0
- data/test/test_map_chunk.rb +226 -0
- metadata +244 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 86f61ce22f69d112815dcccd0800f21f73183c45bc26a8aef3818dfae72cb556
|
4
|
+
data.tar.gz: 4f6ec4c31e86ec0007454fb7e2b4d1c40b8e952671f69347fd429d0e7906deca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 21497433b9c5736683a9ca12db7ed8d728325005b1ca2002e30d619ea97fd7f97c0bc677dd8cab0ed28af8d45aed684e70e83cc1d681f641b4c5077dbe7ccda1
|
7
|
+
data.tar.gz: ac2d9d3adbca86a3f18bc1d3a141465dd7787abff61f6ad17ffdb411385448d39b01141961f2ce7f673957f59620cc078d05240833ff5eb781df518decdba6fb
|
@@ -0,0 +1,62 @@
|
|
1
|
+
name: Release Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags: ['v[0-9]*']
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
release:
|
9
|
+
runs-on: macos-latest
|
10
|
+
|
11
|
+
steps:
|
12
|
+
- name: ruby 3.2
|
13
|
+
uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 3.2
|
16
|
+
|
17
|
+
- name: checkout
|
18
|
+
uses: actions/checkout@v4
|
19
|
+
|
20
|
+
- name: setup gems
|
21
|
+
run: bundle install
|
22
|
+
|
23
|
+
- name: setup dependencies
|
24
|
+
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
25
|
+
|
26
|
+
- name: test
|
27
|
+
run: bundle exec rake quiet packages test
|
28
|
+
|
29
|
+
- name: create gem
|
30
|
+
id: gem
|
31
|
+
run: |
|
32
|
+
bundle exec rake gem
|
33
|
+
echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
|
34
|
+
|
35
|
+
- name: create github release
|
36
|
+
id: release
|
37
|
+
uses: actions/create-release@v1
|
38
|
+
env:
|
39
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
40
|
+
with:
|
41
|
+
tag_name: ${{ github.ref }}
|
42
|
+
release_name: ${{ github.ref }}
|
43
|
+
|
44
|
+
- name: upload to github release
|
45
|
+
uses: actions/upload-release-asset@v1
|
46
|
+
env:
|
47
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
48
|
+
with:
|
49
|
+
upload_url: ${{ steps.release.outputs.upload_url }}
|
50
|
+
asset_path: ./${{ steps.gem.outputs.path }}
|
51
|
+
asset_name: ${{ steps.gem.outputs.path }}
|
52
|
+
asset_content_type: application/zip
|
53
|
+
|
54
|
+
- name: upload to rubygems
|
55
|
+
env:
|
56
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
|
57
|
+
run: |
|
58
|
+
mkdir -p $HOME/.gem
|
59
|
+
touch $HOME/.gem/credentials
|
60
|
+
chmod 0600 $HOME/.gem/credentials
|
61
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
62
|
+
bundle exec rake upload
|
@@ -0,0 +1,35 @@
|
|
1
|
+
name: Tag
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
tag:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
|
11
|
+
steps:
|
12
|
+
- name: ruby 3.2
|
13
|
+
uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 3.2
|
16
|
+
|
17
|
+
- name: checkout
|
18
|
+
uses: actions/checkout@v4
|
19
|
+
with:
|
20
|
+
fetch-depth: 0
|
21
|
+
token: ${{ secrets.PAT }}
|
22
|
+
|
23
|
+
- name: setup dependencies
|
24
|
+
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies only: :xot'"
|
25
|
+
|
26
|
+
- name: setup user name and email
|
27
|
+
run: |
|
28
|
+
git config --global user.email "xordog@gmail.com"
|
29
|
+
git config --global user.name "xord"
|
30
|
+
|
31
|
+
- name: tag versions
|
32
|
+
run: "ruby -I.github/workflows -rutils -e 'tag_versions'"
|
33
|
+
|
34
|
+
- name: push tags
|
35
|
+
run: git push origin --tags
|
@@ -0,0 +1,37 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
runs-on: macos-latest
|
11
|
+
|
12
|
+
steps:
|
13
|
+
- name: ruby 3.2
|
14
|
+
uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: 3.2
|
17
|
+
|
18
|
+
- name: checkout
|
19
|
+
uses: actions/checkout@v4
|
20
|
+
|
21
|
+
- name: setup gems
|
22
|
+
run: bundle install
|
23
|
+
|
24
|
+
- name: setup dependencies
|
25
|
+
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
26
|
+
|
27
|
+
- name: packages
|
28
|
+
run: bundle exec rake packages
|
29
|
+
|
30
|
+
- name: lib
|
31
|
+
run: bundle exec rake lib
|
32
|
+
|
33
|
+
- name: ext
|
34
|
+
run: bundle exec rake ext
|
35
|
+
|
36
|
+
- name: test
|
37
|
+
run: bundle exec rake test
|
@@ -0,0 +1,56 @@
|
|
1
|
+
RENAMES = {reflex: 'reflexion'}
|
2
|
+
|
3
|
+
def sh(cmd)
|
4
|
+
puts cmd
|
5
|
+
system cmd
|
6
|
+
end
|
7
|
+
|
8
|
+
def setup_dependencies(build: true, only: nil)
|
9
|
+
gemspec_path = `git ls-files`.lines(chomp: true).find {|l| l =~ /\.gemspec$/}
|
10
|
+
return unless gemspec_path
|
11
|
+
|
12
|
+
gemspec = File.read gemspec_path
|
13
|
+
name = File.basename gemspec_path, '.gemspec'
|
14
|
+
|
15
|
+
exts = File.readlines('Rakefile')
|
16
|
+
.map {|l| l[%r|^\s*require\W+(\w+)/extension\W+$|, 1]}
|
17
|
+
.compact
|
18
|
+
.reject {|ext| ext == name}
|
19
|
+
exts = exts & [only].flatten.map(&:to_s) if only
|
20
|
+
|
21
|
+
exts.each do |ext|
|
22
|
+
gem = RENAMES[ext.to_sym].then {|s| s || ext}
|
23
|
+
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s*>=\s*([\d\.]+)\s*['"]/, 1]
|
24
|
+
opts = '-c advice.detachedHead=false --depth 1'
|
25
|
+
clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
|
26
|
+
|
27
|
+
# 'rake subtree:push' pushes all subrepos, so cloning by new tag
|
28
|
+
# often fails before tagging each new tag
|
29
|
+
sh %( #{clone} --branch v#{ver} || #{clone} )
|
30
|
+
sh %( cd ../#{ext} && rake ext )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def tag_versions()
|
35
|
+
tags = `git tag`.lines chomp: true
|
36
|
+
vers = `git log --oneline ./VERSION`
|
37
|
+
.lines(chomp: true)
|
38
|
+
.map {|line| line.split.first[/^\w+$/]}
|
39
|
+
.map {|hash| [`git cat-file -p #{hash}:./VERSION 2>/dev/null`[/[\d\.]+/], hash]}
|
40
|
+
.select {|ver, hash| ver && hash}
|
41
|
+
.reverse
|
42
|
+
.to_h
|
43
|
+
|
44
|
+
changes = File.read('ChangeLog.md')
|
45
|
+
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
46
|
+
.slice(1..-1)
|
47
|
+
.each_slice(2)
|
48
|
+
.to_h
|
49
|
+
.transform_values(&:strip!)
|
50
|
+
|
51
|
+
vers.to_a.reverse.each do |ver, hash|
|
52
|
+
tag = "v#{ver}"
|
53
|
+
break if tags.include?(tag)
|
54
|
+
sh %( git tag -a -m \"#{changes[ver]&.gsub '"', '\\"'}\" #{tag} #{hash} )
|
55
|
+
end
|
56
|
+
end
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*~
|
data/ChangeLog.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# reight ChangeLog
|
2
|
+
|
3
|
+
|
4
|
+
## [v0.1.2] - 2025-01-14
|
5
|
+
|
6
|
+
- User can change the file name of user scripts
|
7
|
+
- Rename from 'bin/r8.rb' to 'bin/r8'
|
8
|
+
- Change the file/directory structure of the source code
|
9
|
+
- Update icon images
|
10
|
+
- Update workflow files
|
11
|
+
- Set minumum version for runtime dependency
|
12
|
+
|
13
|
+
- Fix an error on first launch
|
14
|
+
|
15
|
+
|
16
|
+
## [v0.1.1] - 2025-01-13
|
17
|
+
|
18
|
+
- Update README.md
|
19
|
+
|
20
|
+
|
21
|
+
## [v0.1] - 2025-01-13
|
22
|
+
|
23
|
+
- Alpha version
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 xord.org
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
# Reight - A Retro Game Engine for Ruby
|
3
|
+
|
4
|
+
Reight is an open-source Ruby library inspired by the powerful [Processing](https://processing.org/) API, designed to make creative coding accessible and enjoyable for everyone. With support for both Mac and Windows, this library brings the joy of visual programming to Ruby developers.
|
5
|
+
|
6
|
+
## Features
|
7
|
+
|
8
|
+
- **Processing API Compatibility**: Leverage the well-known Processing API to create stunning visuals, animations, and interactive applications using Ruby.
|
9
|
+
- **Cross-Platform**: Works seamlessly on both macOS and Windows environments.
|
10
|
+
- **Ruby-Powered**: Enjoy the elegance and simplicity of Ruby while crafting creative projects.
|
11
|
+
- **Extensible and Open**: Modify and extend the library to fit your unique needs.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Install the gem via RubyGems:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
gem install reight
|
19
|
+
```
|
20
|
+
|
21
|
+
Or add it to your Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'reight'
|
25
|
+
```
|
26
|
+
|
27
|
+
Then run:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
bundle install
|
31
|
+
```
|
32
|
+
|
33
|
+
## Getting Started
|
34
|
+
|
35
|
+
Here’s a simple example to get you started:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# Create a window and draw something
|
39
|
+
draw do
|
40
|
+
background 0
|
41
|
+
$sprites ||= project.maps.first.map(&:to_sprite)
|
42
|
+
sprite $sprites
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Run the script and watch your window come to life!
|
47
|
+
|
48
|
+
```
|
49
|
+
$ bundle exec r8 .
|
50
|
+
```
|
51
|
+
|
52
|
+
## Documentation
|
53
|
+
|
54
|
+
Comprehensive documentation and guides can be found [here](https://www.rubydoc.info/gems/reight/0.1/index).
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
This project is licensed under the [MIT License](LICENSE).
|
59
|
+
|
60
|
+
---
|
61
|
+
|
62
|
+
Happy coding with Ruby and Processing!
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
|
3
|
+
%w[../xot ../rucy ../beeps ../rays ../reflex ../processing ../rubysketch .]
|
4
|
+
.map {|s| File.expand_path "#{s}/lib", __dir__}
|
5
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
6
|
+
|
7
|
+
require 'xot/rake'
|
8
|
+
|
9
|
+
require 'xot/extension'
|
10
|
+
require 'rucy/extension'
|
11
|
+
require 'beeps/extension'
|
12
|
+
require 'rays/extension'
|
13
|
+
require 'reflex/extension'
|
14
|
+
require 'processing/extension'
|
15
|
+
require 'rubysketch/extension'
|
16
|
+
require 'reight/extension'
|
17
|
+
|
18
|
+
|
19
|
+
EXTENSIONS = [Xot, Rucy, Beeps, Rays, Reflex, Processing, RubySketch, Reight]
|
20
|
+
|
21
|
+
default_tasks
|
22
|
+
test_ruby_extension
|
23
|
+
build_ruby_gem
|
24
|
+
|
25
|
+
|
26
|
+
task :run do
|
27
|
+
libs = %w[xot rucy beeps rays reflex processing rubysketch]
|
28
|
+
.map {|lib| "-I#{ENV['ALL']}/#{lib}/lib"}
|
29
|
+
sh %( ruby #{libs.join ' '} -Ilib bin/r8 '#{ENV["path"] || "."}' )
|
30
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.2
|
data/bin/r8
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'reight'
|
4
|
+
using Reight
|
5
|
+
|
6
|
+
|
7
|
+
def r8 = $r8__
|
8
|
+
|
9
|
+
def usage()
|
10
|
+
<<~END
|
11
|
+
USAGE: r8 [path]
|
12
|
+
END
|
13
|
+
end
|
14
|
+
|
15
|
+
Reight::CONTEXT__.tap do |c|
|
16
|
+
path = ARGV.shift or return puts usage
|
17
|
+
path = File.expant_path path, Dir.pwd if path.start_with?('/')
|
18
|
+
c.setup {Reight::R8.new(path).setup}
|
19
|
+
c.draw {r8.draw}
|
20
|
+
c.key_pressed {r8.key_pressed}
|
21
|
+
c.key_released {r8.key_released}
|
22
|
+
c.key_typed {r8.key_typed}
|
23
|
+
c.mouse_pressed {r8.mouse_pressed}
|
24
|
+
c.mouse_released {r8.mouse_released}
|
25
|
+
c.mouse_moved {r8.mouse_moved}
|
26
|
+
c.mouse_dragged {r8.mouse_dragged}
|
27
|
+
c.mouse_clicked {r8.mouse_clicked}
|
28
|
+
c.double_clicked {r8.double_clicked}
|
29
|
+
c.mouse_wheel {r8.mouse_wheel}
|
30
|
+
c.touch_started {r8.touch_started}
|
31
|
+
c.touch_ended {r8.touch_ended}
|
32
|
+
c.touch_moved {r8.touch_moved}
|
33
|
+
c.window_moved {r8.window_moved}
|
34
|
+
c.window_resized {r8.window_resized}
|
35
|
+
end
|
data/lib/reight/all.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Reight
|
2
|
+
def self.to_snake_case(camel_case_names)
|
3
|
+
camel_case_names.map(&:to_s)
|
4
|
+
.map {[_1, _1.gsub(/([a-z])([A-Z])/) {"#{$1}_#{$2.downcase}"}]}
|
5
|
+
end
|
6
|
+
|
7
|
+
# alias snake_case methods
|
8
|
+
[Processing, RubySketch]
|
9
|
+
.map {|mod| mod.constants.map {mod.const_get _1}}
|
10
|
+
.flatten
|
11
|
+
.select {_1.class == Module || _1.class == Class}
|
12
|
+
.each do |klass|
|
13
|
+
Reight.to_snake_case(klass.instance_methods false)
|
14
|
+
.reject {|camel, snake| camel =~ /__$/}
|
15
|
+
.reject {|camel, snake| klass.method_defined? snake}
|
16
|
+
.each {|camel, snake| klass.alias_method snake, camel}
|
17
|
+
end
|
18
|
+
|
19
|
+
w = (ENV['WIDTH'] || 500).to_i
|
20
|
+
h = (ENV['HEIGHT'] || 500).to_i
|
21
|
+
WINDOW__ = Processing::Window.new(w, h) {start}
|
22
|
+
CONTEXT__ = RubySketch::Context.new WINDOW__
|
23
|
+
|
24
|
+
excludes = Reight.to_snake_case(%i[
|
25
|
+
setup draw
|
26
|
+
keyPressed keyReleased keyTyped
|
27
|
+
mousePressed mouseReleased mouseMoved mouseDragged
|
28
|
+
mouseClicked doubleClicked mouseWheel
|
29
|
+
touchStarted touchEnded touchMoved
|
30
|
+
windowMoved windowResized motion
|
31
|
+
]).flatten.uniq
|
32
|
+
refine Object do
|
33
|
+
(CONTEXT__.methods - Object.instance_methods - excludes)
|
34
|
+
.reject {_1 =~ /__$/} # methods for internal use
|
35
|
+
.each do |method|
|
36
|
+
define_method(method) do |*args, **kwargs, &block|
|
37
|
+
CONTEXT__.__send__(method, *args, **kwargs, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end# Reight
|
42
|
+
|
43
|
+
|
44
|
+
require 'reight/extension'
|
45
|
+
require 'reight/helpers'
|
46
|
+
require 'reight/project'
|
47
|
+
require 'reight/history'
|
48
|
+
require 'reight/button'
|
49
|
+
|
50
|
+
require 'reight/reight'
|
51
|
+
require 'reight/chip'
|
52
|
+
require 'reight/map'
|
53
|
+
require 'reight/app'
|
54
|
+
require 'reight/app/navigator'
|
55
|
+
require 'reight/app/runner'
|
56
|
+
require 'reight/app/sprite'
|
57
|
+
require 'reight/app/map'
|
58
|
+
require 'reight/app/sound'
|
59
|
+
require 'reight/app/music'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
using Reight
|
2
|
+
|
3
|
+
|
4
|
+
class Reight::MapEditor::Brush < Reight::MapEditor::BrushBase
|
5
|
+
|
6
|
+
def initialize(app, &block)
|
7
|
+
super app, icon: app.icon(1, 2, 8), &block
|
8
|
+
set_help left: name, right: 'Pick Chip'
|
9
|
+
end
|
10
|
+
|
11
|
+
def brush(cursor_from, cursor_to, chip)
|
12
|
+
x, y, = cursor_to
|
13
|
+
put_or_delete_chip x, y, chip
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def canvas_pressed(...)
|
18
|
+
canvas.begin_editing
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def canvas_released(...)
|
23
|
+
super
|
24
|
+
canvas.end_editing
|
25
|
+
end
|
26
|
+
|
27
|
+
end# Brush
|
@@ -0,0 +1,54 @@
|
|
1
|
+
using Reight
|
2
|
+
|
3
|
+
|
4
|
+
class Reight::MapEditor::BrushBase < Reight::MapEditor::Tool
|
5
|
+
|
6
|
+
def brush(cursor_from, cursor_to, chip) = nil
|
7
|
+
|
8
|
+
def put_or_delete_chip(x, y, chip)
|
9
|
+
return false unless x && y && chip
|
10
|
+
m = canvas.map
|
11
|
+
return false if !@deleting && m[x, y]&.id == chip.id
|
12
|
+
|
13
|
+
result = false
|
14
|
+
m.each_chip x, y, chip.w, chip.h do |ch|
|
15
|
+
m.delete_chip ch
|
16
|
+
result |= history.append [:delete_chip, ch.pos.x, ch.pos.y, ch.id]
|
17
|
+
end
|
18
|
+
unless @deleting
|
19
|
+
m.put x, y, chip
|
20
|
+
result |= history.append [:put_chip, x, y, chip.id]
|
21
|
+
end
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def canvas_pressed(x, y, button)
|
26
|
+
return unless button == LEFT
|
27
|
+
@cursor_from, @deleting = canvas.cursor.dup, chips.chip.empty?
|
28
|
+
@undo_prev = brush @cursor_from, canvas.cursor, chips.chip
|
29
|
+
end
|
30
|
+
|
31
|
+
def canvas_released(x, y, button)
|
32
|
+
return unless button == LEFT
|
33
|
+
end
|
34
|
+
|
35
|
+
def canvas_moved(x, y)
|
36
|
+
update_cursor x, y
|
37
|
+
end
|
38
|
+
|
39
|
+
def canvas_dragged(x, y, button)
|
40
|
+
update_cursor x, y
|
41
|
+
return unless button == LEFT
|
42
|
+
app.undo flash: false if @undo_prev
|
43
|
+
@undo_prev = brush @cursor_from, canvas.cursor, chips.chip
|
44
|
+
end
|
45
|
+
|
46
|
+
def canvas_clicked(x, y, button)
|
47
|
+
pick_chip x, y if button == RIGHT
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_cursor(x, y)
|
51
|
+
canvas.set_cursor x, y, chips.size, chips.size
|
52
|
+
end
|
53
|
+
|
54
|
+
end# BrushBase
|
@@ -0,0 +1,150 @@
|
|
1
|
+
using Reight
|
2
|
+
|
3
|
+
|
4
|
+
class Reight::MapEditor::Canvas
|
5
|
+
|
6
|
+
include Reight::Hookable
|
7
|
+
|
8
|
+
def initialize(app, map, path)
|
9
|
+
hook :tool_changed
|
10
|
+
|
11
|
+
@app, @map, @path = app, map, path
|
12
|
+
@x, @y, @tool, @cursor = 0, 0, nil, nil, nil
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :x, :y
|
16
|
+
|
17
|
+
attr_reader :map, :tool, :cursor
|
18
|
+
|
19
|
+
def save()
|
20
|
+
@app.project.save
|
21
|
+
end
|
22
|
+
|
23
|
+
def tool=(tool)
|
24
|
+
@tool = tool
|
25
|
+
tool_changed! tool
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_cursor(x, y, w, h)
|
29
|
+
@cursor = correct_bounds x, y, w, h
|
30
|
+
end
|
31
|
+
|
32
|
+
def chip_at_cursor()
|
33
|
+
x, y, = cursor
|
34
|
+
map[@x + x, @y + y]
|
35
|
+
end
|
36
|
+
|
37
|
+
def begin_editing(&block)
|
38
|
+
@app.history.begin_grouping
|
39
|
+
block.call if block
|
40
|
+
ensure
|
41
|
+
end_editing if block
|
42
|
+
end
|
43
|
+
|
44
|
+
def end_editing()
|
45
|
+
@app.history.end_grouping
|
46
|
+
save
|
47
|
+
end
|
48
|
+
|
49
|
+
def sprite()
|
50
|
+
@sprite ||= Sprite.new.tap do |sp|
|
51
|
+
pos = -> {to_image sp.mouse_x, sp.mouse_y}
|
52
|
+
sp.draw {draw}
|
53
|
+
sp.mouse_pressed {mouse_pressed( *pos.call, sp.mouse_button)}
|
54
|
+
sp.mouse_released {mouse_released(*pos.call, sp.mouse_button)}
|
55
|
+
sp.mouse_moved {mouse_moved( *pos.call)}
|
56
|
+
sp.mouse_dragged {mouse_dragged( *pos.call, sp.mouse_button)}
|
57
|
+
sp.mouse_clicked {mouse_clicked( *pos.call, sp.mouse_button)}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def to_image(x, y)
|
64
|
+
return x, y unless @x && @y
|
65
|
+
return x - @x, y - @y
|
66
|
+
end
|
67
|
+
|
68
|
+
def correct_bounds(x, y, w, h)
|
69
|
+
x, y, w, h = [x, y, w, h].map &:to_i
|
70
|
+
return x / w * w, y / h * h, w, h
|
71
|
+
end
|
72
|
+
|
73
|
+
def draw()
|
74
|
+
sp = sprite
|
75
|
+
|
76
|
+
clip sp.x, sp.y, sp.w, sp.h
|
77
|
+
translate @x, @y
|
78
|
+
|
79
|
+
fill 0, 0, 0
|
80
|
+
no_stroke
|
81
|
+
rect(-@x, -@y, sp.w, sp.h)
|
82
|
+
|
83
|
+
draw_grids
|
84
|
+
|
85
|
+
map.each_chip(-@x, -@y, sp.w, sp.h, clip_by_chunk: true).each do |chip|
|
86
|
+
pos = chip.pos
|
87
|
+
copy chip.image, *chip.frame, pos.x, pos.y, chip.w, chip.h
|
88
|
+
end
|
89
|
+
|
90
|
+
if @cursor
|
91
|
+
no_fill
|
92
|
+
stroke 255, 255, 255
|
93
|
+
stroke_weight 1
|
94
|
+
rect(*@cursor)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def draw_grids()
|
99
|
+
push do
|
100
|
+
app = Reight::App
|
101
|
+
sw, sh = app::SCREEN_WIDTH, app::SCREEN_HEIGHT
|
102
|
+
mw, mh = sw * 10, sh * 10
|
103
|
+
stroke 20
|
104
|
+
shape grid 8, 8, mw, mh if @app.pressing?(SPACE)
|
105
|
+
stroke 50
|
106
|
+
shape grid sw / 2, sh / 2, mw, mh
|
107
|
+
stroke 100
|
108
|
+
shape grid sw, sh, mw, mh
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def grid(xinterval, yinterval, xmax, ymax)
|
113
|
+
(@grids ||= {})[xinterval] ||= create_shape.tap do |sh|
|
114
|
+
sh.begin_shape LINES
|
115
|
+
(0..xmax).step(xinterval).each do |x|
|
116
|
+
sh.vertex x, 0
|
117
|
+
sh.vertex x, ymax
|
118
|
+
end
|
119
|
+
(0..ymax).step(yinterval).each do |y|
|
120
|
+
sh.vertex 0, y
|
121
|
+
sh.vertex xmax, y
|
122
|
+
end
|
123
|
+
sh.end_shape
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def mouse_pressed(...)
|
128
|
+
tool&.canvas_pressed(...) unless hand?
|
129
|
+
end
|
130
|
+
|
131
|
+
def mouse_released(...)
|
132
|
+
tool&.canvas_released(...) unless hand?
|
133
|
+
end
|
134
|
+
|
135
|
+
def mouse_dragged(...)
|
136
|
+
if hand?
|
137
|
+
sp = sprite
|
138
|
+
@x += sp.mouse_x - sp.pmouse_x
|
139
|
+
@y += sp.mouse_y - sp.pmouse_y
|
140
|
+
else
|
141
|
+
tool&.canvas_dragged(...)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def mouse_moved(...) = tool&.canvas_moved(...)
|
146
|
+
def mouse_clicked(...) = tool&.canvas_clicked(...)
|
147
|
+
|
148
|
+
def hand? = @app.pressing?(SPACE)
|
149
|
+
|
150
|
+
end# Canvas
|