Features: Show text, image and animation. Play audio and video. Simple menu and input box. Fade, move in right left top bottom and zoom.

https://anonfiles.com/TaO2y4seb9/Visual_Novel_20190202_7z

======== ======== ======== ======== edit 2019-02-05 ======== ======== ======== ========

Hello!It's my visual novel script's quickstart. Regrettably, my project no name yet.

My project have several files:

hare_guu.gd and hare_guu.tscn:

It's my test new functions files. I want to add save and load function.

image.gd and image.tscn:

use that show picture. It can be play add, remove, change and loop build-in animation.

What you can use animation include "fade", "dissolve", "moveright", "moveleft", "movetop", "movebottom", "zoominout", "zoomin", "zoomout", "left", "right", "bottom", "top", "turnright", "turnleft", "turntop", "turnbottom", "walk", "leftloop", "rightloop".

viewer.gd and viewer.tscn:

It's used show all items about Visual Novel, such as: background, VideoPlayer, music, sound, dialog_name and dialog_text.

font/cn_font.tres and font/wqy-microhei.ttc:

I used this show chisese's text.

font/dialog_text.tscn:

It's Label, but it have beautiful shadow.

font/gradient.png:

I used it decorative text.

backgrounds/black.png and backgrounds/transparent.png:

Used to some build-in animation.

GUI/*.png:

Some decorations.

main.gd and main.tscn:

Include viewer.tscn and others. You can write your own main.tscn if you are willing.

A simple main.gd like this:

 func _ready():
     $viewer.dia = [
         "\"Hi!",
         "\"I recently made a Visual Novel Script.",
         "\"I'm not sure it works well",
         "jump res://thank.tscn"]
	
     $viewer.cha = [
         #id, name, color,
         ["default","",		Color(0.2,0.2,0.2)], #default must at first.
         ["r",	"Red",		Color(0.2,0.0,0.0)],
         ["g",	"Green",	Color(0.0,0.2,0.0)]]
	
     $viewer.pos = [["default", Vector2(640,600)],    #default must at first.
         		["right", Vector2(980,600)],
         		["left", Vector2(300,600)],
         		["center", Vector2(640,600)]]
				
     $viewer.start()

 func _input(event):
     if event.is_action_pressed("ui_accept"):
         $viewer.read_pressed()

$viewer.dia stored all dialog script.

$viewer.cha stored character's name and text's color.

$viewer.pos stored some position and their id.

I recommend call $wiewer.start(), otherwise I'm ont sure that will work. It's W.I.P.

$wiewer.read_pressed() can display the remaining text or go to next line.

Characters

You can define some characters to show name and change color in the dialog.

example:

     $viewer.dia = [
         "r My color is red, my name is ren too.",
         "g I'm greeeeeen.",
         "\"My color is default color. I nave no name.",
         "jump res://thank.tscn"]
	
     $viewer.cha = [
         #id, name, color,
         ["default","",		Color(0.2,0.2,0.2)], #default must at first.
         ["r",	"Red",		Color(0.2,0.0,0.0)],
         ["g",	"Green",	Color(0.0,0.2,0.0)]]

Images:

You can show image use:

 image pic res://characters/phee.png

Or use this:

 image pic res://characters/phee.png at floating scale 2 walk loop

'pic' is image's name. You can change, remove it by name.

Script:

 image pic1 res://characters/phee.png
 image pic2 res://characters/hare_run.png

You can give two images. But this:

 image pic res://characters/phee.png
 image pic res://characters/hare_run.png

You give only one image. Because first line add a image, but second line change the image.

You can remove it:

 image pic res://characters/phee.png
 remove pic

Note that use same name 'pic'.

 image pic res://characters/phee.png at floating

You must define position, like this:

 $viewer.pos = [["default", Vector2(640,600)],    #default must at first.
            ["right", Vector2(980,600)],
            ["left", Vector2(300,600)],
            ["center", Vector2(640,600)],
            ["floating", Vector2(500,200)]]

So image at coordinate 500,200.

 image pic res://characters/phee.png scale 2

You can use 'scale' to scaling the image. It can be negative number, it'll flip horizontally but not vertically.

 image pic res://characters/phee.png walk

Play animation once.

 image pic res://characters/phee.png walk loop

Play loop animation.

Pause:

 pause

Pause until called $viewer.read_pressed().

 pause 3.0

Pause until called $viewer.read_pressed() or waiting 3 seconds.

Jump:

You can change scene, like this:

 jump res://thank.tscn

Or jump other label, like this:

 "You can reading this
 "You can reading this
 jump otherline
 "You can't reading this
 "You can't reading this
 label otherline
 "You can reading this
 "You can reading this

Menus:

 label jump_begin
 "You can reading this
 "You can reading this
 menu begin
     item If you click me,
         "I'll show some text for you.
         jump jump_label
     item If you click me, you will jump to begin
         jump jump_begin
     item If you click me, 
         "I'll say a lot of words.
         "A long long time ago.
         "A long long time.
         "Let me talk about it next time.
 menu end
 label jump_label

The "menu begin" and "menu end" are necessary.

Download link: https://drive.google.com/file/d/1iujo9-R3PGZOUGLYsB0iwhk4wx-4Nbzo/view?usp=sharing

6 days later

Continue my quickstart.

Animation:

You can use script load a .tscn file to viewer:

 anim hare res://characters/hare.tscn

Or:

 anim hare res://characters/hare.tscn talk at right scale 2

The 'hare' is animation's id, you can change this animation by id later.

'at right' is this animation's position.

use 'scale 2' zoom it. If use 'scale -1', it will be horizontal flip.

Please see the script blow, it implements mouth animation:

 anim mom res://characters/vida.tscn talk at left
 anim sun res://characters/hare.tscn at right
 mom Are you back?
 anim mom stop
 anim sun talk
 sun I'm home.
 anim sun stop
 anim mom talk
 mom Didn't you have a half-day today?
 anim mom stop
 anim sun talk
 sun Yes, half-day.
 anim sun stop
 anim mom talk
 mom You're fighting the boss right now. The last time you saved...was when?
 anim mom stop
 anim sun talk
 sun Today... Not yet.
 anim sun stop

'anim mom talk' will play a animation that named 'talk'. Same as, 'anim mom stop' will play a animation that named 'stop'. What I said is true.

Look that, It is too cumbersome. And then 'anim mom talk' has the same id as 'mom Didn't you have a half-day today?'.

So, you can use this instead:

 anim mom res://characters/vida.tscn talk at left
 anim sun res://characters/hare.tscn at right
 mom Are you back?
 anim mom stop
 sun anim talk I'm home.
 anim sun stop
 mom anim talk Didn't you have a half-day today?
 anim mom stop
 sun anim talk Yes, half-day.
 anim sun stop
 mom anim talk You're fighting the boss right now. The last time you saved...was when?
 anim mom stop
 sun anim talk Today... Not yet.
 anim sun stop

Or this:

 anim mom res://characters/vida.tscn talk at left
 anim sun res://characters/hare.tscn at right
 mom Are you back?
 anim mom stop
 sun anim talk stop I'm home.
 mom anim talk stop Didn't you have a half-day today?
 sun anim talk stop Yes, half-day.
 mom anim talk stop You're fighting the boss right now. The last time you saved...was when?
 sun anim talk stop Today... Not yet.

'sun anim talk stop I'm home.' will

play talk animation -> show "I'm home." -> play animation than named 'stop'.

But 'sun anim talk other_anim I'm home.' will

play talk animation -> show "other_anim I'm home."

If you want to play any animation. please make sure your .tscn file have one or more AnimationPlay node.

My code is like this:

 for a in target.get_children():        # <- looks for the children.
     if a is AnimationPlayer:
         a.play(anim_name)	

So, it only looks for the children of the root node.

I used 'play id anim_name' to play animation before, but I want to remove it.

Signal:

You can emit signal use 'signal':

dia1.txt

 mom balabalabala.
 sun balabalabala.
 signal Hello World!
 mom balabalabala.
 sun balabalabala.

And:

game.gd:

 func _on_viewer_script_control(arg):
     print(arg)

You can use like this:

dia1.txt:

 r I must go now, good-bye.
 g Good-bye.
 signal load res://dia2.txt

dia2.txt:

 g Hello!
 r Good morning.

game.gd:

 func _on_viewer_script_control(arg):
     var arr = arg.split(" ")
     if arr[0] == "load":
         var file = File.new()
         if file.open(arr[1], File.READ) == 0:
             $viewer.dia = file.get_as_text().split("\n")
             $viewer.line = -1
             $viewer.goto_next_string()
         file.close()

Or this:

dia1.txt:

 "I want to buy this
 signal check_gold
 label buying
 "I decided to buy this.
 me Give me this, please.
 jump leave_store
 label not_buying
 "But my gold are not enough.
 label leave_store
 me See you!

game.gd:

 func _on_viewer_script_control(arg):
     if arg == "check_gold":
         if gold > 100:
             $viewer.jump("buying")
         else:
             $viewer.jump("not_buying")

If your gold are enough, it show you:

I want to buy this -> I decided to buy this. -> Give me this, please. -> See you!

else:

I want to buy this -> But my gold are not enough. -> See you!

My code like this:

 func parsing(text, show_all = false) -> int:
     var textArray = split_without_empty(text)
     ...
     ...
     ...
     elif textArray[0] == "signal":
         emit_signal("script_control", text.right(7))

Visual Novel 20190207 download link: https://drive.google.com/file/d/1NAPOn1WmPX2WW4fKLOhW33iCIpFaJhsy/view?usp=sharing

Directly Viewer in one game:

You can use the viewer in your game. This my script's API.

variable dia:

dia = ["dialogue1", "dialogue2", "dialogue3", ...]

This is dialog you want to display.

variable pos:

pos = {"name1":Vector2(x1,y1), "name2":Vector2(x2,y2), ...}

This is define position by name. You can use this set image's or animation's position, like this:

image image_id res_path at name1

Or

anim animation_id res_path at name2

variable line:

Set current line pointer.

function goto_next_string():

Parsing and execute string by dia[line+1].

So usually use:

$viewer.line = -1 $viewer.clear_all() $viewer.goto_next_string()

function clear_all():

Clear all images and animations.

function read_pressed():

Show all text or go to next line. I recommend using this way:

func _input(event): if event.is_action_pressed("ui_accept"): $viewer.read_pressed()

Visual Novel 20190209 download link: https://drive.google.com/file/d/15G925aDmo_WfAHNGgeryaJ50VDDC1Vpn/view?usp=sharing

8 days later
12 days later