Hatena::Groupgamehell

ゲームプログラムめも日記 このページをアンテナに追加 RSSフィード

けんもほろろ  / オススメゲームプログラム本  / 作ったもの置き場  
ゲーム開発のデザパタまとめ  / めも日記まとめ  

2007-02-28

[]誰でも簡単! にゲームが作れるツール「dHell Lite18:06 誰でも簡単! にゲームが作れるツール「dHell Lite」 - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - 誰でも簡単! にゲームが作れるツール「dHell Lite」 - ゲームプログラムめも日記 誰でも簡単! にゲームが作れるツール「dHell Lite」 - ゲームプログラムめも日記 のブックマークコメント

勢いで作ってみた。

http://www5f.biglobe.ne.jp/~kenmo/dest/d/dhelllite.lzh

 

要は、dHellLuaから呼べるようにしただけですが、

しかし、コンパイラー不要なので、インストールが簡単!

 

まあ、こんな風にかけまする。

-- キャプション'dHell Lite' ウィンドウサイズ640x480
Hell_init("dHell Lite", 640, 480)

Hell_write("ポエド")
-- "hell.bmp"ロード。(0, 0)の色を抜き色に
Hell_loadBMP("hell", "hell.bmp", -1);
Hell_write("エグゼリカ")
-- "kin.wav"ロード
Hell_loadWAV("kin", "kin.wav");
Hell_write("カラス")
-- "bgm.ogg"をループ再生
Hell_playBgm("bgm.ogg");
Hell_write("トリオ・ザ・パンチ")

-- ゲームループ開始
while(true) do
	Hell_fillRect()
	-- マウス座標を中心に描画
	Hell_drawEx("hell", Hell_getX(), Hell_getY())
	if Hell_isPushEnter() then
		-- 決定キー(左クリック・Zボタン・ジョイスティックの1ボタン)で
		-- 効果音を鳴らす
		Hell_playWAV("kin")
	end
	Hell_drawFPS()
	Hell_update()
	Hell_wait(33) -- 30FPS
end

 

 

基本の命令はdHellです。

ただ、キー入力周りが、少し違う感じです。

isPush[Press]Enter()

 …決定キー(左クリック/Zキー/ジョイパッドの1ボタン)を押した[押している]かどうか

isPush[Press]Cancel()

 …キャンセルキー(右クリック/Xキー/ジョイパッドの2ボタン)を押した[押している]かどうか

isPush[Press]Left()

 …左(←キー/ジョイパッドの左ボタン)を押した[押している]かどうか

isPush[Press]Up()

 …上(↑キー/ジョイパッドの上ボタン)を押した[押している]かどうか

isPush[Press]Right()

 …右(→キー/ジョイパッドの右ボタン)を押した[押している]かどうか

isPush[Press]Down()

 …下(↓キー/ジョイパッドの下ボタン)を押した[押している]かどうか

getX()

 …マウスカーソルのX座標を取得

getY()

 …マウスカーソルのX座標を取得

 

 

しかし、実は、 

Luaの構文エラーをフックするには、libを作り直さなければならないみたく、

現状、トレース情報が出ないので、

構文エラーデバッグがかなりやりにくいので、実用的ではないですが……。

[]dHell Liteサンプルコード 21:33 dHell Liteサンプルコード - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - dHell Liteサンプルコード - ゲームプログラムめも日記 dHell Liteサンプルコード - ゲームプログラムめも日記 のブックマークコメント

矩形が画面端で跳ね返るだけのコードです。

-- キャプション'dHell Lite' ウィンドウサイズ640x480
Hell_init("dHell Lite", 640, 480)

Player = {}

-- 自機クラス
function Player.new()
	local obj = {
		x = 0,
		y = 0,
		dx = 0,
		dy = 0,
		w = 16,
		h = 16,
		-- 更新
		update = function(self)
			-- キー入力判定
			speed = 5
			if Hell_isPushLeft() then
				self.dx = -speed
				self.dy = 0
			end
			if Hell_isPushUp() then
				self.dx = 0
				self.dy = -speed
			end
			if Hell_isPushRight() then
				self.dx = speed
				self.dy = 0
			end
			if Hell_isPushDown() then
				self.dx = 0
				self.dy = speed
			end
			-- 移動
			self.x = self.x + self.dx
			if self.x < 0 or self.x > 640-self.w then
				-- 反転
				self.dx = -self.dx
			end
			self.y = self.y + self.dy
			if self.y < 0 or self.y > 480-self.h then
				-- 反転
				self.dy = -self.dy
			end
		end,
		-- 描画
		draw = function(self)
			Hell_fillRect(self.x, self.y, self.w, self.h, 0, 255, 0)
		end
	}
	return obj
end

-- ゲームループ開始
player = Player.new()
while(true) do
	Hell_fillRect()
	player:update()
	player:draw()
	Hell_drawFPS()
	Hell_update()
	Hell_wait(1000/60) -- 60FPS
end

作ってて、三角関数とか乱数が使えないことに気づきましたが……。

module("main",package.seeall)

が通らなかった……。

追記

luaopen_math(lua_State* L);

してないだけでした。

あと、moduleモジュールの定義だそうな……。

[]デバッグのフック 01:14 デバッグのフック - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - デバッグのフック - ゲームプログラムめも日記 デバッグのフック - ゲームプログラムめも日記 のブックマークコメント

function myHook(event, line)
	info = debug.getinfo(2)
	Hell_write(info.currentline, ":", info.name)
end

-- フック開始
debug.sethook(myHook, "l")

こんな風に書くと、1行進めるたびに実行している行数と上位の関数名がトレースされるので、

エラー部分が特定できます。

 

……まあ、lua_getinfo()ができればそれにこしたことはないのですが、、。

追記

Hell_write()でログをガリガリ書き続けると、なぜか落ちてしまうので、

Luaグローバル変数に実行行の行番号を設定するようにしてみた。

-- デバッグフック関数
function myHook(event, line)
	__LINE__ = line -- 現在の実行行
end

-- フック開始
debug.sethook(myHook, "l")

こうすれば、D側で、

// Lua内のグローバル変数"__ERROR_MESSAGE"を取得
lua_pushstring(lua, "__LINE__");
lua_gettable(lua, LUA_GLOBALSINDEX);
int line = readInt(lua, "例外フック", -1);
Hell_write(line);
Hell_writeln("行目あたりで問題が起きたようです");

とすれば、

dHellシステムを開始します。
予期せぬエラーが発生しました。
71行あたりで問題が起きたようです

こんな感じでトレースできた!!

よかった、よかった。

 

しかし、構文チェックできないのは相変わらず。むう……。

追記2

Luaの構文チェックができないー、できないー、と思っていたのですが、

http://phi.lho.free.fr/index.en.html

ここから、LuaExe-5.0.2.zipを落としてきて、luaC.exeを通せば、構文チェックできる、

ということで、kenmo的には解決しました。はい。

 

追記3

http://chy.s25.xrea.com/mt/archives/2004/07/lua.html

を参考にVCビルドしたけど、D言語libとはなんか違うみたいで、「Invalid Lib」とか言って怒られてしまいました。

むー、dmcビルドしないとダメみたいですね。

[]リンク集 13:32 リンク集 - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - リンク集 - ゲームプログラムめも日記 リンク集 - ゲームプログラムめも日記 のブックマークコメント

Luaを組み込むにあたって、特に役に立ったリンク集を。

[][]デバッグAPI 追記4 21:37 デバッグAPI 追記4 - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - デバッグAPI 追記4 - ゲームプログラムめも日記 デバッグAPI 追記4 - ゲームプログラムめも日記 のブックマークコメント

dmdでもlibは作れるみたいで、作ってみたのですが、謎のリンカエラー

やけになって、「lua.d」の349行目あたりに、

extern(C):
struct lua_Debug {
・
・
・

「extern(C):」をつけて、

dmd -c lua.d

でobjファイル作って、objをリンクしたら動いたという、しょーもないオチでした。

[]トークントークン管理 00:45 トークンとトークン管理 - ゲームプログラムめも日記 を含むブックマーク はてなブックマーク - トークンとトークン管理 - ゲームプログラムめも日記 トークンとトークン管理 - ゲームプログラムめも日記 のブックマークコメント

ABAさん方式のテンプレートと管理方法をLuaでやってみる。

継承の実現方法がまだ分っていないので、トークンベタですがー。

Particle = {}
-- パーティクルクラス
function Particle.new()
	local obj = {
		x     = 0,
		y     = 0,
		dx    = 0,
		dy    = 0,
		w     = 16,
		h     = 16,
		timer = 0,
		exist = false,
		-- 生成
		create = function(self, x, y, dx, dy)
			self.exist = true
			self.x     = x
			self.y     = y
			self.dx    = dx
			self.dy    = dy
			self.timer = 120
		end,
		-- 消滅
		vanish = function(self)
			self.exist = false
		end,
		-- 更新
		update = function(self)
			self.dx = self.dx * 0.98
			self.dy = self.dy * 0.98
			self.x = self.x + self.dx
			self.y = self.y + self.dy
			if self.x < 0 or self.x > 640 or self.y < 0 or self.y > 480  then
				self.exist = false
			end
			self.timer = self.timer - 1
			if self.timer < 1 then
				self.exist = false
			end
		end,
		-- 描画
		draw = function(self)
			if self.timer < 30 and math.mod(self.timer, 4) < 2 then
				return
			end
			Hell_fillRect(self.x, self.y, self.w, self.h, 0, 255, 0)
		end
	}
	return obj
end

-- トークン管理クラス
TokenManager = {}
function TokenManager.new()
	local obj = {
		tokens = {},
		-- 初期化
		init = function(self, Token, size)
			for i = 0, size do
				self.tokens[i] = Token.new()
			end
		end,
		-- 取得
		getToken = function(self)
			for key, token in pairs(self.tokens) do
				if not token.exist then
					return token
				end
			end
			return nil
		end,
		-- 生成
		create = function(self, x, y, dx, dy)
			token = self:getToken()
			if token == nil then
				return
			end
			token:create(x, y, dx, dy)
		end,
		-- 更新
		update = function(self)
			for key, token in pairs(self.tokens) do
				if token.exist then
					token:update()
				end
			end
		end,
		-- 描画
		draw = function(self)
			for key, token in pairs(self.tokens) do
				if token.exist then
					token:draw()
				end
			end
		end
	}
	return obj
end

ParticleManager = TokenManager.new()
-- インスタンスは64個で
ParticleManager:init(Particle, 64)

-- キャプション'dHell Lite' ウィンドウサイズ640x480
Hell_init("dHell Lite", 640, 480)
-- ゲームループ開始
while(true) do
	if math.random()*100 < 10 then
		-- 1/10で生成
		ParticleManager:create(
			math.random()*320+160, math.random()*240+120,
			math.random()*6-3,     math.random()*6-3)
	end
	Hell_fillRect()
	ParticleManager:update()
	ParticleManager:draw()
	Hell_drawFPS()
	Hell_update()
	Hell_wait(1000/60) -- 60FPS
end

KouMikageKouMikage2007/03/02 21:03>lib
VCのはCOFFとかいうフォーマットらしいです。COFFも古いのと新しいので二種類あるらしいです。
そんでDigitalMarsやBorlandのコンパイラはOMFフォーマットのバイナリをはくのでリンクできないのです…
インポートライブラリだけならVCでdll作ってDMCのimplibで作れますたぶん。

kenmokenmo2007/03/02 21:36みたいですねー。
まあ、結果はlibは無関係という、しょーもないことでして、お騒がせしました、、。