mirror of
https://github.com/SleepingInsomniac/asteroids
synced 2024-12-26 21:59:30 +01:00
Update to render directly to surface
This commit is contained in:
parent
c3e21426e7
commit
3319e18747
12 changed files with 126 additions and 58 deletions
|
@ -6,5 +6,5 @@ shards:
|
||||||
|
|
||||||
sdl:
|
sdl:
|
||||||
git: https://github.com/ysbaddaden/sdl.cr.git
|
git: https://github.com/ysbaddaden/sdl.cr.git
|
||||||
version: 0.1.0+git.commit.d2aa0fb2ee30e42fc8d046d2d00c03c76879cb17
|
version: 0.1.0+git.commit.0ded44711246feb3aa3ba28fea249c9b03be061b
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ class Asteroid < Sprite
|
||||||
include LxGame::VectorSprite
|
include LxGame::VectorSprite
|
||||||
|
|
||||||
property size : Float64 = 1.0
|
property size : Float64 = 1.0
|
||||||
|
property color : Pixel = Pixel.new(128, 128, 128, 255)
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
|
@ -16,11 +17,8 @@ class Asteroid < Sprite
|
||||||
update_position(dt)
|
update_position(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(renderer)
|
def draw(engine)
|
||||||
# renderer.draw_color = SDL::Color[0, 100, 100, 255]
|
|
||||||
# draw_radius(renderer)
|
|
||||||
frame = project_points(points: @frame, scale: Vector2.new(@size, @size))
|
frame = project_points(points: @frame, scale: Vector2.new(@size, @size))
|
||||||
renderer.draw_color = SDL::Color[128, 128, 128, 255]
|
draw_frame(engine, frame, color)
|
||||||
draw_frame(renderer, frame)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,22 +8,6 @@ require "./asteroid"
|
||||||
require "./bullet"
|
require "./bullet"
|
||||||
require "./explosion"
|
require "./explosion"
|
||||||
|
|
||||||
WIDTH = 600
|
|
||||||
HEIGHT = 400
|
|
||||||
SCALE = 2
|
|
||||||
|
|
||||||
module LxGame
|
|
||||||
def draw_point(renderer, x, y)
|
|
||||||
x = x % WIDTH
|
|
||||||
y = y % HEIGHT
|
|
||||||
|
|
||||||
x = WIDTH + x if x < 0
|
|
||||||
y = HEIGHT + y if y < 0
|
|
||||||
|
|
||||||
renderer.draw_point(x, y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Asteroids < Game
|
class Asteroids < Game
|
||||||
@ship : Ship
|
@ship : Ship
|
||||||
@asteroids = [] of Asteroid
|
@asteroids = [] of Asteroid
|
||||||
|
@ -50,6 +34,17 @@ class Asteroids < Game
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# override to wrap the coordinates
|
||||||
|
def draw_point(x : Int32, y : Int32, pixel : Pixel, surface = @screen)
|
||||||
|
x = x % @width
|
||||||
|
y = y % @height
|
||||||
|
|
||||||
|
x = @width + x if x < 0
|
||||||
|
y = @height + y if y < 0
|
||||||
|
|
||||||
|
super(x, y, pixel, surface)
|
||||||
|
end
|
||||||
|
|
||||||
def generate_asteroids
|
def generate_asteroids
|
||||||
center_size = Vector2.new(50.0, 50.0)
|
center_size = Vector2.new(50.0, 50.0)
|
||||||
center_pos = Vector2.new((width.to_f / 2.0) - (center_size.x / 2.0), (height.to_f / 2.0) - (center_size.y / 2.0))
|
center_pos = Vector2.new((width.to_f / 2.0) - (center_size.x / 2.0), (height.to_f / 2.0) - (center_size.y / 2.0))
|
||||||
|
@ -192,15 +187,14 @@ class Asteroids < Game
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw(engine)
|
||||||
@renderer.draw_color = SDL::Color[0, 0, 0, 255]
|
engine.clear
|
||||||
@renderer.clear
|
@ship.draw(engine)
|
||||||
@ship.draw(@renderer)
|
@bullets.each { |b| b.draw(engine) }
|
||||||
@bullets.each { |b| b.draw(@renderer) }
|
@asteroids.each { |a| a.draw(engine) }
|
||||||
@asteroids.each { |a| a.draw(@renderer) }
|
@explosions.each { |e| e.draw(engine) }
|
||||||
@explosions.each { |e| e.draw(@renderer) }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
game = Asteroids.new(WIDTH, HEIGHT, SCALE)
|
game = Asteroids.new(500, 400, 2)
|
||||||
game.run!
|
game.run!
|
||||||
|
|
|
@ -11,10 +11,10 @@ class Bullet < Sprite
|
||||||
update_position(dt)
|
update_position(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(renderer)
|
def draw(engine)
|
||||||
brightness = ((4.0 - self.age) / 4.0) * 255
|
brightness = (((4.0 - self.age) / 4.0) * 255).to_u8
|
||||||
renderer.draw_color = SDL::Color[brightness, brightness, 0]
|
color = Pixel.new(r: brightness, g: brightness, b: 0_u8)
|
||||||
renderer.draw_point(@position.x.to_i, @position.y.to_i)
|
engine.draw_point(@position.x.to_i, @position.y.to_i, color)
|
||||||
end
|
end
|
||||||
|
|
||||||
def collides_with?(other : VectorSprite)
|
def collides_with?(other : VectorSprite)
|
||||||
|
|
|
@ -12,6 +12,8 @@ module LxGame
|
||||||
property emit_angle : Float64 = 2 * Math::PI
|
property emit_angle : Float64 = 2 * Math::PI
|
||||||
property size : Float64 = 0.0
|
property size : Float64 = 0.0
|
||||||
|
|
||||||
|
# property color : Pixel = Pixel.new
|
||||||
|
|
||||||
def generate_particle
|
def generate_particle
|
||||||
Particle.build do |particle|
|
Particle.build do |particle|
|
||||||
particle.position = @position
|
particle.position = @position
|
||||||
|
@ -44,11 +46,9 @@ module LxGame
|
||||||
@particles.reject!(&.dead?)
|
@particles.reject!(&.dead?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(renderer : SDL::Renderer)
|
def draw(engine)
|
||||||
renderer.draw_color = SDL::Color[255, 255, 0, 255]
|
|
||||||
|
|
||||||
@particles.each do |particle|
|
@particles.each do |particle|
|
||||||
particle.draw(renderer)
|
particle.draw(engine)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
require "./lib_sdl"
|
||||||
|
require "./pixel"
|
||||||
|
|
||||||
module LxGame
|
module LxGame
|
||||||
abstract class Game
|
abstract class Game
|
||||||
FPS_INTERVAL = 1.0
|
FPS_INTERVAL = 1.0
|
||||||
|
@ -15,18 +18,63 @@ module LxGame
|
||||||
def initialize(@width, @height, @scale = 1, @title = self.class.name)
|
def initialize(@width, @height, @scale = 1, @title = self.class.name)
|
||||||
SDL.init(SDL::Init::VIDEO)
|
SDL.init(SDL::Init::VIDEO)
|
||||||
@window = SDL::Window.new(@title, @width * @scale, @height * @scale)
|
@window = SDL::Window.new(@title, @width * @scale, @height * @scale)
|
||||||
@renderer = SDL::Renderer.new(@window, flags: SDL::Renderer::Flags::SOFTWARE)
|
@renderer = SDL::Renderer.new(@window, flags: SDL::Renderer::Flags::PRESENTVSYNC) # , flags: SDL::Renderer::Flags::SOFTWARE)
|
||||||
@renderer.scale = {@scale, @scale}
|
@renderer.scale = {@scale, @scale}
|
||||||
|
@screen = SDL::Surface.new(LibSDL.create_rgb_surface(
|
||||||
|
flags: 0, width: @width, height: @height, depth: 32,
|
||||||
|
r_mask: 0xFF000000, g_mask: 0x00FF0000, b_mask: 0x0000FF00, a_mask: 0x000000FF
|
||||||
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract def update(dt : Float64)
|
abstract def update(dt : Float64)
|
||||||
abstract def draw
|
abstract def draw(engine : Game)
|
||||||
|
|
||||||
def elapsed_time
|
def elapsed_time
|
||||||
Time.monotonic.total_milliseconds
|
Time.monotonic.total_milliseconds
|
||||||
end
|
end
|
||||||
|
|
||||||
def engine_update
|
def clear(r = 0, g = 0, b = 0)
|
||||||
|
@screen.fill(0, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_point(x : Int32, y : Int32, pixel : Pixel, surface = @screen)
|
||||||
|
target = surface.pixels + (y * surface.pitch) + (x * 4)
|
||||||
|
target.as(Pointer(UInt32)).value = pixel.format(surface.format)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Draw a line using Bresenham’s Algorithm
|
||||||
|
def draw_line(p1 : Vector2, p2 : Vector2, pixel : Pixel, surface = @screen)
|
||||||
|
return draw_line(p2, p1, pixel, surface) if p1.x > p2.x
|
||||||
|
x1, y1, x2, y2 = p1.x.to_i, p1.y.to_i, p2.x.to_i, p2.y.to_i
|
||||||
|
|
||||||
|
dx = (x2 - x1).abs
|
||||||
|
dy = -(y2 - y1).abs
|
||||||
|
|
||||||
|
sx = x1 < x2 ? 1 : -1
|
||||||
|
sy = y1 < y2 ? 1 : -1
|
||||||
|
|
||||||
|
d = dx + dy
|
||||||
|
x, y = x1, y1
|
||||||
|
|
||||||
|
loop do
|
||||||
|
draw_point(x, y, pixel, surface)
|
||||||
|
break if x == x2 && y == y2
|
||||||
|
|
||||||
|
d2 = d + d
|
||||||
|
|
||||||
|
if d2 >= dy
|
||||||
|
d += dy
|
||||||
|
x += sx
|
||||||
|
end
|
||||||
|
|
||||||
|
if d2 <= dx
|
||||||
|
d += dx
|
||||||
|
y += sy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private def engine_update
|
||||||
@fps_frames += 1
|
@fps_frames += 1
|
||||||
et = elapsed_time
|
et = elapsed_time
|
||||||
|
|
||||||
|
@ -41,8 +89,12 @@ module LxGame
|
||||||
@last_time = et
|
@last_time = et
|
||||||
end
|
end
|
||||||
|
|
||||||
def engine_draw
|
private def engine_draw
|
||||||
draw
|
@screen.lock do
|
||||||
|
draw(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
@renderer.copy(SDL::Texture.from(@screen, @renderer))
|
||||||
@renderer.present
|
@renderer.present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
7
src/lx_game/lib_sdl.cr
Normal file
7
src/lx_game/lib_sdl.cr
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module SDL
|
||||||
|
class Surface
|
||||||
|
def pixels
|
||||||
|
surface.pixels
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,11 +11,11 @@ module LxGame
|
||||||
update_position(dt)
|
update_position(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(renderer : SDL::Renderer)
|
def draw(engine)
|
||||||
return if dead?
|
return if dead?
|
||||||
brightness = ((@lifespan - @age) / @lifespan) * 255
|
brightness = ((((@lifespan - @age) / @lifespan) * 255) / 2).to_u8
|
||||||
renderer.draw_color = SDL::Color[brightness / 2, brightness / 2, brightness / 2]
|
color = Pixel.new(r: brightness, g: brightness, b: brightness)
|
||||||
renderer.draw_point(@position.x.to_i, @position.y.to_i)
|
engine.draw_point(@position.x.to_i, @position.y.to_i, color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
16
src/lx_game/pixel.cr
Normal file
16
src/lx_game/pixel.cr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
module LxGame
|
||||||
|
struct Pixel
|
||||||
|
def self.random
|
||||||
|
new(rand(0_u8..0xFF_u8), rand(0_u8..0xFF_u8), rand(0_u8..0xFF_u8), 0xFF_u8)
|
||||||
|
end
|
||||||
|
|
||||||
|
property r, g, b, a
|
||||||
|
|
||||||
|
def initialize(@r : UInt8 = 255, @g : UInt8 = 255, @b : UInt8 = 255, @a : UInt8 = 255)
|
||||||
|
end
|
||||||
|
|
||||||
|
def format(format)
|
||||||
|
LibSDL.map_rgba(format, @r, @g, @b, @a)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -31,6 +31,6 @@ module LxGame
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract def update(dt : Float64)
|
abstract def update(dt : Float64)
|
||||||
abstract def draw(renderer : SDL::Renderer)
|
abstract def draw(engine : Game)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,17 +55,17 @@ module LxGame
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_frame(renderer : SDL::Renderer, frame = @frame)
|
def draw_frame(engine : Game, frame = @frame, color : Pixel = Pixel.new)
|
||||||
0.upto(frame.size - 1) do |n|
|
0.upto(frame.size - 1) do |n|
|
||||||
draw_line(renderer, frame[n], frame[(n + 1) % frame.size])
|
engine.draw_line(frame[n], frame[(n + 1) % frame.size], color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_radius(renderer : SDL::Renderer, points = 30)
|
def draw_radius(engine : Game, points = 30, color : Pixel = Pixel.new)
|
||||||
circle = self.class.generate_circle(points, average_radius).map do |point|
|
circle = self.class.generate_circle(points, average_radius).map do |point|
|
||||||
point + @position
|
point + @position
|
||||||
end
|
end
|
||||||
draw_frame(renderer, frame: circle)
|
draw_frame(engine, frame: circle, color: color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
13
src/ship.cr
13
src/ship.cr
|
@ -10,6 +10,7 @@ class Ship < Sprite
|
||||||
@r_emitter : Emitter
|
@r_emitter : Emitter
|
||||||
@projected_points : Array(Vector2)? = nil
|
@projected_points : Array(Vector2)? = nil
|
||||||
property blew_up : Bool = false
|
property blew_up : Bool = false
|
||||||
|
@color = Pixel.new
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
|
@ -112,16 +113,16 @@ class Ship < Sprite
|
||||||
@r_emitter.rotation = @rotation + 1.5
|
@r_emitter.rotation = @rotation + 1.5
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(renderer)
|
def draw(engine)
|
||||||
return if @blew_up
|
return if @blew_up
|
||||||
@emitter.draw(renderer)
|
@emitter.draw(engine)
|
||||||
@emitter.emitting = false
|
@emitter.emitting = false
|
||||||
@l_emitter.draw(renderer)
|
@l_emitter.draw(engine)
|
||||||
@l_emitter.emitting = false
|
@l_emitter.emitting = false
|
||||||
@r_emitter.draw(renderer)
|
@r_emitter.draw(engine)
|
||||||
@r_emitter.emitting = false
|
@r_emitter.emitting = false
|
||||||
|
|
||||||
renderer.draw_color = SDL::Color[255, 255, 255, 255]
|
# renderer.draw_color = SDL::Color[255, 255, 255, 255]
|
||||||
draw_frame(renderer, projected_points)
|
draw_frame(engine, projected_points, @color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue