Git Product home page Git Product logo

ray's Introduction

What is Ray?

Ray is a library than can create windows, play music, and draw 2D graphics (or not too complex 3D by doing just a bit more work, thanks to OpenGL). It is meant to be easy and fun to use (à la Shoes), and still flexible and powerful.

Tutorial & Installation

See on this page. Also notice there's an IRC channel on freenode: #ray.

Features

Fun DSL

require 'ray'

Ray.game "Hello" do
  register { add_hook :quit, method(:exit!) }

  scene :hello do
    @text = text "Hello world!", :size => 30, :angle => 30, :at => [50, 50]
    render { |win| win.draw @text }
  end

  scenes << :hello
end

Flexible for more complex games

require 'ray'

class TitleScene < Ray::Scene
  scene_name :title

  def setup
    # setup resources
  end

  def register
    # register for events
  end

  def render(win)
    # draw!
  end

  def clean_up
    # perform cleanup
  end
end

class GameScene < Ray::Scene
  scene_name :game

  # same stuff
end

# ...

class Game < Ray::Game
  def initialize
    super "Awesome Game"

    TitleScene.bind(self)
    GameScene.bind(self)
    # ...

    scenes << :title
  end
end

Drawable API

Ray has a drawable class that specifies a common interface to all the drawable objects – how to perform transformations to them and how to draw them.

 obj = AnyDrawable.new

 window.draw obj

 obj.pos    = [0, 2]   # set position
 obj.angle  = 40       # rotation
 obj.origin = [20, 20] # just sets the origin of transformations
 # ...

 # You can even have a completely custom transformation matrix:
 obj.matrix = Ray::Matrix.translation [2, 3, 4]

Off-screen rendering

When rendering to a window is not enough, you can render on an image just fine:

Ray::ImageTarget.new some_image do |target|
  target.clear Ray::Color.red
  target.draw Ray::Polygon.circle([50, 50], 10, Ray::Color.green)
  target.update
end

OpenGL integration

Ray uses OpenGL, and provides some classes and methods to allow using it from Ray. In fact, Ray::Drawable can simply be used for OpenGL rendering:

# Ray has a more advanced sprite class, of course!
class CustomSprite < Ray::Drawable
  def initialize(image)
    super() # very important: creating the actual drawable

    # Ray allocates a VBO to store your vertices.
    # You could just use your own OpenGL binding to call glBegin and glEnd
    # if you don't want to use it.
    self.vertex_count = 4

    # Tells Ray to enable texturing for this drawable
    self.textured = true

    @image = image
  end

  # return an array of vertices
  def fill_vertices
    rect = @img.tex_rect [0, 0, @img.w, @img.h]

    [
     Ray::Vertex.new([0,      0],      Ray::Color.white, rect.top_left),
     Ray::Vertex.new([@img.w, 0],      Ray::Color.white, rect.top_right),
     Ray::Vertex.new([0,      @img.h], Ray::Color.white, rect.bottom_left),
     Ray::Vertex.new([@img.w, @img.h], Ray::Color.white, rect.bottom_right),
    ]
  end

  # The index parameter is there in case you'd want to use
  # draw_elements. You can fill indices by defining a fill_indices method
  # and setting index_count.
  def render(first, index)
    @image.bind

    # Some low level OpenGL calls are available
    Ray::GL.draw_arrays :triangle_strip, first, 4
  end
end

You can also create and use shaders from Ruby:

shader = Ray::Shader.new :vertex => "vertex_shader.glsl",
                         :frag   => "frag_shader.glsl"
drawable.shader = shader

# You can't assign an image to a render target, but you can recompile it:
window.shader.compile :vertex => "vertex.glsl", :frag => "frag.glsl"

3D rendering

3D rendering is a very cool thing! Even if Ray's graphics module only uses 2D, a 3D API can be created with it. You can just use Ray::Drawable again, but you will ned to specify the layout of your vertices and to write your own shaders (the default shaders are only designed for 2D). You will probably need a custom projection matrix too.

