commit c42dfb23bb429ee580d18cefb2f5ebe6f4028728 Author: Dane Johnson Date: Sun Mar 29 18:43:16 2026 -0500 Ganglock diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/bullet.tscn b/bullet.tscn new file mode 100644 index 0000000..35c542c --- /dev/null +++ b/bullet.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=3 uid="uid://bqkvnody78mr"] + +[ext_resource type="Texture2D" uid="uid://c5dp757bqjhel" path="res://icon.svg" id="1_de7lu"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_4cg8h"] +radius = 5.0 + +[node name="Bullet" type="RigidBody2D"] +collision_layer = 0 +collision_mask = 0 + +[node name="Sprite2D" type="Sprite2D" parent="."] +rotation = 1.5708 +scale = Vector2(0.0295564, 0.0721942) +texture = ExtResource("1_de7lu") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +rotation = 1.5708 +shape = SubResource("CircleShape2D_4cg8h") + +[node name="TTL" type="Timer" parent="."] +one_shot = true +autostart = true + +[connection signal="timeout" from="TTL" to="." method="queue_free"] diff --git a/character_body.gd b/character_body.gd new file mode 100644 index 0000000..f0d7d04 --- /dev/null +++ b/character_body.gd @@ -0,0 +1,66 @@ +extends CharacterBody2D + +@export var move_speed: float +@export var max_jumps: int = 2 +@export var bullet_velocity: float + +var bullet_scene = preload('res://bullet.tscn') + +var jumps_left = 0 +var tgt_position + +func _ready() -> void: + Input.mouse_mode = Input.MOUSE_MODE_CONFINED + +func _input(event: InputEvent) -> void: + if event is InputEventKey: + if event.keycode == KEY_ALT: + if event.pressed: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + else: + Input.mouse_mode = Input.MOUSE_MODE_CONFINED + +func _physics_process(delta: float) -> void: + if not is_multiplayer_authority(): + if tgt_position: + position = lerp(position, tgt_position, delta * 20) + return + + velocity += Vector2.DOWN * ProjectSettings['physics/2d/default_gravity'] * delta + + var movement = Vector2.ZERO + var x_move = Input.get_action_strength('right') - Input.get_action_strength('left') + movement.x = x_move + velocity += movement * delta * move_speed + + if is_on_floor(): + jumps_left = max_jumps + + if (abs(x_move) < 0.01 and is_on_floor()) or sign(x_move) != sign(velocity.x): + velocity -= Vector2.RIGHT * velocity * delta * 5.0 + + if abs(velocity.x) < 0.01: + velocity.x = 0 + + if Input.is_action_just_pressed('jump') and jumps_left > 0: + velocity.y = -500 + jumps_left -= 1 + + move_and_slide() + rpc("update_loc", position) + + if Input.is_action_just_pressed("fire"): + var pos = get_viewport().get_camera_2d().get_global_mouse_position() + rpc("fire", pos) + +@rpc("call_remote") +func update_loc(pos: Vector2): + tgt_position = pos + +@rpc("call_local") +func fire(pos: Vector2): + var bullet: RigidBody2D = bullet_scene.instantiate() + get_parent().add_child(bullet) + bullet.position = position + bullet.look_at(pos) + bullet.apply_central_impulse(bullet.transform.basis_xform(Vector2.RIGHT) * bullet_velocity) diff --git a/demo_level.tscn b/demo_level.tscn new file mode 100644 index 0000000..d75ac8c --- /dev/null +++ b/demo_level.tscn @@ -0,0 +1,45 @@ +[gd_scene load_steps=5 format=3 uid="uid://bio5pq0w6ttfw"] + +[ext_resource type="Texture2D" uid="uid://c5dp757bqjhel" path="res://icon.svg" id="1_2gqtv"] +[ext_resource type="Script" path="res://character_body.gd" id="2_kbwnv"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_6vcao"] +size = Vector2(1153, 74) + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_86nkv"] + +[node name="DemoLevel" type="Node2D"] + +[node name="StaticBody2D" type="StaticBody2D" parent="."] +position = Vector2(574, 612) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"] +shape = SubResource("RectangleShape2D_6vcao") + +[node name="Sprite2D" type="Sprite2D" parent="StaticBody2D"] +position = Vector2(1.50002, -0.499984) +scale = Vector2(8.99219, 0.570313) +texture = ExtResource("1_2gqtv") + +[node name="Body" type="CharacterBody2D" parent="."] +position = Vector2(540, 88) +script = ExtResource("2_kbwnv") +move_speed = 100.0 +bullet_velocity = 5000.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Body"] +shape = SubResource("CapsuleShape2D_86nkv") + +[node name="Sprite2D" type="Sprite2D" parent="Body"] +position = Vector2(-4.17233e-07, 1.19209e-07) +scale = Vector2(0.15625, 0.234375) +texture = ExtResource("1_2gqtv") + +[node name="Camera2D" type="Camera2D" parent="Body"] +rotation = 0.00909587 +limit_bottom = 650 +drag_horizontal_enabled = true +drag_left_margin = 0.1 +drag_right_margin = 0.1 +editor_draw_limits = true +editor_draw_drag_margin = true diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..9d8b7fa --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..1b83c20 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c5dp757bqjhel" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/network_controller.gd b/network_controller.gd new file mode 100644 index 0000000..e72c631 --- /dev/null +++ b/network_controller.gd @@ -0,0 +1,20 @@ +extends Node + +func _ready() -> void: + var host = OS.get_cmdline_args().has('host') + if host: + create_server() + else: + create_client() + +func create_server(): + var peer = ENetMultiplayerPeer.new() + peer.create_server(8008) + multiplayer.multiplayer_peer = peer + print("server connected") + +func create_client(): + var peer = ENetMultiplayerPeer.new() + peer.create_client('localhost', 8008) + multiplayer.multiplayer_peer = peer + print("client connected") diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..5b452ef --- /dev/null +++ b/project.godot @@ -0,0 +1,48 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Ganglock" +run/main_scene="res://demo_level.tscn" +config/features=PackedStringArray("4.3", "GL Compatibility") +config/icon="res://icon.svg" + +[autoload] + +NetworkController="*res://network_controller.gd" + +[input] + +right={ +"deadzone": 0.5, +"events": [null, 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,"location":0,"echo":false,"script":null) +] +} +left={ +"deadzone": 0.5, +"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":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.5, +"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":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +] +} +fire={ +"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":1,"position":Vector2(281, 20),"global_position":Vector2(295, 90),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility"