ãã®èšäºã¯ 2023/12/15 ã« App Store ã§ãªãªãŒã¹ããã iOS 察å¿ã¢ãã€ã«ã²ãŒã ããã®åãäŸãã®ïŒäºåŸã®ïŒéçºãã°ã®ãã¡Godot Engine ã§äœã£ãŠãããããžãã¯ãã«é¢ããèšé²ã§ããããšã¯ãããããŸãå ·äœçãªã³ãŒããªã©ãèŒãããšé·ããªã£ãŠããŸãã®ã§ããã®ãããã¯æ§ããã«ããããšæãã
ããã®åãäŸãã¯äžã® App Store ã®ãããŒãããç¡æã§ããŠã³ããŒãã§ããã®ã§ãèå³ãããã°ãã²éãã§ã¿ãŠã»ããã
å¿ èŠãªç»é¢ã®æŽãåºã
ç§ã¯å²ãšèŠãç®ããå ¥ãã¿ã€ãã ãã²ãŒã éçºãäŸã«æŒãããGodot ã§ããã®åãäŸããäœãå§ããã«ãããããŸãã¯å¿ èŠãªç»é¢ã®æŽãåºãããã¹ã¿ãŒãããããã®æµãã§ç»é¢é·ç§»ãèãããæçµçã«å€æŽç¹ã¯å€ã ãã£ãããããŒã¹ã¯åœåèãããã®ãããã»ã©ãã¬ãŠããªããšæãã
éçºåœåã¯ä»¥äžã®ç»é¢ãçšæããèšç»ã ã£ãã
- ã¹ã¿ãŒãç»é¢
- ãã¬ã€ç»é¢(ããŒãºç»é¢å«ã)
- ã¹ããŒãžéžæç»é¢
- èšå®ç»é¢
æçµçã«ã¯ãããã«ä»¥äžã®ç»é¢ãè¿œå ããããšã«ãªã£ãã
- ããããŒã°ç»é¢
- ã¡ãã¥ãŒç»é¢
- ã¯ã¬ãžããç»é¢
- ã¹ã³ã¢ç»é¢
- èœã¡ç©èšé²ç»é¢
ãã®éçºãã°ã§ã¯ãåœåèšç»ããŠããã²ãŒã ã®äžå¿ãšãªãç»é¢ã«ã€ããŠèšé²ããã
ã¹ã¿ãŒãç»é¢ãšããããŒã°ç»é¢
ã«ãžã¥ã¢ã«ã²ãŒã ãè¿œæ±ãããªãã°ãã¹ã¿ãŒãç»é¢ã¯ãããäžèŠã§ã¯ãªãããšããæã£ãŠããããããããéçºè ã«ãšã£ãŠãã¹ã¿ãŒãç»é¢ã»ã©çšæããããªãç»é¢ãä»ã«ããã ãããïŒãã¶ããããïŒãã¹ã¿ãŒãç»é¢ãããã¬ã€ç»é¢ãèšå®ç»é¢ãã¯ã¬ãžããç»é¢ãžããããé·ç§»ã§ããããã«èããŠããããäžéã®ã¢ãã€ã«ã²ãŒã ã®ä»æ§ãèŠãŠã¿ããšããã ãã¹ã¿ãŒãããã¿ã³ãããã ãã®ãã®ãå²ãšå€ãã£ããæµè¡ã«ã¯ãããªãã«çç±ãããã®ã ããããšããããªãä¿¡ããŠæš¡å£ããããšã«ããã
次ã«ãã¹ã¿ãŒãç»é¢ã«å°ãã§ã楜ããèŠçŽ ãè¿œå ããããããã¬ã€ã€ãŒãã£ã©ã¯ã¿ãŒã®äŸãäžå€®ã«é 眮ããŠãã¢ãã¡ãŒã·ã§ã³ããããéçºåœåããããã¹ã¿ãŒãããã¿ã³ãæŒããšäŸãåãæ¯ã£ãŠããŒãºã決ããã€ã¡ãŒãžãæµ®ããã§ããã®ã§ãããããã®ãŸãŸå®è£ ãããå®éã«ã¯ããã¬ã€ç»é¢ã§äœ¿çšãã Player ã·ãŒã³ãå ã«äœã£ãŠããããæµçšãããšããé çªã§ããã
ãã®åŸãã«ãžã¥ã¢ã«ã²ãŒã ã§ããã«ãé¢ããããè²ã ãªèŠçŽ ãçã蟌ã¿å§ãããæ ç±ãšããåã®ãã«ã§ãããçã蟌ãã èŠçŽ ã®äžã€ãããããŒã°ã ãæåã¯ã¹ã¿ãŒãç»é¢ãæŸçœ®ããŠãããšæ°ç§åŸã«èªåçã«ããããŒã°ç»é¢ã«é·ç§»ããä»çµã¿ã«ããŠããããããã次ç»é¢ã®ããŒãã«å°ãã°ããæéãå¿ èŠã«ãªã£ãŠããããããåŸ ã£ãŠããéã«ã©ããããšèšããã°ããã«ãããããŒã°ããã¿ã³ãã¹ã¿ãŒãç»é¢ã«é 眮ããã
ããããŒã°ç»é¢ã®æ§é ã¯ããã£ãŠã·ã³ãã«ã ãåºæ¬çã«ã¯ TextureRect ããŒãã«èæ¯çšã®ãã¿ãŒã³ãã¯ã¹ãã£ãé©çšãã ScrollContainer ããŒãã«ããããŒã°ã®æç« ãé©çšãã Label ããŒããå ¥ãããšããæ§é ã ãèªåçã«äžããäžã«æµããŠããä»çµã¿ã¯ä»¥äžã®ã³ãŒãã§å®è£ ããã
const MAX_SCROLL : int = 5924
func _process(_delta):
if scroll_container.scroll_vertical < MAX_SCROLL:
scroll_container.scroll_vertical += 1
ãã¬ã€ç»é¢
ãã¬ã€ç»é¢ã¯ã²ãŒã ã®äž»ããããŒããªã®ã§ãããªã¥ãŒããŒã ãGame ã·ãŒã³ãæäžäœãšããŠããã®äžã«å¿ èŠãªã·ãŒã³ãè¿œå ããŠãã£ããæçµåœ¢æ ã¯ãã¡ããã¡ããšçŽ°ããããŒããè¿œå ããŠããããããŒã¹ãšããŠã¯ä»¥äžã®ãããªæ§æã«ãªã£ãŠããã
- Game: Node
- World: Node2D
- Backgournd: Node2D
- Player: CharacterBody2D
- Obj: RigidBody2D
- UI: Control
- World: Node2D
Background ã·ãŒã³
Background ã·ãŒã³ãäœæããŠãããã World ã·ãŒã³ã®ãã©ã³ããšããŠè¿œå ããããã®ã·ãŒã³ã«ã¯ãFull Rect ã® TextureRect ããŒãã«èæ¯ã®ãã¿ãŒã³ãã¯ã¹ãã£ãã»ããããç»é¢äžéšã«ã¯ãã¬ã€ã€ãŒãã£ã©ã¯ã¿ãŒãæ©ãè¶³å Žãšã㊠StaticBody2D ããŒããã»ããããã
现ããæŒåºã ããæ±ãã西ãžåã倪éœãšæºã¡æ¬ ãããæãéçºäžçã§è¿œå ããã倪éœãšæã®ã¹ãã©ã€ãã¯ãAsprite ã¢ããªã§èªäœãããã®ã ã
倪éœãšæã®åããããã³æ¥ã®åºãæ¥æ²¡ãå€ã®æãããªã©ã®ç©ºã®è²ã®å€åãªã©ãèæ¯ã§å€åããéšåã¯ãã¹ãŠ AnimationPlayer ã«ãŸãšããã
Player ã·ãŒã³
Player ã·ãŒã³ãäœæããŠãããããã©ã³ããšã㊠World ããŒãã«è¿œå ããããã®ã·ãŒã³ã¯ CharacterBody2D ããŒããæäžäœã«ããŠãSprite2D ã«ãããçµµã®äŸããã¯ã¹ãã£ãšããŠã»ããããŠããã
èœã¡ç©ã®çã«å¯ŸããŠãäŸåŽã«ãåœããå€å®ãšãªã¢ãå¿ èŠãªãããArea2D ããŒã㧠Hitbox ãçšæãããããã¯ã¹ãšãããªãããç·ã§ãããããããã¬ã€ã€ãŒã«èŠèŠçã«ç€ºãããã«ãHitBox ã® CollisionShape2D ã®ç·ã®é·ããšåã Line2D ããŒããçšæãããè²ã¯ã€ã¡ãŒãžã«ã©ãŒã®çŽ«ã£ãœãè²ã«ãããäŸã®ç»å Žãéå Žãããªã¬ãŒã«åŒã³åºãã¡ãœããããã£ãã®ã§ VisibleOnScreenNotifier2D ããŒããè¿œå ããŠããã®ã·ã°ãã«ãã¹ã¯ãªããå ã§å©çšããŠããã
éçºåŸåã§äŸã«ã»ãªããåãããä»æ§ã«ãããããå¹ãåºã ð¬ ã衚瀺ãã Bubble ã·ãŒã³ãäœããããã Player ã·ãŒã³ã®ãã©ã³ããšããŠè¿œå ããããã® Bubble ã·ãŒã³ã«ã¯ DialogueManager ãšãããã©ã°ã€ã³ãå©çšãããŠããã ããŠãããå®è£ ã«å°ãèŠæŠãããããã¥ãŒããªã¢ã«ããã£ããçšæããŠãããŠããã®ã§ãæ¯èŒçå©çšãããããã©ã°ã€ã³ã ãšæãã
å°ãäŸã®ã¢ã¯ã·ã§ã³ã掟æã«æŒåºããããããã¬ã€ã€ãŒãã£ã©ã¯ã¿ãŒã®ãŽãŒã¹ããšãã§ã¯ããè¿œå ããã
äŸã«äœ¿çšããå¹æé³ãäŸãã°ã足é³ããžã£ã³ããçå°ã®é³ãåã§åãé³ãªã©ã¯ãã¹ãŠãã²ãšã€ã〠AudioStreamPlayer ããŒããè¿œå ãããã·ãŒã³ããªãŒãããåé·ã«ãªããããã¬ã€äžã«å¹æé³ã¢ã»ãããéœåºŠèªã¿èŸŒãã§ããŒãã«ã»ããããããã¯åŠçãéããšèããããã ã
ç»é¢ãã¿ããããŠäŸããžã£ã³ãããã®ãŸãŸã¿ãããããŒãããŠäžå®ã®é«ããŸã§äžæããã®åŸç»é¢ããæããªãªãŒã¹ããŠåœããå€å®ãžããšããæäœæé 㯠unhandled_input()
ã¡ãœããã§å®è£
ãããã¡ãœããå
ã«ã¯ãäŸã®å¹ãåºã ð¬ ãéããæäœãå«ããŠããã
func _unhandled_input(_event):
if player_state == PlayerState.IDLING \
and is_on_floor() \
and Input.is_action_just_pressed("touch"):
if speech_state == SpeechState.SAID:
bubble.hide()
elif speech_state == SpeechState.SILENT:
print("Screen Touched")
is_touching = true
hit_box_col_shape.disabled = false # CollisionShape2D of Hitbox node
sfx_jump.play() # AudioStreamPlayer
anim_player.play("jump") # AnimationPlayer
velocity.y = -JUMP_SPEED
player_state = PlayerState.JUMPING
if is_touching\
and not is_on_floor()\
and Input.is_action_just_released("touch"):
print("Screen Released")
is_touching = false
released.emit()
hit_box.hide()
hit_box_col_shape.disabled = true
if player_state == PlayerState.JUMPING:
velocity.y = move_toward(velocity.y, 0, 1600)
Obj ã·ãŒã³
Obj ãšã¯ãObject ã®ç¥ã§ãèœã¡ç©ã®ããã®ã·ãŒã³ã§ããããã®ã·ãŒã³ã World ã·ãŒã³ã®ãã©ã³ããšããŠè¿œå ãããObj ã·ãŒã³ã®ã«ãŒãã«ã¯ãRigidBody2D ããŒããæ¡çšãããç©çèšç®ãèªåã§ããŠãããã®ã§ãèœã¡ç©ãç»é¢äžéšããèœäžãããã®ã¯éåžžã«ç°¡åã ã£ãã次ã«ãäŸã«åãããèœã¡ç©ãçåããŠåæãããæ¹æ³ã«ã€ããŠå°ãæ©ãã ããããããã Shader ã䜿ãããªããã°ç°¡åã«å®è£ ã§ããã®ãããããªãïŒããŸã ã«å¯èœãããããããªãïŒãããããç§ã¯ Shader ã®ã¹ãã«ããŸãã§ãªãã®ã§ãä»ã®æ¹æ³ã§é²ããä»ãªãã£ããèœã¡ç©ã®ã¹ãã©ã€ãããã®ãŸãŸåè£ãããããšãé£ããã®ã§ããã°ãæ¬äŒŒçã«ããèŠããã°è¯ããšéãããã€ãŸããæåããåãããŠãããã®ã綺éºã«äžŠã¹ããŸãã§åãããŠããªãããã«èŠããããšããæ¹æ³ã ã以äžã®åç»ã¯ããã®æ¹æ³ã§å®è£ ããéçºåæã®ãã®ã ã
æ¬äŒŒçåæã®æŒåºã¯ä»¥äžã®æ¹æ³ã§å®è£ ããããšã«ããã
- èœã¡ç©ãäŸã«åãããããObj ããŒããããªãŒãºãããïŒFreeze ããããã£ããªã³ã«ããïŒ
- Obj ã·ãŒã³ãçåããæ°ã ã ObjPiece ã·ãŒã³ã Obj ããŒãã®åããŒããšããŠè¿œå ãã
- å ObjPiece ããŒãã芪㮠Obj ããŒãã®ã¹ãã©ã€ããšéãªãããã«ãçééã«é 眮ãã
- å ObjPiece ããŒãã«ã¯ãObj ã·ãŒã³ã®ã¹ãã©ã€ããå ã« AtlasTexture ã¯ã©ã¹ã䜿ã£ãŠçåãããã¯ã¹ãã£ãé©çšãã
- å ObjPiece ããŒãã«å¯ŸããŠãAtlasTexture ã®äžéæéšåãã CollisionPolygon2D ãçæããŠåããŒããšããŠé©çšãã
äžèšã®ããžãã¯ãã³ãŒãã£ã³ã°ããã®ã以äžã®ã¹ã¯ãªããã§ããã
Obj ããŒãã®ã¹ã¯ãªããïŒ
const PIECE_SCENE : PackedScene = preload("res://obj_base/obj_piece/obj_piece.tscn")
@onready var sprite: Sprite2D = $Sprite2D
func generate_obj_pieces():
var tex_image = sprite.texture
var tex_size = sprite.texture.get_size()
var h_cuts := 12
var v_cuts := 8
var frag_size = Vector2(tex_size.x / h_cuts, tex_size.y / v_cuts)
for i in h_cuts:
for j in v_cuts:
var pce = PIECE_SCENE.instantiate()
var cor = Vector2(frag_size.x * i, frag_size.y * j)
var pos = (cor + frag_size/2 - tex_size/2)
pieces.call_deferred("add_child", pce)
pce.position = pos
pce.call_deferred("set_sprite", tex_image, cor, frag_size)
pce.call_deferred("set_col_poly")
ObjPiece ããŒãã®ã¹ã¯ãªããïŒ
func set_sprite(tex_image:Texture2D, frag_pos:Vector2, frag_size:Vector2):
var tex := AtlasTexture.new()
tex.set_atlas(tex_image)
tex.set_region(Rect2(frag_pos, frag_size))
sprite.texture = tex
func set_col_poly():
var polygons = sprite.create_polygons()
if not polygons.is_empty():
for i in polygons.size():
var col_poly := CollisionPolygon2D.new()
col_poly.set_polygon(polygons[i])
col_poly.position -= sprite.texture.get_size() / 2
col_poly.disabled = false
call_deferred("add_child", col_poly)
ObjPiece ããŒãã®å Sprite ããŒãã®ã¹ã¯ãªããïŒ
func create_polygons():
var bitmap = BitMap.new()
bitmap.create_from_image_alpha(texture.get_image())
var rect := Rect2(Vector2.ZERO, texture.get_size())
var polygons = bitmap.opaque_to_polygons(rect)
return polygons
ObjPiece ããŒãã ãå
ã«èœäžããããéã«èŠªã® Obj ããŒããèœã¡ãŠããã®ã«åã® ObjPiece ããŒãã ã空äžã«æ®ã£ããããŠããŸãã®ã§ãããªãæ©ãã ãçµæçã«ãäºåã«ã€ã³ã¹ãã¯ã¿ãŒã§ã ObjPiece (RigidBody2D) ã«ãŒãããŒãã® Freeze
ããªã³ã«ããã〠Freeze Mode
ã Kinematic
ã«ããŠããå¿
èŠãããããšã«æ°ã¥ããã
æçµçã«ã¯ãèœã¡ç©ã«ãäžæ¬ããšãæãããã®åœããå€å®é åãèšããããããã§èœã¡ç©ãçåããæ°ã決ããŠãã¹ã¯ãªããäžã§æ¡ä»¶åå²ãããããäžæ¬ãã®ã»ãããã现ããåãïŒããæ°æã¡è¯ãïŒæŒåºã ã
UI ã·ãŒã³
ãã¬ã€ç»é¢ã® UI ãšããŠããŸã HUD ãç»é¢äžç«¯ã«é 眮ããããã㯠Background ã·ãŒã³ã®äŸã®è¶³å Žã§ãã StaticBody2D ããŒãã® CollisionShape2D åããŒãã®é åãšéãªãããã«ããŠããããã® HUD ã«ãäžæåæ¢ããããåéããããèšå®ç»é¢ãéãããã¹ããŒãžéžæç»é¢ã«ç§»åãããã®4ã€ã®ãã¿ã³ãèšããããã¿ã³ã®ãã¶ã€ã³ã¯ãã¢ã€ã³ã³ã®ã¿ãã€ã€ãªãã£ããªãŒã®çŽ æã䜿çšããŠãããããã以å€ã®ãã¿ã³ã®ãã¶ã€ã³ãã¬ã€ã¢ãŠãã¯ãããŒãããããã®ããããã£ã調æŽããã®ã¿ã«ããŠãã·ã³ãã«ã«çããã
äžæåæ¢ç»é¢ã UI ã·ãŒã³ã®ã²ãšã€ãšããŠäœæãããColorRect ããŒãã§å šç»é¢ã«åéæã®èãç·è²ãéããLabel ããŒãã§ãäžæåæ¢äžãã®æåã衚瀺ããããHUD ã®ãäžæåæ¢ããããã¿ã³ä»¥å€ã¯äžæåæ¢äžã§ãªããã°æŒããªãä»æ§ã«ãããããã¯èª€æäœé²æ¢çã®äžã€ã ã
ãã¹ããŒãžéžæç»é¢ã«ç§»åããããã¿ã³ãæŒããéããæ¬åœã«ã²ãŒã ãäžæããŠã¹ããŒãžéžæç»é¢ã«ç§»åããŠãè¯ãããã®ç¢ºèªãã€ã¢ãã°ã衚瀺ãããããã«ãããæçµçãªãªãã·ã§ã³ãã¿ã³ã®æèšã¯ãã¯ãããšãããããã ããéçºåæã¯ãã²ãŒã ã®é°å²æ°ãåºãã®ã«èºèµ·ã«ãªã£ãŠããã®ã§ããæ¿ç¥ããããæããã®ãããªæèšã«ããŠãããé°å²æ°ããããããããã®ã»ããåªå 床ãé«ããšå€æããŠããã«ããã
éçºçµç€ã«ã¯ãã¥ãŒããªã¢ã«ãè¿œå ãããæ£çŽããã¥ãŒããªã¢ã«ããªããŠãããã«ããããããªæäœæ§ã«ããã€ããã ã£ããããã€ã§ããã¥ãŒããªã¢ã«ãèŠãããããã«ããŠããåªããã¯ãã£ãŠãè¯ããšæã£ããããããããã§ãäžæåæ¢äžã«ç»é¢å³äžã®ïŒïŒïŒã¢ã€ã³ã³ãæŒããšãã¥ãŒããªã¢ã«ãå§ãŸãããã«ããã
äŸãåãéã«åããèœã¡ç©ãåæãããã¿ã€ãã³ã°ã§ãåœããå€å®ã®ãäžæ¬ããŸãã¯ãæãããã衚瀺ãããããã«ãããç¹å€§ã®ãã©ã³ããµã€ãºããäžç¬ã§æšæºãµã€ãºã«ã¢ãã¡ãŒã·ã§ã³ããããã«ããŠãããããããéçºçµç€ãŸã§èŠããã ã¡ã¢ãªãªãŒã¯åé¡ã«é¢ãã£ãŠãããçµè«ããèšãã°ãLabel ããŒãã®æåãæ¡å€§çž®å°ããããªã©ã¢ãã¡ãŒã·ã§ã³ããããå ŽåãçŽ çŽã« scale
ããããã£ã®å€ãå€åãããã®ãæ£è§£ã ãããããç§ã¯ãæåã®ãµã€ãºãå€åãããã=ããã©ã³ããµã€ãºãå€åãããããšèããŠããŸã£ãããã㊠AnimationPlayer ããŒãã§ãTheme Overrides Font Size
ããããã£ã®å€ãå€åãããŠããŸã£ãŠããã詳ããçç±ã¯äžæã ãããã®ã¢ãã¡ãŒã·ã§ã³ãå®è¡ããããã³ã«çŽ 150 MB ãã€ã¡ã¢ãªã®æ¶è²»éãå¢ããŠãããããã€ãã¹ããŒãžãã¯ãªã¢ããŠãããšãå¿
ãã²ãŒã ãã¯ã©ãã·ã¥ãããšããç¶æ
ã§ãã£ããæã蟌ã¿ã«ã¯èŠæ³šæã§ããã
ã¹ããŒãžã¯ãªã¢åŸã®ãªãã·ã§ã³ãã¿ã³ãå®è£ ãããã次ãžåãããåã³æãããã¹ããŒãžéžæãã®3ã€ã ãã¢ãã€ã«ã«ãžã¥ã¢ã«ã²ãŒã ãšããã°ãéå€éåŠäžã®é»è»ããã¹ã§ã®æäœãæ³å®ããå¿ èŠãããã ãããå Žåã«ãã£ãŠã¯çæã§ã®æäœããããããããã§ããããã®ãªãã·ã§ã³ãã¿ã³ã¯ç»é¢ã®äžéšã«é 眮ãããã次ãžåãããæŒãæ©äŒãäžçªå€ãã¯ããªã®ã§ãé çªã¯äžçªäžã«ãã£ãŠããã
ã¹ããŒãžéžæç»é¢
ã¹ããŒãžéžæç»é¢ã¯ãã¬ã€ç»é¢ãšã¯å¥ç©ãšããŠçšæããããã®ç»é¢ãèµ·ç¹ã«ãèšå®ç»é¢ãã¡ãã¥ãŒç»é¢ãèœç©èšé²ç»é¢ãžé·ç§»ããããã«ãããã¡ãã¥ãŒç»é¢ã«ã¯ããã«ãã¹ã³ã¢ç»é¢ãã¯ã¬ãžãã/ã©ã€ã»ã³ã¹ç»é¢ãžã®é·ç§»ããAppã¬ãã¥ãŒããŒãžãžã®ãªã³ã¯ãã²ãŒã ããŒã¿æ¶å»æ©èœãå®è£ ããã
ã¹ããŒãžéžæç»é¢ã¯ãåœåãã¹ããŒãžéžæçšã®ã¢ã€ã³ã³ã ScrollContainer ã®äžã«å š200ã¹ããŒãžåçšæããŠãããVisibleOnScreenEnabler2D ããŒãã«ãã£ãŠãç»é¢äžã«è¡šç€ºãããååŸã§ã衚瀺 / é衚瀺ãèªåã§åãæ¿ããã³ã³ãã¥ãŒã¿ã®ãªãœãŒã¹ãç¯çŽãããããªããžãã¯ã§å®è£ ããŠãããããããããã§ãç»é¢ãã¹ã¯ããŒã«ããããšãã®ãã£ããããåããæ°ã«ãªã£ãŠããŸãã¬ãã«ã ã£ãã®ã§ãæ§æãå€æŽãããã¬ãã«åãæ¿ããã¿ã³ãæ°ãã«é 眮ãã1 ç»é¢å ã«ã¯ 1 ã¬ãã« 20 ã¹ããŒãžåã®ã¢ã€ã³ã³ãã衚瀺ãããªãããã«èª¿æŽãããããã«ããããã£ããæã¯ãªããªã£ãã
ãã¬ã€ç»é¢åæ§ããã®ã¹ããŒãžéžæç»é¢ãè¥å¹²æäœæ¹æ³ã«è¿·ãå¯èœæ§ããããšå€æãããã¥ãŒããªã¢ã«ãçšæãããå³äžã®ïŒïŒïŒã¢ã€ã³ã³ãããã€ã§ã衚瀺ã§ããä»çµã¿ããã¬ã€ç»é¢ã®ãããšåãã§ããã
èšå®ç»é¢
èšå®ç»é¢ã®ã€ããèªäœã¯è³ã£ãŠã·ã³ãã«ã ãContainer ç³»ã®ããŒãã䜿ã£ãŠãã¬ã€ã¢ãŠããæŽçããã ãã§ããããã¿ã³ã®ã¢ã€ã³ã³ã¯ãã€ã€ãªãã£ããªãŒã®çŽ æã䜿çšããŠããã
ãã¿ã³ã¯ãã¹ãŠ Toggle Mode
ããªã³ã«ããŠãtoggled(button_pressed: bool)
ã·ã°ãã«ãã«ãŒãããŒãã®ã¹ã¯ãªããã«çŽã¥ãããäŸãã°ãBGMãã¿ã³ã®ã·ã°ãã«ã¯ä»¥äžã®ã¡ãœããã«çŽã¥ããŠããã
func _on_background_music_button_toggled(button_pressed):
if button_pressed:
Gamedata.bgm_enabled = true
if Gamedata.sfx_enabled:
enabled_sound_player.play()
bgm_disabled.emit()
else:
Gamedata.bgm_enabled = false
if Gamedata.sfx_enabled:
disabled_sound_player.play()
bgm_enabled.emit()
bgm_button.release_focus()
äžèšã³ãŒãã®ãã¡ãGamedata
ãšããã®ã¯ãGodot ã® Autoload æ©èœã§èªã¿èŸŒãã§ããã¹ã¯ãªããã ãèšå®ãä¿åããã«ã¯ãèšå®ãã¡ã€ã«ãçšæããå¿
èŠãããã®ã§ãã»ãŒã/ããŒãæ©èœããŸãšãã gamedata.gd ã¹ã¯ãªãããäœããAutoload ã§ã²ãŒã éå§æã«èªåã§èªã¿èŸŒãŸããããã«ãããã¹ã¯ãªããã®ã³ãŒãã¯ä»¥äžã®ããã«ãªã£ãŠããã
const OPTIONS_PATH := "user://options.save"
var bgm_enabled := true
var sfx_enabled := true
var background_pattern := true
var ippon_only := false
var speech_bubble_enabled := true
var speech_bubble_auto_hide := false
func save_options():
var options = {
"bgm_enabled": bgm_enabled,
"sfx_enabled": sfx_enabled,
"background_pattern": background_pattern,
"ippon_only": ippon_only,
"speech_bubble_enabled": speech_bubble_enabled,
"speech_bubble_auto_hide": speech_bubble_auto_hide
}
var file = FileAccess.open(OPTIONS_PATH, FileAccess.WRITE)
file.store_var(options)
file.close()
func load_options():
var file = FileAccess.open(OPTIONS_PATH, FileAccess.READ)
if !file: return
var options = file.get_var()
if !options:
file.close()
return
if options.has("bgm_enabled"):
bgm_enabled = options["bgm_enabled"]
if options.has("sfx_enabled"):
sfx_enabled = options["sfx_enabled"]
if options.has("background_pattern"):
background_pattern = options["background_pattern"]
if options.has("ippon_only"):
ippon_only = options["ippon_only"]
if options.has("speech_bubble_enabled"):
speech_bubble_enabled = options["speech_bubble_enabled"]
if options.has("speech_bubble_auto_hide"):
speech_bubble_auto_hide = options["speech_bubble_auto_hide"]
file.close()
ãããã«
ãšããããšã§ããã®éçºãã°ã«ã¯ããã®åãäŸãã®ããžãã¯ã«é¢ããéšåãèšããã
3D ã²ãŒã ã¯ããããªããã2D ã²ãŒã ã«é¢ããŠã¯ãGodot ã«çšæãããŠããæ§ã ãªã¯ã©ã¹ãçµã¿åãããã°ãå®çŸãããããšã¯ã ãããã§ããŠããŸãã®ã§ã¯ãªããããšæã£ãããããããããšåæã«ãã²ãŒã ã®ã¢ã€ãã¢ãã¢ã«ãŽãªãºã ã«èœãšã蟌ãã§ããããå®çŸããããã«ããã¥ã¡ã³ããèªã¿èŸŒãã§æ€èšŒããäœæ¥ã¯ãæã«çžåœã®å¿èãå¿ èŠã«ãªããšããããšãããã£ãã
ãã®éçºãã°ãã©ãªããã®ã²ãŒã éçºã®äžå©ã«ãªãã°å¹žãã ã