シンプルだが非常にギャンブルのおもちゃを書いています。 このゲームはクラッシュと呼ばれます 彼らは眼鏡を奪うように、圧力Osを避けるために、昆虫を粉砕する必要があります、他の昆虫は眼鏡を追加します。 すべての昆虫のサイズ、報酬、移動速度は異なります。 ゲームには一定の時間が与えられているため、適切な動物のプレッシャーのスキルで、友達と競争することができます。 最良の結果が記録され、ゲーム設定に保存されます。
プロジェクト設定
すべてのプロジェクト設定は、config.luaおよびbuild.settingsファイルに含まれています。 config.luaの内容全体を削除し、次の行のみを残すことにしました。
application = {
}
プロジェクトは、画面の固定サイズが320 * 480(デフォルト)であると「考え」ようと、どのデバイスでも試行しています。常に現在の画面解像度で作業します。 build.settingsファイルで、 settings.android.usesPermissionsセクションに新しい権限を追加しました。この権限は、スズメバチに触れたときに振動でバズする権利を与えます 。 「android.permission.VIBRATE」という行が追加されます。 、コード行system.vibrate()はこれらの権利を使用します。
エントリポイントmain.lua
劇場はハンガーから始まり、プロジェクトはmain.luaファイルの最初の行で飾られます。 このファイルにグローバル変数とグローバル定数を保存し、プロジェクトで必要となる残りのファイルをプロジェクトに接続するのが一般的です。 ファイルの最後に、メインプロジェクトシーンがロードされます。
main.luaの完全なコードは次のとおりです。
--[[ ]] -- StatusBar display.setStatusBar (display.HiddenStatusBar) --[[ ]] -- _W = display.contentWidth _H = display.contentHeight font = 'a_LCDNova'-- time_battle = 10-- -- filePath = system.pathForFile( 'config.dat', system.DocumentsDirectory ) composer = require("composer")-- -- path = 'assets/images/' path_interface = path .. 'interface/' path_bugs = path .. 'bugs/' path_plods = path .. 'plods/' -- widget = require( "widget" )--GUI ls = require "libLoadSave"--/ api = require "libAPI"-- bugs = require "svcBugs"-- finish = require "svcFinish"-- "" game = require "svcGame"-- battle = nil-- ls.load() -- -- game.init() --scMain , composer.gotoScene( "scMain", "crossFade", 0 )
メインシーン
scMain.luaファイルは、ゲームのメインシーンです。 このプロジェクトでは、シーンが1つしかないため、そのアプリケーションは疑わしいですが、トレーニングプロジェクトとシーンは、実験でさらにシーンを追加することにした場合に役立ちます。 メインシーンでは、libGameライブラリからinit()関数を実行するという1つのアクションのみが実行されます。 そして、この関数はゲームの一定のインターフェース全体を描画します。 アプリケーションの使用が終了するまで削除されない部分。 ファイルコードは次のとおりです。
--------------------------------------- -- -- --------------------------------------- local scene = composer.newScene() scene:addEventListener( "show", scene ) function scene:show( event ) if "will" == event.phase then game.init() end end return scene
ゲームの静的コンポーネントのサービス。
このサービスはsvcGame.luaファイルに保存され、プロジェクトへの接続はmain.luaの行によって実行されます。game = require "svcGame" ie コードに沿ってさらにライブラリ関数を呼び出して、ゲーム名に追加します。 ライブラリには次の機能があります。
- game.init() -一度実行すると、草、メニューの上下、現在および最良の結果を表示するためのコンポーネント、ゲーム起動ボタン、バトルタイマーを表示するコンポーネントが作成されます。
- ゲーム。 refresh() -この関数は、ゲームのパラメーターを変更するたびに実行されます。これにより、昆虫が殺され( スコアが更新され )、バトルタイマーがチェックされます ( プログレスバーが更新されます )。 この関数は、すべてのインジケーターの現在の状態を更新します。
- ゲーム。 startGame() -開始ボタンをクリックするためのハンドラー。 この関数は現在の結果をリセットし、time_battle定数で指定された期間ゲームタイマーを開始します。 タイマーでは、昆虫が作成されます。
完全なsvcGame.luaコード:
------------------------------------------------------- -- -- ------------------------------------------------------- local M = { GR = {},-- GUI = {},-- } -- M.startGame = function(event) if event.phase == 'ended' then -- battle.timer = time_battle battle.cur_score = 0 M.refresh() -- timer.performWithDelay(100, function(event) if event.count%10==0 then-- 10- -- battle.timer = battle.timer - 1 M.refresh() end if event.count%2==1 then-- -- bugs.create(M.GR.bugs) end if event.count == time_battle*10 then-- -- finish.show() end end,time_battle*10) end end -- M.refresh = function() -- M.GUI.txt_count.text = battle.cur_score -- M.GUI.txt_best.text = battle.best_score --- M.GUI.pr_txt.text = battle.timer -- M.GUI.pr.width = _W * .79 * (time_battle - battle.timer) / time_battle M.GUI.pr.x = _W * .105 + M.GUI.pr.width * .5 -- 0 M.GUI.pr.isVisible = battle.timer > 0 M.GUI.pr_txt.isVisible = battle.timer > 0 M.GUI.pr_bg.isVisible = battle.timer > 0 -- 0 M.GUI.btn_start.isVisible = battle.timer == 0 end -- M.init = function() -- M.GR.back = display.newGroup()-- M.GR.bugs = display.newGroup()-- M.GR.front = display.newGroup()-- --[[ ]] -- M.GUI.bg = display.newImage(M.GR.back,path_interface..'bg.jpg', _W*.5, _H * .5) M.GUI.bg.width = _W M.GUI.bg.height = _H --[[ ]] -- M.GUI.up = display.newRect(M.GR.front, _W * .5, _H * .05, _W, _H * .1) M.GUI.up.strokeWidth = _H * .01 M.GUI.up:setStrokeColor(0,.5,0) M.GUI.up:setFillColor(0,.3,0) M.GUI.up:addEventListener('touch', function() return true end)-- -- M.GUI.img_count = display.newImage(M.GR.front, path_interface..'count.png', _H * .06, _H * .05) local img = M.GUI.img_count img.width = _H * .07 img.height = _H * .07 -- M.GUI.txt_count = display.newText(M.GR.front, '', _W * .3, _H * .05, font, _W * .1) -- M.GUI.img_best = display.newImage(M.GR.front, path_interface..'best.png', _W * .5 + _H * .06, _H * .05) local img = M.GUI.img_best img.width = _H * .07 img.height = _H * .07 --text M.GUI.txt_best = display.newText(M.GR.front, '', _W * .8, _H * .05, font, _W * .1) -- M.GUI.down = display.newRect(M.GR.front, _W * .5, _H * .95, _W, _H * .1) M.GUI.down.strokeWidth = _H * .01 M.GUI.down:setStrokeColor(0,.5,0) M.GUI.down:setFillColor(0,.3,0) M.GUI.down:addEventListener('touch', function() return true end) -- M.GUI.btn_start = widget.newButton( { width = _H * .07, height = _H * .07, defaultFile = path_interface .. "btn_start_1.png", overFile = path_interface .. "btn_start_2.png", onEvent = M.startGame, x = _W * .5, y = _H * .95, } ) -- -- M.GUI.pr_bg = display.newRoundedRect(M.GR.front, _W * .5, _H * .95, _W * .8, _H * .04, _H * .01) M.GUI.pr_bg.strokeWidth = _H * .005 M.GUI.pr_bg:setStrokeColor(0,.5,0) M.GUI.pr_bg:setFillColor(.4,.7,.4) -- M.GUI.pr = display.newRoundedRect(M.GR.front, _W * .5, _H * .95, _W * .79, _H * .035, _H * .006) M.GUI.pr:setFillColor(.7,.1,.1) -- M.GUI.pr_txt = display.newText(M.GR.front, '', _W * .5, _H * .955, font, _W * .07) M.GUI.pr_txt:setFillColor(0) -- M.refresh() end return M
昆虫作成サービス
このサービスには、ゲーム内で生き物を便利に作成する機能を提供するコンポーネントがいくつかあります。
- bugs.bugs-昆虫の設定。 昆虫は、その可用性を増減することでカスタマイズできます。
- bugs.create-昆虫が作成され、そのパスが計算され、パスに送信されます。 各昆虫には、クリックに対して昆虫が侵入できないようにするハンドラーがあります。 この昆虫とその下の昆虫をワンクリックで殺すことはできません。 また、クリックすると、ハンドラーは昆虫を削除し、ゲームスコアを更新し、新しい昆虫を作成する機能を呼び出します。昆虫を頻繁に殺す場合、昆虫の数は、見るだけの場合よりも速く増加します。
- bugs.plod-昆虫の死の場所にしみを作成します。 ブロッチ自体は0.5秒後に削除されます
svcBugs.luaサービスコードは次のとおりです。
------------------------------------------------ -- , -- -- -- -- -- ------------------------------------------------ local M = { GR = {},-- bugs = {-- -- { size = {20,30},-- - % bonus = 2,-- file = '1.png',-- speed = {30,50},-- - % }, -- { size = {25,35}, bonus = 3, file = '2.png', speed = {50,70}, }, -- { size = {15,25}, bonus = 3, file = '3.png', speed = {40,60}, }, -- { size = {20,30}, bonus = 6, file = '4.png', speed = {60,80}, }, -- { size = {35,50}, bonus = -10,-- = file = '5.png', speed = {25,50}, }, }, AR_BUGS = {},-- } -- M.plod = function(obj) local count_plod = 3-- -- local blod = display.newImage(M.GR, path_plods..math.random(count_plod)..'.png',obj.x, obj.y) -- blod.width = obj.width blod.height = obj.height -- ( ) blod:setFillColor(math.random(),0,math.random()) -- transition.to(blod,{time = 500, alpha = 0, onComplete = function() -- display.remove(blod) end}) end -- M.create = function(GR) M.GR = GR and GR or M.GR -- local sets = M.bugs[math.random(#M.bugs)] -- local bug_sets = { file = sets.file, bonus = sets.bonus, size = (math.random(sets.size[1],sets.size[2]) / 100) * _W, speed = (math.random(sets.speed[1],sets.speed[2]) / 100) * _W, } -- local ar = {-- 2 {x1 = 0, y1 = 0, x2 = _W, y2 = 0}, -- {x1 = 0, y1 = _H, x2 = _W, y2 = _H}, -- {x1 = -_H*.1, y1 = _H*.1, x2 = -_H*.1, y2 = _H*.9}, -- {x1 = _H*1.1, y1 = _H*.1, x2 = _H*1.1, y2 = _H*.9}, -- } -- 2 local l1,l2 = math.random(#ar),math.random(#ar) if l1 == l2 then if l2 == 1 then l2 = math.random(2,#ar) else l2 = l2 - 1 end end -- local x1,y1 = api.get_xy_line(ar[l1]) local x2,y2 = api.get_xy_line(ar[l2]) -- local n = #M.AR_BUGS+1 M.AR_BUGS[n] = display.newImage(M.GR, path_bugs..bug_sets.file, 0, 0) M.AR_BUGS[n].width = bug_sets.size M.AR_BUGS[n].height = bug_sets.size M.AR_BUGS[n].x = x1 M.AR_BUGS[n].y = y1 M.AR_BUGS[n].sets = bug_sets M.AR_BUGS[n].rotation = api.get_angle{x1 = x1, y1 = y1, x2 = x2, y2 = y2}-- M.AR_BUGS[n]:addEventListener('touch',function(event) if event.phase == 'began' then api.play_sound('tits') M.plod(event.target) local sets = event.target.sets battle.cur_score = battle.cur_score + sets.bonus if sets.bonus < 0 then-- system.vibrate()--;) end game.refresh() M.create() display.remove(event.target) end return true end) -- local len = api.get_line_len{x1 = x1, y1 = y1, x2 = x2, y2 = y2}-- local t = len / bug_sets.speed * 1000-- transition.to(M.AR_BUGS[n],{time = t, x = x2, y = y2, onComplete = function() display.remove(M.AR_BUGS[n]) end}) end return M
サービス「終了」
この単純なサービスには、1つのfinish.show()関数のみがあり、バトルの終わりに達するとバトルタイマーで呼び出されます。 この関数は、すべての昆虫を削除し、結果の結論でフォームを開きます。 結果が過去の最高値よりも高い場合、テキスト「NEW SCORE」が発行されます。 フォームの下に、ウィンドウが閉じるまでゲームを再起動できない保護レイヤーが作成されます。 ウィンドウをクリックすると、結果が閉じて設定ファイルに保存されます。 サービスコードの形式は次のとおりです。
------------------------------------------------ -- -- ------------------------------------------------ local M = { GUI = {}, GR = {}, } -- M.show = function() api.play_sound('win') -- for k,v in pairs(bugs.AR_BUGS) do display.remove(bugs.AR_BUGS[k]) end -- local is_new_score = battle.cur_score > battle.best_score if is_new_score then battle.best_score = battle.cur_score end -- M.GR = display.newGroup() -- M.GUI.safe = display.newRect(M.GR, _W * .5, _H * .5, _W, _H) M.GUI.safe.alpha = .5 M.GUI.safe:setFillColor(0) M.GUI.safe:addEventListener('touch', function() return true end) -- M.GUI.wnd = display.newRoundedRect(M.GR, _W * .5, _H * .5, _W * .5, _H * .2, _H * .01) M.GUI.wnd.strokeWidth = _H * .005 M.GUI.wnd:setStrokeColor(0,.5,0) M.GUI.wnd:setFillColor(0,.3,0) M.GUI.wnd:addEventListener('touch',function(event) if event.phase == 'began' then display.remove(M.GR) end end) M.GUI.txt_1 = display.newText(M.GR, 'FINISH', _W * .5, _H * .45, font, _W * .07) M.GUI.txt_2 = display.newText(M.GR, 'NEW SCORE', _W * .5, _H * .5, font, _W * .07) M.GUI.txt_2:setFillColor(1,1,0) M.GUI.txt_2.isVisible = is_new_score M.GUI.txt_2 = display.newText(M.GR, 'SCORE: '..battle.cur_score, _W * .5, _H * .55, font, _W * .07) game.refresh() ls.save()-- end return M
設定を保存およびロードするためのライブラリ
このシンプルなライブラリには、ゲームセッション間で結果を保存できる2つの関数が含まれています。
- ls.load() -ゲームの開始時に1回実行されます。これが最初の開始である場合、保存テンプレートが作成されます。最初ではない場合、過去のゲームの結果がダウンロードされます。
- ls.save() -各戦闘の後に実行され、現在の結果はファイルに保存されます。
設定は、json形式でconfig.datファイルに保存されます。 ライブラリコードの形式は次のとおりです。
------------------------------------- -- -- -- -- ------------------------------------- local M = {} local json = require("json") M.tmp_battle = { cur_score = 0,-- best_score = 0,-- timer = 0,-- } -- M.save = function(new) local file = io.open(filePath, "w") if file then local write_data = '' write_data = json.encode(battle) file:write( write_data ) io.close( file ) end end -- M.load = function() local str = "" local file = io.open( filePath, "r" ) -- if file then local read_data = file:read("*a") battle = json.decode(read_data) io.close( file ) -- else battle = M.tmp_battle M.save() end end return M
汎用機能のライブラリ。
ゲームに必要なすべての機能を格納しますが、どのモジュールにも明示的に関係せず、他の目的に使用できます。 以下の機能が利用可能です:
- api.play_sound-アセット/音楽/にある音楽ファイル(.wav)を再生します。その名前はパラメーターで渡されます
- api.get_xy_line-パラメーターで渡された2点のセグメント上にあるランダムな点の座標を返します。 この関数は、昆虫の動きのランダムな開始点と終了点を生成するために使用されます。
- api.get_line_len -2ポイントで送信されたセグメントの長さを返します。 この関数は、長さと速度から昆虫の移動時間を計算するために使用されます。
- api.get_angle-上に向かう光線と2番目の点に向けられた光線が描かれる最初の透過点の間の角度を定義します。 この関数は、昆虫の絵の回転角度を決定するために使用されます。
--------------------------------------------------- -- -- --------------------------------------------------- local M = {} -- M.play_sound = function(track) local msg = audio.loadSound("assets/music/" .. track .. ".wav") audio.play( msg,{ loops = 0, oncomplete = function(e) audio.dispose(e.handle); e.handle = nil; end}) end -- , M.get_xy_line = function(line) local x1,y1,x2,y2 = line.x1,line.y1,line.x2,line.y2 local x,y = 0,0 if x1 == x2 then x = x1 y = math.random(y1,y2) else y = y1 x = math.random(x1,x2) end return x,y end -- M.get_line_len = function(p) --√ ((X2-X1)²+(Y2-Y1)²) local len = math.sqrt((p.x2 - p.x1)^2 + (p.y2 - p.y1)^2) return len end -- M.get_angle = function(p) return ((math.atan2(p.y1 - p.y2, p.x1-p.x2) / (math.pi / 180)) + 270) % 360 end return M
おわりに
この記事で紹介されているゲームの完全なソースコードは、 こちらにあります。
Lua言語の知識が自信を持ってソースを読むことができない場合、このテーマに関する私の記事を読むことができます。
あなたのための記事は、Denis Goncharov別名execomによって準備されました
皆さんに幸運を!