diff options
Diffstat (limited to 'main.rb')
| -rw-r--r-- | main.rb | 264 |
1 files changed, 264 insertions, 0 deletions
@@ -0,0 +1,264 @@ +GameName = 'Hextest' +Rl.init_window(800, 600, GameName) + +include FECS + +Cmp.new('Shape', :obj) +Cmp.new('ShapeColor', :color) +Cmp.new('BorderColor', :color) + +class Shape + attr_reader :angle, :size, :x, :y, :sides + def initialize(angle: 0, size: 0, x: 0, y: 0, sides: 3) + @sides = sides + @angle = angle + @size = size + @x = x + @y = y + update + end + + def points + @points ||= [] + end + + def sides=(sides) + @sides = sides + self.update + end + + def angle=(angle) + @angle = angle + self.update + end + + def size=(size) + @size = size + self.update + end + + def x=(x) + @x = x + self.update + end + + def y=(y) + @y = y + self.update + end + + private + def update + sides.times do |point_num| + points[point_num] ||= Hash.new + points[point_num][:x] = Math.sin(((point_num/sides.to_f) * Math::PI * 2) - angle) * size + x + points[point_num][:y] = Math.cos(((point_num/sides.to_f) * Math::PI * 2) - angle) * size + y + end + [sides - points.length, 0].max.times do + points.pop # strip extra points + end + end +end + +MouseFollow = Cmp::Shape.new(obj: Shape.new(sides: 3, size: 1)) +Ent.new(MouseFollow) + +Sys.new('InitGrid') do + GameHexArray = Array.new(5) do |x| + Array.new(5) do |y| + x_thingie = 90 + Ent.new( + Cmp::Shape.new( + obj: Shape.new( + x: (x * x_thingie) + (y * (x_thingie/2)) + 150, + y: (y * 50) + (y * 30) + 150, + sides: 6, + size: 50 + ) + ), + Cmp::ShapeColor.new(color: Rl::Color.ray_white), + Cmp::BorderColor.new(color: Rl::Color.dodger_blue) + ) + end + end +end + +Sys::InitGrid.call + +Sys.new('DrawShape') do + Ent.group(Cmp::Shape, Cmp::ShapeColor, Cmp::BorderColor) do |shape_cmp, color_cmp, border_color_cmp, entity| + shape = shape_cmp.obj + Rl.draw_poly(center: Rl::Vector2.new(shape.x, shape.y), + radius: shape.size, + sides: shape.sides, + rotation: shape.angle, + color: color_cmp.color) + Rl.draw_poly_lines(center: Rl::Vector2.new(shape.x, shape.y), + radius: shape.size, + sides: shape.sides, + rotation: shape.angle, + color: border_color_cmp.color, + line_thickness: shape.size/10) + border_color_cmp.color = Rl::Color.dodger_blue + color_cmp.color = Rl::Color.ray_white + end +end + +Sys.new('MouseOver') do + MouseFollow.obj.x = Rl.mouse_x + MouseFollow.obj.y = Rl.mouse_y + mouse_points = Array.new(MouseFollow.obj.sides) do |side| + [MouseFollow.obj.points[side][:x], + MouseFollow.obj.points[side][:y]] + end + + #Ent.group(Cmp::Shape, Cmp::ShapeColor, Cmp::BorderColor) do |shape_cmp| + GameHexArray.each_with_index do |arry, x| + arry.each_with_index do |shape_ent, y| + shape = shape_ent.component[Cmp::Shape] + if SAT.hitbox_check( + mouse_points, + Array.new(shape.obj.sides) do |side| + [shape.obj.points[side][:x], + shape.obj.points[side][:y]] + end + ) + shape_ent.component[Cmp::BorderColor].color = Rl::Color.red + shape_ent.component[Cmp::ShapeColor].color = Rl::Color.fire_brick + unless y == 0 + GameHexArray[x][y-1].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x][y-1].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + unless GameHexArray[x+1].nil? + GameHexArray[x+1][y-1].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x+1][y-1].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + end + end + unless GameHexArray[x+1].nil? + GameHexArray[x+1][y].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x+1][y].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + end + unless GameHexArray[x][y+1].nil? + GameHexArray[x][y+1].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x][y+1].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + unless x == 0 + GameHexArray[x-1][y+1].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x-1][y+1].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + end + end + unless x == 0 + GameHexArray[x-1][y].component[Cmp::BorderColor].color = Rl::Color.red + GameHexArray[x-1][y].component[Cmp::ShapeColor].color = Rl::Color.fire_brick + end + end + end + end +end + +module SAT + class << self + # The hitbox logic + def hitbox_check(shape_a, shape_b) + # Get normals of both shapes + inverted = build_inverted_edges(shape_a) + inverted.concat(build_inverted_edges(shape_b)) + + inverted.each_with_index do |line, line_index| + # Determine max and min of a and b shapes + amax, amin = calculate_minmax(shape_a, line) + bmax, bmin = calculate_minmax(shape_b, line) + + if ((amin <= bmax) && (amin >= bmin)) || ((bmin <= amax) && (bmin >= amin)) + next + else + return false + end + end + true + end + + # Creates edges out using coordinates and then gets the normal + def build_inverted_edges(shape) + edges = [] + shape.each_with_index do |vertex_start, index| + vertex_end = if index == shape.length - 1 + shape[0] + else + shape[index + 1] + end + edges.push [vertex_end[1] - vertex_start[1], + -(vertex_end[0] - vertex_start[0])] + end + edges + end + + # Dot product + def vecDotProd(a, b) + (a[0] * b[0]) + (a[1] * b[1]) + end + + # Calculates the minimum point and maximum point projected onto the line + def calculate_minmax(shape, line) + min = vecDotProd(shape.first, line) + max = vecDotProd(shape.first, line) + shape.each_with_index do |vertex, _vertex_index| + dot = vecDotProd(vertex, line) + if dot > max + max = dot + elsif dot < min + min = dot + end + end + [max, min] + end + end +end + +Rl.target_fps = 60 +Rl.while_window_open do + #if Rl.key_pressed? 61 # plus/equal + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.sides += 1 unless Target.obj.sides == 9 + # else + # MouseFollow.obj.sides += 1 unless MouseFollow.obj.sides == 9 + # end + #end + #if Rl.key_pressed? 45 # minus/underscore + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.sides -= 1 unless Target.obj.sides == 3 + # else + # MouseFollow.obj.sides -= 1 unless MouseFollow.obj.sides == 3 + # end + #end + #if Rl.key_down? 65 # a + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.angle -= (Math::PI/180) * 2 + # else + # MouseFollow.obj.angle -= (Math::PI/180) * 2 + # end + #end + #if Rl.key_down? 68 # d + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.angle += (Math::PI/180) * 2 + # else + # MouseFollow.obj.angle += (Math::PI/180) * 2 + # end + #end + #if Rl.key_down? 87 # w + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.size += 1 + # else + # MouseFollow.obj.size += 1 + # end + #end + #if Rl.key_down? 83 # s + # if (Rl.key_down? 340) || (Rl.key_down? 344) + # Target.obj.size -= 1 + # else + # MouseFollow.obj.size -= 1 + # end + #end + Rl.draw(clear_color: Rl::Color.black) do + Sys::MouseOver.call + Sys::DrawShape.call + end +end |