class Cube < Ray::Drawable
  include Ray::GL

  Vertex = Ray::GL::Vertex.make [
    [:pos, "in_Position", :vector3],
    [:col, "in_Color",    :color]
  ]

  def initialize
    super Vertex
    # ...
  end

  # ...
end

# ...

# Tell the shader what vertex layout to use.
window.shader.apply_vertex Cube::Vertex
window.shader.compile :vertex => "vertex.glsl", :frag => "frag.glsl"

# Ray::Matrix can create 3D transformation and projection matrices!
window.view = Ray::View.new Ray::Matrix.perspective(90, 1, 1, 100)

Audio playback

Ray can play short sounds right away and stream longer ones — it uses OpenAL for this. 3D audio effects can be added as well.

@sound = sound "test.wav"
@music = music "test.ogg"

@sound.pause
@music.play

@music.pause

@music.volume = 80
@music.pitch  = 0.9
@music.pos    = [10, 20, 30]

@music.play

Testing

Ray's events can be faked so that you can simulate user input in your tests:

require 'awesome_scene'

describe AwesomeScene do
  before :each do
    @game = AwesomeGame.new
    @scene = @game.registered_scene(:awesome_scene)

    @scene.register
    @scene.setup
  end

  it "has a cursor at (0, 0)" do
    @scene.cursor.pos.should == [0, 0]
  end

  it "moves its cursor after the mouse moved" do
    @game.raise_event :mouse_motion, Ray::Vector2[100, 100]
    @game.event_runner.run

    @scene.cursor.pos.should == [100, 100]
  end

  it "draws its cursor" do
    @scene.window.should_receive(:draw, @scene.cursor)
    @scene.render @scene.window
  end

  after :each do
    @scene.clean_up
  end
end

Animations

You can animate the fact the state of an object is changing (its position, etc.) using Ray's animation objects:

animations << translation(:from => [0, 0], :to => [100, 100],
                          :duration => 4).start(@some_drawable)

(They can really be used to animate any change, not just those that are visible, and not just those applied to a drawable.)

ray's People

Contributors

bil-bas avatar mon-ouie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ray's Issues

If an image is created that is too large, Ray doesn't complain.

Image.new([10000, 10000]) is accepted, but the size of the image is given as (0, 0) (so I assume it doesn't create a working image). Perhaps it should raise an exception if the image requested is too large to handle? Also might be nice to have a constant on Image that tells us the max size that we can ask for so we don't have to guess :)

Position of Rectangle

Hello,

ruby-1.9.2-p290 :005 > a = Ray::Polygon.rectangle([30, 30, 40, 40], Ray::Color.red)
 => #<Ray::Polygon:0x007fe39341d740> 
ruby-1.9.2-p290 :006 > a.pos
 => (0, 0) 

I would expect the position to be [30,30]. Why is it [0,0]?

Animation progress should be 0..1.0

Currently, progress is measured in percentages, 0..100.0, but this means that for the vast majority of usages, you need to divide by 100 before using it for anything. 0..1.0 can always be multiplied by 100 in the rare cases where you actually want a percentage.

Some sort of GameObject

Since developers will want to move a lot of the game logic away from the scene and into objects like the player and enemies, it makes sense to have a base for this (object or module).

As a minimum:

class GameObject
  include Ray::Helper

  attr_reader :window # This is required if you want to use #holding?

  def initialize(scene)
    @window = scene.window
    self.raiser_runner = scene.raiser_runner # To allow things like animations to raise events.
    self.event_runner = scene.event_runner # To get access to #on
  end 
end    

Segfault on quit!, if music used (win32)

If a Music object has been created, even if not played, then the game will freeze with a segfault when quitting from the game. This happens on win7x64 with Ruby 1.9.2-p360. Doesn't happen if just loading/playing Sounds.

Trouble installing native extensions on Linux 64 bit

Hey there,

I am using Linux Mint 11 64 bit (which is based upon Ubuntu 11.04) and the installation of Ray always aborts. I got all dependencies (I think) installed but now make finishes with an error.

say_context.c: In function ‘say_context_glew_init’:
say_context.c:231:3: error: ‘glVertexAttribDivisor’ undeclared (first use in this function)
say_context.c:231:3: note: each undeclared identifier is reported only once for each function it appears in
make: *** [say_context.o] Error 1

However see this gist for the whole console output: https://gist.github.com/1216617

I hope I didn't simply miss a dependency.

Optimise Vectors

Using Ruby's Profile gem on my game, I found that a significant number of the high-cost methods were on Vector2 and Vector3 (here showing those operations that used 0.99-9.02% of overall run-time; Vector operations, although relatively fast, appear here because they are called a huge number of times). By implementing more of the VectorN methods in C, such as like #-, #length, #dist, a significant amount of time could be saved (compared to optimising the already super-fast drawing). As can be seen, the operations already implemented in C were very much faster than the ones that are still in Ruby.

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name

  9.02     3.84      3.84     3282     1.17    16.71  Range#each
  8.15     7.30      3.46    28854     0.12     0.32  SkewedMap#tile_at_grid
  6.89    10.23      2.93    95508     0.03     0.04  Comparable.between?
  5.81    12.70      2.47   102033     0.02     0.03  Ray::Vector2#[]
  5.21    14.91      2.21    18900     0.12     0.31  Map#tile_at_grid
  4.57    16.86      1.95    16384     0.12     0.18  Ray::Vector2#length
  3.66    18.42      1.56      299     5.21    30.75  Kernel.gem_original_require
  3.46    19.89      1.47   152390     0.01     0.01  Ray::Vector2#x
  3.24    21.27      1.38   154379     0.01     0.01  Ray::Vector2#y
  3.23    22.64      1.37    16783     0.08     0.17  Ray::Vector2#-
  3.00    23.92      1.28   190491     0.01     0.01  Float#<=>
  2.39    24.93      1.02    55850     0.02     0.05  Array#to_vector2
  2.10    25.82      0.89    58870     0.02     0.02  Array#[]
  1.97    26.66      0.84     7764     0.11     2.99  Array#each
  1.80    27.43      0.77   112531     0.01     0.01  Fixnum#-
  1.72    28.16      0.73   102033     0.01     0.01  Ray::Vector2#initialize
  1.40    28.75      0.59    25264     0.02     2.77  Class#new
  1.25    29.29      0.53    56178     0.01     0.01  Float#*
  1.10    29.76      0.47    16384     0.03     0.37  Ray::Vector2#dist
  0.99    30.18      0.42    32049     0.01     0.01  Ray::Vector2#to_vector2

Index Buffers

Ray should handle index buffers to make thing faster.

This implies:

  • an object able to get slices of a bigindex buffer (à la say_buffer_slice);
  • attributing slices to drawables, adding another step when drawing them;
  • making buffer renderers use them.

animation_series

There is an animation_combination which manages multiple animations at once, but animation_series would allow you to chain multiple animations together consecutively.

pop_scene_while

Say I wanted to skip out from a nested state to the menu, or otherwise pop more than one state, it would be useful to be able to do it directly. Also needs to skip over the sub-stacks created by run_state

e.g.

pop_scene_while { |current| not current.is_a? Menu }

Animation loops are jerky

Although Animation#loop! is very convenient, compared to manually restarting animations, it is not smooth on the frame that it restarts (just like manual restarts). This is very apparent when scrolling the background quickly, since it seems to stutter every so often (which would coincide with the restart). When looping, the new progress should be set based on the remainder of time in the previous frame after the animation completed. Without this, there can be up to a whole frame in which no animation occurs between animation runs.

sprite_animation doesn't spend time on the last frame.

A sprite_animation should stay on the last frame for the same amount of time as the other frames. At the moment, if a 3-frame animation has a duration of 12s, it will animate at 6, 12, then finish just as the final frame is shown. What I expect is 4, 4, 4s for each frame. This doesn't generally matter, but it does matter if you are looping the animation or moving on to another animation after the animation is finished.

Point sprites

Handling point sprites could be useful to create particles engines.

Ocra doesn't include all requirements (win32)

In the current release, freetype6.dll and OpenAL32.dll are not included in the generated executable. I know the freetype6.dll issue has been fixed in the v0.2.0.

