print( '=== love test === : '.._VERSION )
require 'class'
require 'LoveUtil'
require 'EnglishData' -- 問題文データ
--[[
# 概要
瞬間英作文ゲーム。
# ゴール
- 繰り返しやりたくなるようにすること
- まんべんなく出題されること
# 機能
- スコア
- スコア保存機能
- ミス回数集計機能
- 出題グループ選択機能
]]
function strip( str )
local beginIndex = 1
local endIndex = 1
for i=1, #str do
if str:sub(i,i) ~= ' ' and
str:sub(i,i) ~= '\t' then
beginIndex = i
break
end
end
for i=#str, 0, -1 do
if str:sub(i,i) ~= ' ' and
str:sub(i,i) ~= '\t' then
endIndex = i
break
end
end
return str:sub( beginIndex, endIndex )
end
function GenerateTableOrder( tableCount, is_shuffle, is_reverse )
ret = {}
if is_reverse then
for i=1, tableCount do
ret[i] = tableCount - i + 1
end
else
for i=1, tableCount do
ret[i] = i
end
end
if is_shuffle then
for i=1, tableCount*5 do
local a = math.random( 10 )
local b = math.random( 10 )
ret[a], ret[b] = ret[b], ret[a]
end
end
return ret
end
----------------------------------------------------------------------
-- Game
----------------------------------------------------------------------
Game = Class()
function Game:init()
-- self.Font
-- self.EnglishDataLst
-- self.LastResumeParam
-- self.Coroutine
end
function Game:load()
self.Coroutine = coroutine.create( function( ... ) self:CoMain( ... ) end )
coroutine.resume( self.Coroutine )
end
function Game:keypressed( key, unicode )
Game.CoResume( self.Coroutine, Game.ResumeType.Keyboard, key, unicode )
end
function Game:update( dt )
Game.CoResume( self.Coroutine, Game.ResumeType.Update )
end
function Game:draw()
Game.CoResume( self.Coroutine, Game.ResumeType.Draw )
end
function Game:GetEnglishDataCount()
return #self.EnglishDataLst
end
function Game:GetEnglishData( index )
return self.EnglishDataLst[index]
end
function Game.DrawJapanese( text )
LoveUtil.DrawTextCenter( text, 0, love.graphics.getHeight() / 2 - 40 )
end
function Game.DrawInputString( text, pronpt, cursor )
local posY = love.graphics.getHeight() / 2
local inputStr = text
inputStrPosX, inputStrWidth = LoveUtil.DrawTextCenter( inputStr, 0, posY )
if pronpt then
love.graphics.print( '>', inputStrPosX - 13, posY )
end
if cursor then
love.graphics.print( '|', inputStrPosX + inputStrWidth, posY )
end
end
Game.ResumeType = { Update=1, Draw=2, Keyboard=3 }
function Game:CoYield()
self.LastResumeParam = { coroutine.yield() }
return self.LastResumeParam
end
function Game.CoResume( ... )
local result = { coroutine.resume( ... ) }
if result[1] == false then -- コルーチン内でエラーがあった場合
print( result[2] )
end
end
function Game:CoMain()
-- 初期化
self.Font = love.graphics.newFont( 'RictyDiscord-Regular.ttf', 20 )
love.graphics.setFont( self.Font )
self.EnglishDataLst = {}
for i=1, #EnglishData_SyunkanEisakubun do
self.EnglishDataLst[i] = EnglishData.new( EnglishData_SyunkanEisakubun[i] )
end
self:CoYield()
while true do
-- モードセレクト画面
local selectIndex, is_shuffle = self:CoModeSelect()
-- 項目出現順番を決定
local ItemOrder = GenerateTableOrder( self.EnglishDataLst[selectIndex]:GetItemCount(), is_shuffle )
local CurrentItemIndex = 1
-- 問題回答ループ
while true do
local CurrentItemIndexRaw = ItemOrder[CurrentItemIndex]
local japaneseString = self.EnglishDataLst[selectIndex]:GetItemTextJapanese( CurrentItemIndexRaw )
local englishString = self.EnglishDataLst[selectIndex]:GetItemTextEnglish ( CurrentItemIndexRaw )
local result = self:CoInputAnswer( japaneseString, englishString )
if result == 'Next' then
-- 次の問題へ
CurrentItemIndex = CurrentItemIndex + 1
-- 終了チェック
if CurrentItemIndex > self.EnglishDataLst[selectIndex]:GetItemCount() then
break
end
elseif result == 'Escape' then
-- 中止
break
end
end
end
end
function Game:CoModeSelect()
local is_shuffle = false
local CursorPos = 1
local resumeParam = self.LastResumeParam
while true do
-- キーボード入力の場合
if resumeParam[1] == Game.ResumeType.Keyboard then
local key, unicode = resumeParam[2], resumeParam[3]
if key == 'up' then
CursorPos = CursorPos - 1
if CursorPos < 1 then CursorPos = 1 end
end
if key == 'down' then
CursorPos = CursorPos + 1
if CursorPos > self:GetEnglishDataCount() then CursorPos = self:GetEnglishDataCount() end
end
if key == 'return' then
return CursorPos, is_shuffle
end
if key == 's' then
is_shuffle = not is_shuffle
end
-- 描画の場合
elseif resumeParam[1] == Game.ResumeType.Draw then
LoveUtil.DrawTextCenter( '問題選択', 0, 20 )
LoveUtil.DrawTextCenter( 'シャッフル(sキーで切り替え)', 0, love.graphics.getHeight() - 40 )
if is_shuffle then
LoveUtil.DrawTextCenter( 'ON', 0, love.graphics.getHeight() - 20 )
else
LoveUtil.DrawTextCenter( 'OFF', 0, love.graphics.getHeight() - 20 )
end
for i=1, self:GetEnglishDataCount() do
-- love.graphics.print( i..' : "'..self:GetEnglishData( i ):GetTitle()..'"', love.graphics.getWidth() / 2 - 60, i * 20 )
local posY = i * 20 + 40
local posX, width = LoveUtil.DrawTextCenter( self:GetEnglishData( i ):GetTitle(), 0, posY )
if i == CursorPos then
local r, g, b, a = love.graphics.getColor()
love.graphics.setColor( 128, 128, 255, 96 )
love.graphics.rectangle( 'fill', posX, posY, width, 20 )
love.graphics.setColor( r, g, b, a )
end
end
end
resumeParam = self:CoYield()
end
end
function Game:CoInputAnswer( japaneseString, englishString )
local resumeParam = self.LastResumeParam
local thisFrameInputString = ''
local currentCollectCount = 0
local beginTime = love.timer.getTime()
local GetTimeElapse = function() return love.timer.getTime() - beginTime end
-- print ( 'japaneseString:'..japaneseString )
-- print ( 'englishString :'..englishString )
while true do
-- キーボード入力の場合
if resumeParam[1] == Game.ResumeType.Keyboard then
local key, unicode = resumeParam[2], resumeParam[3]
if unicode > 31 and unicode < 127 then
thisFrameInputString = thisFrameInputString .. string.char(unicode)
end
if key == 'escape' then
return 'Escape'
end
-- 更新処理の場合
elseif resumeParam[1] == Game.ResumeType.Update then
if englishString:lower():find( thisFrameInputString:lower(), currentCollectCount + 1, true ) == currentCollectCount + 1 then
currentCollectCount = currentCollectCount + #thisFrameInputString
-- 文章が完成したら、次の問題へ
if currentCollectCount == #englishString then
return 'Next'
end
end
thisFrameInputString = ''
-- 描画の場合
elseif resumeParam[1] == Game.ResumeType.Draw then
Game.DrawJapanese( japaneseString )
Game.DrawInputString( englishString:sub( 1, currentCollectCount ), true--[[pronpt]], ( GetTimeElapse() % 2 ) < 1.0 --[[cursor]] )
end
resumeParam = self:CoYield()
end
end
----------------------------------------------------------------------
-- Love Callback
----------------------------------------------------------------------
function love.load()
GameIns = Game.new()
GameIns:load()
end
function love.keypressed(key, unicode)
GameIns:keypressed(key, unicode)
end
function love.update(dt)
GameIns:update(dt)
end
function love.draw()
GameIns:draw()
end