#!ruby -Ks # -*- mode: ruby; encoding: sjis -*- # Last updated: <2014/12/01 09:59:35 +0900> # # 絵文字だけでゲームを作ってみるテスト require 'dxruby' $is_square = false # ---------------------------------------- # 背景表示用クラス class MyBg attr_accessor :yuka_y, :bg_imgs, :yuka_img # コンストラクタ def initialize(yuka_y) @yuka_y = yuka_y @bg_imgs = [] unless $is_square # 絵文字で背景と床画像を作成 code_list = [ ["\u0043", [0, 152, 255], [0, 16, 96], [0, 0, 255]], ["\u0045", [255, 119, 38], [128, 64, 0], [190, 0, 0]], ["\u004d", [175, 210, 255], [0, 210, 255], [255, 255, 255]], ["\u0047", [206, 163, 131], [144, 163, 188], [255, 255, 255]], ] code_list.each do |d| code, bgc, c, ec = d @bg_imgs.push(Image.new(640, 480, bgc).drawFontEx(0, 0, code, Font.new(640, "Webdings"), :color => c, :edge => true, :edge_color => ec, :edge_width => 8)) end @yuka_img = Image.new(64, 64, C_BLACK).drawFontEx(0, 0, "\u2593", Font.new(64, "MS ゴシック"), :color => [176, 45, 0]) else # 四角で背景と床画像を作成 @bg_imgs.push(Image.new(640, 480, [0, 55, 140])) @yuka_img = Image.new(32, 64, [176, 45, 0]) end @bg_num = 0 @count = 0 @alpha = 255 @step = 0 end def update return if $is_square case @step when 0 @count += 1 @step += 1 if @count > 60 * 10 when 1 @alpha -= 2 if @alpha < 0 @alpha = 0 @bg_num = (@bg_num + 1) % @bg_imgs.length @step += 1 end when 2 @alpha += 2 if @alpha > 255 @alpha = 255 @count = 0 @step = 0 end end end # 描画 def draw Window.drawAlpha(0, 0, @bg_imgs[@bg_num], @alpha) 0.step(640, 34) do |lx| Window.draw(lx, @yuka_y, @yuka_img) end end end # ---------------------------------------- # プレイヤーキャラ用クラス class MyPlayer < Sprite attr_accessor :score, :hscore, :dead_step def initialize(sx, sy) super unless $is_square # 絵文字でプレイヤーキャラ画像を作成 img = Image.new(96, 96).drawFontEx(0, 8, "\u20ac", Font.new(96, "Webdings"), :color => C_BLACK, :edge_color => C_WHITE, :edge => true, :edge_width => 3 ) else img = Image.new(32, 96, C_BLACK) end self.image = img self.x = sx self.y = sy - img.height / 2 self.center_x = img.width / 2 self.center_y = img.height / 2 self.offset_sync = true self.collision = [self.center_x, self.center_y, 24] self.collision_enable = true self.collision_sync = false self.score = 0 self.hscore = 0 self.dead_step = 0 end def update super if Input.x != 0 self.x += Input.x * 6 self.x = 16 if self.x < 16 xmax = 640 - 16 self.x = xmax if self.x > xmax end if self.dead_step > 0 # 死亡中 self.dead_step += 1 self.visible = (self.dead_step & 0x02 == 0)? true : false if self.dead_step > 120 self.score = 0 self.collision_enable = true self.dead_step = 0 end end end # スコア加算 def add_score(sc) if self.dead_step == 0 self.score += sc self.hscore = self.score if self.score > self.hscore end end # 死亡処理開始 def dead_start if self.dead_step == 0 self.dead_step = 1 self.collision_enable = false end end end # ---------------------------------------- # アイテム用クラス class MyItem < Sprite attr_accessor :kind, :score, :ang_spd, :dead_step, :y_spd def initialize(img, kind, score) super self.kind = kind self.score = score self.image = img self.x = rand(640) self.y = -(img.height / 2) self.center_x = img.width / 2 self.center_y = img.height / 2 self.offset_sync = true self.ang_spd = ((rand(100) > 50)? 1 : -1) * 3 self.collision = [self.center_x, self.center_y, 10] self.collision_enable = true self.collision_sync = false self.dead_step = 0 self.y_spd = rand * 2.0 + 1.5 end def update super if self.dead_step == 0 self.angle += self.ang_spd self.y += self.y_spd if self.y > 480 # 画面下に消えたら自分で消滅 self.vanish end else # 消滅中 self.alpha -= 10 self.scale_x += 0.2 self.scale_y += 0.2 self.vanish if self.alpha < 0 end end def shot(d) # プレイヤーに当たった return if self.dead_step > 0 if self.score > 0 d.add_score(self.score) # スコア加算 else d.dead_start # プレイヤーを殺す end self.dead_step = 1 self.angle = 0 end end # ---------------------------------------- # 以降メイン処理 # 絵文字でアイテム画像を作成 item_list = { # 文字コード、フォントネーム、色、エッジの色、xずらし量、yずらし量, 点数, 発生確率 :bomb => ["\u004e", "Wingdings", C_BLACK, C_WHITE, 16, 0, 0, 30], :heart => ["\u2665", "MS ゴシック", [255, 80, 255], C_BLACK, 16, 0, 10, 30], :trophy => ["\u0025", "Webdings", [255, 255, 0], C_BLACK, 0, 6, 20, 20], :gold => ["\u2018", "Webdings", [255, 164, 0], C_BLACK, 2, -5, 50, 10], :art => ["\u004a", "Wingdings", [255, 191, 127], C_BLACK, 8, 0, 200, 10], } item_imgs = {} item_born = [] item_w, item_h = 64, 64 item_list.each do |key, value| num, fontname, col, ecol, cx, cy, score, ratio = value unless $is_square img = Image.new(item_w, item_h).drawFontEx(cx, cy, num, Font.new(item_h, fontname), :color => col, :edge => true, :edge_color => ecol, :edge_width => 1) else img = Image.new(32, 32, col) end item_imgs[key] = img # アイテムの発生確率に基づいて発生リストを作成 ratio.times do |i| item_born.push(key) end end bg = MyBg.new(480 - 64) # 背景を発生 player = MyPlayer.new(320, bg.yuka_y) # プレイヤーを発生 items = [] count = 0 alpha = 0 fnt = Font.new(24, "Arial") white_img = Image.new(640, 480, C_WHITE) # メインループ Window.loop do break if Input.keyPush?(K_ESCAPE) # アイテム発生 count -= 1 if count < 0 count = 5 kind = item_born[rand(item_born.length)] score = item_list[kind][6] item = MyItem.new(item_imgs[kind], kind, score) items.push(item) end bg.update # 背景変化 Sprite.update(items) # アイテムの移動 player.update # プレイヤーキャラの移動 Sprite.check(items, player) # 衝突判定 Sprite.clean(items) # アイテム消去 alpha = 255 if player.dead_step == 1 # プレイヤー死亡時のフラッシュを設定 bg.draw # 背景を描画 player.draw # プレイヤーキャラを描画 Sprite.draw(items) # アイテムを描画 if alpha > 0 Window.drawAlpha(0, 0, white_img, alpha) alpha -= 5 alpha = 0 if alpha < 0 end Window.drawFont(4, 4, "Score: #{player.score} HiScore: #{player.hscore}", fnt) end