For now, you can distribute the Ocra exe along with a copy of OpenAL32.dll and it will work if they are in the same directory.

Custom matrix generation for drawables

One may need to generate matrices other than those Ray can generate automatically. This could be implemented as a method on drawable subclasses :

class Foo < Ray::Drawable
  def build_transformation_matrix
    # return a matrix
  end
end

State changes in drawables

Changing states in drawables is sometimes expansive. Drawables should thus not be marked as changed in cases such as this:

sprite.flip_x = true
win.draw sprite

sprite.flip_x = true # doesn't really change anything
win.draw sprite

Installation issue on Ubuntu

Hi!
I'm having some issues installing Ray 0.2.0 on my Ubuntu machine. 0.1.1 works just fine, but not Ray 0.2
Terminal output:

Building native extensions.  This could take a while...
ERROR:  Error installing ray:
  ERROR: Failed to build gem native extension.

        /home/thomas/.rvm/rubies/ruby-1.9.2-p290/bin/ruby extconf.rb
checking for GL/glxext.h... yes
checking for X11/extensions/Xrandr.h... yes
checking for main() in -lXrandr... yes
checking for main() in -lX11... yes
checking for main() in -lGL... yes
checking for main() in -lGLEW... yes
checking for main() in -lopenal... yes
checking for main() in -lsndfile... yes
creating Makefile

make
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o say_basic_type.o -c say_basic_type.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o gl_index_buffer.o -c gl_index_buffer.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o color.o -c color.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o pixel_bus.o -c pixel_bus.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o say_thread.o -c say_thread.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o say_view.o -c say_view.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o image.o -c image.c
image.c: In function ‘ray_image_assert_pos’:
image.c:161:14: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘size_t’
image.c:161:14: warning: format ‘%ld’ expects type ‘long int’, but argument 4 has type ‘size_t’
image.c:165:14: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘size_t’
image.c:165:14: warning: format ‘%ld’ expects type ‘long int’, but argument 4 has type ‘size_t’
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o audio.o -c audio.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o gl_vertex.o -c gl_vertex.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o say_string.o -c say_string.c
gcc -I. -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/i686-linux -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/home/thomas/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -DHAVE_GL_GLXEXT_H -DHAVE_X11_EXTENSIONS_XRANDR_H  -D_FILE_OFFSET_BITS=64  -fPIC -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -fPIC -Wextra -Wall -Wno-unused-parameter -std=gnu99 -I/usr/include/freetype2 -DSAY_X11  -o say_context.o -c say_context.c
say_context.c: In function ‘say_context_glew_init’:
say_context.c:231:3: error: ‘glVertexAttribDivisor’ undeclared (first use in this function)
say_context.c:231:3: note: each undeclared identifier is reported only once for each function it appears in
make: *** [say_context.o] Error 1


Gem files will remain installed in /home/thomas/.rvm/gems/ruby-1.9.2-p290@utvikling/gems/ray-0.2.0 for inspection.
Results logged to /home/thomas/.rvm/gems/ruby-1.9.2-p290@utvikling/gems/ray-0.2.0/ext/gem_make.out

Would appreciate any help, using 0.1.1 until then :)

Thomas

Assign rect position's components value

Hello,

Take a look a this:

ruby-1.9.2-p290 :018 > a = Ray::Polygon.circle([200, 200], 10, Ray::Color.blue)
 => #<Ray::Polygon:0x007f8b88b30400> 
ruby-1.9.2-p290 :019 > a.pos
 => (0, 0) 
ruby-1.9.2-p290 :020 > a.pos.x = 8
 => 8 
ruby-1.9.2-p290 :021 > a.pos
 => (0, 0) 

a.pos should be 8, right?

I am using Ray to make a Liquid Wars clone https://github.com/Nerian/Pugnacious-Juices You are creating an awesome library!

The more Polygons created, the slower creation is

Although this is an extreme example, any large scale game, that creates a large number of objects over a significant amount of time will probably feel the effect of whatever is causing this slowdown. Not tested with other drawables. Perhaps they are broken too?

I felt the effect of this on frame-rate, just creating 10 objects a frame after a few minutes. Not unreasonable if you are creating particles, for example (though you could go to the effort of caching them...but still).

Not a high priority, but could be a simple fix :)

require 'ray'

# The more objects you create, the more time each creation takes.
# For me, this will slowly go down from 45fps to 5fps (and ~80k objects created).
# Pressing space lets the FPS just shoot immediately back up to 45.
#

Ray.game "Invisible text" do
  register { add_hook :quit, method(:exit!) }

  scene :scene do  
    @grind = true
    @text = text "0", at: [100, 100], size: 30
    @num_objects = 0

    on :key_press, key(:space) do
      @grind = false
    end

    always do
      @rects = []

      if @grind
        100.times do    
          @rects << Ray::Polygon.rectangle([0, 0, 100, 100])
        end
        @num_objects += 100
        @text.string = @num_objects.to_s
      end

      sleep 0.02
    end  

    render do |win|
      if @grind
        @rects.each {|rect| win.draw rect }
      end
      win.draw @text
    end
  end

  scenes << :scene
end

Leaving a Game doesn't close its Window

When I closed a Game (with pop_scene in the root scene) and opened another window, it showed a zombie window until the program exited.

Manually closing the window after I popped meant the existing window was closed properly and the new one worked fine.

pop_scene
window.close

additive and multiplicative blending

I have used these alpha blending options to great effect in the past, in Wrath and Alpha Channel, and miss them from Ray (well, strictly I have only used additive for "simple" lighting , but multiplicative would work well for shadows or other effects). I thought I'd be able to do this with shaders, but shading is apparently done quite separately to blending in the pipeline. Of course, one could argue that I add lighting to the shader in every texture being drawn in a similar way to that used in 3D, but that seems to be overkill to me (unless I'm overcomplicating things).

In Gosu, any draw action can have a mode of :default, :additive or :multiplicative.

A Scene class doesn't seem to have 'always' available

In the DSL, you can hook into the "update" using "always do ...end". If using a class inheriting Scene, I can't see a way to hook into that per-frame update (I can override #setup and #render to hook into those effects, but there isn't a #always to override)

A duplicated Text ignores #color=

I duplicated a Text object, then attempted to change its colour, but it stayed the same colour as the original. #color works normally for non-duped Text objects, though.

Collisions

Hello,

Does Ray implements a collisions system?

Window icon inverted

Positive this used to be displayed the right way up, but now it is upside-down.

Text should be able to be horizontally justified

It is usual to place text so that the position given is the at the center or right of the text, so that it can be aligned nicely with other screen elements. This could be done with an :origin, similar to sprites, but that wouldn't work well since Text objects will often be resized.

I suggest something like an :origin, but [0..1, 0..1] or, probably easier to use and coving 99% of use cases, justify: [:left, :right, :center]. For completeness, a vertical alignment could be added (:top, :center, :bottom)

As an extra suggestion, this system might be useful for sprites too, so you could use origin = [:left, :top], since that is more explicit than passing the image size.

The only part that is really important, however, is some way to horizontally justify text.

Set a default font

Usually an application will use a single font throughout (or SHOULD do). Having to always use the option font: "path/to/font.ttf" in every Text created is a bit cumbersome if the value is always the same. Text.default_font_name= could be used to set the default font globally.

This could also apply to default font size, but that is a lot less important since it is usual to have multiple sizes of font in a GUI/overlay.

High-level shader generation

Writing shaders is effectively writing in C and although it is sometimes useful to optimise this, it is also useful, in the Ruby environment, to just be able to add effects easily.

I thought of

shader << Shader::Crop.new(100, 100, 500, 500)
shader << Shader::Pixelation([4, 4])
shader << Shader::Blur.new(2)

shader[:blur].disable # So I can re-enable it at a give point.
shader[:pixelation].factor = [8, 8]

Mon_ouie thought that using a more decoupled system to generate GLSL code would be better (the snippet was my suggestion as a way of doing this):

shader.compile :frag => ShaderGenerator.new(crop: [...], pixelation: [...])

Does give you the advantage that you can just puts the generated code to learn how to write shaders, check it or generate it then hand-optimise it before use.

Alternatively, you could just abstract it out completely (why does anyone need to know that shaders are involved, any more than they need to know that rendering an image uses texture offsets). This, however, would be a lot harder to integrate with user-modified shaders. This would also make it harder to specify the order of shader processes.

window.blur = 5 # Would generate and compile a fragment shader that added blurring.
window.pixelation = 4 # Would re-write the shader to add pixelation to the blur effect.
window.blur = 0 # Would disable blur in the currently written shader.

Allowing to set shader attributes on draw

The shader isn't passed to Ruby to make memory handling easier. Yet, shaders attributes could be set when drawing using a hash:

object.shader_attributes = {
  :something => [0, 1, 2]
}

Rectangle size

Hello,

@point = Ray::Polygon.rectangle([10,10,11,11])

This creates a rectangle. The problem is that it is too big. How could I make it smaller?

I would like it to be around 4 pixels.

Thanks!

Text doesn't always display

The more text objects I have on the screen, the more likely that the first created ones will not be visible, even if requested for rendering.

require 'ray'

# Run this with 20 text objects and I only see numbers 15-19
# Run this with 10 texts and they will all show up.

Ray.game "Invisible text" do
  register { add_hook :quit, method(:exit!) }

  scene :scene do
    @texts = []

    20.times do |i|
      @texts << text("Hello world #{i}", at: [5, i * 10])
    end

    render do |win|
      @texts.each {|t| win.draw t }
    end
  end

  scenes << :scene
end

(Tested specifically on 1.9.2 on win7x64)

Handlers do nothing on nil

Handlers for events, for example, return if the event_runner is nil. Really should raise an error, since if you are raising an event, you DO want to have it do something (and you can't track down a silent ignore).

More animation features

Extra options for Animations for very common patterns:

  • looping (automatically loops the animation back to the start after it has completed).
  • bouncing (makes the animation reverse after it has finished - changing the behaviour of looping).

Both behaviours taken straight from Chingu.

#key doesn't check validity

key doesn't check validity of the key symbol it is given, so it gives a very vague error message at the point when any key is pressed. Just needs to raise an error if the symbol isn't a valid one when it is called, not when the event is raised which gives no indication of where you put in bad data.

No idea where the list of valid symbols is in the source even; I searched in the whole project, but the only references where constants in the C code, which I can only assume you mung into symbols (so a bit hidden).

EDIT: Ah, just needs a tiny patch in Ray::Key#initialize

raise "bad key symbol #{@symbol.inspect}" unless Ray::Keys.has_key? @symbol

I'm happy to edit and request a fork-merge, but I know you dislike giving error messages :D

Having trouble installing on OSX

I'm trying to install this on a fairly new laptop and can't get it to work in 1.8.7 or 1.9.2. I have homebrew and have installed both glew and libsndfile. When I try to install the gem, it can't find libGLEW:

Building native extensions.  This could take a while...
ERROR:  Error installing ray:
    ERROR: Failed to build gem native extension.

        /Users/jeffwhitmire/.rvm/rubies/ruby-1.9.2-p290/bin/ruby extconf.rb
checking for main() in -lGLEW... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

I'm guessing that when it's building the gem, somehow /usr/local/lib is not in the lib path (not sure if that's LDFLAGS or LD_LIBRARY_PATH). I've tried several attempts at fixing this and came up short. Any help would be appreciated.

Not flipping images vertically

Images are currently flipped vertically. This means that transfering pixels from a target onto a texture must be done synchronously, Also, it is quite annoying when using image targets and custom views: the view must be verically flipped to, or it won't render correctly.

Flipping the image when it is loaded and saved so as to keep texture coordinates matching OpenGL convention would avoid those issues.

default scene-name should be based on class.

The name of a Scene is :scene unless you use scene_name to set it manually (or use the DSL, of course). I think it should default to a symbol based on the class name (MainMenu => :main_menu) instead. Should still be able to manually set it, but might as well have a meaningful default.

Sprite#position

pos is not what I'd expect, so alias it to #position please

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.