A simple visual novel script

No_IENo_IE Posts: 9Member
edited February 7 in Projects


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


Tags :

Comments

  • No_IENo_IE Posts: 9Member
    edited February 7

    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

  • No_IENo_IE Posts: 9Member
    edited February 9

    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

  • No_IENo_IE Posts: 9Member

    https://drive.google.com/file/d/12oXXl8BDgvmNWIwhE1gnBCaTz9FjewaI/view?usp=sharing

    This time I remove video player.

    I make a simple load_save dialog and settings dialog.

Sign In or Register to comment.