mieki256's diary



2013/12/24(火) [n年前の日記]

#1 [emacs] ndmacro.elが動かなくなってたけど最新版にしたら解決

emacs上で、キー操作を繰り返した場合にその操作を再生してくれる、ndmacro.el という拡張(?)があるのだけど。気付いたら動かなくなっていて。NTEmacs を 23.4 → 24.3 にしたせいだろうか。それとも自分、その前から動いてなかったけど、気付かなかったのだろうか…。

_snj14/ndmacro.el

github で入手できる最新版と交換したら、バッチリ動くようになりました。ありがたや。この機能、本当に助かります…。

#2 [cg_tools] Inkscapeでビットマップを扱ったら望んだ結果が得られず

ビットマップを含んだsvgを、pngエクスポートすると、ビットマップ部分がぼやけてしまう…。何か設定等で、ぼやけないようにできないのだろうか…。

む。もしかして、コレかな。

_ビットマップのインポート | Inkscape@JP
ビットマップをインポートすると、画像のサイズによって次のようにボケてしまうことがあります。

ビットマップの配置がドキュメント中のピクセルと合っていない場合に、自動的にアンチエイリアスがかかってこのようなボケた表示になります。ドキュメントのピクセルに配置を合わせるにはビットマップを選択してから、「エクステンション(N) > パスの変形 > ピクセルスナップ」を実行します。

手軽に合わせるには、選択ツールのツールボックスバーでX座標とY座標の小数点以下をそれぞれ0に変更します。つまり、XY座標がいずれも整数となるように変更します。

ピクセルスナップエクステンションでは、上記の作業を選択したすべてのオブジェクトに対して実行します。

ビットマップのインポート | Inkscape@JP より

試してみないと…。

#3 [dxruby][game] DXRubyで地形アタリを取りながらプレイヤーキャラの移動その2

今日も、DXRuby を使って、地形の上でプレイヤーキャラを動かす実験をしてみますよ。

以下のソースを動かすには、 _DXRubyでtmxファイルを使ってBG表示 で公開してる、 _dxruby_map_disp_20131222.zip と、 _player_512x256_64x64.png が必要です。

昨日のソースの補足。 :

_昨日のソース について、言及することを忘れてた部分があるので、念のために補足しておきます。

床とアタリチェックする時、ちょっと妙なことをしていまして。
  if pimgnum == 16
    # 落下中
    yadd = 0
  else
    # 床の上に居る
    # 足元よりちょっと下の座標でアタリを取る
    yadd = 16
  end
  nx, ny = bgatari.adjust_bg_hit(px, py + yadd, BgAtari::ADJUST_UP)
図で描くと、下のような感じです。
床アタリを見てる位置

「なんでそんな珍妙なことするの? 足元のBGアタリだけ見ればいいじゃん?」と思う方も居るかもしれませんね。ですので、あえて、足元しか見ないソースを書いて動かしてみました。
  # 足元しか見ないとどうなるかな…?
  yadd = 1
  nx, ny = bgatari.adjust_bg_hit(px, py + yadd, BgAtari::ADJUST_UP)
_playermove1_bug1.rb.txt
足元だけ見て動かしてる版の動作結果

斜め床を登っていく時はいいのですけど、下る時に「あわわわわ!」みたいな状態になりますな。

要は、以下のようなことが起きてしまうわけです。
足元だけ見てると斜め床を下る時にヤバイ
昔のゲームでも、こういうの、たまーに見かけましたけどね…。

なので、足元からちょっと下のあたりをチェックしてるわけです。
足元からちょっと下を見ればヤバくない

ですが、ジャンプ中や落下中も、同じように足元からちょっと下を見てるままだと、よろしくない状態になります。
着地してないのに着地したことになってしまう

ですので、「床の上に立っている時」と「ジャンプ中・落下中」で、BGアタリを見る位置を変えてみたのでした。

このあたり、もっと上手い方法があるんじゃないかと思うのですけど…。これもこれで、地形によっては何か問題が出そうな気もするんですよね…。まあ、今後の課題ってことで。

壁補正をしてみたり。 :

さておき。 _昨日のソース は、壁の中に入ってしまうと大惨事になったので、壁補正を入れてみました。

