From eef53251d1f178ccbef7845716d6eb4c014702eb Mon Sep 17 00:00:00 2001 From: Gordon Pedersen Date: Tue, 21 Mar 2023 16:34:34 +1100 Subject: [PATCH] Beginning refactor. Starting with Sprites. Still don't quite know my way around Ruby yet, so it's a learning experience. --- app/main.rb | 32 ++++++------ app/scenes/cube_tube.rb | 49 +++++++----------- app/scenes/main_menu.rb | 1 - app/sprite.rb | 107 ++++++++++++++++++++++++++++++++-------- lib/coalesce.rb | 18 +++++++ 5 files changed, 139 insertions(+), 68 deletions(-) create mode 100644 lib/coalesce.rb diff --git a/app/main.rb b/app/main.rb index 5f27c1b..626b52a 100644 --- a/app/main.rb +++ b/app/main.rb @@ -1,21 +1,23 @@ -require "app/input.rb" -require "app/sprite.rb" -require "app/util.rb" +require 'lib/coalesce.rb' -require "app/constants.rb" -require "app/menu.rb" -require "app/scene.rb" -require "app/game_setting.rb" -require "app/sound.rb" -require "app/text.rb" +require 'app/input.rb' +require 'app/sprite.rb' +require 'app/util.rb' -require "app/scenes/gameplay.rb" -require "app/scenes/main_menu.rb" -require "app/scenes/paused.rb" -require "app/scenes/settings.rb" +require 'app/constants.rb' +require 'app/menu.rb' +require 'app/scene.rb' +require 'app/game_setting.rb' +require 'app/sound.rb' +require 'app/text.rb' -require "app/scenes/cube_tube.rb" +require 'app/scenes/gameplay.rb' +require 'app/scenes/main_menu.rb' +require 'app/scenes/paused.rb' +require 'app/scenes/settings.rb' + +require 'app/scenes/cube_tube.rb' # NOTE: add all requires above this -require "app/tick.rb" +require 'app/tick.rb' diff --git a/app/scenes/cube_tube.rb b/app/scenes/cube_tube.rb index 819a59d..af6e359 100644 --- a/app/scenes/cube_tube.rb +++ b/app/scenes/cube_tube.rb @@ -80,9 +80,9 @@ class CubeTubeGame @bg_x = 0 - each 0..@grid_w - 1 do |x| + (0..@grid_w - 1).each do |x| @grid[x] = [] - each 0..@grid_h - 1 do |y| + (0..@grid_h - 1).each do |y| @grid[x][y] = 0 end end @@ -118,36 +118,27 @@ class CubeTubeGame @bg_x %= @bg_w end - @args.outputs.sprites << [@bg_x,0,@bg_w,720,Sprite.for(:tunnel)] - @args.outputs.sprites << [@bg_x-@bg_w,0,@bg_w,720,Sprite.for(:tunnel)] + Sprite.for(:tunnel).render(@args, { x: @bg_x, y: 0, w: @bg_w, h: 720 }) + Sprite.for(:tunnel).render(@args, { x: @bg_x - @bg_w, y: 0, w: @bg_w, h: 720 }) - @args.outputs.sprites << [ - 0, - @grid_x - 64, - 1597, - 540, - Sprite.for(:train) - ] + Sprite.for(:train).render(@args, { x: 0, y: @grid_x - 64 }) end def render_foreground - @args.outputs.sprites << [ - 0, - @grid_x - 64, - 1597, - 540, - Sprite.for(:train_fore) - ] + Sprite.for(:train_fore).render(@args, { x: 0, y: @grid_x - 64 }) end # x and y are positions in the grid, not pixels def render_block x, y, color - @args.outputs.sprites << [ - (1280 - @grid_y) - (y * @blocksize) - 6, - @grid_x + (x * @blocksize), - @blocksize + 6, @blocksize, - @sprite_index[color] - ] + @sprite_index[color].render( + @args, + { + x: (1280 - @grid_y) - (y * @blocksize) - 6, + y: @grid_x + (x * @blocksize), + w: @blocksize + 6, + h: @blocksize + } + ) end def render_grid @@ -182,10 +173,7 @@ class CubeTubeGame screen_w = 250 screen_h = 200 - @args.outputs.sprites << [ - screen_x, screen_y + 10, screen_w, screen_h + 10, - Sprite.for(:screen) - ] + Sprite.for(:screen).render(@args, { x: screen_x, y: screen_y + 10, w: screen_w, h: screen_h + 10 }) next_piece = @line_clear_timer <= 0 ? @next_piece : @current_piece # render_grid_border *@next_piece_box, 8 @@ -207,10 +195,7 @@ class CubeTubeGame :screen_s4 end - @args.outputs.sprites << [ - screen_x, screen_y + 10, screen_w, screen_h + 10, - Sprite.for(screen_s) - ] + Sprite.for(screen_s).render(@args, { x: screen_x, y: screen_y + 10, w: screen_w, h: screen_h + 10 }) end def render_score diff --git a/app/scenes/main_menu.rb b/app/scenes/main_menu.rb index 5cddb5d..2fc0423 100644 --- a/app/scenes/main_menu.rb +++ b/app/scenes/main_menu.rb @@ -46,6 +46,5 @@ module Scene args.outputs.labels << labels end - end end diff --git a/app/sprite.rb b/app/sprite.rb index 5c1fb2e..a2dccf3 100644 --- a/app/sprite.rb +++ b/app/sprite.rb @@ -1,26 +1,93 @@ module Sprite + # Create type with ALL sprite properties AND primitive_marker + class SpriteInstance + attr_accessor :x, :y, :w, :h, :path, :angle, :a, :r, :g, :b, + :source_x, :source_y, :source_w, :source_h, + :tile_x, :tile_y, :tile_w, :tile_h, + :flip_horizontally, :flip_vertically, + :angle_anchor_x, :angle_anchor_y, :blendmode_enum + + def primitive_marker + :sprite + end + + def initialize opts + @x = opts[:x] + @y = opts[:y] + @w = opts[:w] + @h = opts[:h] + @path = opts[:path] + @angle = opts[:angle] + @a = opts[:a] + @r = opts[:r] + @g = opts[:g] + @b = opts[:b] + @source_x = opts[:source_x] + @source_y = opts[:source_y] + @source_w = opts[:source_w] + @source_h = opts[:source_h] + @tile_x = opts[:tile_x] + @tile_y = opts[:tile_y] + @tile_w = opts[:tile_w] + @tile_h = opts[:tile_h] + @flip_horizontally = opts[:flip_horizontally] + @flip_vertically = opts[:flip_vertically] + @angle_anchor_x = opts[:angle_anchor_x] + @angle_anchor_y = opts[:angle_anchor_y] + @blendmode_enum = opts[:blendmode_enum] + end + + def render(args, opts = {}) + args.outputs.sprites << [ + opts[:x]._?(@x), + opts[:y]._?(@y), + opts[:w]._?(@w), + opts[:h]._?(@h), + opts[:path]._?(@path), + opts[:angle]._?(@angle), + opts[:a]._?(@a), + opts[:r]._?(@r), + opts[:g]._?(@g), + opts[:b]._?(@b), + opts[:source_x]._?(@source_x), + opts[:source_y]._?(@source_y), + opts[:source_w]._?(@source_w), + opts[:source_h]._?(@source_h), + opts[:tile_x]._?(@tile_x), + opts[:tile_y]._?(@tile_y), + opts[:tile_w]._?(@tile_w), + opts[:tile_h]._?(@tile_h), + opts[:flip_horizontally]._?(@flip_horizontally), + opts[:flip_vertically]._?(@flip_vertically), + opts[:angle_anchor_x]._?(@angle_anchor_x), + opts[:angle_anchor_y]._?(@angle_anchor_y), + opts[:blendmode_enum]._?(@blendmode_enum) + ] + end + end + # annoying to track but useful for reloading with +i+ in debug mode; would be # nice to define a different way SPRITES = { - train: 'sprites/train-1.png', - train_fore: 'sprites/train-2.png', - screen: 'sprites/screen.png', - screen_s1: 'sprites/screen-s1.png', - screen_s2: 'sprites/screen-s2.png', - screen_s3: 'sprites/screen-s3.png', - screen_s4: 'sprites/screen-s4.png', - tunnel: 'sprites/tunnel.png', - pause: 'sprites/pause.png', - gray: 'sprites/box/gray.png', - black: 'sprites/box/black.png', - white: 'sprites/box/white.png', - red: 'sprites/box/red.png', - green: 'sprites/box/green.png', - blue: 'sprites/box/blue.png', - yellow: 'sprites/box/yellow.png', - indigo: 'sprites/box/indigo.png', - violet: 'sprites/box/violet.png', - orange: 'sprites/box/orange.png' + train: SpriteInstance.new({ w: 1597, h: 540, path: 'sprites/train-1.png' }), + train_fore: SpriteInstance.new({ w: 1597, h: 540, path: 'sprites/train-2.png' }), + screen: SpriteInstance.new({ w: 250, h: 210, path: 'sprites/screen.png' }), + tunnel: SpriteInstance.new({ w: 267, h: 144, path: 'sprites/tunnel.png' }), + pause: SpriteInstance.new({ w: 16, h: 16, path: 'sprites/pause.png' }), + gray: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/gray.png' }), + black: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/black.png' }), + white: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/white.png' }), + red: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/red.png' }), + green: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/green.png' }), + blue: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/blue.png' }), + yellow: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/yellow.png' }), + indigo: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/indigo.png' }), + violet: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/violet.png' }), + orange: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/orange.png' }), + screen_s1: SpriteInstance.new({ w: 250, h: 210, path: 'sprites/screen-s1.png' }), + screen_s2: SpriteInstance.new({ w: 250, h: 210, path: 'sprites/screen-s2.png' }), + screen_s3: SpriteInstance.new({ w: 250, h: 210, path: 'sprites/screen-s3.png' }), + screen_s4: SpriteInstance.new({ w: 250, h: 210, path: 'sprites/screen-s4.png' }), } class << self @@ -32,5 +99,5 @@ module Sprite SPRITES.fetch(key) end end -end +end \ No newline at end of file diff --git a/lib/coalesce.rb b/lib/coalesce.rb new file mode 100644 index 0000000..752ab2a --- /dev/null +++ b/lib/coalesce.rb @@ -0,0 +1,18 @@ +# Handy null coalesing operator, taken from +# https://github.com/kibiz0r/coalesce/blob/bc4389ae8a8bb456cd10ec8a3523df1fc775124f/lib/coalesce.rb + +class Object + def _?(x = nil) + self + end +end + +class NilClass + def _?(x = nil) + if block_given? + yield + else + x + end + end +end