Asset Store
Discover high-quality assets for your next game project, or create your own with AI.
Create AssetDiscover high-quality assets for your next game project, or create your own with AI.
Create Asset
Made with Nano Banana 2 Lite · CC0 · 3 Oct 2026
Generated from: a scene from a small video game about: extends CharacterBody3D signal hp_changed(new_hp) signal coin_collected() const SPEED = 7.0 const JUMP_VELOCITY = 10.0 const DASH_SPEED = 22.0 var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") var max_hp = 100 var current_hp = 100 var is_dead = false # Sistema de Combate e Loja var active_weapon = "padrao" # "padrao", "fogo", "raio" var is_attacking = false var is_parrying = false # Sistema de Esquiva (Dash) var is_dashing = false var can_dash = true var facing_direction = 1 # 1 para Direita, -1 para Esquerda @onready var dash_timer = $DashTimer @onready var dash_cooldown = $DashCooldown @onready var sword_area = $SwordArea # Area3D na lâmina da espada func _ready(): add_to_group("player") dash_timer.timeout.connect(_on_dash_timer_timeout) dash_cooldown.timeout.connect(_on_dash_cooldown_timeout) current_hp = max_hp load_weapon_skin() func _physics_process(delta): if is_dead: return # Aplicar Gravidade if not is_on_floor() and not is_dashing: velocity.y -= gravity * delta # Pulo if Input.is_action_just_pressed("ui_accept") and is_on_floor() and not is_dashing: velocity.y = JUMP_VELOCITY # Movimentação Lateral (Eixo X apenas, mantendo Z travado) var input_dir = Input.get_axis("ui_left", "ui_right") if input_dir != 0 and not is_dashing: facing_direction = sign(input_dir) # Rotaciona o modelo 3D para olhar para a direção certa rotation.y = atan2(-input_dir, 0) velocity.x = input_dir * SPEED elif not is_dashing: velocity.x = move_toward(velocity.x, 0, SPEED) # Executar Dash (Shift ou Botão Virtual) if Input.is_action_just_pressed("dash") and can_dash and not is_dashing: start_dash() # Aplicar velocidade do Dash if is_dashing: velocity.x = facing_direction * DASH_SPEED velocity.y = 0 # Ignora gravidade no dash spawn_ghost_effect() move_and_slide() # Ataque / Parry (Z ou Botão Ataque) if Input.is_action_just_pressed("attack") and not is_attacking and not is_dashing: attack() func attack(): is_attacking = true is_parrying = true trigger_weapon_particles(true) # Janela de Parry dura 0.15 segundos await get_tree().create_timer(0.15).timeout is_parrying = false # Verifica colisão do ataque com inimigos var targets = sword_area.get_overlapping_bodies() for body in targets: if body.is_in_group("enemies"): body.take_damage(active_weapon) await get_tree().create_timer(0.2).timeout trigger_weapon_particles(false) is_attacking = false func start_dash(): is_dashing = true can_dash = false dash_timer.start(0.3) # Duração do Dash dash_cooldown.start(1.5) # Cooldown do Dash # Notificar a interface para desativar visualmente o botão de dash func _on_dash_timer_timeout(): is_dashing = false func _on_dash_cooldown_timeout(): can_dash = true func take_damage(amount): if is_dashing: return # Invencível durante o Dash if is_parrying: trigger_parry_vfx() return # Parry com sucesso! Não toma dano. current_hp -= amount hp_changed.emit(current_hp) if current_hp <= 0: die() func die(): is_dead = true # Aciona tela de Game Over puxando a lógica do Main global func trigger_parry_vfx(): # Congela o jogo rapidamente por impacto (Hitstop) Engine.time_scale = 0.05 await get_tree().create_timer(0.05, true, false, true).timeout Engine.time_scale = 1.0 # Lógica para instanciar faíscas azuis (Partículas 3D) na posição da espada var main = get_tree().current_scene if main.has_method("screen_shake"): main.screen_shake(0.2, 15) func spawn_ghost_effect(): # Cria efeito de rastro criando cópias mesh transparentes temporárias pass func trigger_weapon_particles(enabled: bool): if active_weapon == "fogo": $SwordArea/FireParticles.emitting = enabled elif active_weapon == "raio": $SwordArea/LightningParticles.emitting = enabled func load_weapon_skin(): active_weapon = SaveSystem.get_equipped_katana() extends CharacterBody3D const BASE_DAMAGE = 15 var speed = 4.0 var hp = 1 var player = null @onready var coin_scene = preload("res://Coin.tscn") func _ready(): add_to_group("enemies") player = get_tree().get_first_node_in_group("player") func _physics_process(delta): if not player or player.is_dead: return # Persegue o jogador no eixo horizontal (X) var direction = sign(player.global_position.x - global_position.x) velocity.x = direction * speed # Gravidade simples para o inimigo 3D if not is_on_floor(): velocity.y -= 9.8 * delta move_and_slide() # Se encostar no jogador, causa dano for i in get_slide_collision_count(): var collision = get_slide_collision(i) if collision.get_collider().is_in_group("player"): collision.get_collider().take_damage(BASE_DAMAGE) func take_damage(weapon_type): hp -= 1 if hp <= 0: die(weapon_type) func die(weapon_type): # Hitstop ao derrotar inimigo Engine.time_scale = 0.1 var main = get_tree().current_scene if main.has_method("screen_shake"): main.screen_shake(0.3, 20) await get_tree().create_timer(0.08, true, false, true).timeout Engine.time_scale = 1.0 # Drop de moedas (1 a 3 moedas) var coin_count = randi_range(1, 3) for i in range(coin_count): var coin = coin_scene.instantiate() main.add_child(coin) # Spawna levemente disperso em 3D coin.global_position = global_position + Vector3(randf_range(-0.5, 0.5), 0.5, 0) main.enemy_killed() queue_free() extends Node const SAVE_PATH = "user://save_game.dat" var save_data = { "coins": 0, "unlocked_katanas": ["padrao"], "equipped_katana": "padrao" } func _ready(): load_game() func save_game(): var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE) if file: file.store_var(save_data) func load_game(): if FileAccess.file_exists(SAVE_PATH): var file = FileAccess.open(SAVE_PATH, FileAccess.READ) if file: var data = file.get_var() if data is Dictionary: save_data = data func get_coins() -> int: return save_data["coins"] func add_coins(amount: int): save_data["coins"] += amount save_game() func unlock_katana(id: String) -> bool: if not save_data["unlocked_katanas"].has(id): save_data["unlocked_katanas"].append(id) save_game() return true return false func get_equipped_katana() -> String: return save_data["equipped_katana"] func equip_katana(id: String): save_data["equipped_katana"] = id save_game() extends Node3D var survival_time = 0.0 var kills = 0 var difficulty_multiplier = 1.0 @onready var enemy_scene = preload("res://Enemy.tscn") @onready var camera = $Camera3D @onready var hp_bar = $HUD/ProgressBar @onready var kills_label = $HUD/KillsLabel @onready var time_label = $HUD/TimeLabel # Variáveis do tremor da câmera var shake_amount = 0.0 var shake_duration = 0.0 var original_cam_pos : Vector3 func _ready(): original_cam_pos = camera.global_position $EnemySpawnTimer.timeout.connect(_on_spawn_timer_timeout) $DifficultyTimer.timeout.connect(_on_difficulty_timer_timeout) $Player.hp_changed.connect(_on_player_hp_changed) hp_bar.max_value = 100 hp_bar.value = 100 func _process(delta): if not $Player.is_dead: survival_time += delta time_label.text = "Tempo: " + str(int(survival_time)) + "s" # Processamento físico do tremor da câmera if shake_duration > 0: camera.global_position = original_cam_pos + Vector3( randf_range(-shake_amount, shake_amount), randf_range(-shake_amount, shake_amount), 0 ) shake_duration -= delta else: camera.global_position = original_cam_pos func screen_shake(duration: float, amount: float): shake_duration = duration shake_amount = amount * 0.01 func _on_spawn_timer_timeout(): if $Player.is_dead: return # Decide se o inimigo vem da esquerda ou direita da tela no cenário 3D var spawn_side = [Vector3(-15, 0, 0), Vector3(15, 0, 0)].pick_random() var enemy = enemy_scene.instantiate() add_child(enemy) enemy.global_position = $Player.global_position + spawn_side # Aplica o aumento progressivo de atributos do inimigo pelas ondas enemy.speed *= difficulty_multiplier func _on_difficulty_timer_timeout(): # Disp, as an in-game screenshot in flat colour 2D shapes with a bright limited palette. Palette: sky blue #8ecae6, grass #3a7d44, player sunflower #ffb703, threat red #d62828, accent white #fdfcdc. Everything is original: never draw or resemble characters, places or logos from existing games, films or brands (no red-capped plumbers, no famous mascots), even when the idea names one. Keep the pictures honest: they promise what a small first version of this game, made in a game engine in a few days, can look like. Simple readable shapes, clear silhouettes, few flat materials, the in-game camera view. Never film stills, photoreal renders, AAA key art, detailed textures, cinematic lighting, or anything that looks like a big-studio game. No text, UI, HUD, logos or editor screens inside any image.
Creator
Luan Micaep
Sign in to join the conversation.
Sign in to comment🌍CC0
Use, share, and remix the model freely with no restrictions and no attribution needed.