_playermove2_bug.rb.txt
# プレイヤーキャラを動かしてみるサンプルその2
#
# 横移動、落下処理、床補正に加えて、壁補正もするが…

require 'dxruby'
require 'tmx'
require_relative 'dxrbtmx'
require_relative 'bgatari'

# 画像読み込み
pimg = Image.loadTiles("player_512x256_64x64.png", 512 / 64, 256 / 64)
bgimg = Image.loadTiles("bg_attari.png", 256 / 16, 256 / 16)

# tmx読み込み
scrw, scrh = Window.width, Window.height
tmx = DxrbTmx.new("./bg_atari_test.tmx", scrw, scrh)

# Bgレイヤーマップデータ取得
atari_layer = tmx.get_layer("bg_atari")
bg_layer0 = tmx.get_layer("layer0")
bg_layer1 = tmx.get_layer("layer1")
bg_layer2 = tmx.get_layer("layer2")
bg_layer3 = tmx.get_layer("layer3")

bgtw, bgth = tmx.screenwidth, tmx.screenheight

# BGアタリテーブル作成
bgatari = BgAtari.new(bgimg, atari_layer, scrw, scrh, 0, 22, 30)

# カーソル描画用メソッド
def draw_cursor(x, y, col)
  w = 2
  Window.drawLine(x - w, y, x + w, y, col)
  Window.drawLine(x, y - w, x, y + (w + 1), col)
end

# プレイヤーのアニメパターンを定義
ppat = { "walk" => 0, "jump" => 16}
pimgnum = ppat["jump"]

bx, by = 0, 0
px, py = scrw / 2, scrh / 2
dx, dy = 0, 0
gravity = 0.45
bgatari_disp = false

# メインループ
Window.loop do
  break if Input.keyPush?(K_ESCAPE)

  # Bキーを押したらBGアタリ表示と切替
  bgatari_disp = !bgatari_disp if Input.keyPush?(K_B)

  # プレイヤー移動処理

  # 左右キーで横移動
  # x速度に、キー入力に応じて加速度を加算
  dx += Input.x * 0.2

  # 横方向の最大速度を超えないようにする
  spdmax = 6.0
  dx = spdmax if dx >= spdmax
  dx = -spdmax if dx < -spdmax

  # 左右キーを押してなければ、速度を減らしていく
  dx *= 0.95 if Input.x == 0

  # 速度を加算
  px += dx
  py += dy

  # ----------------------------------------
  # 壁アタリで補正する ← new!

  # 右側にBGアタリがあるかチェック
  xadd, yadd = 32, -32
  nx, ny = bgatari.adjust_bg_hit(px + xadd, py + yadd, BgAtari::ADJUST_LEFT)
  if nx
    # 右方向にアタリがある
    px = nx - xadd # 座標を補正
    dx = 0 # x速度を0に
  end

  # 左側にBGアタリがあるかチェック
  xadd, yadd = -32, -32
  nx, ny = bgatari.adjust_bg_hit(px + xadd, py + yadd, BgAtari::ADJUST_RIGHT)
  if nx
    # 左方向にアタリがある
    px = nx -xadd # 座標を補正
    dx = 0 # x速度を0に
  end

  # 壁アタリ補正ここまで
  # ----------------------------------------

  # 床アタリで補正する

  # 床の上に居る時だけ、足元よりちょっと下の座標でアタリを取る
  yadd = (pimgnum == ppat["jump"])? 0 : 12
  nx, ny = bgatari.adjust_bg_hit(px, py + yadd, BgAtari::ADJUST_UP)

  if nx == nil
    # 足元に床が無い
    dy += gravity # 重力加速度を、速度に加算
    pimgnum = ppat["jump"] # 落下ポーズに変更
  else
    # 足元に床がある
    py = ny
    dy = 0 # y速度を0にする
    pimgnum = ppat["walk"] # 床の上に居るポーズに変更
  end

  # プレイヤー移動処理ここまで

  # プレイヤーの位置から、BGスクロール座標を決定
  bx += ((px.to_i - (scrw / 2) - bx) * 0.2).to_i
  by += ((py.to_i - (scrh / 2) - by) * 0.2).to_i

  # BG描画
  if bgatari_disp
    Window.drawTile(0, 0, atari_layer, bgimg, bx, by, bgtw, bgth)
  else
    Window.drawTile(0, 0, bg_layer3, bgimg, bx / 8, by / 8, bgtw, bgth)
    Window.drawTile(0, 0, bg_layer2, bgimg, bx / 4, by / 4, bgtw, bgth)
    Window.drawTile(0, 0, bg_layer1, bgimg, bx / 2, by / 2, bgtw, bgth)
    Window.drawTile(0, 0, bg_layer0, bgimg, bx, by, bgtw, bgth)
  end

  # プレイヤー描画
  x = px - bx
  y = py - by
  img = pimg[pimgnum]
  Window.draw(x - 32, y - 57, img)

  # プレイヤー座標にカーソルを描画
  draw_cursor(x, y, C_RED)
  draw_cursor(x + 32, y - 32, C_RED)
  draw_cursor(x - 32, y - 32, C_RED)
