Play zones

This commit is contained in:
Иван Кузьменко 2023-08-19 14:25:16 +03:00
parent 4826bc4035
commit 7cce797ded
7 changed files with 150 additions and 58 deletions

View file

@ -5,6 +5,7 @@
- rndtrash - coding
- friendlywithmeat - coding, sprite batch conversion, math behind the flashlight
- mrzuerg - graphics and level design
- jerumansama - title screen graphics
## Used resources

View file

@ -1,6 +1,8 @@
Вишлист Говнодо:
- движок срёт эррорами при перезагрузке карты с ViewportTexture
- перетаскивание папок в фавориты
- инвестирование карты нормалей -> инвертирование
- размер лимита -> лимит размера
- Фикс https://github.com/godotengine/godot/issues/75868
- Фикс https://github.com/godotengine/godot/issues/75868
- ParallaxBackground сломан???

View file

@ -1,6 +1,20 @@
[gd_scene load_steps=2 format=3 uid="uid://bdtjnmjopi5h2"]
[gd_scene load_steps=3 format=3 uid="uid://bdtjnmjopi5h2"]
[ext_resource type="Script" path="res://scripts/PlayZone.cs" id="1_k3xi5"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1bby8"]
size = Vector2(2, 1)
[node name="PlayZone" type="Node2D"]
script = ExtResource("1_k3xi5")
[node name="Area2D" type="Area2D" parent="."]
collision_layer = 4
collision_mask = 4
monitorable = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_1bby8")
[connection signal="body_entered" from="Area2D" to="." method="BodyEntered"]
[connection signal="body_exited" from="Area2D" to="." method="BodyExited"]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=27 format=3 uid="uid://dhn7yt46fyac8"]
[gd_scene load_steps=28 format=3 uid="uid://dhn7yt46fyac8"]
[ext_resource type="PackedScene" uid="uid://bhulqhxesd5gc" path="res://prefabs/player.tscn" id="1_65a7v"]
[ext_resource type="AudioStream" uid="uid://bsy2d0bl3lgg0" path="res://sounds/crank.ogg" id="1_cweq4"]
@ -11,11 +11,12 @@
[ext_resource type="Script" path="res://scripts/GameCamera.cs" id="6_quua3"]
[ext_resource type="Script" path="res://scripts/PointLight2DWorkaround.cs" id="6_slohe"]
[ext_resource type="PackedScene" uid="uid://ccg3n7sobsvdw" path="res://prefabs/enemies/watcher.tscn" id="10_fsiss"]
[ext_resource type="PackedScene" uid="uid://bpusphyhhg074" path="res://prefabs/enemies/living_armor.tscn" id="11_x3ep3"]
[ext_resource type="PackedScene" path="res://prefabs/enemies/living_armor.tscn" id="11_x3ep3"]
[ext_resource type="PackedScene" uid="uid://bj1ixwjdpnooo" path="res://prefabs/entities/pressure_plate.tscn" id="12_ynt5e"]
[ext_resource type="PackedScene" uid="uid://dqx43vr727ft8" path="res://prefabs/entities/spikes.tscn" id="13_w1hk1"]
[ext_resource type="Script" path="res://scripts/DeathScreen.cs" id="15_12mhe"]
[ext_resource type="PackedScene" uid="uid://bmyjqerhno5vi" path="res://prefabs/enemies/wretched.tscn" id="16_ejflu"]
[ext_resource type="PackedScene" path="res://prefabs/enemies/wretched.tscn" id="16_ejflu"]
[ext_resource type="PackedScene" uid="uid://bdtjnmjopi5h2" path="res://prefabs/play_zone.tscn" id="17_mxxy2"]
[sub_resource type="Curve" id="Curve_o5byr"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
@ -27,7 +28,7 @@ light_mode = 2
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m680d"]
shader = ExtResource("5_64d71")
[sub_resource type="ViewportTexture" id="ViewportTexture_pym12"]
[sub_resource type="ViewportTexture" id="ViewportTexture_q4yg2"]
viewport_path = NodePath("FlashlightViewport")
[sub_resource type="CircleShape2D" id="CircleShape2D_prnh4"]
@ -54,8 +55,10 @@ light_mode = 2
[node name="Root" type="Node2D"]
y_sort_enabled = true
[node name="GameManager" type="Node" parent="."]
[node name="GameManager" type="Node" parent="." node_paths=PackedStringArray("FirstZone", "Player")]
script = ExtResource("1_ij566")
FirstZone = NodePath("../TestPlayZone")
Player = NodePath("../Player")
[node name="Sounds" type="Node" parent="."]
@ -123,7 +126,7 @@ CameraBounds = Vector2(30, 20)
[node name="PointLight2D" type="PointLight2D" parent="PlayerCamera" node_paths=PackedStringArray("LightViewport")]
blend_mode = 2
range_item_cull_mask = 2
texture = SubResource("ViewportTexture_pym12")
texture = SubResource("ViewportTexture_q4yg2")
script = ExtResource("6_slohe")
LightViewport = NodePath("../../FlashlightViewport")
@ -222,4 +225,19 @@ position = Vector2(-120, 42)
[node name="Wretched2" parent="." instance=ExtResource("16_ejflu")]
position = Vector2(-139, -39)
[node name="TestPlayZone" parent="." node_paths=PackedStringArray("TopLeftCorner", "BottomRightCorner", "PlayerSpawnPoint") instance=ExtResource("17_mxxy2")]
position = Vector2(79, 99)
TopLeftCorner = NodePath("TopLeft")
BottomRightCorner = NodePath("BottomRight")
PlayerSpawnPoint = NodePath("SpawnPoint")
[node name="TopLeft" type="Node2D" parent="TestPlayZone"]
[node name="BottomRight" type="Node2D" parent="TestPlayZone"]
position = Vector2(97, 67)
[node name="SpawnPoint" type="Node2D" parent="TestPlayZone"]
position = Vector2(56, 34)
[connection signal="timeout" from="CanvasLayer/DeathScreen/Timer" to="CanvasLayer/DeathScreen" method="Timeout"]
[connection signal="ZoneEntered" from="TestPlayZone" to="GameManager" method="SetCurrentZone"]

View file

@ -13,6 +13,45 @@
[ext_resource type="Shader" path="res://shaders/dithering.gdshader" id="11_qi6kn"]
[ext_resource type="Shader" path="res://shaders/light_shader.gdshader" id="12_64ts1"]
[sub_resource type="Animation" id="Animation_i3sd6"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewport/CG:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(0, 0, 0, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MenuBackground/CloudsLayer/CloudsGround:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 57)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MenuBackground/CloudsLayer/CloudsUpper:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_6kcty"]
resource_name = "intro_animation"
length = 2.0
@ -69,45 +108,6 @@ tracks/2/keys = {
"values": [Vector2(0, -100), Vector2(0, 0)]
}
[sub_resource type="Animation" id="Animation_i3sd6"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewport/CG:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(0, 0, 0, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MenuBackground/CloudsLayer/CloudsGround:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 57)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MenuBackground/CloudsLayer/CloudsUpper:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_mjata"]
_data = {
"RESET": SubResource("Animation_i3sd6"),

View file

@ -3,36 +3,61 @@ using Godot;
public partial class GameManager : Node
{
public struct GameInfo
{
public ulong GameStart = 0;
public ulong GameEnd = 0;
public int Attempts = 0;
public Node2D Checkpoint;
public GameInfo(Node2D checkpoint)
{
Checkpoint = checkpoint;
}
}
public static bool IsPlaying = true;
public ulong GameStart = 0;
public ulong GameEnd = 0;
public int Attempts = 0;
public Node2D Checkpoint = null;
[Export] public PlayZone FirstZone;
[Export] public Player Player;
[Signal]
public delegate void GameOverEventHandler();
private static GameInfo _gameInfo;
public override void _Ready()
{
if (!IsPlaying)
{
IsPlaying = true;
_gameInfo = new GameInfo(FirstZone.PlayerSpawnPoint);
}
StartGame();
}
public void StartGame() => GameStart = Time.GetTicksMsec();
public void StartGame()
{
_gameInfo.GameStart = Time.GetTicksMsec();
Player.Position = _gameInfo.Checkpoint.GlobalPosition;
}
public void EndGame()
{
GameEnd = Time.GetTicksMsec();
_gameInfo.GameEnd = Time.GetTicksMsec();
EmitSignal(SignalName.GameOver);
}
public string GetFormattedTimeElapsed() => TimeSpan.FromMilliseconds(GameEnd - GameStart).ToString(@"hh\:mm\:ss.fff");
public string GetFormattedTimeElapsed() =>
TimeSpan.FromMilliseconds(_gameInfo.GameEnd - _gameInfo.GameStart).ToString(@"hh\:mm\:ss.fff");
public void OnPlayerDied() => Attempts++;
public void OnPlayerDied() => _gameInfo.Attempts++;
public void SetCurrentZone(PlayZone zone)
{
GD.Print($"New zone {zone}");
_gameInfo.Checkpoint = zone.PlayerSpawnPoint;
}
}

View file

@ -1,16 +1,48 @@
using Godot;
using System;
public partial class PlayZone : Node2D
{
[Export] public Node2D TopLeftCorner;
[Export] public Node2D BottomRightCorner;
[Export] public Node2D PlayerSpawnPoint;
[Signal]
public delegate void ZoneEnteredEventHandler(PlayZone sender);
[Signal]
public delegate void ZoneLeftEventHandler(PlayZone sender);
public Rect2I Bounds = new Rect2I(0, 0, 0, 0);
private Area2D _area2D;
private CollisionShape2D _collisionShape2D;
public override void _Ready()
{
_area2D = (Area2D)FindChild("Area2D");
_collisionShape2D = (CollisionShape2D)FindChild("CollisionShape2D");
var size = BottomRightCorner.Position - TopLeftCorner.Position;
Bounds = new Rect2I((int)TopLeftCorner.Position.X, (int)TopLeftCorner.Position.Y, (int)size.X, (int)size.Y);
var middle = (BottomRightCorner.Position + TopLeftCorner.Position) / 2;
_area2D.Position = middle;
_collisionShape2D.Shape = new RectangleShape2D { Size = size };
}
private void BodyEntered(Node2D body)
{
if (body is not Player player)
return;
EmitSignal(SignalName.ZoneEntered, this);
}
private void BodyExited(Node2D body)
{
if (body is not Player player)
return;
EmitSignal(SignalName.ZoneLeft, this);
}
}