diff options
| -rw-r--r-- | main.rb | 109 |
1 files changed, 89 insertions, 20 deletions
@@ -5,21 +5,47 @@ WHITE = Color.new(r: 255, g: 255, b: 255, a: 255) BLACK = Color.new(r: 0, g: 0, b: 0, a: 255) GRAY = Color.new(r: 100, g: 100, b: 100, a: 255) -screen_width = 800 -screen_height = 450 -init_window(width: screen_width, height: screen_height, title: "Card Example Thingie") +CardWidth = 80 +CardHeight = (CardWidth * (4.0/3.0)).to_i + +# By how many steps to subdivide +# more can be smoother but needs more time to process +SmoothenSteps = 3 + +ScreenWidth = 900 +ScreenHeight = 650 + +# how far the border is from the edge of the screen +ScreenBorder = 60 +ScreenBorderThickness = 5 + +# visual game border +BorderRec = Rectangle.new( + x: ScreenBorder - ScreenBorderThickness, + y: ScreenBorder - ScreenBorderThickness, + width: ScreenWidth - ((ScreenBorder - ScreenBorderThickness) * 2), + height: ScreenHeight - ((ScreenBorder - ScreenBorderThickness) * 2), +) + +# Card arena limits +MaxCardHeight = ScreenBorder +MinCardHeight = ScreenHeight - ScreenBorder - CardHeight +MaxCardWidth = ScreenBorder +MinCardWidth = ScreenWidth - ScreenBorder - CardWidth + +init_window(width: ScreenWidth, height: ScreenHeight, title: "Card Example Thingie") Test.target_fps = 60 DefaultOrigin = Vector2.new(x: 0, y: 0) class Card # size of cards - Width = 80 - Height = (Width * (4.0/3.0)).to_i + Width = CardWidth + Height = CardHeight # list of valid coordinates a card can spawn - ValidSpawnRange = [(0..(800-Card::Width)).to_a, (0..(450-Card::Height)).to_a] + ValidSpawnRange = [(ScreenBorder..(ScreenWidth-Card::Width-ScreenBorder)).to_a, (ScreenBorder..(ScreenHeight-Card::Height-ScreenBorder)).to_a] # stores any new cards that are created Objects = [] @@ -27,7 +53,7 @@ class Card # stores groups of cards that are overlapping Resolver = [] - attr_accessor :rec, :text, :color, :dragged + attr_accessor :rec, :text, :color, :dragged, :momentum def initialize(rec: Rectangle.new(x: ValidSpawnRange[0].sample, y: ValidSpawnRange[1].sample, width: Card::Width, height: Card::Height), text: "New Card", @@ -36,6 +62,7 @@ class Card self.text = text self.color = color self.dragged = false + self.momentum = [0.0, 0.0] Card::Objects.push self end @@ -66,12 +93,22 @@ class Card end # if holding click -> check which one is being clicked -> drag it elsif mouse_button_down?(0) && self.card_dragged - card_dragged.rec = Rectangle.new(x: (self.card_offset[0] + mouse_x), y: (self.card_offset[1] + mouse_y), width: card_dragged.rec.width, height: card_dragged.rec.height) + card_dragged.rec = Rectangle.new( + x: (self.card_offset[0] + mouse_x).clamp(MaxCardWidth, MinCardWidth), + y: (self.card_offset[1] + mouse_y).clamp(MaxCardHeight, MinCardHeight), + width: card_dragged.rec.width, + height: card_dragged.rec.height, + ) # if let go of click -> remove click state elsif mouse_button_up?(0) && self.card_dragged #card_dragged.rec.x = self.card_offset[0] + mouse_x #card_dragged.rec.y = self.card_offset[1] + mouse_y - card_dragged.rec = Rectangle.new(x: (self.card_offset[0] + mouse_x), y: (self.card_offset[1] + mouse_y), width: card_dragged.rec.width, height: card_dragged.rec.height) + card_dragged.rec = Rectangle.new( + x: (self.card_offset[0] + mouse_x).clamp(MaxCardWidth, MinCardWidth), + y: (self.card_offset[1] + mouse_y).clamp(MaxCardHeight, MinCardHeight), + width: card_dragged.rec.width, + height: card_dragged.rec.height, + ) Resolver.push [card_dragged] self.card_dragged.dragged = false self.card_dragged = false @@ -82,16 +119,18 @@ class Card def check_overlap # check overlaps if !Resolver.empty? - old_resolver = Resolver.inject(:+) + old_resolver = Resolver.flatten Resolver.clear old_resolver.each do |colliding_card| + next if colliding_card.dragged Resolver.push [] Card::Objects.each do |card| - next if card == colliding_card + next if (card == colliding_card) || card.dragged if check_collision_recs(rec1: card.rec, rec2: colliding_card.rec) old_resolver.delete card Resolver.last.push colliding_card unless Resolver.last.include? colliding_card Resolver.last.push card + recurse_check(card, old_resolver) end end Resolver.pop if Resolver.last.empty? @@ -99,9 +138,20 @@ class Card end end + def recurse_check(colliding_card, old_resolver) + Card::Objects.each do |card| + next if (card == colliding_card) || card.dragged || (Resolver.last.include? card) + if check_collision_recs(rec1: card.rec, rec2: colliding_card.rec) + old_resolver.delete card + Resolver.last.push colliding_card unless Resolver.last.include? colliding_card + Resolver.last.push card + recurse_check(card, old_resolver) + end + end + end + def resolve_overlap if !Resolver.empty? - Resolver.each do |segment| center = [0.0, 0.0] segment.each do |card| @@ -118,9 +168,22 @@ class Card dir[0] = dir[0] / Math.sqrt((dir[0] ** 2) + (dir[1] ** 2)) dir[1] = dir[1] / Math.sqrt((dir[0] ** 2) + (dir[1] ** 2)) + # smoothens out the movement + card.momentum[0] += dir[0] + card.momentum[1] += dir[1] + card.momentum[0] /= SmoothenSteps.to_f + card.momentum[1] /= SmoothenSteps.to_f + + dest = [ + (card.rec.x + card.momentum[0]).clamp(MaxCardWidth, MinCardWidth), + (card.rec.y + card.momentum[1]).clamp(MaxCardHeight, MinCardHeight), + ] + + + card.rec = Rectangle.new( - x: card.rec.x + dir[0], - y: card.rec.y + dir[1], + x: dest[0],#card.rec.x + dir[0], + y: dest[1],#card.rec.y + dir[1], width: card.rec.width, height: card.rec.height, ) @@ -141,8 +204,10 @@ end ColorRange = (0..255).to_a -('A'..'E').each do |letter| - Card.new(text: letter, color: Color.new(r: ColorRange.sample, g: ColorRange.sample, b: ColorRange.sample, a: 255)) +CardNames = ('A'..'ZZ').to_a.reverse + +15.times do + Card.new(text: CardNames.pop, color: Color.new(r: ColorRange.sample, g: ColorRange.sample, b: ColorRange.sample, a: 255)) end while !window_should_close do @@ -150,12 +215,16 @@ while !window_should_close do clear_background(WHITE) + draw_rectangle_lines_ex(rec: BorderRec, line_thick: 5, color: BLACK) + + SmoothenSteps.times do + Card.resolve_drag + Card.check_overlap + Card.resolve_overlap + end Card.draw - Card.resolve_drag - Card.check_overlap - Card.resolve_overlap - #draw_text(text: "Congrats! You created your first window!", pos_x: 190, pos_y: 200, font_size: 20, color: GRAY) + draw_fps(pos_x: 10, pos_y: 10) end_drawing end |
