Class: MiniGL::Sprite

Inherits:
Object
  • Object
show all
Defined in:
lib/minigl/game_object.rb

Overview

This class represents an (optionally animated) image inside the game screen.

Direct Known Subclasses

Effect, GameObject

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, y, img, sprite_cols = nil, sprite_rows = nil, retro = nil) ⇒ Sprite

Creates a new sprite.

Parameters:

x

The x-coordinate in the screen (or map) where the sprite will be drawn. This can be modified later via the x attribute.

y

The y-coordinate in the screen (or map) where the sprite will be drawn. This can be modified later via the y attribute.

img

The path to a PNG image or spritesheet, following the MiniGL convention: images must be inside a ‘data/img’ directory, relative to the code file, and you must only provide the file name, without extension, in this case. If the image is inside a subdirectory of ‘data/img’, you must prefix the file name with each subdirectory name, followed by an underscore (so the file and directories names must not contain underscores). For example, if your image is ‘data/img/sprite/1.png’, you must provide "sprite_1" or :sprite_1.

sprite_cols

The number of columns in the spritesheet. Use nil if the image is not a spritesheet.

sprite_rows

The number of rows in the spritesheet. Use nil if the image is not a spritesheet.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/minigl/game_object.rb', line 38

def initialize(x, y, img, sprite_cols = nil, sprite_rows = nil, retro = nil)
  @x = x; @y = y
  retro = Res.retro_images if retro.nil?
  @img =
    if sprite_cols.nil?
      [Res.img(img, false, false, '.png', retro)]
    else
      Res.imgs img, sprite_cols, sprite_rows, false, '.png', retro
    end
  @anim_counter = 0
  @img_index = 0
  @index_index = 0
  @animate_once_control = 0
end

Instance Attribute Details

#imgObject (readonly)

The list of images of this sprite (i.e. the spritesheet).



7
8
9
# File 'lib/minigl/game_object.rb', line 7

def img
  @img
end

#img_indexObject (readonly)

The index of the current sprite in the spritesheet being drawn.



10
11
12
# File 'lib/minigl/game_object.rb', line 10

def img_index
  @img_index
end

#xObject

The x-coordinate of the image in the screen.



13
14
15
# File 'lib/minigl/game_object.rb', line 13

def x
  @x
end

#yObject

The y-coordinate of the image in the screen.



16
17
18
# File 'lib/minigl/game_object.rb', line 16

def y
  @y
end

Instance Method Details

#animate(indices, interval) ⇒ Object

Performs time checking to update the image index according to the sequence of indices and the interval.

Parameters:

indices

The sequence of image indices used in the animation. The indices are determined from left to right, and from top to bottom, inside the spritesheet. All indices must be in the interval 0..(sprite_cols * sprite_rows).

interval

The amount of frames between each change in the image index. A frame will usually represent 1/60 second (roughly 17 milliseconds).



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/minigl/game_object.rb', line 64

def animate(indices, interval)
  @animate_once_control = 0 if @animate_once_control != 0

  @anim_counter += 1
  if @anim_counter >= interval
    @index_index += 1
    @index_index = 0 if @index_index >= indices.length
    @img_index = indices[@index_index]
    @anim_counter = 0
  end
end

#animate_once(indices, interval) ⇒ Object

Causes the sprite to animate through the indices array exactly once, so that the animation stops once it reaches the last index in the array. Subsequent calls with the same parameters will have no effect, but if the index or interval changes, or if set_animation is called, then a new animation cycle will begin.

Parameters:

indices

The sequence of image indices used in the animation. See animate for details.

interval

The amount of frames between each change in the image index. See animate for details.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/minigl/game_object.rb', line 87

def animate_once(indices, interval)
  if @animate_once_control == 2
    return if indices == @animate_once_indices && interval == @animate_once_interval
    @animate_once_control = 0
  end

  unless @animate_once_control == 1
    @anim_counter = 0
    @img_index = indices[0]
    @index_index = 0
    @animate_once_indices = indices
    @animate_once_interval = interval
    @animate_once_control = 1
    return
  end

  @anim_counter += 1
  return unless @anim_counter >= interval

  if @index_index == indices.length - 1
    @animate_once_control = 2
    yield if block_given?
  else
    @index_index += 1
    @img_index = indices[@index_index]
    @anim_counter = 0
  end
end

#draw(map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, flip = nil, z_index = 0, round = false) ⇒ Object

Draws the sprite in the screen

Parameters:

map

A Map object, relative to which the sprite will be drawn (the x and y coordinates of the sprite will be changed according to the position of the camera).

scale_x

A scale factor to be applied horizontally to the image.

scale_y

A scale factor to be applied vertically to the image.

alpha

The opacity with which the image will be drawn. Valid values vary from 0 (fully transparent) to 255 (fully opaque).

color

A color filter to apply to the image. A white (0xffffff) filter will keep all colors unchanged, while a black (0x000000) filter will turn all colors to black. A red (0xff0000) filter will keep reddish colors with slight or no change, whereas bluish colors will be darkened, for example.

angle

A rotation, in degrees, to be applied to the image, relative to its center.

flip

Specify :horiz to draw the image horizontally flipped or :vert to draw it vertically flipped.

z_index

The z-order to draw the object. Objects with larger z-orders will be drawn on top of the ones with smaller z-orders.

round

Specify whether the drawing coordinates should be rounded to an integer before drawing, to avoid little distortions of the image. Only applies when the image is not rotated.

Obs.: This method accepts named parameters.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/minigl/game_object.rb', line 154

def draw(map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, flip = nil, z_index = 0, round = false)
  if map.is_a? Hash
    scale_x = map.fetch(:scale_x, 1)
    scale_y = map.fetch(:scale_y, 1)
    alpha = map.fetch(:alpha, 0xff)
    color = map.fetch(:color, 0xffffff)
    angle = map.fetch(:angle, nil)
    flip = map.fetch(:flip, nil)
    z_index = map.fetch(:z_index, 0)
    round = map.fetch(:round, false)
    map = map.fetch(:map, nil)
  end

  color = (alpha << 24) | color
  if angle
    @img[@img_index].draw_rot @x - (map ? map.cam.x : 0) + @img[0].width * scale_x * 0.5,
                              @y - (map ? map.cam.y : 0) + @img[0].height * scale_y * 0.5,
                              z_index, angle, 0.5, 0.5, (flip == :horiz ? -scale_x : scale_x),
                              (flip == :vert ? -scale_y : scale_y), color
  else
    x = @x - (map ? map.cam.x : 0) + (flip == :horiz ? scale_x * @img[0].width : 0)
    y = @y - (map ? map.cam.y : 0) + (flip == :vert ? scale_y * @img[0].height : 0)
    @img[@img_index].draw (round ? x.round : x), (round ? y.round : y),
                          z_index, (flip == :horiz ? -scale_x : scale_x),
                          (flip == :vert ? -scale_y : scale_y), color
  end
end

#set_animation(index) ⇒ Object

Resets the animation timer and immediately changes the image index to the specified value.

Parameters:

index

The image index to be set.



121
122
123
124
125
126
# File 'lib/minigl/game_object.rb', line 121

def set_animation(index)
  @anim_counter = 0
  @img_index = index
  @index_index = 0
  @animate_once_control = 0
end

#visible?(map = nil) ⇒ Boolean

Returns whether this sprite is visible in the given map (i.e., in the viewport determined by the camera of the given map). If no map is given, returns whether the sprite is visible on the screen.

Returns:

  • (Boolean)


185
186
187
188
189
# File 'lib/minigl/game_object.rb', line 185

def visible?(map = nil)
  r = Rectangle.new @x, @y, @img[0].width, @img[0].height
  return Rectangle.new(0, 0, G.window.width, G.window.height).intersect? r if map.nil?
  map.cam.intersect? r
end