end
床補正をする直前に、壁補正を入れてみました。

さて、結果は。
壁アタリ処理を追加したが…

Oops! 左右に進めません…。なんでや…。

こういう状態になってるわけですな。


さて、どうやって解決しよう…。

考えてみたら、壁として扱うべきBGアタリは、今のところ四角いブロックだけですので…。横方向にBGアタリがあった際、ソレが四角いブロック(壁相当)だった時だけ、壁補正をすることにしてみましょうか。
壁は四角いブロックだけ

_playermove2.rb.txt

  # 右側にBGアタリがあるかチェック
  xadd, yadd = 32, -32
  nx, ny = bgatari.adjust_bg_hit(px + xadd, py + yadd, BgAtari::ADJUST_LEFT)
  if nx and (1..2).member?(bgatari.bg_code)
    # 右方向に「壁」アタリがある
    px = nx - xadd # 座標を補正
    dx = 0 # x速度を0に
  end
(1..2).member?(bgatari.bg_code) で、BGアタリ番号が 1〜2 の時だけ、壁補正をする、という処理になってます。

…Ruby って、「その範囲の中に入ってるか?」を、こういう風に書けるのですな。今まで知りませんでした…。(ググってみて知りました…。) Ruby、便利だなあ。

壁補正もしている版

うむ。これで大丈夫そうです。

しかし、コレ、穴に落ちたら脱出できませんな…。明日は、ジャンプ処理を追加して、もっとあちこちに動けるようにしましょうかね。

壁補正についての余談。 :

ところで。上記の解決方法 ―― 壁相当とだけ壁補正をするというやり方も、ちと問題がありまして。下のような地形では、マズイことになるのです。
バグが発生する事例その1

どうやって解決するかは…。さて、どうすればいいのでしょう?

自分が今思いつくのは、2つぐらい、かなあ…。

一つは、壁相当とだけ壁補正するのはやっぱりやめて、BGアタリがあったらとにかく「壁」扱いしちゃう方法。最初の実装に戻しちゃうというか。その代わり、斜め床まで壁になったりしない程度に、壁をチェックする距離を短くする、とか。
壁アタリを見る位置を変える方法

もう一つは、壁アタリをチェックする位置を、もっと増やす方法。
壁アタリを複数チェックする方法
ただし、メインの壁補正 → 床補正 → サブの壁補正、といった具合に、チェックする順番に工夫が必要かもしれません。そうしないと、下図のようなバグが発生しそうだなと。
どこまでも続く「床」を、どこまでも続く「壁」として扱って、どこまでも補正され続けるバグ
あるいは、「どうも壁っぽいものがありそうなんだけど…普段見ている位置のBGアタリ番号だけでは確定できないなあ。念のために他の位置もあちこち見て判断するか」てな対処でもいいのかしら。

まあ、手っ取り早い解決策として、「おかしなことになる地形は作らない」という手も…。最悪、解決策がさっぱり思いつかないなら、そういうルールでマップを用意するのもアリですね。

2017/03/19追記。 :

Dropboxのpublicフォルダが死んだのでファイルの置き場所を変更。

#4 [zatta] ソース書いてる時間より説明図作ってる時間のほうが長いな

説明図をサクサク作れるツールとかないものか。

手描きでメモ用紙にサラサラ描いて、スキャンしてアップしちゃってもいいんだろうけど。むしろそのほうが、手作り感・趣味っぽい感じが出て良かったりして…?

以上、1 日分です。

過去ログ表示

Prev - 2013/12 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project