#!/usr/bin/env ruby require "starruby" include StarRuby field_texture = Texture.load("images/ruby-logo-R") star_texture = Texture.load("images/star") Airship = Struct.new(:x, :y, :yaw, :pitch, :roll, :height, :screen_x, :screen_y) airship = Airship.new airship.x = field_texture.width / 2 airship.y = field_texture.height airship.yaw = 0 airship.pitch = 0 airship.roll = 0 airship.height = 25 airship.screen_x = 0 airship.screen_y = 0 fearless = false font = Font.new("fonts/ORANGEKI", 12) yellow = Color.new(255, 255, 128) Game.run(320, 240, :title => "Airship") do |game| # Begin Inputing if Input.keys(:keyboard, :duration => 1).include?(:f) fearless = ! fearless end keys = Input.keys(:keyboard) # Terminate if the ESC key is pressed break if keys.include?(:escape) # Go left or right if keys.include?(:left) airship.yaw = (airship.yaw + 358) % 360 airship.roll = [airship.roll - (fearless ? 8 : 3), fearless ? -180 : -20].max elsif keys.include?(:right) airship.yaw = (airship.yaw + 2) % 360 airship.roll = [airship.roll + (fearless ? 8 : 3), fearless ? 180 : 20].min else # If not pressed the left or the right key, # the airship will be set its original position gradually. if 0 < airship.roll airship.roll = [airship.roll - (fearless ? 8 : 3), 0].max elsif airship.roll < 0 airship.roll = [airship.roll + (fearless ? 8 : 3), 0].min end end # Go forward if keys.include?(:space) airship.x = (airship.x + 10 * Math.sin(airship.yaw.degree)).to_i airship.y = (airship.y - 10 * Math.cos(airship.yaw.degree)).to_i end # Go up or down if keys.include?(:down) airship.height = [airship.height + 2, 45].min airship.pitch = [airship.pitch + (fearless ? 8 : 3), fearless ? 180 : 20].min elsif keys.include?(:up) airship.height = [airship.height - 2, 5].max airship.pitch = [airship.pitch - (fearless ? 8 : 3), fearless ? -180 : -20].max else # If not pressed the up or the down key, # the airship will be set its original position gradually. if 0 < airship.pitch airship.pitch = [airship.pitch - (fearless ? 8 : 3), 0].max elsif airship.pitch < 0 airship.pitch = [airship.pitch + (fearless ? 8 : 3), 0].min end end # Move the camera if keys.include?(:a) airship.screen_x -= 1 elsif keys.include?(:s) airship.screen_x += 1 end if keys.include?(:w) airship.screen_y -= 1 elsif keys.include?(:z) airship.screen_y += 1 end # End Inputing # Begin View s = game.screen s.fill(Color.new(128, 128, 128)) options = { :camera_x => airship.x, :camera_y => airship.y, :camera_height => airship.height, :camera_yaw => airship.yaw.degree, :camera_pitch => airship.pitch.degree, :camera_roll => airship.roll.degree, :intersection_x => s.width / 2 + airship.screen_x, :intersection_y => s.height / 2 + airship.screen_y, :loop => true, :blur => :background, } # Render the ground s.render_in_perspective(field_texture, options) # Render stars # The following array means stars' coords ([x, y, height]). [[-20, -20, 0], [-20, 20, 0], [20, -20, 0], [20, 20, 0], [0, 0, 20]].map do |x, y, height| x += field_texture.width / 2 y += field_texture.height / 2 # The following statement returns an array ([x, y, scale]) s.transform_in_perspective(x, y, height, options) # The following code was deprecated since the version 0.2 # Texture.transform_in_perspective(x, y, height, options) end.select do |x, y, scale| # If either x, y or scale holds nil value, # the star will not be shown. x and y and scale and 0 < scale end.sort do |a, b| # Sort by each scale a[2] <=> b[2] end.each do |x, y, scale| # Adjust the rendering position x -= star_texture.width / 2 y -= star_texture.height # If x or y value is not Fixnum, skip rendering. next unless x.kind_of?(Fixnum) and y.kind_of?(Fixnum) s.render_texture(star_texture, x, y, :scale_x => scale, :scale_y => scale, # A star's center is its lower center. :center_x => star_texture.width / 2, :center_y => star_texture.height, :angle => 2 * Math::PI - options[:camera_roll]) end # Render texts s.render_text("[Arrow] Rotate Camera", 8, 8, font, yellow) s.render_text("[Space] Go Forward", 8, 8 + 16, font, yellow) s.render_text("[W][A][S][Z] Move Screen", 8, 8 + 32, font, yellow) str = "[F] Fearless? #{fearless ? '(Yes)' : '(No)'}" s.render_text(str, 8, 8 + 48, font, yellow) # End Viewing end