Class: MyWindow

Inherits:
Gosu::Window
  • Object
show all
Defined in:
lib/tumblr-game/gosu.rb

Overview

MY WINDOW CLASS. This class is the main workhorse class of the game. It maintains all of the objects and variables associated with the game, as well as rendering the window and allowing the user to interface with the tiles through picking. Each function is described in a comment block above the function declaration.

Constant Summary collapse

LTOP_COLOR =

constants that will represent the background color for the window when the user loses

Gosu::Color.new(255, 225, 100, 100)
LBOTTOM_COLOR =
Gosu::Color.new(255, 200, 125, 125)
WTOP_COLOR =

constants that will represent the background color for the window when the user wins

Gosu::Color.new(255, 100, 225, 100)
WBOTTOM_COLOR =
Gosu::Color.new(255, 125, 225, 125)
TOP_COLOR =

constants that will represent the background color for the window

Gosu::Color.new(255, 44, 71, 98)
BOTTOM_COLOR =
Gosu::Color.new(255, 125, 125, 125)

Instance Method Summary collapse

Constructor Details

#initialize(w, h) ⇒ MyWindow

Returns a new instance of MyWindow.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
115
116
117
118
# File 'lib/tumblr-game/gosu.rb', line 24

def initialize(w, h)

 ## define variables for the width and height of the window
 @width = w
 @height = h  
 
 ## variables for WIN or LOSE state
 @win = false
 @lose = false  
 
 ## initialize the window and caption it
 super(@width, @height, false) 
 self.caption = 'Tumblr Image Match!'
 
 ## define a variable that indicates what state the game is in
 # when phase = 0, that indicates that the user is in the "picking" stage of the game and is selecting a face down card for an
 # initial guess
 # when phase = 1, that indicates that the user is in the "matching" stage of the game and is selecting another card to see if it
 # matches the previous one. after the user clicks the mouse, the images will be shown and then they will be left face up if they match,
 # otherwise both cards will go back to facedown. phase is always set to 0 after this stage.
 @phase = 0
 @frameCounter = 0
 
 ## define two variables that indicates the ID of the first card that was selected when phase was 0 and the ID of the second card selected when 
 # phase = 1
 @picked = 0
 @picked2 = 0
 
 # variable that indicates the second card was actually picked
 @pickedSecond = false
	
 ## initialize a Timer object that will keep track of the time remaining for the given game
 # also create a Gosu font object that will be passed to the Timer object
 font = Gosu::Font.new(self, Gosu::default_font_name, 20)
 @timer = Timer.new(font, @width/2, @height/2, 30)
 
 ## create a font for the end of the game, either win or lose
 @endFont = Gosu::Font.new(self, Gosu::default_font_name, 20)

 # create a pseudorandom number generator for shuffling
 prng = Random.new(Random.new_seed())
 
 # create a hash of the image names that we are using along with their associated id
 imgNames = Hash[
 	File.join(Dir.home, 'Desktop/image1.png') => 0,
 	File.join(Dir.home, 'Desktop/image2.png') => 1,
 	File.join(Dir.home, 'Desktop/image3.png') => 2,
 	File.join(Dir.home, 'Desktop/image4.png') => 3,
 	File.join(Dir.home, 'Desktop/image5.png') => 4,
 	File.join(Dir.home, 'Desktop/image6.png') => 0,
 	File.join(Dir.home, 'Desktop/image7.png') => 1,
 	File.join(Dir.home, 'Desktop/image8.png') => 2,
 	File.join(Dir.home, 'Desktop/image9.png') => 3,
 	File.join(Dir.home, 'Desktop/image10.png') => 4 ]
 
 ## Durstenfield's Shuffling Algorithm 
 # convert the hash from above into a two-dimensional array that will be shuffled in order to
 # randomize the appearance of the images on the board
 imgArr = imgNames.to_a
 for i in(9).downto(1)
   j = prng.rand(i)
   tempK = imgArr[i][0]
   tempV = imgArr[i][1]
   imgArr[i][0] = imgArr[j][0]
   imgArr[i][1] = imgArr[j][1]
   imgArr[j][0] = tempK
   imgArr[j][1] = tempV
 end
 
 # create the Gosu images so they can be put in to each Tile object
 chk = Gosu::Image.new(self, File.join(File.dirname(File.expand_path('../..', __FILE__)), '/resources/check.png'), true)      # completion image
 img0 = Gosu::Image.new(self, File.join(File.dirname(File.expand_path('../..', __FILE__)), '/resources/tumblr.png'), true)    # the back of each card
 img1 = Gosu::Image.new(self, imgArr[0][0], true)
 img2 = Gosu::Image.new(self, imgArr[1][0], true)
 img3 = Gosu::Image.new(self, imgArr[2][0], true)
 img4 = Gosu::Image.new(self, imgArr[3][0], true)
 img5 = Gosu::Image.new(self, imgArr[4][0], true)
 img6 = Gosu::Image.new(self, imgArr[5][0], true)
 img7 = Gosu::Image.new(self, imgArr[6][0], true)
 img8 = Gosu::Image.new(self, imgArr[7][0], true)
 img9 = Gosu::Image.new(self, imgArr[8][0], true)
 img10 = Gosu::Image.new(self, imgArr[9][0], true)
 
 # initialize the game board with the tile objects
 @game_board = Board.new( Tile.new(img1, 0, 0, img0, imgArr[0][1], chk), 
 							Tile.new(img2, 250, 0, img0, imgArr[1][1], chk), 
 							Tile.new(img3, 500, 0, img0, imgArr[2][1], chk), 
 							Tile.new(img4, 750, 0, img0, imgArr[3][1], chk), 
 							Tile.new(img5, 1000, 0, img0, imgArr[4][1], chk), 
 							Tile.new(img6, 0, 500, img0, imgArr[5][1], chk), 
 							Tile.new(img7, 250, 500, img0, imgArr[6][1], chk), 
 							Tile.new(img8, 500, 500, img0, imgArr[7][1], chk), 
 							Tile.new(img9, 750, 500, img0, imgArr[8][1], chk), 
 							Tile.new(img10, 1000, 500, img0, imgArr[9][1], chk) )
