Ruby を使用して Gosu で描画アプリケーションを作成しようとしていますが、CPU 使用率が高くなります。考えられる原因の 1 つを知っています。
まず、ユーザーがマウス ボタンをクリックするたびに (またはマウス ボタンを押したままにしておくと、画面が更新されるたびに、1 秒あたり約 60 回発生すると思われます)、プリミティブをハッシュに追加するだけです。画面が再描画されるたびに、プログラムにハッシュをループさせ、すべてのプリミティブを再描画させます。誰かがマウス ボタンを押したままにすると、プリミティブが重なり合ったままになり、他の状況ではプリミティブが単にレイヤー化されます。それが最終的にハッシュ内の大量のメモリを消費することがわかります。
最良の解決策は、画面上のピクセルを単純に色付けし、それらをハッシュに保存する必要のない、ある種の低レベル関数を使用することだと思います。Gosu がそれをサポートしているかどうかはわかりません。誰かがGosuでこれを手伝ってくれるか、別の方法や別のプログラムを使用することを提案できますか? ありがとうございました!
(以下は私のプログラムの完全なコードです。)
require 'Gosu'
require 'socket'
class GameWindow < Gosu::Window
def initialize
super 1280, 960, false
self.caption = "Drawz Server"
@background_image = Gosu::Image.new(self, "media/Space.png", true)
@player = Player.new(self)
# Platform is the blank image for the epicycle to be drawn on.
@earth_image = Gosu::Image.new(self, "media/earth.bmp", true)
@cursor_image = Gosu::Image.new(self, "media/cursor.bmp", true)
puts "Please enter port..."
port = gets.strip!
puts "Server is running."
# Initialized Instance variables for all methods.
@square_drawing_number = 0
@client_coordinates_array = []
@client_coordinates_array_array = []
@client_quad_hash = {}
server = TCPServer.open("10.64.8.2", port)
@client = server.accept
manage_client_data = Thread.new do
x = 0
loop do
@client_coordinates_array[x] = @client.gets
x += 1
end
end
@x = 0
@quad_hash = {}
# Start up value of things in draw method, because draw is called before update. Hence I put the start up values here so that when draw is called it has location of things in
# its arguments.
@cx = 0
@cy = 0
end
class QuadCoords
attr_reader :x1, :y1, :x2, :y2, :x3, :y3, :x4, :y4
def initialize(x1, y1, x2, y2, x3, y3, x4, y4)
@x1 = x1
@y1 = y1
@x2 = x2
@y2 = y2
@x3 = x3
@y3 = y3
@x4 = x4
@y4 = y4
end
end
# Mean't to change location (x and y) and such of things in draw method.
def update
@cx = mouse_x
@cy = mouse_y
@x += 1
# Adds square locations to hash which is then accessed by draw function to retrieve and draw squares.
if button_down? Gosu::MsLeft
@x += 1
quad_coords_obj = QuadCoords.new(@cx - 5, @cy - 5, @cx, @cy - 5, @cx - 5, @cy, @cx, @cy)
@quad_hash["quad#{@x}"] = quad_coords_obj
# Sends location of squares to client for it to draw.
@client.puts "#{quad_coords_obj.x1}---#{quad_coords_obj.y1}---#{quad_coords_obj.x2}---#{quad_coords_obj.y2}---#{quad_coords_obj.x3}---#{quad_coords_obj.y3}---#{quad_coords_obj.x4}---#{quad_coords_obj.y4}"
end
if @client_coordinates_array.length > @square_drawing_number
new_squares_to_add = @client_coordinates_array.length - @square_drawing_number
@client_coordinates_array[-1 * new_squares_to_add..-1].each do |value|
@client_coordinates_array_array << value.split(/\---/)
end
x = 1
new_squares_to_add.times do
@x += 1
@client_quad_coords_obj = QuadCoords.new(@client_coordinates_array_array[-1 * x][0].to_i,
@client_coordinates_array_array[-1 * x][1].to_i,
@client_coordinates_array_array[-1 * x][2].to_i,
@client_coordinates_array_array[-1 * x][3].to_i,
@client_coordinates_array_array[-1 * x][4].to_i,
@client_coordinates_array_array[-1 * x][5].to_i,
@client_coordinates_array_array[-1 * x][6].to_i,
@client_coordinates_array_array[-1 * x][7].to_i)
@client_quad_hash["quad#{@x}"] = @client_quad_coords_obj
x += 1
@square_drawing_number += 1
end
end
end
# Draw is called before update.
def draw
@background_image.draw(0,0,0)
@earth_image.draw(295,215,1)
# x1,y1 = Upper Left Hand Corner; x2,y2 = Lower Left Hand Corner; x3,y3 = Upper Right Hand Corner; x4,y4 = Lower Right Hand Corner
@quad_hash.each_value do |value|
draw_quad(value.x1, value.y1, 0xff00ffff, value.x2, value.y2, 0xff00ffff, value.x3, value.y3, 0xff00ffff, value.x4, value.y4, 0xff00ffff, z = 0, mode = :default)
end
@client_quad_hash.each_value do |value|
draw_quad(value.x1, value.y1, 0xff00ff00, value.x2, value.y2, 0xff00ff00, value.x3, value.y3, 0xff00ff00, value.x4, value.y4, 0xff00ff00, z = 0, mode = :default)
end
@cursor_image.draw(@cx, @cy, 1)
end
def button_down(id)
if id == Gosu::KbEscape
close
end
end
end
class Player
attr_accessor :x, :y, :update_called
def initialize(window)
@image = Gosu::Image.new(window, "media/Sun.bmp", false)
end
end
window = GameWindow.new
window.show