Compare commits

...

5 Commits

Author SHA1 Message Date
bog 52436feb3d ADD: strikes. 2023-09-30 20:21:50 +02:00
bog 93003abb2a ADD: doors. 2023-09-30 18:05:08 +02:00
bog 407e12fd38 ADD: lose screen. 2023-09-30 17:09:31 +02:00
bog b913e87654 ADD: field destruction. 2023-09-30 15:56:43 +02:00
bog 751fe607bd ADD: bears can shoot at player. 2023-09-30 12:46:55 +02:00
25 changed files with 403 additions and 39 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 438 B

View File

@ -25,6 +25,9 @@ func to_falling():
m_state = preload("res://Actor/Falling.gd").new() m_state = preload("res://Actor/Falling.gd").new()
m_state.this = self m_state.this = self
func is_dead():
return m_state.state_name == 'Dead'
func to_dead(): func to_dead():
m_state = preload("res://Actor/Dead.gd").new() m_state = preload("res://Actor/Dead.gd").new()
m_state.this = self m_state.this = self

View File

@ -4,9 +4,9 @@
[ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="2_itibm"] [ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="2_itibm"]
[sub_resource type="CircleShape2D" id="CircleShape2D_e2sef"] [sub_resource type="CircleShape2D" id="CircleShape2D_e2sef"]
radius = 16.0312 radius = 6.0
[node name="Actor" type="CharacterBody2D"] [node name="Actor" type="CharacterBody2D" groups=["actors"]]
script = ExtResource("1_0612w") script = ExtResource("1_0612w")
[node name="Sprite2D" type="Sprite2D" parent="."] [node name="Sprite2D" type="Sprite2D" parent="."]

View File

@ -1,7 +1,24 @@
extends Node2D extends Node2D
var m_world = null
var m_target = null
var m_shoot_time = 2.0
var m_shoot_timer = 0.0
var m_range = 300.0
func _ready(): func _ready():
$Actor/Sprite2D.modulate = Color.RED $Actor/Sprite2D.modulate = Color.RED
m_shoot_timer = randf_range(0.0, m_shoot_time)
func _process(_delta):
pass func _process(delta):
if m_target and $Actor.is_normal() and not m_target.get_node('Actor').is_dead():
if m_shoot_timer >= m_shoot_time:
var to_target = m_target.get_node('Actor').global_position - $Actor.global_position
var dir = to_target.normalized()
var dist = to_target.length()
if dist < m_range:
m_world.throw_bomb($Actor.global_position, dir, dist)
m_shoot_timer = 0.0
m_shoot_timer += delta

View File

@ -3,7 +3,7 @@
[ext_resource type="Script" path="res://Bear/bear.gd" id="1_yppa7"] [ext_resource type="Script" path="res://Bear/bear.gd" id="1_yppa7"]
[ext_resource type="PackedScene" uid="uid://c0kqx6dsury58" path="res://Actor/actor.tscn" id="2_6n7sl"] [ext_resource type="PackedScene" uid="uid://c0kqx6dsury58" path="res://Actor/actor.tscn" id="2_6n7sl"]
[node name="Bear" type="Node2D"] [node name="Bear" type="Node2D" groups=["bears"]]
script = ExtResource("1_yppa7") script = ExtResource("1_yppa7")
[node name="Actor" parent="." instance=ExtResource("2_6n7sl")] [node name="Actor" parent="." instance=ExtResource("2_6n7sl")]

33
src/Door/door.gd Normal file
View File

@ -0,0 +1,33 @@
extends StaticBody2D
@export var ID : int = 0
var m_state = null
var m_open_timer = 0.0
var m_open_time = 0.2
@onready var m_init_y_scale = $Sprite2D.scale.y
@onready var m_init_y_pos = $Sprite2D.global_position.y
func _ready():
m_state = self.process_idle
func open():
m_state = self.process_open
pass
func _process(delta):
if m_state != null:
m_state.call(delta)
func process_idle(_delta):
pass
func process_open(delta):
if m_open_timer >= m_open_time:
queue_free()
else:
var t = min(1.0, m_open_timer / m_open_time)
var ratio = (1.0 - t) * m_init_y_scale
$Sprite2D.scale.y = ratio
m_open_timer += delta

18
src/Door/door.tscn Normal file
View File

@ -0,0 +1,18 @@
[gd_scene load_steps=4 format=3 uid="uid://d30oryxv0w7pf"]
[ext_resource type="Script" path="res://Door/door.gd" id="1_62c16"]
[ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="1_urwyt"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2o8ax"]
size = Vector2(74, 20)
[node name="Door" type="StaticBody2D" groups=["doors"]]
script = ExtResource("1_62c16")
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color(1, 0, 1, 1)
scale = Vector2(0.5, 0.25)
texture = ExtResource("1_urwyt")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_2o8ax")

View File

@ -0,0 +1,17 @@
extends Area2D
@export var ID : int = 0
func _ready():
pass
func _process(_delta):
pass
func _on_body_entered(body):
if body in get_tree().get_nodes_in_group('bombs'):
body._explode(0)
for door in get_tree().get_nodes_in_group('doors'):
if door.ID == self.ID:
door.open()
queue_free()

View File

@ -0,0 +1,24 @@
[gd_scene load_steps=4 format=3 uid="uid://c5f7m5oi32kr5"]
[ext_resource type="Script" path="res://DoorCommand/door_command.gd" id="1_l2uva"]
[ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="1_uchk3"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6j0py"]
size = Vector2(36, 60)
[node name="DoorCommand" type="Area2D"]
collision_layer = 2
collision_mask = 2
script = ExtResource("1_l2uva")
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color(0.329412, 0.329412, 0.329412, 1)
position = Vector2(-0.5, -8.5)
scale = Vector2(0.179688, 0.382812)
texture = ExtResource("1_uchk3")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(3, -10)
shape = SubResource("RectangleShape2D_6j0py")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

32
src/Levels/level_0.tscn Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://ch3n607i8yqy8"]
[node name="LoseMenu" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="ColorRect" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 1)
[node name="Label" type="Label" parent="."]
layout_mode = 0
offset_left = 473.0
offset_top = 54.0
offset_right = 551.0
offset_bottom = 77.0
text = "YOU LOSE"

15
src/MainMenu/main_menu.gd Normal file
View File

@ -0,0 +1,15 @@
extends Control
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func _on_button_pressed():
get_tree().change_scene_to_file("res://Levels/level_0.tscn")

View File

@ -0,0 +1,23 @@
[gd_scene load_steps=2 format=3 uid="uid://sj7j3yxfjkko"]
[ext_resource type="Script" path="res://MainMenu/main_menu.gd" id="1_ga0yx"]
[node name="MainMenu" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ga0yx")
[node name="Button" type="Button" parent="."]
layout_mode = 0
offset_left = 518.0
offset_top = 184.0
offset_right = 565.0
offset_bottom = 215.0
text = "PLAY
"
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]

View File

@ -15,11 +15,12 @@ func _ready():
func _process(_delta): func _process(_delta):
pass pass
func throw_at(pos: Vector2, dir: Vector2): func throw_at(pos: Vector2, dir: Vector2, dist: float):
self.position = pos self.position = pos
m_origin = pos m_origin = pos
m_dir = dir m_dir = dir
m_state = self._moving m_state = self._moving
m_dist = dist
func _physics_process(delta): func _physics_process(delta):
if (m_origin - self.position).length_squared() >= m_dist * m_dist: if (m_origin - self.position).length_squared() >= m_dist * m_dist:
@ -29,9 +30,10 @@ func _physics_process(delta):
m_state.call(delta) m_state.call(delta)
func _explode(_delta): func _explode(_delta):
emit_signal('on_explode', self) emit_signal('on_explode', self, 1)
queue_free() queue_free()
func _moving(delta): func _moving(delta):
self.velocity = m_dir * m_speed self.velocity = m_dir * m_speed
move_and_collide(self.velocity * delta) move_and_collide(self.velocity * delta)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=4 format=3 uid="uid://b212rruvxhwqe"] [gd_scene load_steps=5 format=3 uid="uid://b212rruvxhwqe"]
[ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="1_ga5l4"] [ext_resource type="Texture2D" uid="uid://blr8qcmuqs5vl" path="res://icon.svg" id="1_ga5l4"]
[ext_resource type="Script" path="res://Molotov/molotov.gd" id="1_uepii"] [ext_resource type="Script" path="res://Molotov/molotov.gd" id="1_uepii"]
@ -6,8 +6,11 @@
[sub_resource type="CircleShape2D" id="CircleShape2D_oq4si"] [sub_resource type="CircleShape2D" id="CircleShape2D_oq4si"]
radius = 14.0 radius = 14.0
[node name="Molotov" type="CharacterBody2D"] [sub_resource type="CircleShape2D" id="CircleShape2D_v1u5d"]
collision_layer = 0 radius = 34.0147
[node name="Molotov" type="CharacterBody2D" groups=["bombs"]]
collision_layer = 2
collision_mask = 0 collision_mask = 0
script = ExtResource("1_uepii") script = ExtResource("1_uepii")
@ -18,3 +21,8 @@ texture = ExtResource("1_ga5l4")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_oq4si") shape = SubResource("CircleShape2D_oq4si")
[node name="Area2D" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("CircleShape2D_v1u5d")

View File

@ -1,8 +1,24 @@
extends Node2D extends Node2D
func _physics_process(_dt): var m_world = null
var delta = Vector2(0, 0) var m_shoot_time = 0.2
var m_shoot_timer = 0.0
func _physics_process(dt):
var delta = Vector2(0, 0)
if Input.is_action_just_pressed("player_shoot") \
and m_shoot_timer >= m_shoot_time \
and not $Actor.is_dead():
var coord = get_global_mouse_position()
var to_mouse = coord - $Actor.global_position
var dir = to_mouse.normalized()
var dist = to_mouse.length()
m_world.throw_bomb($Actor.global_position, dir, dist)
m_shoot_timer = 0.0
m_shoot_timer += dt
if Input.is_action_pressed("player_up"): if Input.is_action_pressed("player_up"):
delta.y -= 1.0 delta.y -= 1.0
if Input.is_action_pressed("player_down"): if Input.is_action_pressed("player_down"):

View File

@ -3,7 +3,7 @@
[ext_resource type="Script" path="res://Player/player.gd" id="1_2pfvx"] [ext_resource type="Script" path="res://Player/player.gd" id="1_2pfvx"]
[ext_resource type="PackedScene" uid="uid://c0kqx6dsury58" path="res://Actor/actor.tscn" id="2_s40rr"] [ext_resource type="PackedScene" uid="uid://c0kqx6dsury58" path="res://Actor/actor.tscn" id="2_s40rr"]
[node name="Player" type="Node2D"] [node name="Player" type="Node2D" groups=["player"]]
script = ExtResource("1_2pfvx") script = ExtResource("1_2pfvx")
[node name="Actor" parent="." instance=ExtResource("2_s40rr")] [node name="Actor" parent="." instance=ExtResource("2_s40rr")]

41
src/Sandbox/Strikes.gd Normal file
View File

@ -0,0 +1,41 @@
extends Node2D
class Line:
var m_time: float = 0.0
var m_source: Vector2 = Vector2(0.0, 0.0)
var m_position: Vector2 = Vector2(0.0, 0.0)
var m_color : Color = Color.RED
var m_timer : float = 0.0
func _init(t, src, pos, col):
m_time = t
m_source = src
m_position = pos
m_color = col
var m_lines = []
# Called when the node enters the scene tree for the first time.
func _ready():
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
for line in m_lines:
line.m_timer += delta
var t = min(1.0, line.m_timer / line.m_time)
line.m_color = Color(1, 0, 0, 1.0 - t)
m_lines = m_lines.filter(func (x): return x.m_timer < x.m_time)
queue_redraw()
func add_line(pos: Vector2, duration: float):
var src = Vector2(randf_range(0, 800), 0)
m_lines.push_back(Line.new(duration, src, pos, Color.RED))
func _draw():
for line in m_lines:
draw_line(line.m_source, line.m_position, line.m_color, 3)

View File

@ -1,37 +1,106 @@
extends Node2D extends Node2D
var m_broken_timer = 0.0
var m_broken_time = 0.2
var process_state = null
var m_death_timer = 0.0
var m_death_time = 2.0
var m_strike_time = 1.0
var m_strike_timer = 0.0
var m_strikes = []
func _ready(): func _ready():
pass for bear in get_tree().get_nodes_in_group('bears'):
bear.m_target = $Player
bear.m_world = self
$Player.m_world = self
self.process_state = self.process
func _process(_delta): func _process(delta):
if Input.is_action_just_pressed("ui_accept"): if self.process_state:
throw_bomb(Vector2(512, 256), Vector2(0, 1)) self.process_state.call(delta)
if is_outside($Player/Actor) and $Player/Actor.is_normal(): func process(delta):
$Player/Actor.to_falling() for actor in get_tree().get_nodes_in_group('actors'):
if is_outside(actor) and actor.is_normal():
actor.to_falling()
if is_outside($Bear/Actor) and $Bear/Actor.is_normal(): if m_strike_timer >= m_strike_time:
$Bear/Actor.to_falling() var all = $TileMap.get_used_cells(0)
all.shuffle()
var ground = null
for t in all:
var data = $TileMap.get_cell_tile_data(0, t)
if data.get_custom_data('type') == 'ground':
ground = t
break
self.add_broken_ground(ground, 1, 0.8)
$Strikes.add_line(to_global($TileMap.map_to_local(ground)), 0.15)
m_strike_timer = 0.0
m_strike_time = randf() * 5.0
m_strike_timer += delta
if m_broken_timer >= m_broken_time:
var k = 0
var N = 2
var all_cell = $TileMap.get_used_cells(0)
all_cell.shuffle()
for t in all_cell:
var data = $TileMap.get_cell_tile_data(0, t)
var type = data.get_custom_data('type')
if type == 'broken' and k < N:
$TileMap.set_cell(0, t, 0, Vector2i(1, 0))
add_broken_ground(t, 1, 0.4)
k += 1
m_broken_timer = 0.0
m_broken_timer += delta
if $Player/Actor.is_dead():
self.process_state = self.process_death
m_death_timer = 0.0
func process_death(delta):
var f = m_death_timer/m_death_time
$CanvasLayer/ColorRect.modulate = Color(0, 0, 0, f)
if m_death_timer >= m_death_time:
get_tree().change_scene_to_file("res://LoseMenu/lose_menu.tscn")
m_death_timer += delta
func is_outside(actor): func is_outside(actor):
var coord = $TileMap.local_to_map(actor.global_position) var coord = $TileMap.local_to_map(actor.global_position)
var tile : TileData = $TileMap.get_cell_tile_data(0, coord) var tile : TileData = $TileMap.get_cell_tile_data(0, coord)
return tile.get_custom_data('is_void') if tile:
return tile.get_custom_data('type') == 'void'
func throw_bomb(from: Vector2, dir: Vector2): func throw_bomb(from: Vector2, dir: Vector2, dist: float):
var bomb = preload("res://Molotov/molotov.tscn").instantiate() var bomb = preload("res://Molotov/molotov.tscn").instantiate()
bomb.on_explode.connect(_on_bomb_explode) bomb.on_explode.connect(_on_bomb_explode)
bomb.throw_at(from, dir) bomb.throw_at(from, dir, dist)
add_child(bomb) add_child(bomb)
func _on_bomb_explode(bomb): func _on_bomb_explode(bomb, _level):
var tilemap: TileMap = $TileMap var tilemap: TileMap = $TileMap
var pos = tilemap.local_to_map(bomb.position) var pos = tilemap.local_to_map(bomb.position)
var rad = bomb.m_explosion_radius var rad = bomb.m_explosion_radius
var extra = 2
var proba = 0.6
add_broken_ground(pos, extra, proba)
for i in range(pos.y - rad, pos.y + rad ): for i in range(pos.y - rad, pos.y + rad ):
for j in range(pos.x - rad, pos.x + rad ): for j in range(pos.x - rad, pos.x + rad ):
tilemap.set_cell(0, Vector2i(j, i), 0, Vector2i(1, 0)) tilemap.set_cell(0, Vector2i(j, i), 0, Vector2i(1, 0))
func add_broken_ground(pos: Vector2i, rad, proba):
for i in range(pos.y - rad , pos.y + rad):
for j in range(pos.x - rad, pos.x + rad):
if randf() <= proba:
var data = $TileMap.get_cell_tile_data(0, Vector2i(j, i))
if data and data.get_custom_data('type') == 'ground':
$TileMap.set_cell(0, Vector2i(j, i), 0, Vector2i(2, 0))

File diff suppressed because one or more lines are too long

View File

@ -8,16 +8,21 @@ texture_region_size = Vector2i(32, 32)
0:0/0 = 0 0:0/0 = 0
0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
0:0/0/physics_layer_0/angular_velocity = 0.0 0:0/0/physics_layer_0/angular_velocity = 0.0
0:0/0/custom_data_0 = "ground"
1:0/0 = 0 1:0/0 = 0
1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
1:0/0/physics_layer_0/angular_velocity = 0.0 1:0/0/physics_layer_0/angular_velocity = 0.0
1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) 1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
1:0/0/custom_data_0 = true 1:0/0/custom_data_0 = "void"
2:0/0 = 0
2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
2:0/0/physics_layer_0/angular_velocity = 0.0
2:0/0/custom_data_0 = "broken"
[resource] [resource]
tile_size = Vector2i(32, 32) tile_size = Vector2i(32, 32)
physics_layer_0/collision_layer = 0 physics_layer_0/collision_layer = 0
physics_layer_0/collision_mask = 0 physics_layer_0/collision_mask = 0
custom_data_layer_0/name = "is_void" custom_data_layer_0/name = "type"
custom_data_layer_0/type = 1 custom_data_layer_0/type = 4
sources/0 = SubResource("TileSetAtlasSource_0k0yx") sources/0 = SubResource("TileSetAtlasSource_0k0yx")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 438 B

0
src/export_presets.cfg Normal file
View File

View File

@ -11,7 +11,7 @@ config_version=5
[application] [application]
config/name="Ludum Dare 54" config/name="Ludum Dare 54"
run/main_scene="res://Sandbox/sandbox.tscn" run/main_scene="res://MainMenu/main_menu.tscn"
config/features=PackedStringArray("4.2", "GL Compatibility") config/features=PackedStringArray("4.2", "GL Compatibility")
config/icon="res://icon.svg" config/icon="res://icon.svg"
@ -37,6 +37,11 @@ player_right={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null)
] ]
} }
player_shoot={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
[rendering] [rendering]