end

Instance Method Details

#check_matchObject

the check_match function will be called after the the frameCounter has reached a certain point. this function will check if the two tiles that have been selected match. it will compare the strings that determine each tile’s id. if the strings are the same then the two tiles match; the strings are the path to that tile’s main image. if the strings do not match then the tiles are flipped over and the game is set back to phase 0.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/tumblr-game/gosu.rb', line 285

def check_match
	if @phase == 1 and @pickedSecond == true
		# check if they match
		if(@game_board.get_id(@picked) == @game_board.get_id(@picked2))
			@game_board.matchTile(@picked)
			@game_board.matchTile(@picked2)
      
      # increment match counter
      @game_board.inc_match
		else
			# flip the tiles 
			@game_board.flip_tile(@picked, false)
			@game_board.flip_tile(@picked2, false)
		end
		@pickedSecond = false
		@phase = 0
	end
end

#check_winObject

this function is called at the end of the display period for images. since pictures display for a few seconds before flipping over again, this function will allow the user to win if they flip over the last pair when the time left is less than the display period.



340
341
342
343
344
345
346
347
# File 'lib/tumblr-game/gosu.rb', line 340

def check_win
  if @game_board.return_count == 5 and @timer.return_time >= 0
    @win = true
  end
  if @game_board.return_count < 5 and @timer.return_time == 0
    @lose = true
  end
end

#drawObject

draw function. this function will draw one of the three backgrounds for the game. if the game is in the LOSE state, if the time has run out and the player has not matched 5 tiles, the player loses. if the player matches 5 tiles before the time runs out, then they win. else, the regular game board is drawn for the user to play on. when the user wins or loses, that screen is displayed for 120 frames and the window calls its close function to exit properly



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/tumblr-game/gosu.rb', line 147

def draw
  if (!@win and @lose) or (@frameCounter == 0 and @game_board.return_count < 5 and @timer.return_time == 0)
    draw_lose
  elsif (@win and !@lose)
    draw_win
  elsif (!@win and !@lose)
    draw_background
    @game_board.draw_board
    @timer.draw  
  end
end

#draw_backgroundObject

function that will be used to draw a blue background with a slight gradient towards the bottom



310
311
312
313
314
315
316
# File 'lib/tumblr-game/gosu.rb', line 310

def draw_background
    draw_quad( 0, 0, TOP_COLOR,
               @width, 0, TOP_COLOR,
               0, @height, BOTTOM_COLOR,
               @width, @height, BOTTOM_COLOR,
               -1 )
end

#draw_loseObject

function that draws the background and losing font when the users loses the game



329
330
331
332
333
334
335
336
# File 'lib/tumblr-game/gosu.rb', line 329

def draw_lose
  draw_quad( 0, 0, LTOP_COLOR,
             @width, 0, LTOP_COLOR,
             0, @height, LBOTTOM_COLOR,
             @width, @height, LBOTTOM_COLOR,
             -1 )
  @endFont.draw("You lose...", @width/2 - 150, @height/2, 0, 4, 4, 0xFFFFFFFF)
end

#draw_winObject

function that draws the background and winning font when the user wins the game



319
320
321
322
323
324
325
326
# File 'lib/tumblr-game/gosu.rb', line 319

def draw_win
  draw_quad( 0, 0, WTOP_COLOR,
             @width, 0, WTOP_COLOR,
             0, @height, WBOTTOM_COLOR,
             @width, @height, WBOTTOM_COLOR,
             -1 )
  @endFont.draw("You win!", @width/2 - 150, @height/2, 0, 4, 4, 0xFFFFFFFF)
end

#needs_cursor?Boolean

this function specifies that the cursor should be displayed when it is inside the main gosu window

Returns:

  • (Boolean)


305
306
307
# File 'lib/tumblr-game/gosu.rb', line 305

def needs_cursor?
	true
end

#pick_tilesObject

pick_tiles function this function has two parts. if the game is in phase 0, the user is picking an initial tile. the function will check the location of the user’s mouse and flip the appropriate tile and keep track of which tile was flipped. then, the game is set to phase 1. in phase 1, the user is picking the tile they want to match with the first one. if a tile is successfully picked, the pickedSecond variable is set to true and the game stores which tile was picked and flipped.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/tumblr-game/gosu.rb', line 164

def pick_tiles
  if button_down? Gosu::KbEscape then
    close
  end
	if @phase == 0 
		if button_down? Gosu::MsLeft then
			# TILE 1
			if (mouse_x >= 0 and mouse_x <= 250) and (mouse_y >= 0 and mouse_y <= 250) and (!@game_board.is_matched(0)) then
				@game_board.flip_tile(0, true)
				@picked = 0
				@phase = 1
			# TILE 2
			elsif (mouse_x > 250  and mouse_x <= 500) and (mouse_y >= 0 and mouse_y <= 250) and (!@game_board.is_matched(1)) then
				@game_board.flip_tile(1, true)
				@picked = 1
				@phase = 1
			# TILE 3
			elsif (mouse_x > 500  and mouse_x <= 750) and (mouse_y >= 0 and mouse_y <= 250) and (!@game_board.is_matched(2)) then
				@game_board.flip_tile(2, true)
				@picked = 2
				@phase = 1
			# TILE 4
			elsif (mouse_x > 750  and mouse_x <= 1000) and (mouse_y >= 0 and mouse_y <= 250) and (!@game_board.is_matched(3))then
				@game_board.flip_tile(3, true)
				@picked = 3
				@phase = 1
			# TILE 5
			elsif (mouse_x > 1000  and mouse_x <= 1250) and (mouse_y >= 0 and mouse_y <= 250) and (!@game_board.is_matched(4)) then
				@game_board.flip_tile(4, true)
				@picked = 4
				@phase = 1
			# TILE 6
			elsif (mouse_x >= 0 and mouse_x <= 250) and (mouse_y > 500 and mouse_y <= 750) and (!@game_board.is_matched(5)) then
				@game_board.flip_tile(5, true)
				@picked = 5
				@phase = 1
			# TILE 7
			elsif (mouse_x > 250  and mouse_x <= 500) and (mouse_y > 500 and mouse_y <= 750) and (!@game_board.is_matched(6)) then
				@game_board.flip_tile(6, true)
				@picked = 6
				@phase = 1
			# TILE 8
			elsif (mouse_x > 500  and mouse_x <= 750) and (mouse_y > 500 and mouse_y <= 750) and (!@game_board.is_matched(7)) then
				@game_board.flip_tile(7, true)
				@picked = 7
				@phase = 1
			# TILE 9
			elsif (mouse_x > 750  and mouse_x <= 1000) and (mouse_y > 500 and mouse_y <= 750) and (!@game_board.is_matched(8)) then
				@game_board.flip_tile(8, true)
				@picked = 8
				@phase = 1
			# TILE 10
			elsif (mouse_x > 1000  and mouse_x <= 1250) and (mouse_y > 500 and mouse_y <= 750) and (!@game_board.is_matched(9)) then
				@game_board.flip_tile(9, true)
				@picked = 9
				@phase = 1
			end
			sleep(0.2) # needs delay because gosu's mouse click event seems to be hyper sensitive and picks up multiple clicks instead of 1
		end
	else @phase == 1
		if button_down? Gosu::MsLeft then
  		# TILE 1
			if (mouse_x >= 0 and mouse_x <= 250) and (mouse_y >= 0 and mouse_y <= 250) and (@picked != 0) and (!@game_board.is_matched(0)) then
				@game_board.flip_tile(0, true)
				@picked2 = 0
				@pickedSecond = true
			# TILE 2
			elsif (mouse_x > 250  and mouse_x <= 500) and (mouse_y >= 0 and mouse_y <= 250) and (@picked != 1) and (!@game_board.is_matched(1)) then
				@game_board.flip_tile(1, true)
				@picked2 = 1
				@pickedSecond = true
			# TILE 3
			elsif (mouse_x > 500  and mouse_x <= 750) and (mouse_y >= 0 and mouse_y <= 250) and (@picked != 2) and (!@game_board.is_matched(2)) then
				@game_board.flip_tile(2, true)
				@picked2 = 2
				@pickedSecond = true
			# TILE 4
			elsif (mouse_x > 750  and mouse_x <= 1000) and (mouse_y >= 0 and mouse_y <= 250) and (@picked != 3) and (!@game_board.is_matched(3)) then
				@game_board.flip_tile(3, true)
				@picked2 = 3
				@pickedSecond = true
			# TILE 5
			elsif (mouse_x > 1000  and mouse_x <= 1250) and (mouse_y >= 0 and mouse_y <= 250) and (@picked != 4) and (!@game_board.is_matched(4)) then
				@game_board.flip_tile(4, true)
				@picked2 = 4
				@pickedSecond = true
			# TILE 6
			elsif (mouse_x >= 0 and mouse_x <= 250) and (mouse_y > 500 and mouse_y <= 750) and (@picked != 5) and (!@game_board.is_matched(5)) then
				@game_board.flip_tile(5, true)
				@picked2 = 5
				@pickedSecond = true
			# TILE 7
			elsif (mouse_x > 250  and mouse_x <= 500) and (mouse_y > 500 and mouse_y <= 750) and (@picked != 6) and (!@game_board.is_matched(6)) then
				@game_board.flip_tile(6, true)
				@picked2 = 6
				@pickedSecond = true
			# TILE 8
			elsif (mouse_x > 500  and mouse_x <= 750) and (mouse_y > 500 and mouse_y <= 750) and (@picked != 7) and (!@game_board.is_matched(7)) then
				@game_board.flip_tile(7, true)
				@picked2 = 7
				@pickedSecond = true
			# TILE 9
			elsif (mouse_x > 750  and mouse_x <= 1000) and (mouse_y > 500 and mouse_y <= 750) and (@picked != 8) and (!@game_board.is_matched(8)) then
				@game_board.flip_tile(8, true)
				@picked2 = 8
				@pickedSecond = true
			# TILE 10
			elsif (mouse_x > 1000  and mouse_x <= 1250) and (mouse_y > 500 and mouse_y <= 750) and (@picked != 9) and (!@game_board.is_matched(9)) then
				@game_board.flip_tile(9, true)
				@picked2 = 9
				@pickedSecond = true
			end
	sleep(0.2) # needs delay because gosu's mouse click event seems to be hyper sensitive and picks up multiple clicks instead of 1
		end
	end
end

#updateObject

update function. this function contains all of the game logic



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/tumblr-game/gosu.rb', line 121

def update
	## only allow the user to pick tiles if the frameCounter is at 0
	# this means that the user can only pick tiles when two tiles are not being displayed
	# after the 96 frames of display are over, we then call the check_match function and set the frameCounter back to 0 
  
  if @frameCounter == 0 then 
		pick_tiles	
	elsif @frameCounter == 96 then
		check_match
    check_win
	 	@frameCounter = 0
	end
	
	## if the user has picked their second tile then we increment the frame counter to display both of them for a few seconds
	if @phase == 1 and @pickedSecond then
	 @frameCounter += 1
	end
  
  ## update the Timer object
  @timer.update
end