From 23b0112b45e9587d6dc08c594894b280b0806e82 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Mon, 6 Jul 2020 21:58:42 +0200 Subject: [PATCH] Add computers and sprinting --- Actors/Objects/Computer/Computer.gd | 45 ++++++++++++ Actors/Objects/Computer/Computer.tscn | 65 ++++++++++++++++++ Actors/Objects/Door/Door.tscn | 14 ++-- Actors/Player/Player.gd | 63 ++++++++++++++++- Graphics/tgstation/computer-screens.png | Bin 0 -> 6150 bytes .../tgstation/computer-screens.png.import | 34 +++++++++ Graphics/tgstation/computer.png | Bin 0 -> 1104 bytes Graphics/tgstation/computer.png.import | 34 +++++++++ Scenes/Maps/odyssey.tscn | 41 +++++++---- Scenes/Rendering/Occluder.gd | 14 +++- Scenes/Test.tscn | 3 +- project.godot | 26 +++++-- 12 files changed, 310 insertions(+), 29 deletions(-) create mode 100644 Actors/Objects/Computer/Computer.gd create mode 100644 Actors/Objects/Computer/Computer.tscn create mode 100644 Graphics/tgstation/computer-screens.png create mode 100644 Graphics/tgstation/computer-screens.png.import create mode 100644 Graphics/tgstation/computer.png create mode 100644 Graphics/tgstation/computer.png.import diff --git a/Actors/Objects/Computer/Computer.gd b/Actors/Objects/Computer/Computer.gd new file mode 100644 index 0000000..852996f --- /dev/null +++ b/Actors/Objects/Computer/Computer.gd @@ -0,0 +1,45 @@ +tool + +extends StaticBody2D + +enum Direction { LEFT, RIGHT, UP, DOWN } +enum ComputerType { ShipCommand, Comms, Medical, Research, ShipEngine, Atmos } + +export(Direction) var direction = Direction.DOWN setget set_direction +export(ComputerType) var computer_type = ComputerType.ShipCommand setget set_type + +var screen_region_offset = Vector2.ZERO + +func set_type(val): + computer_type = val + match computer_type: + ComputerType.ShipCommand: + screen_region_offset = Vector2(0, 0) + ComputerType.Comms: + screen_region_offset = Vector2(0, 32) + ComputerType.Medical: + screen_region_offset = Vector2(0, 64) + ComputerType.Research: + screen_region_offset = Vector2(128, 0) + ComputerType.ShipEngine: + screen_region_offset = Vector2(128, 224) + ComputerType.Atmos: + screen_region_offset = Vector2(0, 256) + # Refresh sprite + set_direction(direction) + +func set_direction(dir): + direction = dir + match direction: + Direction.DOWN: + $computer.region_rect.position = Vector2(0, 0) + $computer/screen.region_rect.position = screen_region_offset + Vector2(0, 0) + Direction.UP: + $computer.region_rect.position = Vector2(0, 32) + $computer/screen.region_rect.position = screen_region_offset + Vector2(32, 0) + Direction.LEFT: + $computer.region_rect.position = Vector2(32, 32) + $computer/screen.region_rect.position = screen_region_offset + Vector2(96, 0) + Direction.RIGHT: + $computer.region_rect.position = Vector2(32, 0) + $computer/screen.region_rect.position = screen_region_offset + Vector2(64, 0) diff --git a/Actors/Objects/Computer/Computer.tscn b/Actors/Objects/Computer/Computer.tscn new file mode 100644 index 0000000..6e97c87 --- /dev/null +++ b/Actors/Objects/Computer/Computer.tscn @@ -0,0 +1,65 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://Graphics/tgstation/computer-screens.png" type="Texture" id=1] +[ext_resource path="res://Graphics/tgstation/computer.png" type="Texture" id=2] +[ext_resource path="res://Actors/Objects/Computer/Computer.gd" type="Script" id=3] + +[sub_resource type="RectangleShape2D" id=1] +extents = Vector2( 16, 16 ) + +[sub_resource type="Animation" id=2] +resource_name = "off" +tracks/0/type = "value" +tracks/0/path = NodePath("computer/screen:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 0, 0, 0, 1 ) ] +} + +[sub_resource type="Animation" id=3] +resource_name = "on" +length = 5.5 +loop = true +step = 0.0 +tracks/0/type = "value" +tracks/0/path = NodePath("computer/screen:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.63955, 0.93955, 2.44742, 2.74742, 4.94041, 4.98068, 5.01527, 5.0544, 5.08947 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 1 ), Color( 0.682353, 0.682353, 0.682353, 1 ), Color( 1, 1, 1, 1 ), Color( 0.682353, 0.682353, 0.682353, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 0.584314, 0.584314, 0.584314, 1 ), Color( 1, 1, 1, 1 ), Color( 0.584314, 0.584314, 0.584314, 1 ), Color( 1, 1, 1, 1 ) ] +} + +[node name="Computer" type="StaticBody2D"] +script = ExtResource( 3 ) + +[node name="computer" type="Sprite" parent="."] +texture = ExtResource( 2 ) +centered = false +region_enabled = true +region_rect = Rect2( 0, 0, 32, 32 ) + +[node name="screen" type="Sprite" parent="computer"] +texture = ExtResource( 1 ) +centered = false +region_enabled = true +region_rect = Rect2( 0, 0, 32, 32 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( 16, 16 ) +shape = SubResource( 1 ) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +autoplay = "on" +anims/off = SubResource( 2 ) +anims/on = SubResource( 3 ) diff --git a/Actors/Objects/Door/Door.tscn b/Actors/Objects/Door/Door.tscn index e0fbb5b..f3aa2d3 100644 --- a/Actors/Objects/Door/Door.tscn +++ b/Actors/Objects/Door/Door.tscn @@ -3,11 +3,11 @@ [ext_resource path="res://Actors/Objects/Door/Door.gd" type="Script" id=1] [ext_resource path="res://Graphics/tgstation/opening-sheet.png" type="Texture" id=2] -[sub_resource type="AtlasTexture" id=5] +[sub_resource type="AtlasTexture" id=1] atlas = ExtResource( 2 ) region = Rect2( 0, 64, 32, 32 ) -[sub_resource type="AtlasTexture" id=4] +[sub_resource type="AtlasTexture" id=2] atlas = ExtResource( 2 ) region = Rect2( 32, 32, 32, 32 ) @@ -15,22 +15,22 @@ region = Rect2( 32, 32, 32, 32 ) atlas = ExtResource( 2 ) region = Rect2( 0, 32, 32, 32 ) -[sub_resource type="AtlasTexture" id=2] +[sub_resource type="AtlasTexture" id=4] atlas = ExtResource( 2 ) region = Rect2( 32, 0, 32, 32 ) -[sub_resource type="AtlasTexture" id=1] +[sub_resource type="AtlasTexture" id=5] atlas = ExtResource( 2 ) region = Rect2( 0, 0, 32, 32 ) [sub_resource type="SpriteFrames" id=6] animations = [ { -"frames": [ SubResource( 5 ), SubResource( 4 ), SubResource( 3 ), SubResource( 2 ), SubResource( 1 ) ], +"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ) ], "loop": false, "name": "close", "speed": 20.0 }, { -"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ) ], +"frames": [ SubResource( 5 ), SubResource( 4 ), SubResource( 3 ), SubResource( 2 ), SubResource( 1 ) ], "loop": false, "name": "open", "speed": 20.0 @@ -39,7 +39,7 @@ animations = [ { [sub_resource type="RectangleShape2D" id=7] extents = Vector2( 16, 16 ) -[node name="Node2D" type="StaticBody2D"] +[node name="Door" type="StaticBody2D"] input_pickable = true script = ExtResource( 1 ) diff --git a/Actors/Player/Player.gd b/Actors/Player/Player.gd index d20db1f..7e54b50 100755 --- a/Actors/Player/Player.gd +++ b/Actors/Player/Player.gd @@ -1,21 +1,78 @@ extends KinematicBody2D -const SPEED = 320.0 +const BASE_SPEED = 300.0 const EPSILON = 0.1 +const MAX_STAMINA = 3.0 +const BOOST_COEFF = 50.0 +const STAMINA_RECOVER_RATE = 0.3 + +var velocity = Vector2.ZERO +var grip = 1.0 +var stamina = MAX_STAMINA +var speed_boost = 0 + +export(NodePath) var mapNode +onready var map = get_node(mapNode) as Map export var is_controlled = false setget set_is_controlled func _ready(): $Camera.current = is_controlled -func _physics_process(_delta): +func _physics_process(delta): var motion = Vector2( Input.get_action_strength("ui_right")-Input.get_action_strength("ui_left"), Input.get_action_strength("ui_down")-Input.get_action_strength("ui_up")) if motion.length() > EPSILON: $Sprite/AnimationTree.set("parameters/direction/blend_position", motion) - move_and_slide(motion.clamped(1.0) * SPEED) + + # Check sprinting + var speed = BASE_SPEED + if Input.is_action_pressed("sprint"): + if motion.length() > EPSILON and stamina > 0: + speed_boost += BOOST_COEFF * delta * ease(stamina/MAX_STAMINA, 1.1) + stamina -= delta + update() + else: + if stamina < MAX_STAMINA: + stamina += delta * STAMINA_RECOVER_RATE + update() + + # Apply friction to speed boost and the boost itself, if any + if speed_boost > 0: + speed_boost /= 2 + speed *= 1.0 + speed_boost + if speed_boost < EPSILON: + speed_boost = 0 + + # Set velocity + velocity = velocity * (1.0-grip) + motion.clamped(1.0) * speed * grip + velocity = move_and_slide(velocity) + + # Check what tile I'm on + var tilemap = map.tilemap as TileMap + var cell = tilemap.get_cellv(tilemap.world_to_map(transform.origin)) + match cell: + -1: # I'm in outer space! + grip = 0 + _: + grip = 1 func set_is_controlled(val): is_controlled = val $Camera.current = val + +func _draw(): + if stamina+EPSILON < MAX_STAMINA: + draw_circle_arc_poly(Vector2(-10, -30), 6, 0, stamina/MAX_STAMINA * 360, Color.orange) + +func draw_circle_arc_poly(center, radius, angle_from, angle_to, color): + var nb_points = 32 + var points_arc = PoolVector2Array() + points_arc.push_back(center) + var colors = PoolColorArray([color]) + + for i in range(nb_points + 1): + var angle_point = deg2rad(angle_from + i * (angle_to - angle_from) / nb_points - 90) + points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius) + draw_polygon(points_arc, colors) diff --git a/Graphics/tgstation/computer-screens.png b/Graphics/tgstation/computer-screens.png new file mode 100644 index 0000000000000000000000000000000000000000..46c68ab8db6a950bf3fe0b4f009a89cd5e1b3d4e GIT binary patch literal 6150 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 literal 0 HcmV?d00001 diff --git a/Graphics/tgstation/computer-screens.png.import b/Graphics/tgstation/computer-screens.png.import new file mode 100644 index 0000000..4833523 --- /dev/null +++ b/Graphics/tgstation/computer-screens.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/computer-screens.png-7928a3d734fcaf9eb632492d13eb7e21.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Graphics/tgstation/computer-screens.png" +dest_files=[ "res://.import/computer-screens.png-7928a3d734fcaf9eb632492d13eb7e21.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Graphics/tgstation/computer.png b/Graphics/tgstation/computer.png new file mode 100644 index 0000000000000000000000000000000000000000..5eb6a8b854174bebce984cea9f20cf000c527f03 GIT binary patch literal 1104 zcmV-W1h4yvP)l&)N+4C#^(T(~wSMGCihJH`K@G2_YJ z?Z2m)yFGmHBiWXAZ@!zI+nX7moJ`<&b#}J58f>Bnm7deD>)(wozkF|m_wEodpbUQd z=WmF_h?0}XXZ3gS{{4rKja(sU0Fm+n@cR7R7lHs7Lb;Q+OGX30D-55_X1)+oOCYrz zx|T@p^Na`R3n9j(JOBXZ^SK`c2{y96qLd3@Ht2N$ST2|ULFgTP@c~&|k;+{yYj6(0 zYPEWR(6;2L*rNep@CZc!*lxG`&1Td5jNd;yJxwZm>$Cts)l)+Pc>dz${>|HW&AfOI z;d?XyIcZGbAsKHd02Y2P0E@+9zh19hgt3MM;Nk&O2H@fWh^`piLpoAV#sg{vpm&1d zF#rR5XfiPX6GYzznXRw|pm&C0F<^BctOP>THdqY8TqOYP&JKUqOV!l_+ICW2Vm!b; z3#4Fv`+55S!7T;|0Qr*lD+|Cr4W{<@pFUqcg5c@__@WHp`N{&Y!gs#@xOpTC!QBHQ zRO$gb23Pq;pPU?6n@$N|)l5cotE)WK+K-kJ^u-cH9Ay+lg9ZR!V%yD$b{O!10) zdd$;32J0cH)p*-K(5r`_#s&%IoF(#O+p7z_MRV2KAHdc#T>!|_V5Gd-TWl#$HboXd zQFU1I0TGYFY(AjWc%2POc|c-!Sa(8%iACCYWQMx{&_PiHh)9Q(W`uN9x6&D57C=!- zY|JH)i$zisKqeS9fe-*=r^RuylFJhhl9XB)fZ7TpV!VwZ;T}*+X>4#0sI53UiU-ux zAThcJjNK#D#{*J3!CnAr=n@;%18V3KJT?Z%&aW6iWVa~O=3e3fy7fkkPt_G^0JZcA zvmPME+l;UVUHmLiL$^5N0or)f1>4&4i=PI^{(k}11FZ3>GFeeJs;262&I5AB+tPZG z2aNqcLlTR+JRoO$s<&WrWm7@JMb=AJ5Z#!K1EdISx?b18`H zvjB1zp^x!2fXKT6n+#2Li7`C^+W6iL5^ar%9y*)=Q^V6W{X5$`nCc18y#rmn1r&hb z0LTE)104;PySaefwW^{L9a%BKwc`jmXZ*OE|c`jped2n=ZE@^FHXJsx>PDe5{MQ&qn WWMy)w27m4V0000