http://roguebasin.com/api.php?action=feedcontributions&user=Bolthar&feedformat=atomRogueBasin - User contributions [en]2024-03-28T19:36:34ZUser contributionsMediaWiki 1.36.0http://roguebasin.com/index.php?title=Ruby&diff=17797Ruby2009-05-26T11:27:01Z<p>Bolthar: /* Line of sight */</p>
<hr />
<div>=Ruby=<br />
<br />
Ruby is still coming of age in the roguelike field -- there are no roguelike libraries and only a few finished games in the language. That said, Ruby is very powerful, combining an elegant syntax with an incredibly dynamic object system. It's also incredibly fun to code with. But beware! Many dangers lurk within beneath its alluring facade!<br />
<br />
==Reasons not to use Ruby==<br />
<br />
* <b>Speed:</b> Ruby 1.8 measures far below Python in terms of performance. This is mostly due to Python having a bytecode compiler. On the other hand, Ruby 1.9 has JIT compilation and <i>out-performs</i> Python.<br />
<br />
* <b>Documentation:</b> The language is not well documented in relation to other languages, but this is getting better all the time. There are quite a few gotchas (like using <tt>setter=</tt> methods inside of classes).<br />
<br />
* <b>Libraries:</b> Ruby has no roguelike library, nor are there many (if any) roguelike sources to borrow from. Built-in [[Curses]] support has no colors under Windows and is generally a mess.<br />
<br />
==But!==<br />
<br />
The first two of these issues will be fixed by the time your roguelike is finished :) <br />
<br />
As people begin to use Ruby for RL development, code will surface. There are already a few algorithms implemented and put up at RogueBasin.<br />
<br />
Cross-platform, true curses support can be achieved using [[NCurses]] (see below).<br />
<br />
==Okay, I'm going to use Ruby. What now?==<br />
<br />
You'll need to install a copy of Ruby 1.8 from http://www.ruby-lang.org/ (I recommend the one-click installer) or your package manager (<tt>apt-get install ruby</tt>). Then acquaint yourself with the Ruby tools: <tt>irb</tt>, <tt>ri</tt> and <tt>rdoc</tt>. A good version of the standard library API can be found at http://www.noobkit.com/<br />
<br />
===ncurses-ruby===<br />
<br />
It is possible to use the built-in curses on linux and other platforms, and interface with the Win32 console via the Win32 API for Windows support. However, this is a relative pain. Instead, install the non-standard ncurses-ruby package!<br />
<br />
<b>On Windows:</b><br />
* Download <tt>ncurses-ruby1.8-0.9.1-i386-mswin32.zip</tt> from http://ncurses-ruby.berlios.de/<br />
* Copy <tt>lib/ncurses.rb</tt> and <tt>ncurses.so</tt> into your code directory (don't copy the <tt>lib</tt> directory itself!)<br />
* In your script, <tt>require 'ncurses'</tt><br />
<br />
That's it! You can now use ncurses (see the zdennis's ncurses examples at http://github.com/zdennis/ncurses_examples/tree/master or the C API, which is very similar). At some point an example roguelike using ncurses will be uploaded.<br />
<br />
===Line of sight===<br />
<br />
[[Bresenham's Line Algorithm|Here]] is a Bresenham's Line Algorithm implementation in Ruby<br />
<br />
===Field of View===<br />
<br />
A few [[Field of Vision|field of view]] algorithms have been implemented in Ruby<br />
<br />
* [[Ruby shadowcasting implementation]]<br />
* [[Ruby precise permissive FOV implementation]]<br />
<br />
===Bitfields===<br />
<br />
For certain intensive operations it may be prudent to use a [[Ruby bitfield|Bitfield]]. One example is storing which map tiles have been visited by your player (and will be drawn).<br />
<br />
Using this library, it is easy to add methods to your Map class for FOV calculation:<br />
<br />
<pre><br />
def initialize(map)<br />
....<br />
@visited = BitField.new(@width * @height) # visited by player (drawn in grey)<br />
@lit = BitField.new(@width * @height) # seen by player this round (drawn in white)<br />
end<br />
<br />
# Return true if the square is lit (seen by player)<br />
def lit?(x, y)<br />
@lit[y * @width + x] == 1<br />
end<br />
<br />
# Returns true if square has been visited by player<br />
def visited?(x, y)<br />
@visited[y * @width + x] == 1<br />
end<br />
<br />
# Set lit status for square. Also visits the square<br />
def light(x, y)<br />
idx = y * @width + x<br />
@lit[idx] = @visited[idx] = 1<br />
end<br />
<br />
# Unlight everything (call after doing FOV calc + map draw)<br />
def reset_light<br />
@lit.clear<br />
end<br />
</pre><br />
[[Category:Programming languages]]</div>Boltharhttp://roguebasin.com/index.php?title=Ruby&diff=17796Ruby2009-05-26T11:26:43Z<p>Bolthar: /* Okay, I'm going to use Ruby. What now? */</p>
<hr />
<div>=Ruby=<br />
<br />
Ruby is still coming of age in the roguelike field -- there are no roguelike libraries and only a few finished games in the language. That said, Ruby is very powerful, combining an elegant syntax with an incredibly dynamic object system. It's also incredibly fun to code with. But beware! Many dangers lurk within beneath its alluring facade!<br />
<br />
==Reasons not to use Ruby==<br />
<br />
* <b>Speed:</b> Ruby 1.8 measures far below Python in terms of performance. This is mostly due to Python having a bytecode compiler. On the other hand, Ruby 1.9 has JIT compilation and <i>out-performs</i> Python.<br />
<br />
* <b>Documentation:</b> The language is not well documented in relation to other languages, but this is getting better all the time. There are quite a few gotchas (like using <tt>setter=</tt> methods inside of classes).<br />
<br />
* <b>Libraries:</b> Ruby has no roguelike library, nor are there many (if any) roguelike sources to borrow from. Built-in [[Curses]] support has no colors under Windows and is generally a mess.<br />
<br />
==But!==<br />
<br />
The first two of these issues will be fixed by the time your roguelike is finished :) <br />
<br />
As people begin to use Ruby for RL development, code will surface. There are already a few algorithms implemented and put up at RogueBasin.<br />
<br />
Cross-platform, true curses support can be achieved using [[NCurses]] (see below).<br />
<br />
==Okay, I'm going to use Ruby. What now?==<br />
<br />
You'll need to install a copy of Ruby 1.8 from http://www.ruby-lang.org/ (I recommend the one-click installer) or your package manager (<tt>apt-get install ruby</tt>). Then acquaint yourself with the Ruby tools: <tt>irb</tt>, <tt>ri</tt> and <tt>rdoc</tt>. A good version of the standard library API can be found at http://www.noobkit.com/<br />
<br />
===ncurses-ruby===<br />
<br />
It is possible to use the built-in curses on linux and other platforms, and interface with the Win32 console via the Win32 API for Windows support. However, this is a relative pain. Instead, install the non-standard ncurses-ruby package!<br />
<br />
<b>On Windows:</b><br />
* Download <tt>ncurses-ruby1.8-0.9.1-i386-mswin32.zip</tt> from http://ncurses-ruby.berlios.de/<br />
* Copy <tt>lib/ncurses.rb</tt> and <tt>ncurses.so</tt> into your code directory (don't copy the <tt>lib</tt> directory itself!)<br />
* In your script, <tt>require 'ncurses'</tt><br />
<br />
That's it! You can now use ncurses (see the zdennis's ncurses examples at http://github.com/zdennis/ncurses_examples/tree/master or the C API, which is very similar). At some point an example roguelike using ncurses will be uploaded.<br />
<br />
===Line of sight===<br />
<br />
[[Here|Bresenham's Line Algorithm]] is a Bresenham's Line Algorithm implementation in Ruby<br />
<br />
===Field of View===<br />
<br />
A few [[Field of Vision|field of view]] algorithms have been implemented in Ruby<br />
<br />
* [[Ruby shadowcasting implementation]]<br />
* [[Ruby precise permissive FOV implementation]]<br />
<br />
===Bitfields===<br />
<br />
For certain intensive operations it may be prudent to use a [[Ruby bitfield|Bitfield]]. One example is storing which map tiles have been visited by your player (and will be drawn).<br />
<br />
Using this library, it is easy to add methods to your Map class for FOV calculation:<br />
<br />
<pre><br />
def initialize(map)<br />
....<br />
@visited = BitField.new(@width * @height) # visited by player (drawn in grey)<br />
@lit = BitField.new(@width * @height) # seen by player this round (drawn in white)<br />
end<br />
<br />
# Return true if the square is lit (seen by player)<br />
def lit?(x, y)<br />
@lit[y * @width + x] == 1<br />
end<br />
<br />
# Returns true if square has been visited by player<br />
def visited?(x, y)<br />
@visited[y * @width + x] == 1<br />
end<br />
<br />
# Set lit status for square. Also visits the square<br />
def light(x, y)<br />
idx = y * @width + x<br />
@lit[idx] = @visited[idx] = 1<br />
end<br />
<br />
# Unlight everything (call after doing FOV calc + map draw)<br />
def reset_light<br />
@lit.clear<br />
end<br />
</pre><br />
[[Category:Programming languages]]</div>Boltharhttp://roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm&diff=16256Bresenham's Line Algorithm2009-03-24T13:30:28Z<p>Bolthar: </p>
<hr />
<div>Here's a C++ version; as in the previous article plot() draws a "dot" at (x, y):<br />
<br />
#include <cmath><br />
<br />
////////////////////////////////////////////////////////////////////////////////<br />
void Bresenham(int x1,<br />
int y1,<br />
int x2,<br />
int y2)<br />
{<br />
int delta_x = std::abs(x2 - x1) << 1;<br />
int delta_y = std::abs(y2 - y1) << 1;<br />
<br />
// if x1 == x2 or y1 == y2, then it does not matter what we set here<br />
signed char ix = x2 > x1?1:-1;<br />
signed char iy = y2 > y1?1:-1;<br />
<br />
plot(x1, y1);<br />
<br />
if (delta_x >= delta_y)<br />
{<br />
// error may go below zero<br />
int error = delta_y - (delta_x >> 1);<br />
<br />
while (x1 != x2)<br />
{<br />
if (error >= 0)<br />
{<br />
if (error || (ix > 0))<br />
{<br />
y1 += iy;<br />
error -= delta_x;<br />
}<br />
// else do nothing<br />
}<br />
// else do nothing<br />
<br />
x1 += ix;<br />
error += delta_y;<br />
<br />
plot(x1, y1);<br />
}<br />
}<br />
else<br />
{<br />
// error may go below zero<br />
int error = delta_x - (delta_y >> 1);<br />
<br />
while (y1 != y2)<br />
{<br />
if (error >= 0)<br />
{<br />
if (error || (iy > 0))<br />
{<br />
x1 += ix;<br />
error -= delta_y;<br />
}<br />
// else do nothing<br />
}<br />
// else do nothing<br />
<br />
y1 += iy;<br />
error += delta_x;<br />
<br />
plot(x1, y1);<br />
}<br />
}<br />
}<br />
<br />
And here 's a Ruby version, it returns an array of points, each being an hash with 2 elements (x and y)<br />
<br />
<br />
def get_line(x0,x1,y0,y1)<br />
points = []<br />
steep = ((y1-y0).abs) > ((x1-x0).abs)<br />
if steep<br />
x0,y0 = y0,x0<br />
x1,y1 = y1,x1<br />
end<br />
if x0 > x1<br />
x0,x1 = x1,x0<br />
y0,y1 = y1,y0<br />
end<br />
deltax = x1-x0<br />
deltay = (y1-y0).abs<br />
error = (deltax / 2).to_i<br />
y = y0<br />
ystep = nil<br />
if y0 < y1<br />
ystep = 1<br />
else<br />
ystep = -1<br />
end<br />
for x in x0..x1<br />
if steep<br />
points << {:x => y, :y => x}<br />
else<br />
points << {:x => x, :y => y}<br />
end<br />
error -= deltay<br />
if error < 0<br />
y += ystep<br />
error += deltax<br />
end<br />
end<br />
return points<br />
end<br />
<br />
[[Category:Articles]]</div>Boltharhttp://roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm&diff=16255Bresenham's Line Algorithm2009-03-24T13:30:03Z<p>Bolthar: </p>
<hr />
<div>Here's a C++ version; as in the previous article plot() draws a "dot" at (x, y):<br />
<br />
#include <cmath><br />
<br />
////////////////////////////////////////////////////////////////////////////////<br />
void Bresenham(int x1,<br />
int y1,<br />
int x2,<br />
int y2)<br />
{<br />
int delta_x = std::abs(x2 - x1) << 1;<br />
int delta_y = std::abs(y2 - y1) << 1;<br />
<br />
// if x1 == x2 or y1 == y2, then it does not matter what we set here<br />
signed char ix = x2 > x1?1:-1;<br />
signed char iy = y2 > y1?1:-1;<br />
<br />
plot(x1, y1);<br />
<br />
if (delta_x >= delta_y)<br />
{<br />
// error may go below zero<br />
int error = delta_y - (delta_x >> 1);<br />
<br />
while (x1 != x2)<br />
{<br />
if (error >= 0)<br />
{<br />
if (error || (ix > 0))<br />
{<br />
y1 += iy;<br />
error -= delta_x;<br />
}<br />
// else do nothing<br />
}<br />
// else do nothing<br />
<br />
x1 += ix;<br />
error += delta_y;<br />
<br />
plot(x1, y1);<br />
}<br />
}<br />
else<br />
{<br />
// error may go below zero<br />
int error = delta_x - (delta_y >> 1);<br />
<br />
while (y1 != y2)<br />
{<br />
if (error >= 0)<br />
{<br />
if (error || (iy > 0))<br />
{<br />
x1 += ix;<br />
error -= delta_y;<br />
}<br />
// else do nothing<br />
}<br />
// else do nothing<br />
<br />
y1 += iy;<br />
error += delta_x;<br />
<br />
plot(x1, y1);<br />
}<br />
}<br />
}<br />
<br />
And here 's a Ruby version, it returns an array of points, each being an hash with 2 elements (x and y)<br />
<br />
def get_line(x0,x1,y0,y1)<br />
points = []<br />
steep = ((y1-y0).abs) > ((x1-x0).abs)<br />
if steep<br />
x0,y0 = y0,x0<br />
x1,y1 = y1,x1<br />
end<br />
if x0 > x1<br />
x0,x1 = x1,x0<br />
y0,y1 = y1,y0<br />
end<br />
deltax = x1-x0<br />
deltay = (y1-y0).abs<br />
error = (deltax / 2).to_i<br />
y = y0<br />
ystep = nil<br />
if y0 < y1<br />
ystep = 1<br />
else<br />
ystep = -1<br />
end<br />
for x in x0..x1<br />
if steep<br />
points << {:x => y, :y => x}<br />
else<br />
points << {:x => x, :y => y}<br />
end<br />
error -= deltay<br />
if error < 0<br />
y += ystep<br />
error += deltax<br />
end<br />
end<br />
return points<br />
end<br />
<br />
[[Category:Articles]]</div>Bolthar