Войти на сайт
×
ТЕМА: [ССС]Мини игра
[ССС]Мини игра 9 года 7 мес. назад #79684
|
Итак, тема конкурса: мини игра.
Для разработки разрешен любой мейкер. Все демо прикладывать в данную тему. И ТОЛЬКО ДЕМО ПО КОНКУРСУ Прочие сообщения будут считаться оффтопом и на автора будет безжалостно спущен Церб на пару с Эльфом В 00:00 по понедельнику прием скриптов будет закрыт. Удачи |
"Стрелок, что-то ты неочень похож на свой аватар..."(с)
Последнее редактирование: 9 года 7 мес. назад от strelokhalfer.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: NettySvit
|
[ССС]Мини игра 9 года 7 мес. назад #79748
|
Сделал тетрис.
проект на битбакете Демка на яндекс диске Сам скрипт (все файлы с проекта слиты в один) ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ][ Нажмите, чтобы скрыть ] #Для использование вызовите SceneManager.call Tetris::Scene
module Tetris
end
module Tetris::Settings
DEFAULTS = {
speed: 40,
width: 12,
height: 18,
level_score: 2000,
per_layer_score: 400,
color: [0, 255, 0]
}
DEFAULTS.keys.each do |key|
instance_eval { attr_writer key }
define_method key do
instance_variable_get("@#{key}") || DEFAULTS[key]
end
end
extend self
end
class Tetris::Sprite < Sprite_Base
def initialize(e_height, e_width, window, padding = 0, multiplier = 1)
super()
@e_height, @e_width = e_height, e_width
@window, @padding, @multiplier = window, padding, multiplier
self.visible = false
create_bitmap
set_position
set_color
end
def update
super
self.visible = @e_height >= 0
end
private
def set_color
self.bitmap.fill_rect 1, 1, width - 1, height - 1, color
end
def color
Color.new(*Tetris::Settings.color)
end
def set_position
self.x = @e_width * width + 2 + @window.x + @padding
self.y = @e_height * height + @window.y + @padding
end
def create_bitmap
self.bitmap = Bitmap.new width, height
end
def width
Tetris::Sizes.cell * @multiplier
end
def height
Tetris::Sizes.cell * @multiplier
end
end
class Tetris::Scene < Scene_Base
def start
super
@game = Tetris::Game.new self
@game.start
create_windows
end
def terminate
@game = nil
Tetris::Game::Figure.next = nil
super
end
def update
check_keys
@game.update
super
end
private
def create_windows
create_field_window
create_next_window
create_score_window
create_level_window
end
def create_next_window
@next_window = Tetris::Window::Next.new(
@game, Tetris::Sizes.window_width, 0,
Tetris::Sizes.info_width, Tetris::Sizes.next_height
)
end
def create_score_window
@score_window = Tetris::Window::Text::Score.new(
@game, Tetris::Sizes.window_width, Tetris::Sizes.next_height,
Tetris::Sizes.info_width, Tetris::Sizes.score_height
)
end
def create_level_window
@level_window = Tetris::Window::Text::Level.new(
@game, Tetris::Sizes.window_width, Tetris::Sizes.next_height + Tetris::Sizes.score_height,
Tetris::Sizes.info_width, Tetris::Sizes.level_height
)
end
def create_field_window
@field_window = Tetris::Window::Field.new(
@game, 0, Tetris::Sizes.padding,
Tetris::Sizes.window_width, Tetris::Sizes.window_height
)
end
def check_keys
@game.left! if Input.trigger? Input::LEFT
@game.right! if Input.trigger? Input::RIGHT
@game.down! if Input.press? Input::DOWN
@game.turn! if Input.trigger? Input::UP
end
end
class Tetris::Game
attr_reader :field, :score, :level
def initialize(scene)
@scene = scene
@field = Tetris::Game::Field.new self
@level = 1
@score = 0
@ticked = -1
end
def start
@field.add_figure
end
def update
return if @game_overed
@ticked += 1
if @ticked % speed == 0
down!
try_game_over
end
end
def terminate
@scene.terminate
end
def left!
@field.left!
try_merge
end
def right!
@field.right!
try_merge
end
def down!
try_merge
@field.down!
end
def turn!
try_merge
@field.turn!
end
def add_score(points)
@score += points
@level = @score / Tetris::Settings.level_score + 1
end
private
def speed
(Tetris::Settings.speed / @level.to_f).to_i
end
def game_over
@game_overed = true
SceneManager.call Scene_Map
end
def try_merge
if @field.landed?
@field.merge!
@field.add_figure
end
end
def try_game_over
game_over if @field.overflowed?
end
end
class Tetris::Game::Base
attr_reader :matrix
def elements(&block)
matrix_elements(@matrix, &block)
end
private
def matrix_elements(matrix)
Marshal.load(Marshal.dump matrix).each.with_index do |row, h|
row.each.with_index { |el, w| yield h, w if el }
end
end
end
class Tetris::Game::Figure < Tetris::Game::Base
attr_reader :figure, :row, :column
class << self
attr_accessor :next
def register!
klasses << self
end
def random(field)
current = @next || calculate_next(field)
@next = calculate_next(field)
current
end
def calculate_next(field)
klasses.sample.new(field).tap do |figure|
(1..3).to_a.sample.times { figure.turn! }
end
end
private
def klasses
@@klasses ||= []
end
end
def initialize(field)
@matrix = field.matrix
@figure = self.class.figure
@row = -1
@column = (@matrix.first.length - @figure.first.length) / 2
end
def left!
@column -= 1
end
def right!
@column += 1
end
def down!
@row += 1
end
def turn!
res = Array.new(@figure.first.length) { [] }
old_figure = @figure
@figure = @figure.each.with_object(res) do |row, res|
row.each.with_index do |el, i|
res[i].unshift el
end
end
@figure = old_figure if overlaps?
end
def landed?
landed_on_bottom? || landed_on_element?
end
def full?
@row >= @figure.length - 1
end
def blocks_left?
blocks_on_field_left? || blocks_left_on_element?
end
def blocks_right?
blocks_on_field_right? || blocks_right_on_element?
end
def figure_elements(&block)
matrix_elements(@figure, &block)
end
private
def overlaps?
return true if @column < 0 || @column + @figure.first.size > @matrix.first.size
return true if @row >= @matrix.size
all_elements do |h, w, f_h, f_w|
return true if same_column?(f_w, w) && same_row?(f_h, h)
end
false
end
def blocks_on_field_left?
@column <= 0
end
def blocks_on_field_right?
@column + @figure.first.size >= @matrix.first.size
end
def landed_on_bottom?
@row >= @matrix.length - 1
end
def blocks_left_on_element?
check_all_elements do |height, width, figure_height, figure_width|
same_column?(figure_width, width, -1) && same_row?(figure_height, height)
end
end
def blocks_right_on_element?
check_all_elements do |height, width, figure_height, figure_width|
same_column?(figure_width, width, 1) && same_row?(figure_height, height)
end
end
def landed_on_element?
check_all_elements do |height, width, figure_height, figure_width|
same_column?(figure_width, width) && same_row?(figure_height, height, 1)
end
end
def all_elements
elements { |h, w| figure_elements { |f_h, f_w| yield h, w, f_h, f_w } }
end
def check_all_elements
all_elements do |h, w, f_h, f_w|
return true if yield h, w, f_h, f_w
end
false
end
def same_column?(figure_width, width, offset = 0)
figure_width + @column + offset == width
end
def same_row?(figure_height, height, offset = 0)
@row - @figure.length + figure_height + 1 + offset == height
end
end
class Tetris::Game::Figure::Square < Tetris::Game::Figure
def self.figure
[
[1, 1],
[1, 1]
]
end
register!
end
class Tetris::Game::Figure::Gose < Tetris::Game::Figure
def self.figure
[
[1, 1],
[1, nil],
[1, nil]
]
end
register!
end
class Tetris::Game::Figure::ReversedGose < Tetris::Game::Figure
def self.figure
[
[1, 1],
[nil, 1],
[nil, 1]
]
end
register!
end
class Tetris::Game::Figure::T < Tetris::Game::Figure
def self.figure
[
[1, 1, 1],
[nil, 1, nil]
]
end
register!
end
class Tetris::Game::Figure::Line < Tetris::Game::Figure
def self.figure
[
[1, 1, 1, 1]
]
end
register!
end
class Tetris::Game::Figure::Z < Tetris::Game::Figure
def self.figure
[
[1, 1, nil],
[nil, 1, 1]
]
end
register!
end
class Tetris::Game::Figure::ReversedZ < Tetris::Game::Figure
def self.figure
[
[nil, 1, 1],
[1, 1, nil]
]
end
register!
end
class Tetris::Game::Field < Tetris::Game::Base
def initialize(game)
@game = game
@matrix = load_matrix
end
def add_figure
@figure = Tetris::Game::Figure.random(self)
end
def merge!
@overflowed = !@figure.full?
figure_elements do |h, w|
@matrix[h][w] = 1 if h >= 0 && w >= 0
end
destroy_layer
@figure = nil
end
def overflowed?
!!@overflowed
end
def left!
@figure.left! unless @figure.blocks_left?
end
def right!
@figure.right! unless @figure.blocks_right?
end
def down!
@figure.down! unless landed?
end
def turn!
@figure.turn!
end
def landed?
@figure.landed?
end
def field_elements(&block)
elements(&block)
figure_elements(&block)
end
private
def destroy_layer
@matrix.map.with_index { |row, i| i if row.all? }.compact.each do |i|
@matrix.delete_at i
@matrix.unshift [nil] * Tetris::Settings.width
@game.add_score Tetris::Settings.per_layer_score
end
end
def figure_elements
matrix_elements @figure.figure do |h, w|
yield @figure.row - @figure.figure.length + h + 1, w + @figure.column
end
end
def load_matrix
Array.new Tetris::Settings.height do
[nil] * Tetris::Settings.width
end
end
end
module Tetris::Sizes
def cell
if Tetris::Settings.height > Tetris::Settings.width
(Graphics.height / Tetris::Settings.height.to_f).to_i
else
((Graphics.width * 0.66) / Tetris::Settings.width).to_i
end
end
def window_width
cell * Tetris::Settings.width + 4
end
def window_height
cell * Tetris::Settings.height + 4
end
def padding
Graphics.height - window_height
end
def info_width
Graphics.width - window_width
end
def next_height
Graphics.height / 2
end
def score_height
Graphics.height / 4
end
def level_height
Graphics.height / 4
end
extend self
end
module Tetris::Window
end
class Tetris::Window::Field < Window_Base
def initialize(game, *args)
@game = game
@sprites = {}
super(*args)
end
def update
super
update_sprites
end
def dispose
super
dispose_sprites
end
def update_sprites
dispose_sprites_except create_sprites
@sprites.values.each(&:update)
end
def dispose_sprites_except(keys)
(@sprites.keys - keys).each do |key|
@sprites[key].dispose
@sprites.delete key
end
end
def create_sprites
keys = []
@game.field.field_elements do |height, width|
keys << [height, width]
@sprites[[height, width]] ||= Tetris::Sprite.new(height, width, self)
end
keys
end
def dispose_sprites
@sprites.values.each(&:dispose)
end
end
class Tetris::Window::Next < Window_Base
def initialize(game, *args)
@game = game
@sprites = []
@next = nil
super(*args)
end
def update
super
if Tetris::Game::Figure.next != @next
dispose_sprites
@next = Tetris::Game::Figure.next
create_sprites
end
update_sprites
end
def dispose
super
dispose_sprites
end
def update_sprites
@sprites.each(&:update)
end
def create_sprites
@sprites = []
@next.figure_elements do |h, w|
@sprites << Tetris::Sprite.new(h, w, self, 50, 1.6)
end
end
def dispose_sprites
@sprites.each(&:dispose)
end
end
class Tetris::Window::Text < Window_Base
LINE_HEIGHT = 36
def initialize(game, *args)
@game = game
super(*args)
end
def update
super
if @text != calculate_text
@text = calculate_text
alert
end
end
private
def alert
contents.clear
@text.lines.each.with_index do |line, index|
contents.draw_text(*sizes(index), line.strip)
end
end
def sizes(index)
[0, LINE_HEIGHT * index, contents.rect.width, LINE_HEIGHT * (index + 1)]
end
end
class Tetris::Window::Text::Level < Tetris::Window::Text
def calculate_text
"Уровень: #{@game.level}"
end
end
class Tetris::Window::Text::Score < Tetris::Window::Text
def calculate_text
"Cчет: #{@game.score}"
end
end Update - немного подправил код. Теперь балка состоит из 4-х клеток, и можно подсунуть фигуру под другую фигуру. |
Последнее редактирование: 9 года 7 мес. назад от Iren_Rin.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: I_LORD, Ren310, strelokhalfer, Демий, NettySvit, Lipton, zmeelov66, peter8031983
|
Время создания страницы: 0.251 секунд