Слияние кода завершено, страница обновится автоматически
#include "scenecontrol.hpp"
namespace VN{
bool second=false;
void ChooseProgress::OnChanged(double v){}
ChooseProgress::ChooseProgress(Window* w,SDL_Rect& r,double init,SDL_Color back,
SDL_Color front,int bound):ProgressBar(w,r,init,back,front,bound){}
const string _audio_path("audio/"),_sound_path("sound/");
GameScene& GameScene::Choose(vector<TextMod> text,
vector<Sentence> o,int t,void(*timeout)(GameScene*)){
limit_value=1./t;
limit_time->SetProgress(1);
limit_time->SetVisible(true);
limit_time->SetEnable(true);
limit_task=new Task{0,(TaskCallback)timeout,0,(unsigned int)t};
return Choose(text,o);
}
void GameScene::OpenBackLog(){
backlog->SetVisible(!backlog->visible());
}
void GameScene::ChooseLimit(GameScene* g){
g->limit_time->SetProgress(g->limit_time->GetProgress()-g->limit_value);
if(g->limit_time->GetProgress()-g->limit_value<0.){
g->limit_task->finish(g);
g->EndChoose();
}
}
void GameScene::LoadAudio(){
auto& m=audio;
for(auto& s:pack.GetDir("audio/")->file){
auto v=Mix_LoadMUS_RW(SDL_RWFromConstMem(s.second->c_str(),s.second->size()),1);
auto temp=s.first;
for(auto i=temp.begin(),e=temp.end();i!=e;i++){
if(*i=='.'){
temp.erase(i,temp.end());
break;
}
}
m.emplace(temp,v);
}
}
void GameScene::LoadSound(){
auto& m=sound;
for(auto& s:pack.GetDir("sound/")->file){
auto v=Mix_LoadWAV_RW(SDL_RWFromConstMem(s.second->c_str(),s.second->size()),1);
auto temp=s.first;
for(auto i=temp.begin(),e=temp.end();i!=e;i++){
if(*i=='.'){
temp.erase(i,temp.end());
break;
}
}
m.emplace(temp,v);
}
}
GameScene& GameScene::NextAction(int t,Action f){
next_action=f,next_time=t;
return *this;
}
void GameScene::ShakeCallback(GameScene* g,int t){
static int _x[8]={-20,0,0,20,20,0,0,-20},
_y[8]={-20,20,20,0,0,-20,-20,20};
t--;
g->game_back->OffsetPosition(_x[t&7],_y[t&7]);
}
GameScene& GameScene::ShakeBackground(int times){
return AddAction(8*times,ShakeCallback);
}
bool GameScene::IsCGUnlock(initializer_list<const char*> l){
for(auto& name:l){
if(cg.find(name)==cg.end())return false;
}
return true;
}
GameScene::GameScene(const char* default_language,Font* main_font,initializer_list<SDL_Color> _control_color,initializer_list<int> control_size,initializer_list<UIConfig> config,const char* version,Window* w,SDL_Color default_text_color,const char* main_back_path,const char* init_main_back,
const char* general_back_path,const char* dialog_back,const char* name_back,
const char* back_group_name,const char* first_game_back,const char* main_music,SDL_Color time_color,
initializer_list<ResGroup>& res_pair,initializer_list<Chapter*>& chapters,
SaveFunc sf,SaveFunc lf,vector<SDL_Point> control_pos,const char* progress_bg,const char* effect_fg,const char* music_fg):version(version),Control(w),save_f(sf),load_f(lf),
default_text_color(default_text_color),pack("assets"),main_music(main_music),chapter(chapters),res(res_pair.size()),cur_language(default_language),main_font(main_font),control_color(_control_color),ui_size(control_size){
ui_config.reserve(config.size());
limit_task=0;
is_gaming=false;
music_cache="";
next_time=0;
LoadAudio();
LoadSound();
auto _r=w->renderer;
progress_t=_r->LoadTexture(progress_bg);
music_t=_r->LoadTexture(music_fg);
effect_t=_r->LoadTexture(effect_fg);
for(auto& n:res_pair){
res.emplace(n.name,new ResUnit(_r,pack,n.dir));
}
naction=0;
fade_end=false;
_auto=0;
layer=-1;
_area.x=0,_area.y=0,_area.w=1280,_area.h=720;
effect_mute=false;
music_mute=false;
music_volume=SDL_MIX_MAXVOLUME;
effect_volume=SDL_MIX_MAXVOLUME;//480*270
general_back=(Image*)w->AddControl(new Image(w,{0,0},general_back_path));
cg_go_back=(TextButton*)w->AddControl(new GoBack(control_pos[5],this,"",default_text_color));
SDL_Rect r{280,0,1000,720};
cg_view=(ListView*)w->AddControl(new CGList(w,r,40,20,480,270,{255,175,115,130},{255,175,115,130},{255,175,115,130}));
save_go_back=(TextButton*)w->AddControl(new GoBack(control_pos[5],this,"",default_text_color));
confirm=(TextButton*)w->AddControl(new ConfirmSaveButton({50,500},this,"",default_text_color));
save_list=(ListView*)w->AddControl(new TableView(w,r,0,0,500,360,{255,175,115,130},{255,175,115,130},{255,175,115,130}));
r={50,400,160,60};
save_name=(InputBox*)w->AddControl(new SaveName(w,r,""));
option_go_back=(TextButton*)w->AddControl(new GoBack(control_pos[5],this,"",default_text_color));
auto p6=control_pos[6],p7=control_pos[7];
p6.x-=default_font->height(),p7.x-=default_font->height();
effect_box=(CheckBox*)w->AddControl(new EffectBox(p6,this));
music_box=(CheckBox*)w->AddControl(new MusicBox(p7,this));
auto s=default_font->height();
auto& lp=control_pos[12];
r={lp.x,lp.y,120,s+10};
language_select=(LanguageSelect*)w->AddControl(new LanguageSelect(this,r,{},s));
SDL_Rect bar_rect;
effect_text=(Label*)w->AddControl(new Label(w,control_pos[6],"",default_text_color));
music_text=(Label*)w->AddControl(new Label(w,control_pos[7],"",default_text_color));
bgm_text=(Label*)w->AddControl(new Label(w,control_pos[11],"",default_text_color));
p6=control_pos[6],p7=control_pos[7];
p6.x+=effect_text->area().w;
p7.x+=music_text->area().w;
effect_bar=(TextureBar*)w->AddControl(new EffectBar(SDL_Rect{p6.x,p6.y,512,s},this,effect_t,progress_t));
music_bar=(TextureBar*)w->AddControl(new MusicBar(SDL_Rect{p7.x,p7.y,512,s},this,music_t,progress_t));
speed_text=(Label*)w->AddControl(new Label(w,control_pos[8],"",default_text_color));
speed_normal=(TextButton*)w->AddControl(new AutoPlayNormalButton(control_pos[9],this,"",default_text_color));
speed_fast=(TextButton*)w->AddControl(new AutoPlayFastButton(control_pos[10],this,"",default_text_color));
r={0,0,1280,720};
main_back=(CGImage*)w->AddControl(new CGImage(w));
start_game=(TextButton*)w->AddControl(new StartGameButton(control_pos[0],this,"",default_text_color));
load=(TextButton*)w->AddControl(new LoadSaveButton(control_pos[1],this,"",default_text_color));
enter_cg=(TextButton*)w->AddControl(new EnterCGButton(control_pos[2],this,"",default_text_color));
main_option=(TextButton*)w->AddControl(new EnterOptionButton(control_pos[3],this,"",default_text_color));
quit=(TextButton*)w->AddControl(new QuitButton(control_pos[4],w,"",default_text_color));
SDL_SetTextureBlendMode(start_game->_t,SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(load->_t,SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(enter_cg->_t,SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(main_option->_t,SDL_BLENDMODE_BLEND);
SDL_SetTextureBlendMode(quit->_t,SDL_BLENDMODE_BLEND);
back_main=new EnterMainButton({50,650},this,"",default_text_color);
auto_play=new AutoPlayButton({750,550},this,"",default_text_color);
go_save=new EnterSaveButton({1000,550},this,"",default_text_color);
go_load=new LoadSaveButton({900,550},this,"",default_text_color);
go_option=new EnterOptionButton({1100,550},this,"",default_text_color);
open_backlog=new OpenBackLogButton({550,550},this,"",default_text_color);
skip=new SkipButton({650,550},this,"",default_text_color);
r={25,490,200,40};
name=new NameImage(this,r,name_back);
r={0,0,1280,720};
auto unit=res.find(back_group_name)->second;
game_back=new LayerImage(w,unit,r);
r.y=520,r.h=200;
dialog=new AutoPlayText(w,r,dialog_back,(TaskCallback)DialogCallback,this);
r.y=0;
r.h=520;
backlog=new ListView(w,r,2,s,{255,175,115,130},{255,175,115,130},{255,175,115,130});
r=bgm_text->area();
r.y+=ui_size[11];
r.w=200;
r.h=520-r.y;
music_list=(ListView*)w->AddControl(new ListView(w,r,10,s,{255,175,115,130},{255,175,115,130},{255,175,115,130}));
for(auto& n:audio){
music_list->AddItem(new MusicItem(this,n.first.c_str(),main_font));
}
backlog->SetVisible(false);
dialog->SetEnable(false);
_visible=true;
game_back->SetLayerVisible({first_game_back},true).AddLayer({first_game_back});
cur_ch=chapter.begin();
on_choose=false;
r={440,0,400,50};
limit_time=new ChooseProgress(w,r,1.,Color::Black,time_color);
limit_time->SetVisible(false);
limit_time->SetEnable(false);
is_flash=false;
for(auto& n:config)ui_config.emplace(n.language,n),language_select->Add(n.language);
auto g=ui_config.find(default_language);
if(g!=ui_config.end()){
auto& c=g->second;
auto& size=ui_size;
auto& a=c.text;
start_game->SetText(a[0],main_font,control_color[0],size[0],{255,255,255,255});
load->SetText(a[1],main_font,control_color[1],size[1],{255,255,255,255});
enter_cg->SetText(a[2],main_font,control_color[2],size[2],{255,255,255,255});
main_option->SetText(a[3],main_font,control_color[3],size[3],{255,255,255,255});
quit->SetText(a[4],main_font,control_color[4],size[4],{255,255,255,255});
go_option->SetText(a[3]);
cg_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
save_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
option_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
effect_text->SetText(a[6],main_font,control_color[6],size[6],{255,255,255,255});
music_text->SetText(a[7],main_font,control_color[7],size[7],{255,255,255,255});
auto& er=effect_text->area();
auto& mr=music_text->area();
effect_bar->SetPosition(er.x+er.w,er.y);
music_bar->SetPosition(mr.x+mr.w,mr.y);
effect_bar->area().h=er.h;
music_bar->area().h=mr.h;
speed_text->SetText(a[8],main_font,control_color[8],size[8],{255,255,255,255});
speed_normal->SetText(a[9],main_font,control_color[9],size[9],{255,255,255,255});
speed_fast->SetText(a[10],main_font,control_color[10],size[10],{255,255,255,255});
bgm_text->SetText(a[11],main_font,control_color[11],size[11],{255,255,255,255});
save_name->SetAlert(a[12]);
confirm->SetText(a[13]);
skip->SetText(a[14]);
auto_play->SetText(a[15]);
go_load->SetText(a[16]);
go_save->SetText(a[17]);
back_main->SetText(a[18]);
open_backlog->SetText(a[19]);
auto ch=*cur_ch;
ch->pos=(*cur_ch)->content.find(default_language)->second.begin();
}
else{
throw "Err:default language error\n";
}
unsigned int n=1;
TableItem* ti;
auto ch_dir=pack.GetDir("cg/");
auto& _map=unit->res_map;
auto& _v=unit->res;
for(auto& item:ch_dir->file){
string p(item.first);
auto ptr=item.second;
auto i=p.begin(),e=p.end();
while(i!=e){
if(*i=='.'){
p.erase(i,e);
break;
}
i++;
}
auto t=_belong->renderer->LoadTextureRW(ptr->data(),ptr->size());
SDL_SetTextureBlendMode(t,SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(t,0);
cg.emplace(p,CGPack{t,false});
}
for(auto& v:cg){
auto o=new CGItem(this,&v.second);
if(n){
ti=(TableItem*)cg_view->AddItem(new TableItem());
n=0;
}
else{
n=1;
}
ti->children.push_back(o);
_map.emplace(v.first,_v.size());
_v.push_back({v.second.t,false});
}
auto f=GetDirFile("save");
n=1;
for(auto& item:*f){
auto o=new SaveObject(("./save/"+*item).c_str());
save.emplace(o->name,o);
auto k=new SaveItem(this,o);
if(n){
ti=(TableItem*)save_list->AddItem(new TableItem());
n=0;
}
else{
n=1;
}
ti->children.push_back(k);
delete item;
}
delete f;
ch_dir=pack.GetDir("mainback/");
for(auto& item:ch_dir->file){
auto s=item.first;
auto i=s.begin(),e=s.end();
while(i!=e){
if(*i=='.'){
break;
}
i++;
}
auto v=item.second;
SDL_SetTextureBlendMode(
backs.emplace(s.substr(0,i-s.begin()),w->renderer->LoadTextureRW(v->data(),v->size()))
.first->second,SDL_BLENDMODE_BLEND);
}
main_back->Show(backs.find(init_main_back)->second);
EnterMain();
PlayMusic(main_music);
cg_whole=(CGImage*)w->AddControl(new CGImage(w));
FILE* fp=fopen("__","rb");
unsigned int l;
fread(&l,4,1,fp);
while(l--){
unsigned int v;
fread(&v,4,1,fp);
auto cache=new char[v+1]();
fread(cache,v,1,fp);
cg.find(cache)->second.unlock=true;
delete[] cache;
}
fclose(fp);
}
const char* GameScene::CurrentLanguage(){return cur_language;}
void GameScene::SetMainBackground(const char* name){
auto f=backs.find(name);
if(f!=backs.end()){
main_back->Show(f->second);
}
}
void GameScene::_press(int x,int y,int clicks,unsigned char key){
if(!backlog->visible())return;
auto& r=backlog->area();
if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h){
backlog->pressed=true;
backlog->_press(x,y,clicks,key);
}
}
void GameScene::_mouse_wheel(SDL_MouseWheelEvent& event){
if(backlog->visible())backlog->_mouse_wheel(event);
}
void GameScene::_mouse_move(int x,int y){
if(!backlog->visible())return;
auto& r=backlog->area();
if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h){
backlog->_mouse_move(x,y);
}
}
void GameScene::SetLanguage(const char* name){
auto f=ui_config.find(name);
if(f!=ui_config.end()){
auto& size=ui_size;
auto& a=f->second.text;
start_game->SetText(a[0],main_font,control_color[0],size[0],{255,255,255,255});
load->SetText(a[1],main_font,control_color[1],size[1],{255,255,255,255});
enter_cg->SetText(a[2],main_font,control_color[2],size[2],{255,255,255,255});
main_option->SetText(a[3],main_font,control_color[3],size[3],{255,255,255,255});
quit->SetText(a[4],main_font,control_color[4],size[4],{255,255,255,255});
go_option->SetText(a[3]);
cg_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
save_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
option_go_back->SetText(a[5],main_font,control_color[5],size[5],{255,255,255,255});
effect_text->SetText(a[6],main_font,control_color[6],size[6],{255,255,255,255});
music_text->SetText(a[7],main_font,control_color[7],size[7],{255,255,255,255});
auto& er=effect_text->area();
auto& mr=music_text->area();
effect_bar->SetPosition(er.x+er.w,er.y);
music_bar->SetPosition(mr.x+mr.w,mr.y);
effect_bar->area().h=er.h;
music_bar->area().h=mr.h;
speed_text->SetText(a[8],main_font,control_color[8],size[8],{255,255,255,255});
speed_normal->SetText(a[9],main_font,control_color[9],size[9],{255,255,255,255});
speed_fast->SetText(a[10],main_font,control_color[10],size[10],{255,255,255,255});
bgm_text->SetText(a[11],main_font,control_color[11],size[11],{255,255,255,255});
save_name->SetAlert(a[12]);
confirm->SetText(a[13]);
skip->SetText(a[14]);
auto_play->SetText(a[15]);
go_load->SetText(a[16]);
go_save->SetText(a[17]);
back_main->SetText(a[18]);
open_backlog->SetText(a[19]);
auto ch=*cur_ch;
auto& c=ch->content.find(name)->second;
ch->pos=c.begin()+(ch->pos-ch->content.find(cur_language)->second.begin());
cur_language=name;
ProcessText();
}
}
//前提:保证t有效
void GameScene::ShowCG(SDL_Texture* t){
cg_whole->SetEnable(true);
cg_whole->SetVisible(true);
cg_whole->Show(t);
}
void GameScene::FlashCheck(GameScene* g){
if(g->flash_in){
if(g->flash_t++==g->flash_duration){
g->flash_in=false;
g->flash_t=0;
return;
}
g->flash_color.a+=g->flash_value;
return;
}
//淡出
if(g->flash_t++==g->flash_duration){
if(--g->flash_time){
g->flash_in=true;
g->flash_t=0;
return;
}
g->is_flash=false;
g->_belong->RemoveTask(g->flash_task);
if(!--g->naction)g->fade_end=true;
return;
}
g->flash_color.a-=g->flash_value;
}
void GameScene::FlashCheckTexture(GameScene* g){
if(g->flash_in){
if(g->flash_t++==g->flash_duration){
g->flash_in=false;
g->flash_t=0;
return;
}
g->flash_color.a+=g->flash_value;
g->flash_target->SetAlpha(g->flash_color.a);
return;
}
//淡出
if(g->flash_t++==g->flash_duration){
if(--g->flash_time){
g->flash_in=true;
g->flash_t=0;
return;
}
g->is_flash=false;
g->_belong->RemoveTask(g->flash_task);
if(!--g->naction)g->fade_end=true;
return;
}
g->flash_color.a-=g->flash_value;
g->flash_target->SetAlpha(g->flash_color.a);
}
GameScene& GameScene::Flash(LayerImage* target,SDL_Rect area,unsigned char init_alpha,size_t times,size_t t){
if(is_flash)return *this;
flash_value=init_alpha/t;
target->SetAlpha(0);
target->_area=area;
flash_target=target;
naction++;
flash_t=0;
flash_duration=t;
flash_color.a=0;
flash_time=times;
fade_end=false;
flash_in=true;
is_flash=true;
flash_area=area;
flash_mode=false;
flash_task=_belong->AddTask((void(*)(void*))FlashCheckTexture,this,1,true,true);
return *this;
}
GameScene& GameScene::Flash(SDL_Color color,size_t times,size_t t){
if(is_flash)return *this;
flash_value=color.a/t;
naction++;
flash_t=0;
flash_duration=t;
flash_color=color;
flash_color.a=0;
flash_time=times;
fade_end=false;
flash_in=true;
is_flash=true;
flash_area={0,0,1280,720};
flash_mode=true;
flash_task=_belong->AddTask((void(*)(void*))FlashCheck,this,1,true,true);
return *this;
}
GameScene::~GameScene(){
delete limit_time;
for(auto& n:chapter)delete n;
for(auto& n:character)delete n.second;
for(auto& n:res)delete n.second;
for(auto& n:sound)Mix_FreeChunk(n.second);
for(auto& n:audio)Mix_FreeMusic(n.second);
delete game_back;
delete name;
delete dialog;
delete auto_play;
delete go_save;
delete go_load;
delete go_option;
delete back_main;
delete skip;
delete backlog;
delete open_backlog;
}
void GameScene::CGChangeFade(GameScene* g){
g->game_back->SetAlpha(g->game_back->Alpha()-1);
}
void GameScene::CGChangeFade2(GameScene* g){
g->_belong->AddTask((TaskCallback)CGChangeFade3,g,255,true,false,
(TaskCallback)SceneFadeFinish,g);
g->game_back->Reset().SetLayerVisible(g->next_scene_name,true).
ClearLayer().AddLayer(g->next_scene_name);
}
void GameScene::CGChangeFade3(GameScene* g){
g->game_back->SetAlpha(g->game_back->Alpha()+1);
}
void GameScene::SceneChangeFade(GameScene* g){
g->game_back->SetAlpha(g->game_back->Alpha()-5);
}
void GameScene::SceneChangeFade2(GameScene* g){
g->_belong->AddTask((TaskCallback)SceneChangeFade3,g,51,true,false,
(TaskCallback)SceneFadeFinish,g);
g->game_back->Reset().SetLayerVisible(g->next_scene_name,true).
ClearLayer().AddLayer(g->next_scene_name);
}
void GameScene::SceneChangeFade3(GameScene* g){
g->game_back->SetAlpha(g->game_back->Alpha()+5);
}
void GameScene::SceneFadeFinish(GameScene* g){
if(!--g->naction)g->fade_end=true;
}
void GameScene::CharacterFadein(LayerImage* g){
g->SetAlpha(g->Alpha()+5);
}
void GameScene::CharacterFadeout(LayerImage* g){
g->SetAlpha(g->Alpha()-5);
}
GameScene& GameScene::Jump(const char* name){
auto cur=*cur_ch;
auto& m=cur->label;
auto f=m.find(name);
if(f!=m.end()){
last_name=this->name->cache;
SaveBackLog();
auto& l=cur->content.find(cur_language)->second;
cur->pos=l.begin()+f->second.find(cur_language)->second;
ProcessText();
}
return *this;
}
GameScene& GameScene::Fadein(LayerImage* a){
fade_end=false;
naction++;
_belong->AddTask((TaskCallback)CharacterFadein,a,51,true,false,
(TaskCallback)SceneFadeFinish,this);
return *this;
}
GameScene& GameScene::StopSound(){
Mix_HaltChannel(-1);
return *this;
}
GameScene& GameScene::Fadeout(LayerImage* a){
fade_end=false;
naction++;
_belong->AddTask((TaskCallback)CharacterFadeout,a,51,true,false,
(TaskCallback)SceneFadeFinish,this);
return *this;
}
GameScene& GameScene::ChangeBackground(initializer_list<const char*>visible_name,unsigned int mode){
last_scene_name=next_scene_name;
next_scene_name=visible_name;
switch(mode){
case sc_default:
case sc_cg_fade:
naction++;
fade_end=false;
_belong->AddTask((TaskCallback)SceneChangeFade,this,51,true,false,
(TaskCallback)SceneChangeFade2,this);
return *this;
case sc_dissolve:
case sc_cg_dissolve:
return CrossDissolve(game_back,visible_name);
}
return *this;
}
void GameScene::ActionFinish(ActionPack* g){
if(!--g->g->naction){
g->g->fade_end=true;
}
g->g->actions.erase(g->pos);
delete g;
}
void GameScene::ActionCallback(ActionPack* g){
g->f(g->g,++g->t);
}
GameScene::DissolvePack::DissolvePack(GameScene*g,LayerImage* l,
initializer_list<const char*>& next):g(g),l(l),next(next),t(0),last(l->last){}
GameScene::DissolvePack::DissolvePack(GameScene*g,LayerImage* l,
initializer_list<const char*>& last,initializer_list<const char*>&next):g(g),l(l),last(last),next(next),t(0){}
GameScene& GameScene::CrossDissolve(LayerImage* l,initializer_list<const char*>& next){
naction++;
fade_end=false;
auto pack=new DissolvePack(this,l,next);
_belong->AddTask((TaskCallback)DissolveCallback,pack,51,true,false,
(TaskCallback)DissolveFinish,pack);
l->AddLayer(next).SetLayerVisible(next,true).SetAlpha(next,0);
return *this;
}
GameScene& GameScene::CrossDissolveSlow(LayerImage* l,initializer_list<const char*>& next){
naction++;
fade_end=false;
auto pack=new DissolvePack(this,l,next);
_belong->AddTask((TaskCallback)DissolveSlowCallback,pack,255,true,false,
(TaskCallback)DissolveFinish,pack);
l->SetLayerVisible(next,true).SetAlpha(next,0).AddLayer(next);
return *this;
}
GameScene& GameScene::CrossDissolve(LayerImage* l,initializer_list<const char*> last,
initializer_list<const char*> next){
naction++;
fade_end=false;
auto pack=new DissolvePack(this,l,last,next);
_belong->AddTask((TaskCallback)DissolveCallback,pack,51,true,false,
(TaskCallback)DissolveFinish,pack);
l->SetLayerVisible(next,true).SetAlpha(next,0).AddLayer(next);
return *this;
}
GameScene& GameScene::CrossDissolveSlow(LayerImage* l,initializer_list<const char*> last,
initializer_list<const char*> next){
naction++;
fade_end=false;
auto pack=new DissolvePack(this,l,last,next);
_belong->AddTask((TaskCallback)DissolveSlowCallback,pack,255,true,false,
(TaskCallback)DissolveFinish,pack);
l->SetLayerVisible(next,true).SetAlpha(next,0).AddLayer(next);
return *this;
}
void GameScene::DissolveCallback(DissolvePack* g){
auto v=5*(++g->t);
g->l->SetAlpha(g->last,255-v).SetAlpha(g->next,v);
}
void GameScene::DissolveSlowCallback(DissolvePack* g){
auto v=++g->t;
g->l->SetAlpha(g->last,255-v).SetAlpha(g->next,v);
}
void GameScene::DissolveFinish(DissolvePack* g){
if(!--g->g->naction){
g->g->fade_end=true;
}
g->l->PopLayer(g->last.size()+g->next.size()).AddLayer(g->next);
delete g;
}
GameScene::ActionPack::ActionPack(GameScene*g,int t,Action a):g(g),t(t),f(a){}
GameScene& GameScene::AddAction(int t,Action a){
if(!t)return *this;
naction++;
fade_end=false;
auto v=new ActionPack(this,0,a);
v->pos=actions.insert(actions.end(),v);
_belong->AddTask((TaskCallback)ActionCallback,v,t,true,false,(TaskCallback)ActionFinish,v);
return *this;
}
GameScene& GameScene::SetBackgroundVisible(const char* name,bool v){
game_back->SetLayerVisible({name},v);
return *this;
}
GameScene& GameScene::PlaySound(const char* name,int times){
auto f=sound.find(name);
if(f!=sound.end()){
Mix_PlayChannel(-1,f->second,times);
}
return *this;
}
GameScene& GameScene::PlayMusic(const char* name){
auto f=audio.find(name);
if(f!=audio.end()){
Mix_PlayMusic(f->second,-1);
music_cache=name;
}
return *this;
}
LayerImage* GameScene::AddCharacter(const char* group,
initializer_list<const char*>visible_name,SDL_Rect& r){
auto f=res.find(group);
if(f!=res.end()){
auto u=f->second;
auto temp=new LayerImage(_belong,u,r);
auto& m=u->res_map;
auto& a=u->res;
for(auto& n:visible_name){
auto g=m.find(n);
if(g!=m.end()){
a[g->second].visible=true;
}
}
character.emplace(group,temp);
temp->AddLayer(visible_name);
return temp;
}
return 0;
}
LayerImage* GameScene::GetCharacter(const char* group){
auto f=character.find(group);
if(f!=character.end())return f->second;
return 0;
}
GameScene& GameScene::RemoveCharacter(const char* group){
auto f=character.find(group);
if(f!=character.end()){
delete f->second;
character.erase(f);
}
return *this;
}
GameScene& GameScene::StopMusic(){
Mix_HaltMusic();
music_cache="";
return *this;
}
GameScene& GameScene::Wait(int t){
return *this;
}
void GameScene::SetAutoSpeed(bool fast){
if(fast){
dialog->PlayFast();
return;
}
dialog->Play();
}
void GameScene::_release(int x,int y,int clicks,unsigned char key){
auto& r=backlog->area();
if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h&&backlog->visible()){
backlog->pressed=false;
return;
}
if(dialog->enable()&&_enabled){
auto& r3=auto_play->area();
if(r3.x<=x&&x<=r3.x+r3.w&&r3.y<=y&&y<=r3.y+r3.h){
auto_play->_release(x,y,clicks,key);
return;
}
auto& r4=back_main->area();
if(r4.x<=x&&x<=r4.x+r4.w&&r4.y<=y&&y<=r4.y+r4.h){
back_main->_release(x,y,clicks,key);
return;
}
auto& r5=open_backlog->area();
if(r5.x<=x&&x<=r5.x+r5.w&&r5.y<=y&&y<=r5.y+r5.h){
open_backlog->_release(x,y,clicks,key);
return;
}
}
if(!_enabled||!fade_end||!dialog->enable())return;
auto& r1=go_option->area();
if(r1.x<=x&&x<=r1.x+r1.w&&r1.y<=y&&y<=r1.y+r1.h){
go_option->_release(x,y,clicks,key);
return;
}
auto& r2=go_save->area();
if(r2.x<=x&&x<=r2.x+r2.w&&r2.y<=y&&y<=r2.y+r2.h){
go_save->_release(x,y,clicks,key);
return;
}
auto& r4=go_load->area();
if(r4.x<=x&&x<=r4.x+r4.w&&r4.y<=y&&y<=r4.y+r4.h){
go_load->_release(x,y,clicks,key);
return;
}
for(auto& n:choose){
auto& r=n->area();
if(r.x<=x&&x<=r.x+r.w&&r.y<=y&&y<=r.y+r.h){
n->_release(x,y,clicks,key);
return;
}
}
if(on_choose)return;
dialog->_release(x,y,clicks,key);
}
void GameScene::_draw(){
auto r=_belong->renderer;
if(in_main){
return;
}
if(limit_task){
if(++limit_task->cur<limit_task->max)ChooseLimit(this);
else{
delete limit_task;
limit_task=0;
}
}
auto mod=SDL_GetModState();
if(mod==KMOD_LCTRL||mod==KMOD_RCTRL)Skip();
if(_enabled){
game_back->_draw();
if(limit_time->visible())limit_time->_draw();
for(auto& n:character)n.second->_draw();
if(is_flash){
auto r=_belong->renderer;
if(flash_mode)
{
r->SetColor(flash_color);
r->FillRect(flash_area);
}
else{
flash_target->_draw();
}
}
for(auto& n:choose)n->_draw();
if(dialog->enable()){
dialog->_draw();
if(backlog->visible())backlog->_draw();
if(name->visible())name->_draw();
auto_play->_draw();
back_main->_draw();
open_backlog->_draw();
if(fade_end){
go_save->_draw();
go_load->_draw();
go_option->_draw();
}
}
}
}
void GameScene::SetEnable(bool v){
cg_go_back->SetEnable(v);
cg_view->SetEnable(v);
save_go_back->SetEnable(v),confirm->SetEnable(v);
save_list->SetEnable(v);
option_go_back->SetEnable(v);
effect_box->SetEnable(v),music_box->SetEnable(v);
effect_bar->SetEnable(v),music_bar->SetEnable(v);
effect_text->SetEnable(v),music_text->SetEnable(v),speed_text->SetEnable(v);
main_back->SetEnable(v);
start_game->SetEnable(v),load->SetEnable(v),enter_cg->SetEnable(v),quit->SetEnable(v);
for(auto& n:character)n.second->SetEnable(v);
auto_play->SetEnable(v);
name->SetEnable(v),game_back->SetEnable(v);
dialog->SetEnable(v);
}
void GameScene::_draw_edge(){}
void GameScene::SetVisible(bool v){
cg_go_back->SetVisible(v);
cg_view->SetVisible(v);
save_go_back->SetVisible(v),confirm->SetVisible(v);
save_list->SetVisible(v);
option_go_back->SetVisible(v);
effect_box->SetVisible(v),music_box->SetVisible(v);
effect_bar->SetVisible(v),music_bar->SetVisible(v);
effect_text->SetVisible(v),music_text->SetVisible(v),speed_text->SetVisible(v);
main_back->SetVisible(v);
start_game->SetVisible(v),load->SetVisible(v),enter_cg->SetVisible(v),quit->SetVisible(v);
for(auto& n:character)n.second->SetVisible(v);
auto_play->SetVisible(v);
name->SetVisible(v),game_back->SetVisible(v);
dialog->SetVisible(v);
}
bool GameScene::IsAutoPlay(){return _auto;}
GameScene& GameScene::Lock(){
need_lock=true;
return *this;
}
ResUnit* GameScene::QueryRes(const char* name){
auto f=res.find(name);
if(f!=res.end()){
return f->second;
}
return 0;
}
GameScene& GameScene::Choose(vector<TextMod> text,vector<Sentence> s){
last_name=name->cache;
choose.clear();
choose.resize(s.size());
on_choose=true;
SaveBackLog();
dialog->SetText(text);
auto b=dialog->Background();
auto cur=choose.begin();
auto w=_belong;
int y=80;
for(auto& n:s){
auto c=new ChooseButton(b,this,n.text,n.logic);
*cur=c;
auto& a=c->area();
auto& b=c->_rect;
a.y=y;
b.x=(1280>>1)-(b.w>>1),b.y=y+25-(b.h>>1);
y+=75;
cur++;
}
return *this;
}
void GameScene::EndChoose(){
for(auto& n:choose)delete n;
choose.clear();
on_choose=false;
limit_time->SetVisible(false);
limit_time->SetEnable(false);
if(limit_task){
delete limit_task;
limit_task=0;
}
}
void GameScene::MuteEffect(){
if(effect_mute){
Mix_Volume(-1,effect_volume);
effect_mute=false;
return;
}
effect_mute=true;
Mix_Volume(-1,0);
}
void GameScene::MuteMusic(){
if(music_mute){
Mix_VolumeMusic(music_volume);
music_mute=false;
return;
}
music_mute=true;
Mix_VolumeMusic(0);
}
void GameScene::Back(){
if(in_main){
EnterMain();
return;
}
EnterGame();
dialog->SetEnable(dialog_state);
name->SetVisible(name_state);
}
void GameScene::SetMusicVolume(double p){
Mix_VolumeMusic(SDL_MIX_MAXVOLUME*p);
}
void GameScene::SetEffectVolume(double p){
Mix_Volume(-1,p*SDL_MIX_MAXVOLUME);
}
void GameScene::AutoPlayCallback(GameScene* a){
if(a->dialog->Finish())DialogCallback(a);
}
void GameScene::AutoPlay(){
if(_auto){
_belong->RemoveTask(_auto);
_auto=0;
return;
}
_auto=_belong->AddTask((TaskCallback)AutoPlayCallback,this,60,false,true);
}
void GameScene::GameDialogFadein(AutoPlayText* g){
g->SetAlpha(g->Alpha()+5);
}
void GameScene::GameDialogFadeout(AutoPlayText* g){
g->SetAlpha(g->Alpha()-5);
}
void GameScene::GameBackFinish(GameScene* g){
g->dialog->SetVisible(true);
g->_belong->AddTask((TaskCallback)GameDialogFadein,g->dialog,51,true,
false,(TaskCallback)GameEntered,g);
}
void GameScene::EndGame(){
is_gaming=false;
second=true;
EnterMain();
}
void GameScene::GameEntered(GameScene* g){
g->fade_end=true;
g->need_lock=false;
g->on_choose=false;
g->cur_ch=g->chapter.begin();
auto ch=*g->cur_ch;
ch->pos=ch->content.find(g->cur_language)->second.begin();
g->ProcessText();
g->dialog->SetEnable(true);
g->dialog->Play();
}
bool GameScene::IsGaming(){return is_gaming;}
void GameScene::StartGame(){
EnterGame();
if(is_gaming)return;
StopMusic();
is_gaming=true;
dialog->SetAlpha(0);
dialog->SetEnable(false);
game_back->ClearLayer();
game_back->SetAlpha(0);
backlog->Clear();
_belong->AddTask((TaskCallback)GameBackFadein,game_back,51,
true,false,(TaskCallback)GameBackFinish,this);
}
void GameScene::SetSaveInput(const char* text){
save_name->SetText(text);
}
void GameScene::Save(const string& name){
auto f=save.find(name);
auto o=new SaveObject(this,name,save_f);
if(f==save.end()){
//新存档
auto k=new SaveItem(this,o);
if(save.size()&1){
//奇数
((TableItem*)save_list->GetItem(save_list->count()-1))->children.push_back(k);
}
else{
((TableItem*)save_list->AddItem(new TableItem()))->children.push_back(k);
}
save.emplace(name,o);
return;
}
f->second->item->Update(o);
delete f->second;
f->second=o;
}
void GameScene::Load(const string& name){
auto f=save.find(name);
if(f==save.end())return;
for(auto& c:character)delete c.second;
for(auto& c:choose)delete c;
choose.clear();
character.clear();
EnterGame();
is_gaming=true;
auto s=f->second;
s->Load(this,load_f);
backlog->Clear();
need_lock=false;
on_choose=false;
dialog->SetAlpha(255);
fade_end=true;
dialog->SetEnable(true);
dialog->Play();
}
void GameScene::ConfirmSave(){
//对于存档 列表选择时会将存档名设置到输入框中 如果输入框=已有则为覆盖
//对于读档 当且仅当输入框=已有才允许读取 读取结束后切到游戏界面
auto& s=*save_name->text();
if(s.empty())return;
if(is_load){
Load(s);
return;
}
Save(s);
}
void GameScene::ProcessText(){
if(cur_ch==chapter.end())return;
auto ch=*cur_ch;
auto& pos=ch->pos;
if(pos==ch->content.find(cur_language)->second.end())return;
dialog->SetText(*pos->text);
}
void GameScene::DialogCallback(GameScene* g){
if(!g->_enabled||g->on_choose||!g->fade_end||!g->dialog->enable())return;
auto& cur_ch=g->cur_ch;
if(cur_ch==g->chapter.end()){
//结束游戏
return;
}
auto ch=*cur_ch;
auto& pos=ch->pos;
auto& content=ch->content.find(g->cur_language)->second;
if(pos==content.end()){
cur_ch++;
//下一章
g->ProcessText();
return;
}
g->last_name=g->name->cache;
pos->logic(g);
if(g->on_choose||g->need_lock){
g->need_lock=false;
return;
}
g->SaveBackLog();
g->AddAction(g->next_time,g->next_action).next_time=0;
pos++;
g->ProcessText();
}
void GameScene::SaveBackLog(){
auto b=backlog;
auto w=(Window*)window();
auto item=(BackLogItem*)b->AddItem(new BackLogItem(w,
last_name,dialog->_cache));
auto t=item->content_t;
int sum=0;
for(size_t i=0,max=item->info.size();i<max;i++){
auto& info=item->info[i];
b->AddItem(new LogTextItem(w,info.first,info.second,sum,t));
sum+=info.second;
}
}
GameScene& GameScene::Next(){
SaveBackLog();
AddAction(next_time,next_action).next_time=0;
(*cur_ch)->pos++;
ProcessText();
return *this;
}
GameScene& GameScene::HideDialog(){
dialog->SetEnable(false);
_belong->AddTask((TaskCallback)GameDialogFadeout,dialog,51,true);
return *this;
}
GameScene& GameScene::ShowDialog(){
dialog->SetEnable(true);
_belong->AddTask((TaskCallback)GameDialogFadein,dialog,51,true);
return *this;
}
void GameScene::Redirect(unsigned int ch,unsigned int index){
cur_ch=chapter.begin()+ch;
(*cur_ch)->pos=(*cur_ch)->content.find(cur_language)->second.begin()+index;
ProcessText();
}
void GameScene::GetChapterInfo(size_t& ch,size_t& index){
auto c=*cur_ch;
ch=cur_ch-chapter.begin();
index=c->pos-c->content.find(cur_language)->second.begin();
}
void GameScene::Skip(){
if(!is_gaming)return;
_belong->FinalizeTask();
DialogCallback(this);
}
GameScene& GameScene::UnlockCG(const char* name){
auto f=cg.find(name);
if(f!=cg.end()){
f->second.unlock=true;
vector<string> cache;
for(auto& n:cg){
if(n.second.unlock)cache.push_back(n.first);
}
FILE* fp=fopen("__","wb");
size_t l=cache.size();
fwrite(&l,4,1,fp);
for(auto& n:cache){
l=n.size();
fwrite(&l,4,1,fp);
fwrite(n.c_str(),l,1,fp);
}
fclose(fp);
}
return *this;
}
SceneState* GameScene::QueryState(FILE* fp,size_t& total){
auto state=GetState();
state->Write(fp);
total+=state->total;
return state;
}
SceneState* GameScene::GetState(){
auto temp=new SceneState();
GetChapterInfo(temp->ch,temp->index);
temp->music=music_cache;
temp->back.resize(game_back->GetMemberNum());
game_back->QueryLayer(temp->back);
temp->character.resize(character.size());
auto begin=character.begin();
for(auto& ch:temp->character){
begin->second->QueryLayer(ch.ch);
auto& s=begin->first;
auto _s=new char[s.length()+1]();
memcpy(_s,s.c_str(),s.length());
ch.name=_s;
ch.rect=begin->second->area();
begin++;
}
auto ch=*cur_ch;
temp->content=*ch->pos->text;
temp->index=ch->pos-ch->content.find(cur_language)->second.begin();
temp->name=name->cache;
return temp;
}
SaveObject::SaveObject(GameScene* g,const string n,SaveFunc f){
state=g->GetState();
name=new char[n.length()+1]();
memcpy(name,n.c_str(),n.length());
string p("./save/"+n);
FILE* fp=fopen(p.c_str(),"wb");
auto l=n.length();
auto game_back=g->game_back;
auto _nb=game_back->GetMemberNum();
time_t nowtime=time(NULL); //获取计算机从1970年1月1日到目前过去的总秒数
time_s=new char[64]();
strftime(time_s,64,"%Y-%m-%d %H:%M:%S",localtime(&nowtime));
size_t ch,index;
g->GetChapterInfo(ch,index);
//统一写入
fwrite("LBVN",4,1,fp);
fwrite(g->version,4,1,fp);
fwrite(&l,4,1,fp);
fwrite(n.c_str(),l,1,fp);
fwrite(time_s,64,1,fp);
total=80+l;
state=g->QueryState(fp,total);
f(fp);
fclose(fp);
memcpy(version,g->version,4);
}
SaveObject::SaveObject(const char* path){
FILE* fp=fopen(path,"rb");
char buffer[4];
fread(buffer,4,1,fp);
if(strncmp(buffer,"LBVN",4)){
throw SaveException();
}
fread(version,4,1,fp);
unsigned int nl;
fread(&nl,4,1,fp);
name=new char[nl+1]();
time_s=new char[64]();
fread(name,nl,1,fp);
fread(time_s,64,1,fp);
total=80+nl;
state=new SceneState();
state->Load(fp);
total+=state->total;
fclose(fp);
}
SceneState::~SceneState(){
for(auto& n:cache)delete[] n;
}
void SaveObject::Load(GameScene* g,SaveFunc f){
string path("save/");
path.append(name);
FILE* fp=fopen(path.c_str(),"rb");
fseek(fp,total,SEEK_CUR);
f(fp);
fclose(fp);
if(!state->music.empty()){
g->StopMusic();
g->PlayMusic(state->music.c_str());
}
state->Load(g);
}
SaveObject::~SaveObject(){
delete[] name;
delete[] time_s;
delete state;
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )