libtcod 0.0.2 → 0.0.3
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.
- data/.gitignore +1 -0
- data/Gemfile +4 -4
- data/LICENSE +21 -21
- data/README.md +81 -81
- data/Rakefile +2 -2
- data/clib/i686/SDL.dll +0 -0
- data/clib/i686/libtcod-mingw.dll +0 -0
- data/examples/python_tutorial_part_1/main.rb +58 -58
- data/examples/tile_demo/oryx_tiles.png +0 -0
- data/examples/tile_demo/tile_demo.rb +341 -0
- data/lib/libtcod.rb +10 -9
- data/lib/libtcod/bindings.rb +642 -640
- data/lib/libtcod/color_consts.rb +225 -225
- data/lib/libtcod/console.rb +80 -46
- data/lib/libtcod/consts.rb +218 -218
- data/lib/libtcod/struct.rb +34 -34
- data/lib/libtcod/system.rb +7 -0
- data/lib/libtcod/version.rb +3 -3
- data/libtcod.gemspec +21 -21
- data/test/color.rb +39 -39
- data/test/console.rb +8 -8
- data/test/helpers.rb +2 -2
- metadata +7 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
# Specify your gem's dependencies in libtcod.gemspec
|
4
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in libtcod.gemspec
|
4
|
+
gemspec
|
data/LICENSE
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
Copyright (c) 2013 Jaiden Mispy
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
1
|
+
Copyright (c) 2013 Jaiden Mispy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
22
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,81 +1,81 @@
|
|
1
|
-
# libtcod-ruby 0.0.
|
2
|
-
|
3
|
-
Ruby bindings for [libtcod 1.5.1](http://doryen.eptalys.net/libtcod/)
|
4
|
-
|
5
|
-
Currently
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
gem install libtcod
|
10
|
-
|
11
|
-
## Examples
|
12
|
-
|
13
|
-
Here's a straight port of the [example code](http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_1_code#Moving_around) from part 1 of the python tutorial:
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
require 'libtcod'
|
17
|
-
|
18
|
-
#actual size of the window
|
19
|
-
SCREEN_WIDTH = 80
|
20
|
-
SCREEN_HEIGHT = 50
|
21
|
-
|
22
|
-
LIMIT_FPS = 20 #20 frames-per-second maximum
|
23
|
-
|
24
|
-
def handle_keys
|
25
|
-
#key = TCOD.console_check_for_keypress() #real-time
|
26
|
-
key = TCOD.console_wait_for_keypress(true) #turn-based
|
27
|
-
|
28
|
-
if key.vk == TCOD::KEY_ENTER && key.lalt
|
29
|
-
#Alt+Enter: toggle fullscreen
|
30
|
-
TCOD.console_set_fullscreen(!TCOD.console_is_fullscreen())
|
31
|
-
elsif key.vk == TCOD::KEY_ESCAPE
|
32
|
-
return true #exit game
|
33
|
-
end
|
34
|
-
|
35
|
-
#movement keys
|
36
|
-
if TCOD.console_is_key_pressed(TCOD::KEY_UP)
|
37
|
-
$playery -= 1
|
38
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_DOWN)
|
39
|
-
$playery += 1
|
40
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_LEFT)
|
41
|
-
$playerx -= 1
|
42
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_RIGHT)
|
43
|
-
$playerx += 1
|
44
|
-
end
|
45
|
-
|
46
|
-
false
|
47
|
-
end
|
48
|
-
|
49
|
-
#############################################
|
50
|
-
# Initialization & Main Loop
|
51
|
-
#############################################
|
52
|
-
|
53
|
-
TCOD.console_set_custom_font('arial10x10.png', TCOD::FONT_TYPE_GREYSCALE | TCOD::FONT_LAYOUT_TCOD, 0, 0)
|
54
|
-
TCOD.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'ruby/TCOD tutorial', false, TCOD::RENDERER_SDL)
|
55
|
-
TCOD.sys_set_fps(LIMIT_FPS)
|
56
|
-
|
57
|
-
$playerx = SCREEN_WIDTH/2
|
58
|
-
$playery = SCREEN_HEIGHT/2
|
59
|
-
|
60
|
-
until TCOD.console_is_window_closed
|
61
|
-
TCOD.console_set_default_foreground(nil, TCOD::Color::WHITE)
|
62
|
-
TCOD.console_put_char(nil, $playerx, $playery, '@'.ord, TCOD::BKGND_NONE)
|
63
|
-
|
64
|
-
TCOD.console_flush()
|
65
|
-
|
66
|
-
TCOD.console_put_char(nil, $playerx, $playery, ' '.ord, TCOD::BKGND_NONE)
|
67
|
-
|
68
|
-
#handle keys and exit game if needed
|
69
|
-
will_exit = handle_keys
|
70
|
-
break if will_exit
|
71
|
-
end
|
72
|
-
```
|
73
|
-
|
74
|
-
|
75
|
-
## Contributing
|
76
|
-
|
77
|
-
1. Fork it
|
78
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
79
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
80
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
81
|
-
5. Create new Pull Request
|
1
|
+
# libtcod-ruby 0.0.3
|
2
|
+
|
3
|
+
Ruby bindings for [libtcod 1.5.1](http://doryen.eptalys.net/libtcod/)
|
4
|
+
|
5
|
+
Currently tested on Linux and Windows using Ruby 1.9.3; other platforms may work if you have libtcod in a place where ffi\_lib knows to get it. Basic wrapping of the C functions is complete, and a more idiomatic Ruby API is in progress.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
gem install libtcod
|
10
|
+
|
11
|
+
## Examples
|
12
|
+
|
13
|
+
Here's a straight port of the [example code](http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_1_code#Moving_around) from part 1 of the python tutorial:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'libtcod'
|
17
|
+
|
18
|
+
#actual size of the window
|
19
|
+
SCREEN_WIDTH = 80
|
20
|
+
SCREEN_HEIGHT = 50
|
21
|
+
|
22
|
+
LIMIT_FPS = 20 #20 frames-per-second maximum
|
23
|
+
|
24
|
+
def handle_keys
|
25
|
+
#key = TCOD.console_check_for_keypress() #real-time
|
26
|
+
key = TCOD.console_wait_for_keypress(true) #turn-based
|
27
|
+
|
28
|
+
if key.vk == TCOD::KEY_ENTER && key.lalt
|
29
|
+
#Alt+Enter: toggle fullscreen
|
30
|
+
TCOD.console_set_fullscreen(!TCOD.console_is_fullscreen())
|
31
|
+
elsif key.vk == TCOD::KEY_ESCAPE
|
32
|
+
return true #exit game
|
33
|
+
end
|
34
|
+
|
35
|
+
#movement keys
|
36
|
+
if TCOD.console_is_key_pressed(TCOD::KEY_UP)
|
37
|
+
$playery -= 1
|
38
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_DOWN)
|
39
|
+
$playery += 1
|
40
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_LEFT)
|
41
|
+
$playerx -= 1
|
42
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_RIGHT)
|
43
|
+
$playerx += 1
|
44
|
+
end
|
45
|
+
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
#############################################
|
50
|
+
# Initialization & Main Loop
|
51
|
+
#############################################
|
52
|
+
|
53
|
+
TCOD.console_set_custom_font('arial10x10.png', TCOD::FONT_TYPE_GREYSCALE | TCOD::FONT_LAYOUT_TCOD, 0, 0)
|
54
|
+
TCOD.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'ruby/TCOD tutorial', false, TCOD::RENDERER_SDL)
|
55
|
+
TCOD.sys_set_fps(LIMIT_FPS)
|
56
|
+
|
57
|
+
$playerx = SCREEN_WIDTH/2
|
58
|
+
$playery = SCREEN_HEIGHT/2
|
59
|
+
|
60
|
+
until TCOD.console_is_window_closed
|
61
|
+
TCOD.console_set_default_foreground(nil, TCOD::Color::WHITE)
|
62
|
+
TCOD.console_put_char(nil, $playerx, $playery, '@'.ord, TCOD::BKGND_NONE)
|
63
|
+
|
64
|
+
TCOD.console_flush()
|
65
|
+
|
66
|
+
TCOD.console_put_char(nil, $playerx, $playery, ' '.ord, TCOD::BKGND_NONE)
|
67
|
+
|
68
|
+
#handle keys and exit game if needed
|
69
|
+
will_exit = handle_keys
|
70
|
+
break if will_exit
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
1. Fork it
|
78
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
79
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
80
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
81
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
require "bundler/gem_tasks"
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
data/clib/i686/SDL.dll
ADDED
Binary file
|
Binary file
|
@@ -1,58 +1,58 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'libtcod'
|
4
|
-
|
5
|
-
#actual size of the window
|
6
|
-
SCREEN_WIDTH = 80
|
7
|
-
SCREEN_HEIGHT = 50
|
8
|
-
|
9
|
-
LIMIT_FPS = 20 #20 frames-per-second maximum
|
10
|
-
|
11
|
-
def handle_keys
|
12
|
-
#key = TCOD.console_check_for_keypress() #real-time
|
13
|
-
key = TCOD.console_wait_for_keypress(true) #turn-based
|
14
|
-
|
15
|
-
if key.vk == TCOD::KEY_ENTER && key.lalt
|
16
|
-
#Alt+Enter: toggle fullscreen
|
17
|
-
TCOD.console_set_fullscreen(!TCOD.console_is_fullscreen())
|
18
|
-
elsif key.vk == TCOD::KEY_ESCAPE
|
19
|
-
return true #exit game
|
20
|
-
end
|
21
|
-
|
22
|
-
#movement keys
|
23
|
-
if TCOD.console_is_key_pressed(TCOD::KEY_UP)
|
24
|
-
$playery -= 1
|
25
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_DOWN)
|
26
|
-
$playery += 1
|
27
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_LEFT)
|
28
|
-
$playerx -= 1
|
29
|
-
elsif TCOD.console_is_key_pressed(TCOD::KEY_RIGHT)
|
30
|
-
$playerx += 1
|
31
|
-
end
|
32
|
-
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
|
-
#############################################
|
37
|
-
# Initialization & Main Loop
|
38
|
-
#############################################
|
39
|
-
|
40
|
-
TCOD.console_set_custom_font('arial10x10.png', TCOD::FONT_TYPE_GREYSCALE | TCOD::FONT_LAYOUT_TCOD, 0, 0)
|
41
|
-
TCOD.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'ruby/TCOD tutorial', false, TCOD::RENDERER_SDL)
|
42
|
-
TCOD.sys_set_fps(LIMIT_FPS)
|
43
|
-
|
44
|
-
$playerx = SCREEN_WIDTH/2
|
45
|
-
$playery = SCREEN_HEIGHT/2
|
46
|
-
|
47
|
-
until TCOD.console_is_window_closed
|
48
|
-
TCOD.console_set_default_foreground(nil, TCOD::Color::WHITE)
|
49
|
-
TCOD.console_put_char(nil, $playerx, $playery, '@'.ord, TCOD::BKGND_NONE)
|
50
|
-
|
51
|
-
TCOD.console_flush()
|
52
|
-
|
53
|
-
TCOD.console_put_char(nil, $playerx, $playery, ' '.ord, TCOD::BKGND_NONE)
|
54
|
-
|
55
|
-
#handle keys and exit game if needed
|
56
|
-
will_exit = handle_keys
|
57
|
-
break if will_exit
|
58
|
-
end
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'libtcod'
|
4
|
+
|
5
|
+
#actual size of the window
|
6
|
+
SCREEN_WIDTH = 80
|
7
|
+
SCREEN_HEIGHT = 50
|
8
|
+
|
9
|
+
LIMIT_FPS = 20 #20 frames-per-second maximum
|
10
|
+
|
11
|
+
def handle_keys
|
12
|
+
#key = TCOD.console_check_for_keypress() #real-time
|
13
|
+
key = TCOD.console_wait_for_keypress(true) #turn-based
|
14
|
+
|
15
|
+
if key.vk == TCOD::KEY_ENTER && key.lalt
|
16
|
+
#Alt+Enter: toggle fullscreen
|
17
|
+
TCOD.console_set_fullscreen(!TCOD.console_is_fullscreen())
|
18
|
+
elsif key.vk == TCOD::KEY_ESCAPE
|
19
|
+
return true #exit game
|
20
|
+
end
|
21
|
+
|
22
|
+
#movement keys
|
23
|
+
if TCOD.console_is_key_pressed(TCOD::KEY_UP)
|
24
|
+
$playery -= 1
|
25
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_DOWN)
|
26
|
+
$playery += 1
|
27
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_LEFT)
|
28
|
+
$playerx -= 1
|
29
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_RIGHT)
|
30
|
+
$playerx += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
#############################################
|
37
|
+
# Initialization & Main Loop
|
38
|
+
#############################################
|
39
|
+
|
40
|
+
TCOD.console_set_custom_font('arial10x10.png', TCOD::FONT_TYPE_GREYSCALE | TCOD::FONT_LAYOUT_TCOD, 0, 0)
|
41
|
+
TCOD.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'ruby/TCOD tutorial', false, TCOD::RENDERER_SDL)
|
42
|
+
TCOD.sys_set_fps(LIMIT_FPS)
|
43
|
+
|
44
|
+
$playerx = SCREEN_WIDTH/2
|
45
|
+
$playery = SCREEN_HEIGHT/2
|
46
|
+
|
47
|
+
until TCOD.console_is_window_closed
|
48
|
+
TCOD.console_set_default_foreground(nil, TCOD::Color::WHITE)
|
49
|
+
TCOD.console_put_char(nil, $playerx, $playery, '@'.ord, TCOD::BKGND_NONE)
|
50
|
+
|
51
|
+
TCOD.console_flush()
|
52
|
+
|
53
|
+
TCOD.console_put_char(nil, $playerx, $playery, ' '.ord, TCOD::BKGND_NONE)
|
54
|
+
|
55
|
+
#handle keys and exit game if needed
|
56
|
+
will_exit = handle_keys
|
57
|
+
break if will_exit
|
58
|
+
end
|
Binary file
|
@@ -0,0 +1,341 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# TCOD ruby tutorial with tiles
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'libtcod'
|
7
|
+
|
8
|
+
#actual size of the window
|
9
|
+
SCREEN_WIDTH = 50
|
10
|
+
SCREEN_HEIGHT = 37
|
11
|
+
|
12
|
+
#size of the $map
|
13
|
+
MAP_WIDTH = SCREEN_WIDTH
|
14
|
+
MAP_HEIGHT = SCREEN_HEIGHT
|
15
|
+
|
16
|
+
#parameters for dungeon generator
|
17
|
+
ROOM_MAX_SIZE = 10
|
18
|
+
ROOM_MIN_SIZE = 6
|
19
|
+
MAX_ROOMS = 30
|
20
|
+
|
21
|
+
FOV_ALGO = 0 #default FOV algorithm
|
22
|
+
FOV_LIGHT_WALLS = true #light walls or not
|
23
|
+
TORCH_RADIUS = 10
|
24
|
+
|
25
|
+
LIMIT_FPS = 20 #20 frames-per-second maximum
|
26
|
+
|
27
|
+
GROUND_COLOR = TCOD::Color.rgb(77, 60, 41)
|
28
|
+
|
29
|
+
WALL_TILE = 256 #first tile in the first row of tiles
|
30
|
+
MAGE_TILE = 256 + 32 #first tile in the 2nd row of tiles
|
31
|
+
SKELETON_TILE = 256 + 32 + 1 #2nd tile in the 2nd row of tiles
|
32
|
+
|
33
|
+
class Tile
|
34
|
+
attr_accessor :blocked, :explored, :block_sight
|
35
|
+
|
36
|
+
#a tile of the $map and its properties
|
37
|
+
def initialize(blocked, block_sight = nil)
|
38
|
+
@blocked = blocked
|
39
|
+
|
40
|
+
#all tiles start unexplored
|
41
|
+
@explored = false
|
42
|
+
|
43
|
+
#by default, if a tile.equal? blocked, it also blocks sight
|
44
|
+
if block_sight.nil?
|
45
|
+
@block_sight = blocked
|
46
|
+
else
|
47
|
+
@block_sight = block_sight
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Rect
|
53
|
+
attr_accessor :x1, :y1, :x2, :y2
|
54
|
+
#a rectangle on the $map. used to characterize a room.
|
55
|
+
def initialize (x, y, w, h)
|
56
|
+
@x1 = x
|
57
|
+
@y1 = y
|
58
|
+
@x2 = x + w
|
59
|
+
@y2 = y + h
|
60
|
+
end
|
61
|
+
|
62
|
+
def center
|
63
|
+
center_x = (@x1 + @x2) / 2
|
64
|
+
center_y = (@y1 + @y2) / 2
|
65
|
+
[center_x, center_y]
|
66
|
+
end
|
67
|
+
|
68
|
+
def intersect (other)
|
69
|
+
#returns true if this rectangle intersects with another one
|
70
|
+
return (@x1 <= other.x2 and @x2 >= other.x1 and
|
71
|
+
@y1 <= other.y2 and @y2 >= other.y1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class Obj
|
76
|
+
attr_accessor :x, :y, :char, :color
|
77
|
+
|
78
|
+
#this.equal? a generic object: the $player, a monster, an item, the stairs...
|
79
|
+
#it's always represented by a character on screen.
|
80
|
+
def initialize (x, y, char, color)
|
81
|
+
@x = x
|
82
|
+
@y = y
|
83
|
+
@char = char
|
84
|
+
@color = color
|
85
|
+
end
|
86
|
+
|
87
|
+
def move (dx, dy)
|
88
|
+
#move by the given amount, if the destination.equal? not blocked
|
89
|
+
if not $map[@x + dx][@y + dy].blocked
|
90
|
+
@x += dx
|
91
|
+
@y += dy
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def draw
|
96
|
+
#only show if it's visible to the $player
|
97
|
+
if TCOD.map_is_in_fov($fov_map, @x, @y)
|
98
|
+
#set the color and then draw the character that represents this object at its position
|
99
|
+
TCOD.console_set_default_foreground($con, @color)
|
100
|
+
TCOD.console_put_char($con, @x, @y, @char.ord, TCOD::BKGND_NONE)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def clear
|
105
|
+
#erase the character that represents this object
|
106
|
+
TCOD.console_put_char($con, @x, @y, ' '.ord, TCOD::BKGND_NONE)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_room(room)
|
111
|
+
#go through the tiles in the rectangle and make them passable
|
112
|
+
p "#{room.x1}, #{room.x2}, #{room.y1}, #{room.y2}"
|
113
|
+
(room.x1 + 1 ... room.x2).each do |x|
|
114
|
+
(room.y1 + 1 ... room.y2).each do |y|
|
115
|
+
$map[x][y].blocked = false
|
116
|
+
$map[x][y].block_sight = false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def create_h_tunnel(x1, x2, y)
|
122
|
+
#horizontal tunnel. min() and max() are used in case x1>x2
|
123
|
+
([x1,x2].min ... [x1,x2].max + 1).each do |x|
|
124
|
+
$map[x][y].blocked = false
|
125
|
+
$map[x][y].block_sight = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def create_v_tunnel(y1, y2, x)
|
130
|
+
#vertical tunnel
|
131
|
+
([y1,y2].min ... [y1,y2].max + 1).each do |y|
|
132
|
+
$map[x][y].blocked = false
|
133
|
+
$map[x][y].block_sight = false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def make_map
|
138
|
+
# fill $map with "blocked" tiles
|
139
|
+
#$map = [[0]*MAP_HEIGHT]*MAP_WIDTH
|
140
|
+
$map = []
|
141
|
+
0.upto(MAP_WIDTH-1) do |x|
|
142
|
+
$map.push([])
|
143
|
+
0.upto(MAP_HEIGHT-1) do |y|
|
144
|
+
$map[x].push(Tile.new(true))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
rooms = []
|
149
|
+
num_rooms = 0
|
150
|
+
|
151
|
+
0.upto(MAX_ROOMS) do |r|
|
152
|
+
#random width and height
|
153
|
+
w = TCOD.random_get_int(nil, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
|
154
|
+
h = TCOD.random_get_int(nil, ROOM_MIN_SIZE, ROOM_MAX_SIZE)
|
155
|
+
#random position without going out of the boundaries of the $map
|
156
|
+
x = TCOD.random_get_int(nil, 0, MAP_WIDTH - w - 1)
|
157
|
+
y = TCOD.random_get_int(nil, 0, MAP_HEIGHT - h - 1)
|
158
|
+
|
159
|
+
|
160
|
+
#"Rect" class makes rectangles easier to work with
|
161
|
+
new_room = Rect.new(x, y, w, h)
|
162
|
+
|
163
|
+
#run through the other rooms and see if they intersect with this one
|
164
|
+
failed = false
|
165
|
+
rooms.each do |other_room|
|
166
|
+
if new_room.intersect(other_room)
|
167
|
+
failed = true
|
168
|
+
break
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
unless failed
|
173
|
+
#this means there are no intersections, so this room.equal? valid
|
174
|
+
|
175
|
+
#"paint" it to the $map's tiles
|
176
|
+
create_room(new_room)
|
177
|
+
|
178
|
+
#center coordinates of new room, will be useful later
|
179
|
+
new_x, new_y = new_room.center
|
180
|
+
|
181
|
+
|
182
|
+
#there's a 30% chance of placing a skeleton slightly off to the center of this room
|
183
|
+
if TCOD.random_get_int(nil, 1, 100) <= 30
|
184
|
+
skeleton = Obj.new(new_x + 1, new_y, SKELETON_TILE, TCOD::Color::LIGHT_YELLOW)
|
185
|
+
$objects.push(skeleton)
|
186
|
+
end
|
187
|
+
|
188
|
+
if num_rooms == 0
|
189
|
+
#this.equal? the first room, where the $player starts at
|
190
|
+
$player.x = new_x
|
191
|
+
$player.y = new_y
|
192
|
+
else
|
193
|
+
#all rooms after the first
|
194
|
+
#connect it to the previous room with a tunnel
|
195
|
+
|
196
|
+
#center coordinates of previous room
|
197
|
+
prev_x, prev_y = rooms[num_rooms-1].center()
|
198
|
+
|
199
|
+
#draw a coin(random number that.equal? either 0 or 1)
|
200
|
+
if TCOD.random_get_int(nil, 0, 1) == 1
|
201
|
+
#first move horizontally, then vertically
|
202
|
+
create_h_tunnel(prev_x, new_x, prev_y)
|
203
|
+
create_v_tunnel(prev_y, new_y, new_x)
|
204
|
+
else
|
205
|
+
#first move vertically, then horizontally
|
206
|
+
create_v_tunnel(prev_y, new_y, prev_x)
|
207
|
+
create_h_tunnel(prev_x, new_x, new_y)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
#finally, append the new room to the list
|
212
|
+
rooms.push(new_room)
|
213
|
+
num_rooms += 1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
def render_all
|
220
|
+
if $fov_recompute
|
221
|
+
#recompute FOV if needed(the $player moved or something)
|
222
|
+
$fov_recompute = false
|
223
|
+
TCOD.map_compute_fov($fov_map, $player.x, $player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO)
|
224
|
+
|
225
|
+
#go through all tiles, and set their background color according to the FOV
|
226
|
+
0.upto(MAP_HEIGHT-1) do |y|
|
227
|
+
0.upto(MAP_WIDTH-1) do |x|
|
228
|
+
visible = TCOD.map_is_in_fov($fov_map, x, y)
|
229
|
+
wall = $map[x][y].block_sight
|
230
|
+
if not visible
|
231
|
+
#if it's not visible right now, the $player can only see it if it's explored
|
232
|
+
if $map[x][y].explored
|
233
|
+
if wall
|
234
|
+
TCOD.console_put_char_ex($con, x, y, WALL_TILE.ord, TCOD::Color::WHITE * 0.5, TCOD::Color::BLACK)
|
235
|
+
else
|
236
|
+
TCOD.console_put_char_ex($con, x, y, ' '.ord, TCOD::Color::BLACK, GROUND_COLOR * 0.5)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
else
|
240
|
+
#it's visible
|
241
|
+
if wall
|
242
|
+
TCOD.console_put_char_ex($con, x, y, WALL_TILE.ord, TCOD::Color::WHITE, TCOD::Color::BLACK)
|
243
|
+
else
|
244
|
+
TCOD.console_put_char_ex($con, x, y, ' '.ord, TCOD::Color::BLACK, GROUND_COLOR)
|
245
|
+
end
|
246
|
+
#since it's visible, explore it
|
247
|
+
$map[x][y].explored = true
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
#draw all objects in the list
|
254
|
+
$objects.each do |object|
|
255
|
+
object.draw()
|
256
|
+
end
|
257
|
+
|
258
|
+
#blit the contents of "con" to the root console
|
259
|
+
TCOD.console_blit($con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, nil, 0, 0, 1.0, 1.0)
|
260
|
+
end
|
261
|
+
|
262
|
+
def handle_keys
|
263
|
+
#key = TCOD.console_check_for_keypress() #real-time
|
264
|
+
key = TCOD.console_wait_for_keypress(true) #turn-based
|
265
|
+
|
266
|
+
if key.vk == TCOD::KEY_ENTER and key.lalt
|
267
|
+
#Alt+Enter: toggle fullscreen
|
268
|
+
TCOD.console_set_fullscreen(!TCOD.console_is_fullscreen)
|
269
|
+
elsif key.vk == TCOD::KEY_ESCAPE
|
270
|
+
return true #exit game
|
271
|
+
end
|
272
|
+
|
273
|
+
#movement keys
|
274
|
+
if TCOD.console_is_key_pressed(TCOD::KEY_UP)
|
275
|
+
$player.move(0, -1)
|
276
|
+
$fov_recompute = true
|
277
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_DOWN)
|
278
|
+
$player.move(0, 1)
|
279
|
+
$fov_recompute = true
|
280
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_LEFT)
|
281
|
+
$player.move(-1, 0)
|
282
|
+
$fov_recompute = true
|
283
|
+
elsif TCOD.console_is_key_pressed(TCOD::KEY_RIGHT)
|
284
|
+
$player.move(1, 0)
|
285
|
+
$fov_recompute = true
|
286
|
+
end
|
287
|
+
false
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
#############################################
|
292
|
+
# Initialization & Main Loop
|
293
|
+
#############################################
|
294
|
+
|
295
|
+
#note that we must specify the number of tiles on the font, which was enlarged a bit
|
296
|
+
TCOD.console_set_custom_font('oryx_tiles.png', TCOD::FONT_TYPE_GREYSCALE | TCOD::FONT_LAYOUT_TCOD, 32, 12)
|
297
|
+
TCOD.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'python/TCOD tutorial', false, TCOD::RENDERER_SDL)
|
298
|
+
TCOD.sys_set_fps(LIMIT_FPS)
|
299
|
+
$con = TCOD.console_new(SCREEN_WIDTH, SCREEN_HEIGHT)
|
300
|
+
|
301
|
+
|
302
|
+
TCOD.console_map_ascii_codes_to_font(256, 32, 0, 5) #$map all characters in 1st row
|
303
|
+
TCOD.console_map_ascii_codes_to_font(256+32, 32, 0, 6) #$map all characters in 2nd row
|
304
|
+
|
305
|
+
|
306
|
+
#create object representing the $player
|
307
|
+
$player = Obj.new(0, 0, MAGE_TILE, TCOD::Color::WHITE)
|
308
|
+
|
309
|
+
#the list of objects with just the $player
|
310
|
+
$objects = [$player]
|
311
|
+
|
312
|
+
#generate $map(at this point it's not drawn to the screen)
|
313
|
+
make_map()
|
314
|
+
|
315
|
+
#create the FOV $map, according to the generated $map
|
316
|
+
$fov_map = TCOD.map_new(MAP_WIDTH, MAP_HEIGHT)
|
317
|
+
0.upto(MAP_HEIGHT-1) do |y|
|
318
|
+
0.upto(MAP_WIDTH-1) do |x|
|
319
|
+
TCOD.map_set_properties($fov_map, x, y, !$map[x][y].block_sight, !$map[x][y].blocked)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
$fov_recompute = true
|
325
|
+
|
326
|
+
until TCOD.console_is_window_closed()
|
327
|
+
|
328
|
+
#render the screen
|
329
|
+
render_all()
|
330
|
+
|
331
|
+
TCOD.console_flush()
|
332
|
+
|
333
|
+
#erase all objects at their old locations, before they move
|
334
|
+
$objects.each do |object|
|
335
|
+
object.clear()
|
336
|
+
end
|
337
|
+
|
338
|
+
#handle keys and exit game if needed
|
339
|
+
will_exit = handle_keys()
|
340
|
+
break if will_exit
|
341
|
+
end
|