diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/overview/networking_implementation_plan.md b/overview/networking_implementation_plan.md new file mode 100644 index 0000000..b4fed6b --- /dev/null +++ b/overview/networking_implementation_plan.md @@ -0,0 +1,264 @@ +# Networking Implementation Plan + +Step-by-step breakdown for taking Spacewar from single-player-only to working +multiplayer. `tech.md` describes the target architecture; this doc is the +ordered checklist for getting there from the current codebase. + +**Current state (as of this doc):** zero networking code exists anywhere in +the project. The server browser's JOIN button and the main menu's CASUAL +button just set local `GameConfig` fields and load `world.tscn` — no +connection is ever made. Everything downstream assumes exactly one player. + +**Guiding principle:** get two peers moving/shooting/dying correctly over +ENet *first*, with ugly/no prediction. Polish feel (prediction, +reconciliation, lag comp) only after the authoritative loop is proven +correct. Don't build matchmaking/Steam/galaxy-war until basic peer-to-peer +combat works. + +--- + +## Phase 0 — Decisions to make before writing code + +- [ ] Pick topology for early dev: dedicated headless server instance vs. + one client acting as host. (Recommend: always run a dedicated server, + even locally — avoids a host-migration refactor later, and matches + the authoritative-server model in `tech.md`.) +- [ ] Decide the connection target for now: hardcoded `127.0.0.1` / LAN IP + is fine until Phase 8. Don't build matchmaking yet. +- [ ] Confirm max casual match size (25v25 per `overview.md`) — this affects + how much you can get away with naive replication before needing + interest management / area-of-interest culling. + +--- + +## Phase 1 — ENet bootstrap & connect flow + +**Goal:** two Godot instances can connect over ENet and see each other join/leave. + +- [ ] Add a `NetworkManager` autoload (new, alongside `GameConfig` in + `autoload/`) that owns the `ENetMultiplayerPeer`, exposes + `host_server(port)` / `join_server(ip, port)`, and connects to + `multiplayer.peer_connected` / `peer_disconnected` / `connected_to_server` + / `connection_failed`. +- [ ] Wire `menu/server_browser.gd`'s `_on_join_pressed` (currently just sets + `GameConfig` fields and changes scene) to actually call + `NetworkManager.join_server(...)` and only transition to `world.tscn` + on `connected_to_server`. +- [ ] Add a minimal headless server launch path (`--server` CLI flag or a + separate export target) that calls `host_server()` and loads + `world.tscn` without a local player. +- [ ] Smoke test: launch one headless server + two client instances, confirm + `peer_connected` fires on the server for both and each client sees the + other's peer_id. + +--- + +## Phase 2 — Per-peer player state + +**Goal:** replace the single-player assumption in `GameConfig` with a real +per-peer registry. + +- [ ] Split `autoload/game_config.gd`: keep shared/match-wide constants + (thrust, speed, fire rate, `world_bounds`, etc.) as-is, but move the + per-player fields (`player_name`, `player_race`, `player_ship_path`, + `player_ship_scale`, `player_ship_speed_factor`) out of flat globals + into a `Dictionary[int, PlayerInfo]` keyed by `peer_id`, on + `NetworkManager` or a new `PlayerRegistry` autoload. +- [ ] On connect, client sends its chosen name/race/ship to the server via + RPC (`@rpc("any_peer", "call_local", "reliable") submit_loadout(...)`); + server stores it in the registry and relays to all peers so everyone + knows everyone's loadout. +- [ ] Update `menu/team_select.gd` (currently sets `GameConfig` fields + directly and emits local `team_selected`) to submit the choice via + this RPC path instead. +- [ ] Update anywhere still reading `GameConfig.player_name` / + `player_race` / `player_ship_path` directly to read from the local + peer's entry in the registry instead. + +--- + +## Phase 3 — Spawning multiple ships + +**Goal:** N ships exist in `world.tscn`, one per connected peer, each owned +by the right client. + +- [ ] `world.tscn` currently has a single hardcoded ship node named "Player" + as a direct child. Remove it; replace with an empty `Node2D` + container (e.g. `Ships`) that ships get added to at runtime. +- [ ] Add a `MultiplayerSpawner` in `world.tscn` pointed at the `Ships` + container, with `ship.tscn` in its spawnable scene list. +- [ ] Server-side: on `peer_connected` (or once loadout is submitted), + instantiate `ship.tscn` for that peer under `Ships`, set + `set_multiplayer_authority(peer_id)` on the ship root, name the node + by peer_id (e.g. `str(peer_id)`) so it replicates deterministically. +- [ ] On `peer_disconnected`, despawn that peer's ship and remove it from + the registry. +- [ ] **Camera2D fix:** `ship.tscn` currently bakes a `Camera2D` into the + scene itself, which breaks with multiple instances. Move the camera + out of `ship.tscn`; in `ship_movement.gd`'s `_ready()`, only create/ + activate a `Camera2D` if `is_multiplayer_authority()` is true (i.e. + this is the local player's own ship). +- [ ] **HUD fix:** `ship_movement.gd` currently pushes health to + `/root/World/HUD/HealthLabel` via a hardcoded absolute path. Gate this + the same way — only the locally-authoritative ship should update the + local HUD. + +--- + +## Phase 4 — Split input from simulation + +**Goal:** stop reading `Input.is_action_pressed()` inside the shared +simulation code; every ship's movement should be driven by whoever is +authoritative for it (server), fed by input coming from the owning client. + +- [ ] In `ship_movement.gd`, extract the current `_physics_process` block + (lines ~45–66, direct `Input.is_action_pressed` calls) into a small + input struct/dictionary (`{thrust: bool, rotate: float, firing: bool}`) + gathered only when `is_multiplayer_authority()` on the *client* side. +- [ ] Add `@rpc("any_peer", "call_remote", "unreliable") send_input(input)` + on the ship: client calls it every physics tick with its local input; + server receives it, validates the sender is this ship's owning peer, + and stores it as "current input" for that ship. +- [ ] Server's `_physics_process` runs the actual movement/`move_and_slide` + simulation using the last-received input for every ship it owns + authority over (the server owns authority over all ships in the + dedicated-server model). +- [ ] Add a `MultiplayerSynchronizer` per ship replicating `position`, + `rotation`, `velocity` from server → clients. +- [ ] Get this working *without* prediction first: local ship will feel + laggy (input → server → back). That's expected at this stage — fixed + in Phase 7. + +--- + +## Phase 5 — Shooting / bullets over the network + +**Goal:** bullets are server-simulated and replicated, not spawned locally +by each client. + +- [ ] `ship_movement.gd`'s fire logic (~line 72) currently does + `get_parent().add_child(bullet)` directly on whichever peer runs it. + Change so firing is just another bit in the input struct from Phase 4; + server decides when a shot is actually fired (respecting fire-rate + cooldown server-side, not trusting client timing). +- [ ] Server instantiates `bullet.tscn` via a `MultiplayerSpawner` (or + manual spawn + RPC) under a shared `Bullets` container in + `world.tscn`. +- [ ] `bullet.gd` currently self-simulates movement in `_process` and + resolves damage locally via `body_entered`. Keep bullet *movement* + client-side-predicted for visual smoothness if desired, but damage + resolution (`take_damage()` call, ~lines 15–20) must only happen on + the server's copy of the bullet. +- [ ] Despawn bullets server-side when out of `world_bounds`; replicate + despawn to clients. + +--- + +## Phase 6 — Server-authoritative health / death / respawn + +**Goal:** no client can kill, heal, or respawn anything except by asking the +server. + +- [ ] Move `take_damage` / `_die` / `_respawn` (`ship_movement.gd` lines + ~104–135) so the actual state mutation only runs where + `multiplayer.is_server()` is true. Clients only ever display the + replicated result. +- [ ] Add an authority check at the top of `take_damage`: reject calls that + didn't originate from the server (bullets are already server-spawned + after Phase 5, so this mostly falls out naturally — but double check + nothing client-side can still call it directly). +- [ ] Replicate `health`, `is_dead` (or similar) via the ship's + `MultiplayerSynchronizer` from Phase 4 so HUD and visuals update on + all clients. +- [ ] Respawn: server decides timing/position and re-broadcasts spawn + state; don't let respawn timers run independently on each client. + +--- + +## Phase 7 — Client-side prediction & reconciliation + +**Goal:** local ship feels responsive despite server round-trip; remote +ships move smoothly despite update-rate gaps. + +- [ ] Local client: predict own ship's movement immediately on input + (re-run the same movement function locally that the server runs), + rather than waiting for the server echo. +- [ ] Server periodically sends authoritative position/velocity/tick back to + the owning client; client reconciles by snapping/blending toward it + if prediction drifted (basic version: hard snap if error exceeds a + threshold; polish later with smoothing). +- [ ] Remote ships (not locally owned): interpolate between the last two + received network states instead of snapping on every update. +- [ ] This is the highest-skill, most iterative phase — budget real time for + tuning "feel," not just correctness. + +--- + +## Phase 8 — Real server browser / connect flow + +**Goal:** menus do what they currently only pretend to do. + +- [ ] `menu/server_browser.gd`'s server list is a single hardcoded + "Trench Wars 0/32" entry. Replace with either: (a) a small manual + "enter IP" field for direct-connect testing, or (b) if a lightweight + server-list service exists by this point, query it. +- [ ] `menu/main_menu.gd`'s CASUAL/RANKED buttons currently skip networking + entirely and load `world.tscn` locally. Route CASUAL through the same + `NetworkManager.join_server` path once a target server is chosen. +- [ ] Handle connection failure / timeout UI (currently nothing exists for + this — `connection_failed` signal has no handler anywhere). + +--- + +## Phase 9 — Testing & hardening + +- [ ] Test with 2 clients, then push toward the real casual target (25v25) + to find where naive full-replication breaks down (bandwidth, spawn + storms). Consider interest management / relevance culling only if + needed at that scale — don't build it preemptively. +- [ ] Artificially add latency/packet loss locally (Godot has debug tools + for this, or use `tc`/`netem` on Linux) and verify prediction/ + reconciliation still feels acceptable. +- [ ] Verify a client can't cheat: send garbage/rapid-fire input via a + modified client and confirm the server-side rate limits / bounds + checks (added in Phases 4–6) actually hold. + +--- + +## Phase 10 — Deferred / parallelizable (not blocking core multiplayer) + +These don't block getting ship-vs-ship combat working over the network and +can happen in parallel or after Phases 1–9: + +- [ ] Matchmaking backend (queue, MMR, lobby assignment) — see `tech.md`'s + Go/Node + Redis + Postgres sketch. +- [ ] GodotSteam integration (auth, VAC, lobbies). +- [ ] Lag compensation (server-side rewind for hit validation) — only + matters once hit-detection precision is actually being contested; + skip until basic damage registration is proven reliable. +- [ ] Bot fill for casual matches (`bots.md`) — depends on Phases 3–6 being + done, since bots need to be simulate-able the same way real players' + ships are. +- [ ] Galaxy war meta / sector control — orthogonal system, layer on top + once match-level multiplayer is solid. + +--- + +## Effort summary + +| Phase | Relative effort | Notes | +|---|---|---| +| 1. ENet bootstrap | Small | 1–2 days | +| 2. Per-peer state | Small–Medium | Mechanical, touches every menu script | +| 3. Spawning | Medium | Camera/HUD ownership bugs are the sharp edges | +| 4. Input/sim split | Medium | The core refactor of `ship_movement.gd` | +| 5. Bullets | Small–Medium | Mostly follows the pattern from Phase 4 | +| 6. Authoritative health | Medium | Mostly enforcement of what Phase 4/5 set up | +| 7. Prediction/reconciliation | Medium–Large | Iterative feel-tuning, not just correctness | +| 8. Real menus | Small | UI wiring once NetworkManager exists | +| 9. Testing/hardening | Medium | Scales with target match size (25v25) | +| 10. Deferred systems | Large, but parallelizable | Doesn't block core multiplayer | + +**Bare working version (Phases 1–6, no prediction polish):** roughly 1–2 +weeks of focused work. **Feeling good at 25v25 (through Phase 9):** the long +pole — budget significantly more for iteration on Phase 7 in particular. diff --git a/overview/structure.md b/overview/structure.md index ce5cc57..ff957dd 100644 --- a/overview/structure.md +++ b/overview/structure.md @@ -18,15 +18,18 @@ spacewar/ ← repo root │ ├── ship_movement.gd ← player ship logic │ └── bullet.tscn/gd ← projectile ├── world/ - │ ├── world.tscn ← game world - │ └── tile_map.tscn ← unused prototype tilemap + │ ├── world.tscn ← game world; world.gd loads the active map into MapContainer + │ ├── world.gd ← picks/instances a map scene from world/maps/ + │ ├── world_tileset.tres ← shared TileSet resource (walls.png + asteroids.png atlas sources) + │ └── maps/ + │ └── map_01.tscn ← hand-painted map: Walls + Asteroids TileMapLayers, team spawn Marker2Ds └── assets/ ├── icon.svg └── images/ ├── background/skybox/ ← 6 space background PNGs (1.png – 6.png) ├── effects/ ← explosion1.png ├── ships/example_ships/ ← 4 placeholder ship sprites (1.png, 1B.png, 2a.png, 3b.png) - └── tiles/ ← bwQ7rQ.png, used by tile_map.tscn + └── tiles/ ← walls.png, asteroids.png, used by world_tileset.tres ``` > **Note:** `asteroid_movement.gd` referenced in an earlier version of this doc does not exist yet — it's still an open task (see `CLAUDE.md`). @@ -40,8 +43,8 @@ MainMenu (Control) ← main_menu.gd builds all UI in _ready() ### `world/world.tscn` — game world ``` -World (Node2D) -├── TextureRect ← static space background (skybox/1.png) +World (Node2D) ← world.gd instances MAP_SCENE into MapContainer on _ready() +├── MapContainer (Node2D) ← holds the instanced map (world/maps/map_01.tscn), background included ├── Player ← instance of ships/ship.tscn ├── HUD (CanvasLayer) │ └── HealthLabel @@ -49,6 +52,17 @@ World (Node2D) └── TeamSelect (CanvasLayer, layer=20) ← menu/team_select.tscn; queue_free()s after selection ``` +### `world/maps/map_01.tscn` — hand-painted map +``` +Map01 (Node2D) +├── Background (TextureRect) ← per-map space background (skybox/1.png); visible while editing this scene +├── Walls (TileMapLayer) ← painted by hand in the Godot Tile Editor, uses world_tileset.tres +├── Asteroids (TileMapLayer) ← painted by hand, same shared tileset +└── SpawnPoints (Node2D) + ├── TeamASpawn1 (Marker2D) ← group "team_a_spawn" + └── TeamBSpawn1 (Marker2D) ← group "team_b_spawn" +``` + ### `ships/ship.tscn` — player ship ``` Player (CharacterBody2D) ← ship_movement.gd diff --git a/spacewar/assets/images/tiles/asteroids.png b/spacewar/assets/images/tiles/asteroids.png new file mode 100644 index 0000000..a9a68d8 Binary files /dev/null and b/spacewar/assets/images/tiles/asteroids.png differ diff --git a/spacewar/assets/images/tiles/asteroids.png.import b/spacewar/assets/images/tiles/asteroids.png.import new file mode 100644 index 0000000..2a4a576 --- /dev/null +++ b/spacewar/assets/images/tiles/asteroids.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c7vt2kqf8ugux" +path="res://.godot/imported/asteroids.png-ee88b2c6e2e07aea70f4dd513b385c96.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/images/tiles/asteroids.png" +dest_files=["res://.godot/imported/asteroids.png-ee88b2c6e2e07aea70f4dd513b385c96.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 diff --git a/spacewar/assets/images/tiles/bwQ7rQ.png b/spacewar/assets/images/tiles/bwQ7rQ.png deleted file mode 100644 index 75f4ac8..0000000 Binary files a/spacewar/assets/images/tiles/bwQ7rQ.png and /dev/null differ diff --git a/spacewar/assets/images/tiles/walls.png b/spacewar/assets/images/tiles/walls.png new file mode 100644 index 0000000..62a488d Binary files /dev/null and b/spacewar/assets/images/tiles/walls.png differ diff --git a/spacewar/assets/images/tiles/bwQ7rQ.png.import b/spacewar/assets/images/tiles/walls.png.import similarity index 74% rename from spacewar/assets/images/tiles/bwQ7rQ.png.import rename to spacewar/assets/images/tiles/walls.png.import index e58a999..fc4079d 100644 --- a/spacewar/assets/images/tiles/bwQ7rQ.png.import +++ b/spacewar/assets/images/tiles/walls.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dglp131j5tga6" -path="res://.godot/imported/bwQ7rQ.png-f54459e0d6bfa1fb00ae56276884677f.ctex" +uid="uid://b0arbt71qfb8l" +path="res://.godot/imported/walls.png-6781334e49c209c81b477da0160ec804.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/images/tiles/bwQ7rQ.png" -dest_files=["res://.godot/imported/bwQ7rQ.png-f54459e0d6bfa1fb00ae56276884677f.ctex"] +source_file="res://assets/images/tiles/walls.png" +dest_files=["res://.godot/imported/walls.png-6781334e49c209c81b477da0160ec804.ctex"] [params] diff --git a/spacewar/autoload/game_config.gd b/spacewar/autoload/game_config.gd index 88802d1..b277d3d 100644 --- a/spacewar/autoload/game_config.gd +++ b/spacewar/autoload/game_config.gd @@ -15,12 +15,18 @@ var bullet_speed: float = 450.0 var ship_max_health: int = 100 var ship_respawn_delay: float = 3.0 var ship_invincibility_time: float = 2.0 -var ship_wall_damage: int = 1 var bullet_damage: int = 40 +# Environment collision (asteroids only) — bounce-back and impact damage scale with impact speed +var ship_bounce_restitution: float = 0.45 +var ship_collision_damage_scale: float = 0.064 + # Set before entering a game var player_name: String = "" var player_race: int = 0 var player_ship_path: String = "" var player_ship_scale: float = 1.0 var player_ship_speed_factor: float = 1.0 + +# Current map's play area, in world coordinates. Set by world.gd on load. +var world_bounds: Rect2 = Rect2(0, 0, 1152, 648) diff --git a/spacewar/project.godot b/spacewar/project.godot index 1bbf9a4..91c3fdc 100644 --- a/spacewar/project.godot +++ b/spacewar/project.godot @@ -21,9 +21,11 @@ GameConfig="*res://autoload/game_config.gd" [display] -window/size/viewport_width=1280 -window/size/viewport_height=800 -window/size/resizable=false +window/size/viewport_width=2560 +window/size/viewport_height=1440 +window/size/mode=3 +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" [input] diff --git a/spacewar/ships/bullet.gd b/spacewar/ships/bullet.gd index 5dbb414..95781d7 100644 --- a/spacewar/ships/bullet.gd +++ b/spacewar/ships/bullet.gd @@ -8,9 +8,8 @@ func _ready() -> void: func _process(delta: float) -> void: global_position += velocity * delta - var screen = get_viewport_rect().size - if (global_position.x < 0 or global_position.x > screen.x or - global_position.y < 0 or global_position.y > screen.y): + var bounds = GameConfig.world_bounds.grow(64.0) + if not bounds.has_point(global_position): queue_free() func _on_body_entered(body: Node) -> void: diff --git a/spacewar/ships/ship.tscn b/spacewar/ships/ship.tscn index 4390113..c89f83a 100644 --- a/spacewar/ships/ship.tscn +++ b/spacewar/ships/ship.tscn @@ -16,3 +16,9 @@ scale = Vector2(0.229, 0.229) texture = ExtResource("2_epypp") [node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="." unique_id=1504818491] + +[node name="Camera2D" type="Camera2D" parent="."] +current = true +rotating = false +position_smoothing_enabled = true +position_smoothing_speed = 8.0 diff --git a/spacewar/ships/ship_movement.gd b/spacewar/ships/ship_movement.gd index 208e7c8..1fcc55e 100644 --- a/spacewar/ships/ship_movement.gd +++ b/spacewar/ships/ship_movement.gd @@ -57,7 +57,9 @@ func _physics_process(delta: float) -> void: velocity = velocity.limit_length(max_speed) + var velocity_before_move := velocity move_and_slide() + _handle_environment_collisions(velocity_before_move) # 4. SHOOT _fire_cooldown -= delta @@ -70,15 +72,34 @@ func _physics_process(delta: float) -> void: get_parent().add_child(bullet) # 5. WALL COLLISION - var screen = get_viewport_rect().size - if global_position.x < 0 or global_position.x > screen.x: + var bounds = GameConfig.world_bounds + if global_position.x < bounds.position.x or global_position.x > bounds.end.x: velocity.x = 0 - global_position.x = clamp(global_position.x, 0, screen.x) - take_damage(GameConfig.ship_wall_damage) - if global_position.y < 0 or global_position.y > screen.y: + global_position.x = clamp(global_position.x, bounds.position.x, bounds.end.x) + if global_position.y < bounds.position.y or global_position.y > bounds.end.y: velocity.y = 0 - global_position.y = clamp(global_position.y, 0, screen.y) - take_damage(GameConfig.ship_wall_damage) + global_position.y = clamp(global_position.y, bounds.position.y, bounds.end.y) + +func _handle_environment_collisions(previous_velocity: Vector2) -> void: + for i in get_slide_collision_count(): + var collision := get_slide_collision(i) + var collider := collision.get_collider() as Node + if collider == null: + continue + var is_hazard: bool = collider.is_in_group("environment_hazard") + var is_wall: bool = collider.is_in_group("environment_wall") + if not (is_hazard or is_wall): + continue + var normal := collision.get_normal() + var impact_speed := -previous_velocity.dot(normal) + if impact_speed <= 0.0: + continue + velocity = previous_velocity.bounce(normal) * GameConfig.ship_bounce_restitution + if is_hazard: + var damage := int(impact_speed * GameConfig.ship_collision_damage_scale) + if damage > 0: + take_damage(damage) + func take_damage(amount: int) -> void: if _invincible or _dead: @@ -96,8 +117,7 @@ func _die() -> void: _respawn() func _respawn() -> void: - var screen = get_viewport_rect().size - global_position = screen / 2.0 + global_position = _get_spawn_position() velocity = Vector2.ZERO rotation = 0.0 health = GameConfig.ship_max_health @@ -107,6 +127,13 @@ func _respawn() -> void: _invincible_timer = GameConfig.ship_invincibility_time _update_hud() +func _get_spawn_position() -> Vector2: + var markers := get_tree().get_nodes_in_group("team_a_spawn") + get_tree().get_nodes_in_group("team_b_spawn") + if markers.size() > 0: + return markers[randi() % markers.size()].global_position + return GameConfig.world_bounds.get_center() + + func _update_hud() -> void: var label = get_node_or_null("/root/World/HUD/HealthLabel") if label: diff --git a/spacewar/world/maps/map_01.tscn b/spacewar/world/maps/map_01.tscn new file mode 100644 index 0000000..7edb4d8 --- /dev/null +++ b/spacewar/world/maps/map_01.tscn @@ -0,0 +1,33 @@ +[gd_scene format=4 uid="uid://cecn8fghm8h3j"] + +[ext_resource type="TileSet" uid="uid://cufng7112p6a7" path="res://world/world_tileset.tres" id="1_tileset"] +[ext_resource type="Texture2D" uid="uid://d0i6jwqh131b1" path="res://assets/images/background/skybox/1.png" id="2_skybox"] + +[node name="Map01" type="Node2D" unique_id=1843060857] + +[node name="Background" type="TextureRect" parent="." unique_id=1935208901] +texture_repeat = 2 +offset_left = -7008.0 +offset_top = -3000.0 +offset_right = 7008.0 +offset_bottom = 3000.0 +texture = ExtResource("2_skybox") +expand_mode = 3 + +[node name="Walls" type="TileMapLayer" parent="." unique_id=1965607014] +scale = Vector2(0.15, 0.15) +tile_map_data = PackedByteArray("AAAFACYAAAABAAAAAAAFABkAAAABAAAAAAAFAA0AAAABAAAAAAAFAAAAAAABAAAAAAAFAPT/AAABAAAAAAARABEAAAABAAEAAAA=") +tile_set = ExtResource("1_tileset") + +[node name="Asteroids" type="TileMapLayer" parent="." unique_id=1745417803] +scale = Vector2(0.15, 0.15) +tile_map_data = PackedByteArray("AAAMAAEAAQAAAAMAAAALAPz/AQAAAAMAAAD6////AQAAAAMAAAD6/wgAAQAAAAMAAAAOAAgAAQAAAAMAAAA=") +tile_set = ExtResource("1_tileset") + +[node name="SpawnPoints" type="Node2D" parent="." unique_id=1668900368] + +[node name="TeamASpawn1" type="Marker2D" parent="SpawnPoints" unique_id=946644647 groups=["team_a_spawn"]] +position = Vector2(5304, 0) + +[node name="TeamBSpawn1" type="Marker2D" parent="SpawnPoints" unique_id=449830331 groups=["team_b_spawn"]] +position = Vector2(-5304, 0) diff --git a/spacewar/world/tile_map.tscn b/spacewar/world/tile_map.tscn deleted file mode 100644 index 1d4e2da..0000000 --- a/spacewar/world/tile_map.tscn +++ /dev/null @@ -1,1550 +0,0 @@ -[gd_scene format=3 uid="uid://cxarety0nbcme"] - -[ext_resource type="Texture2D" uid="uid://dglp131j5tga6" path="res://assets/images/tiles/bwQ7rQ.png" id="1_7yhko"] - -[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_1n30v"] -texture = ExtResource("1_7yhko") -0:0/0 = 0 -1:0/0 = 0 -2:0/0 = 0 -3:0/0 = 0 -4:0/0 = 0 -5:0/0 = 0 -6:0/0 = 0 -7:0/0 = 0 -8:0/0 = 0 -9:0/0 = 0 -10:0/0 = 0 -11:0/0 = 0 -12:0/0 = 0 -13:0/0 = 0 -14:0/0 = 0 -15:0/0 = 0 -16:0/0 = 0 -17:0/0 = 0 -18:0/0 = 0 -19:0/0 = 0 -20:0/0 = 0 -21:0/0 = 0 -22:0/0 = 0 -23:0/0 = 0 -24:0/0 = 0 -25:0/0 = 0 -26:0/0 = 0 -27:0/0 = 0 -28:0/0 = 0 -29:0/0 = 0 -30:0/0 = 0 -31:0/0 = 0 -32:0/0 = 0 -33:0/0 = 0 -34:0/0 = 0 -35:0/0 = 0 -36:0/0 = 0 -37:0/0 = 0 -38:0/0 = 0 -39:0/0 = 0 -40:0/0 = 0 -41:0/0 = 0 -42:0/0 = 0 -43:0/0 = 0 -44:0/0 = 0 -45:0/0 = 0 -46:0/0 = 0 -47:0/0 = 0 -0:1/0 = 0 -1:1/0 = 0 -2:1/0 = 0 -3:1/0 = 0 -4:1/0 = 0 -5:1/0 = 0 -6:1/0 = 0 -7:1/0 = 0 -8:1/0 = 0 -9:1/0 = 0 -10:1/0 = 0 -11:1/0 = 0 -12:1/0 = 0 -13:1/0 = 0 -14:1/0 = 0 -15:1/0 = 0 -16:1/0 = 0 -17:1/0 = 0 -18:1/0 = 0 -19:1/0 = 0 -20:1/0 = 0 -21:1/0 = 0 -22:1/0 = 0 -23:1/0 = 0 -24:1/0 = 0 -25:1/0 = 0 -26:1/0 = 0 -27:1/0 = 0 -28:1/0 = 0 -29:1/0 = 0 -30:1/0 = 0 -31:1/0 = 0 -32:1/0 = 0 -33:1/0 = 0 -34:1/0 = 0 -35:1/0 = 0 -36:1/0 = 0 -37:1/0 = 0 -38:1/0 = 0 -39:1/0 = 0 -40:1/0 = 0 -41:1/0 = 0 -42:1/0 = 0 -43:1/0 = 0 -44:1/0 = 0 -45:1/0 = 0 -46:1/0 = 0 -47:1/0 = 0 -0:2/0 = 0 -1:2/0 = 0 -2:2/0 = 0 -3:2/0 = 0 -4:2/0 = 0 -5:2/0 = 0 -6:2/0 = 0 -7:2/0 = 0 -8:2/0 = 0 -9:2/0 = 0 -10:2/0 = 0 -11:2/0 = 0 -12:2/0 = 0 -13:2/0 = 0 -14:2/0 = 0 -15:2/0 = 0 -16:2/0 = 0 -17:2/0 = 0 -18:2/0 = 0 -19:2/0 = 0 -20:2/0 = 0 -21:2/0 = 0 -22:2/0 = 0 -23:2/0 = 0 -24:2/0 = 0 -25:2/0 = 0 -26:2/0 = 0 -27:2/0 = 0 -28:2/0 = 0 -29:2/0 = 0 -30:2/0 = 0 -31:2/0 = 0 -32:2/0 = 0 -33:2/0 = 0 -34:2/0 = 0 -35:2/0 = 0 -36:2/0 = 0 -37:2/0 = 0 -38:2/0 = 0 -39:2/0 = 0 -40:2/0 = 0 -41:2/0 = 0 -42:2/0 = 0 -43:2/0 = 0 -44:2/0 = 0 -45:2/0 = 0 -46:2/0 = 0 -47:2/0 = 0 -0:3/0 = 0 -1:3/0 = 0 -2:3/0 = 0 -3:3/0 = 0 -4:3/0 = 0 -5:3/0 = 0 -6:3/0 = 0 -7:3/0 = 0 -8:3/0 = 0 -9:3/0 = 0 -10:3/0 = 0 -11:3/0 = 0 -12:3/0 = 0 -13:3/0 = 0 -14:3/0 = 0 -15:3/0 = 0 -16:3/0 = 0 -17:3/0 = 0 -18:3/0 = 0 -19:3/0 = 0 -20:3/0 = 0 -21:3/0 = 0 -22:3/0 = 0 -23:3/0 = 0 -24:3/0 = 0 -25:3/0 = 0 -26:3/0 = 0 -27:3/0 = 0 -28:3/0 = 0 -29:3/0 = 0 -30:3/0 = 0 -31:3/0 = 0 -32:3/0 = 0 -33:3/0 = 0 -34:3/0 = 0 -35:3/0 = 0 -36:3/0 = 0 -37:3/0 = 0 -38:3/0 = 0 -39:3/0 = 0 -40:3/0 = 0 -41:3/0 = 0 -42:3/0 = 0 -43:3/0 = 0 -44:3/0 = 0 -45:3/0 = 0 -46:3/0 = 0 -47:3/0 = 0 -0:4/0 = 0 -1:4/0 = 0 -2:4/0 = 0 -3:4/0 = 0 -4:4/0 = 0 -5:4/0 = 0 -6:4/0 = 0 -7:4/0 = 0 -8:4/0 = 0 -9:4/0 = 0 -10:4/0 = 0 -11:4/0 = 0 -12:4/0 = 0 -13:4/0 = 0 -14:4/0 = 0 -15:4/0 = 0 -16:4/0 = 0 -17:4/0 = 0 -18:4/0 = 0 -19:4/0 = 0 -20:4/0 = 0 -21:4/0 = 0 -22:4/0 = 0 -23:4/0 = 0 -24:4/0 = 0 -25:4/0 = 0 -26:4/0 = 0 -27:4/0 = 0 -28:4/0 = 0 -29:4/0 = 0 -30:4/0 = 0 -31:4/0 = 0 -32:4/0 = 0 -33:4/0 = 0 -34:4/0 = 0 -35:4/0 = 0 -36:4/0 = 0 -37:4/0 = 0 -38:4/0 = 0 -39:4/0 = 0 -40:4/0 = 0 -41:4/0 = 0 -42:4/0 = 0 -43:4/0 = 0 -44:4/0 = 0 -45:4/0 = 0 -46:4/0 = 0 -47:4/0 = 0 -0:5/0 = 0 -1:5/0 = 0 -2:5/0 = 0 -3:5/0 = 0 -4:5/0 = 0 -5:5/0 = 0 -6:5/0 = 0 -7:5/0 = 0 -8:5/0 = 0 -9:5/0 = 0 -10:5/0 = 0 -11:5/0 = 0 -12:5/0 = 0 -13:5/0 = 0 -14:5/0 = 0 -15:5/0 = 0 -16:5/0 = 0 -17:5/0 = 0 -18:5/0 = 0 -19:5/0 = 0 -20:5/0 = 0 -21:5/0 = 0 -22:5/0 = 0 -23:5/0 = 0 -24:5/0 = 0 -25:5/0 = 0 -26:5/0 = 0 -27:5/0 = 0 -28:5/0 = 0 -29:5/0 = 0 -30:5/0 = 0 -31:5/0 = 0 -32:5/0 = 0 -33:5/0 = 0 -34:5/0 = 0 -35:5/0 = 0 -36:5/0 = 0 -37:5/0 = 0 -38:5/0 = 0 -39:5/0 = 0 -40:5/0 = 0 -41:5/0 = 0 -42:5/0 = 0 -43:5/0 = 0 -44:5/0 = 0 -45:5/0 = 0 -46:5/0 = 0 -47:5/0 = 0 -0:6/0 = 0 -1:6/0 = 0 -2:6/0 = 0 -3:6/0 = 0 -4:6/0 = 0 -5:6/0 = 0 -6:6/0 = 0 -7:6/0 = 0 -8:6/0 = 0 -9:6/0 = 0 -10:6/0 = 0 -11:6/0 = 0 -12:6/0 = 0 -13:6/0 = 0 -14:6/0 = 0 -15:6/0 = 0 -16:6/0 = 0 -17:6/0 = 0 -18:6/0 = 0 -19:6/0 = 0 -20:6/0 = 0 -21:6/0 = 0 -22:6/0 = 0 -23:6/0 = 0 -24:6/0 = 0 -25:6/0 = 0 -26:6/0 = 0 -27:6/0 = 0 -28:6/0 = 0 -29:6/0 = 0 -30:6/0 = 0 -31:6/0 = 0 -32:6/0 = 0 -33:6/0 = 0 -34:6/0 = 0 -35:6/0 = 0 -36:6/0 = 0 -37:6/0 = 0 -38:6/0 = 0 -39:6/0 = 0 -40:6/0 = 0 -41:6/0 = 0 -42:6/0 = 0 -43:6/0 = 0 -44:6/0 = 0 -45:6/0 = 0 -46:6/0 = 0 -47:6/0 = 0 -0:7/0 = 0 -1:7/0 = 0 -2:7/0 = 0 -3:7/0 = 0 -4:7/0 = 0 -5:7/0 = 0 -6:7/0 = 0 -7:7/0 = 0 -8:7/0 = 0 -9:7/0 = 0 -10:7/0 = 0 -11:7/0 = 0 -12:7/0 = 0 -13:7/0 = 0 -14:7/0 = 0 -15:7/0 = 0 -16:7/0 = 0 -17:7/0 = 0 -18:7/0 = 0 -19:7/0 = 0 -20:7/0 = 0 -21:7/0 = 0 -22:7/0 = 0 -23:7/0 = 0 -24:7/0 = 0 -25:7/0 = 0 -26:7/0 = 0 -27:7/0 = 0 -28:7/0 = 0 -29:7/0 = 0 -30:7/0 = 0 -31:7/0 = 0 -32:7/0 = 0 -33:7/0 = 0 -34:7/0 = 0 -35:7/0 = 0 -36:7/0 = 0 -37:7/0 = 0 -38:7/0 = 0 -39:7/0 = 0 -40:7/0 = 0 -41:7/0 = 0 -42:7/0 = 0 -43:7/0 = 0 -44:7/0 = 0 -45:7/0 = 0 -46:7/0 = 0 -47:7/0 = 0 -0:8/0 = 0 -1:8/0 = 0 -2:8/0 = 0 -3:8/0 = 0 -4:8/0 = 0 -5:8/0 = 0 -6:8/0 = 0 -7:8/0 = 0 -8:8/0 = 0 -9:8/0 = 0 -10:8/0 = 0 -11:8/0 = 0 -12:8/0 = 0 -13:8/0 = 0 -14:8/0 = 0 -15:8/0 = 0 -16:8/0 = 0 -17:8/0 = 0 -18:8/0 = 0 -19:8/0 = 0 -20:8/0 = 0 -21:8/0 = 0 -22:8/0 = 0 -23:8/0 = 0 -24:8/0 = 0 -25:8/0 = 0 -26:8/0 = 0 -27:8/0 = 0 -28:8/0 = 0 -29:8/0 = 0 -30:8/0 = 0 -31:8/0 = 0 -32:8/0 = 0 -33:8/0 = 0 -34:8/0 = 0 -35:8/0 = 0 -36:8/0 = 0 -37:8/0 = 0 -38:8/0 = 0 -39:8/0 = 0 -40:8/0 = 0 -41:8/0 = 0 -42:8/0 = 0 -43:8/0 = 0 -44:8/0 = 0 -45:8/0 = 0 -46:8/0 = 0 -47:8/0 = 0 -0:9/0 = 0 -1:9/0 = 0 -2:9/0 = 0 -3:9/0 = 0 -4:9/0 = 0 -5:9/0 = 0 -6:9/0 = 0 -7:9/0 = 0 -8:9/0 = 0 -9:9/0 = 0 -10:9/0 = 0 -11:9/0 = 0 -12:9/0 = 0 -13:9/0 = 0 -14:9/0 = 0 -15:9/0 = 0 -16:9/0 = 0 -17:9/0 = 0 -18:9/0 = 0 -19:9/0 = 0 -20:9/0 = 0 -21:9/0 = 0 -22:9/0 = 0 -23:9/0 = 0 -24:9/0 = 0 -25:9/0 = 0 -26:9/0 = 0 -27:9/0 = 0 -28:9/0 = 0 -29:9/0 = 0 -30:9/0 = 0 -31:9/0 = 0 -32:9/0 = 0 -33:9/0 = 0 -34:9/0 = 0 -35:9/0 = 0 -36:9/0 = 0 -37:9/0 = 0 -38:9/0 = 0 -39:9/0 = 0 -40:9/0 = 0 -41:9/0 = 0 -42:9/0 = 0 -43:9/0 = 0 -44:9/0 = 0 -45:9/0 = 0 -46:9/0 = 0 -47:9/0 = 0 -0:10/0 = 0 -1:10/0 = 0 -2:10/0 = 0 -3:10/0 = 0 -4:10/0 = 0 -5:10/0 = 0 -6:10/0 = 0 -7:10/0 = 0 -8:10/0 = 0 -9:10/0 = 0 -10:10/0 = 0 -11:10/0 = 0 -12:10/0 = 0 -13:10/0 = 0 -14:10/0 = 0 -15:10/0 = 0 -16:10/0 = 0 -17:10/0 = 0 -18:10/0 = 0 -19:10/0 = 0 -20:10/0 = 0 -21:10/0 = 0 -22:10/0 = 0 -23:10/0 = 0 -24:10/0 = 0 -25:10/0 = 0 -26:10/0 = 0 -27:10/0 = 0 -28:10/0 = 0 -29:10/0 = 0 -30:10/0 = 0 -31:10/0 = 0 -32:10/0 = 0 -33:10/0 = 0 -34:10/0 = 0 -35:10/0 = 0 -36:10/0 = 0 -37:10/0 = 0 -38:10/0 = 0 -39:10/0 = 0 -40:10/0 = 0 -41:10/0 = 0 -42:10/0 = 0 -43:10/0 = 0 -44:10/0 = 0 -45:10/0 = 0 -46:10/0 = 0 -47:10/0 = 0 -0:11/0 = 0 -1:11/0 = 0 -2:11/0 = 0 -3:11/0 = 0 -4:11/0 = 0 -5:11/0 = 0 -6:11/0 = 0 -7:11/0 = 0 -8:11/0 = 0 -9:11/0 = 0 -10:11/0 = 0 -11:11/0 = 0 -12:11/0 = 0 -13:11/0 = 0 -14:11/0 = 0 -15:11/0 = 0 -16:11/0 = 0 -17:11/0 = 0 -18:11/0 = 0 -19:11/0 = 0 -20:11/0 = 0 -21:11/0 = 0 -22:11/0 = 0 -23:11/0 = 0 -24:11/0 = 0 -25:11/0 = 0 -26:11/0 = 0 -27:11/0 = 0 -28:11/0 = 0 -29:11/0 = 0 -30:11/0 = 0 -31:11/0 = 0 -32:11/0 = 0 -33:11/0 = 0 -34:11/0 = 0 -35:11/0 = 0 -36:11/0 = 0 -37:11/0 = 0 -38:11/0 = 0 -39:11/0 = 0 -40:11/0 = 0 -41:11/0 = 0 -42:11/0 = 0 -43:11/0 = 0 -44:11/0 = 0 -45:11/0 = 0 -46:11/0 = 0 -47:11/0 = 0 -0:12/0 = 0 -1:12/0 = 0 -2:12/0 = 0 -3:12/0 = 0 -4:12/0 = 0 -5:12/0 = 0 -6:12/0 = 0 -7:12/0 = 0 -8:12/0 = 0 -9:12/0 = 0 -10:12/0 = 0 -11:12/0 = 0 -12:12/0 = 0 -13:12/0 = 0 -14:12/0 = 0 -15:12/0 = 0 -16:12/0 = 0 -17:12/0 = 0 -18:12/0 = 0 -19:12/0 = 0 -20:12/0 = 0 -21:12/0 = 0 -22:12/0 = 0 -23:12/0 = 0 -24:12/0 = 0 -25:12/0 = 0 -26:12/0 = 0 -27:12/0 = 0 -28:12/0 = 0 -29:12/0 = 0 -30:12/0 = 0 -31:12/0 = 0 -32:12/0 = 0 -33:12/0 = 0 -34:12/0 = 0 -35:12/0 = 0 -36:12/0 = 0 -37:12/0 = 0 -38:12/0 = 0 -39:12/0 = 0 -40:12/0 = 0 -41:12/0 = 0 -42:12/0 = 0 -43:12/0 = 0 -44:12/0 = 0 -45:12/0 = 0 -46:12/0 = 0 -47:12/0 = 0 -0:13/0 = 0 -1:13/0 = 0 -2:13/0 = 0 -3:13/0 = 0 -4:13/0 = 0 -5:13/0 = 0 -6:13/0 = 0 -7:13/0 = 0 -8:13/0 = 0 -9:13/0 = 0 -10:13/0 = 0 -11:13/0 = 0 -12:13/0 = 0 -13:13/0 = 0 -14:13/0 = 0 -15:13/0 = 0 -16:13/0 = 0 -17:13/0 = 0 -18:13/0 = 0 -19:13/0 = 0 -20:13/0 = 0 -21:13/0 = 0 -22:13/0 = 0 -23:13/0 = 0 -24:13/0 = 0 -25:13/0 = 0 -26:13/0 = 0 -27:13/0 = 0 -28:13/0 = 0 -29:13/0 = 0 -30:13/0 = 0 -31:13/0 = 0 -32:13/0 = 0 -33:13/0 = 0 -34:13/0 = 0 -35:13/0 = 0 -36:13/0 = 0 -37:13/0 = 0 -38:13/0 = 0 -39:13/0 = 0 -40:13/0 = 0 -41:13/0 = 0 -42:13/0 = 0 -43:13/0 = 0 -44:13/0 = 0 -45:13/0 = 0 -46:13/0 = 0 -47:13/0 = 0 -0:14/0 = 0 -1:14/0 = 0 -2:14/0 = 0 -3:14/0 = 0 -4:14/0 = 0 -5:14/0 = 0 -6:14/0 = 0 -7:14/0 = 0 -8:14/0 = 0 -9:14/0 = 0 -10:14/0 = 0 -11:14/0 = 0 -12:14/0 = 0 -13:14/0 = 0 -14:14/0 = 0 -15:14/0 = 0 -16:14/0 = 0 -17:14/0 = 0 -18:14/0 = 0 -19:14/0 = 0 -20:14/0 = 0 -21:14/0 = 0 -22:14/0 = 0 -23:14/0 = 0 -24:14/0 = 0 -25:14/0 = 0 -26:14/0 = 0 -27:14/0 = 0 -28:14/0 = 0 -29:14/0 = 0 -30:14/0 = 0 -31:14/0 = 0 -32:14/0 = 0 -33:14/0 = 0 -34:14/0 = 0 -35:14/0 = 0 -36:14/0 = 0 -37:14/0 = 0 -38:14/0 = 0 -39:14/0 = 0 -40:14/0 = 0 -41:14/0 = 0 -42:14/0 = 0 -43:14/0 = 0 -44:14/0 = 0 -45:14/0 = 0 -46:14/0 = 0 -47:14/0 = 0 -0:15/0 = 0 -1:15/0 = 0 -2:15/0 = 0 -3:15/0 = 0 -4:15/0 = 0 -5:15/0 = 0 -6:15/0 = 0 -7:15/0 = 0 -8:15/0 = 0 -9:15/0 = 0 -10:15/0 = 0 -11:15/0 = 0 -12:15/0 = 0 -13:15/0 = 0 -14:15/0 = 0 -15:15/0 = 0 -16:15/0 = 0 -17:15/0 = 0 -18:15/0 = 0 -19:15/0 = 0 -20:15/0 = 0 -21:15/0 = 0 -22:15/0 = 0 -23:15/0 = 0 -24:15/0 = 0 -25:15/0 = 0 -26:15/0 = 0 -27:15/0 = 0 -28:15/0 = 0 -29:15/0 = 0 -30:15/0 = 0 -31:15/0 = 0 -32:15/0 = 0 -33:15/0 = 0 -34:15/0 = 0 -35:15/0 = 0 -36:15/0 = 0 -37:15/0 = 0 -38:15/0 = 0 -39:15/0 = 0 -40:15/0 = 0 -41:15/0 = 0 -42:15/0 = 0 -43:15/0 = 0 -44:15/0 = 0 -45:15/0 = 0 -46:15/0 = 0 -47:15/0 = 0 -0:16/0 = 0 -1:16/0 = 0 -2:16/0 = 0 -3:16/0 = 0 -4:16/0 = 0 -5:16/0 = 0 -6:16/0 = 0 -7:16/0 = 0 -8:16/0 = 0 -9:16/0 = 0 -10:16/0 = 0 -11:16/0 = 0 -12:16/0 = 0 -13:16/0 = 0 -14:16/0 = 0 -15:16/0 = 0 -16:16/0 = 0 -17:16/0 = 0 -18:16/0 = 0 -19:16/0 = 0 -20:16/0 = 0 -21:16/0 = 0 -22:16/0 = 0 -23:16/0 = 0 -24:16/0 = 0 -25:16/0 = 0 -26:16/0 = 0 -27:16/0 = 0 -28:16/0 = 0 -29:16/0 = 0 -30:16/0 = 0 -31:16/0 = 0 -32:16/0 = 0 -33:16/0 = 0 -34:16/0 = 0 -35:16/0 = 0 -36:16/0 = 0 -37:16/0 = 0 -38:16/0 = 0 -39:16/0 = 0 -40:16/0 = 0 -41:16/0 = 0 -42:16/0 = 0 -43:16/0 = 0 -44:16/0 = 0 -45:16/0 = 0 -46:16/0 = 0 -47:16/0 = 0 -0:17/0 = 0 -1:17/0 = 0 -2:17/0 = 0 -3:17/0 = 0 -4:17/0 = 0 -5:17/0 = 0 -6:17/0 = 0 -7:17/0 = 0 -8:17/0 = 0 -9:17/0 = 0 -10:17/0 = 0 -11:17/0 = 0 -12:17/0 = 0 -13:17/0 = 0 -14:17/0 = 0 -15:17/0 = 0 -16:17/0 = 0 -17:17/0 = 0 -18:17/0 = 0 -19:17/0 = 0 -20:17/0 = 0 -21:17/0 = 0 -22:17/0 = 0 -23:17/0 = 0 -24:17/0 = 0 -25:17/0 = 0 -26:17/0 = 0 -27:17/0 = 0 -28:17/0 = 0 -29:17/0 = 0 -30:17/0 = 0 -31:17/0 = 0 -32:17/0 = 0 -33:17/0 = 0 -34:17/0 = 0 -35:17/0 = 0 -36:17/0 = 0 -37:17/0 = 0 -38:17/0 = 0 -39:17/0 = 0 -40:17/0 = 0 -41:17/0 = 0 -42:17/0 = 0 -43:17/0 = 0 -44:17/0 = 0 -45:17/0 = 0 -46:17/0 = 0 -47:17/0 = 0 -0:18/0 = 0 -1:18/0 = 0 -2:18/0 = 0 -3:18/0 = 0 -4:18/0 = 0 -5:18/0 = 0 -6:18/0 = 0 -7:18/0 = 0 -8:18/0 = 0 -9:18/0 = 0 -10:18/0 = 0 -11:18/0 = 0 -12:18/0 = 0 -13:18/0 = 0 -14:18/0 = 0 -15:18/0 = 0 -16:18/0 = 0 -17:18/0 = 0 -18:18/0 = 0 -19:18/0 = 0 -20:18/0 = 0 -21:18/0 = 0 -22:18/0 = 0 -23:18/0 = 0 -24:18/0 = 0 -25:18/0 = 0 -26:18/0 = 0 -27:18/0 = 0 -28:18/0 = 0 -29:18/0 = 0 -30:18/0 = 0 -31:18/0 = 0 -32:18/0 = 0 -33:18/0 = 0 -34:18/0 = 0 -35:18/0 = 0 -36:18/0 = 0 -37:18/0 = 0 -38:18/0 = 0 -39:18/0 = 0 -40:18/0 = 0 -41:18/0 = 0 -42:18/0 = 0 -43:18/0 = 0 -44:18/0 = 0 -45:18/0 = 0 -46:18/0 = 0 -47:18/0 = 0 -0:19/0 = 0 -1:19/0 = 0 -2:19/0 = 0 -3:19/0 = 0 -4:19/0 = 0 -5:19/0 = 0 -6:19/0 = 0 -7:19/0 = 0 -8:19/0 = 0 -9:19/0 = 0 -10:19/0 = 0 -11:19/0 = 0 -12:19/0 = 0 -13:19/0 = 0 -14:19/0 = 0 -15:19/0 = 0 -16:19/0 = 0 -17:19/0 = 0 -18:19/0 = 0 -19:19/0 = 0 -20:19/0 = 0 -21:19/0 = 0 -22:19/0 = 0 -23:19/0 = 0 -24:19/0 = 0 -25:19/0 = 0 -26:19/0 = 0 -27:19/0 = 0 -28:19/0 = 0 -29:19/0 = 0 -30:19/0 = 0 -31:19/0 = 0 -32:19/0 = 0 -33:19/0 = 0 -34:19/0 = 0 -35:19/0 = 0 -36:19/0 = 0 -37:19/0 = 0 -38:19/0 = 0 -39:19/0 = 0 -40:19/0 = 0 -41:19/0 = 0 -42:19/0 = 0 -43:19/0 = 0 -44:19/0 = 0 -45:19/0 = 0 -46:19/0 = 0 -47:19/0 = 0 -0:20/0 = 0 -1:20/0 = 0 -2:20/0 = 0 -3:20/0 = 0 -4:20/0 = 0 -5:20/0 = 0 -6:20/0 = 0 -7:20/0 = 0 -8:20/0 = 0 -9:20/0 = 0 -10:20/0 = 0 -11:20/0 = 0 -12:20/0 = 0 -13:20/0 = 0 -14:20/0 = 0 -15:20/0 = 0 -16:20/0 = 0 -17:20/0 = 0 -18:20/0 = 0 -19:20/0 = 0 -20:20/0 = 0 -21:20/0 = 0 -22:20/0 = 0 -23:20/0 = 0 -24:20/0 = 0 -25:20/0 = 0 -26:20/0 = 0 -27:20/0 = 0 -28:20/0 = 0 -29:20/0 = 0 -30:20/0 = 0 -31:20/0 = 0 -32:20/0 = 0 -33:20/0 = 0 -34:20/0 = 0 -35:20/0 = 0 -36:20/0 = 0 -37:20/0 = 0 -38:20/0 = 0 -39:20/0 = 0 -40:20/0 = 0 -41:20/0 = 0 -42:20/0 = 0 -43:20/0 = 0 -44:20/0 = 0 -45:20/0 = 0 -46:20/0 = 0 -47:20/0 = 0 -0:21/0 = 0 -1:21/0 = 0 -2:21/0 = 0 -3:21/0 = 0 -4:21/0 = 0 -5:21/0 = 0 -6:21/0 = 0 -7:21/0 = 0 -8:21/0 = 0 -9:21/0 = 0 -10:21/0 = 0 -11:21/0 = 0 -12:21/0 = 0 -13:21/0 = 0 -14:21/0 = 0 -15:21/0 = 0 -16:21/0 = 0 -17:21/0 = 0 -18:21/0 = 0 -19:21/0 = 0 -20:21/0 = 0 -21:21/0 = 0 -22:21/0 = 0 -23:21/0 = 0 -24:21/0 = 0 -25:21/0 = 0 -26:21/0 = 0 -27:21/0 = 0 -28:21/0 = 0 -29:21/0 = 0 -30:21/0 = 0 -31:21/0 = 0 -32:21/0 = 0 -33:21/0 = 0 -34:21/0 = 0 -35:21/0 = 0 -36:21/0 = 0 -37:21/0 = 0 -38:21/0 = 0 -39:21/0 = 0 -40:21/0 = 0 -41:21/0 = 0 -42:21/0 = 0 -43:21/0 = 0 -44:21/0 = 0 -45:21/0 = 0 -46:21/0 = 0 -47:21/0 = 0 -0:22/0 = 0 -1:22/0 = 0 -2:22/0 = 0 -3:22/0 = 0 -4:22/0 = 0 -5:22/0 = 0 -6:22/0 = 0 -7:22/0 = 0 -8:22/0 = 0 -9:22/0 = 0 -10:22/0 = 0 -11:22/0 = 0 -12:22/0 = 0 -13:22/0 = 0 -14:22/0 = 0 -15:22/0 = 0 -16:22/0 = 0 -17:22/0 = 0 -18:22/0 = 0 -19:22/0 = 0 -20:22/0 = 0 -21:22/0 = 0 -22:22/0 = 0 -23:22/0 = 0 -24:22/0 = 0 -25:22/0 = 0 -26:22/0 = 0 -27:22/0 = 0 -28:22/0 = 0 -29:22/0 = 0 -30:22/0 = 0 -31:22/0 = 0 -32:22/0 = 0 -33:22/0 = 0 -34:22/0 = 0 -35:22/0 = 0 -36:22/0 = 0 -37:22/0 = 0 -38:22/0 = 0 -39:22/0 = 0 -40:22/0 = 0 -41:22/0 = 0 -42:22/0 = 0 -43:22/0 = 0 -44:22/0 = 0 -45:22/0 = 0 -46:22/0 = 0 -47:22/0 = 0 -0:23/0 = 0 -1:23/0 = 0 -2:23/0 = 0 -3:23/0 = 0 -4:23/0 = 0 -5:23/0 = 0 -6:23/0 = 0 -7:23/0 = 0 -8:23/0 = 0 -9:23/0 = 0 -10:23/0 = 0 -11:23/0 = 0 -12:23/0 = 0 -13:23/0 = 0 -14:23/0 = 0 -15:23/0 = 0 -16:23/0 = 0 -17:23/0 = 0 -18:23/0 = 0 -19:23/0 = 0 -20:23/0 = 0 -21:23/0 = 0 -22:23/0 = 0 -23:23/0 = 0 -24:23/0 = 0 -25:23/0 = 0 -26:23/0 = 0 -27:23/0 = 0 -28:23/0 = 0 -29:23/0 = 0 -30:23/0 = 0 -31:23/0 = 0 -32:23/0 = 0 -33:23/0 = 0 -34:23/0 = 0 -35:23/0 = 0 -36:23/0 = 0 -37:23/0 = 0 -38:23/0 = 0 -39:23/0 = 0 -40:23/0 = 0 -41:23/0 = 0 -42:23/0 = 0 -43:23/0 = 0 -44:23/0 = 0 -45:23/0 = 0 -46:23/0 = 0 -47:23/0 = 0 -0:24/0 = 0 -1:24/0 = 0 -2:24/0 = 0 -3:24/0 = 0 -4:24/0 = 0 -5:24/0 = 0 -6:24/0 = 0 -7:24/0 = 0 -8:24/0 = 0 -9:24/0 = 0 -10:24/0 = 0 -11:24/0 = 0 -12:24/0 = 0 -13:24/0 = 0 -14:24/0 = 0 -15:24/0 = 0 -16:24/0 = 0 -17:24/0 = 0 -18:24/0 = 0 -19:24/0 = 0 -20:24/0 = 0 -21:24/0 = 0 -22:24/0 = 0 -23:24/0 = 0 -24:24/0 = 0 -25:24/0 = 0 -26:24/0 = 0 -27:24/0 = 0 -28:24/0 = 0 -29:24/0 = 0 -30:24/0 = 0 -31:24/0 = 0 -32:24/0 = 0 -33:24/0 = 0 -34:24/0 = 0 -35:24/0 = 0 -36:24/0 = 0 -37:24/0 = 0 -38:24/0 = 0 -39:24/0 = 0 -40:24/0 = 0 -41:24/0 = 0 -42:24/0 = 0 -43:24/0 = 0 -44:24/0 = 0 -45:24/0 = 0 -46:24/0 = 0 -47:24/0 = 0 -0:25/0 = 0 -1:25/0 = 0 -2:25/0 = 0 -3:25/0 = 0 -4:25/0 = 0 -5:25/0 = 0 -6:25/0 = 0 -7:25/0 = 0 -8:25/0 = 0 -9:25/0 = 0 -10:25/0 = 0 -11:25/0 = 0 -12:25/0 = 0 -13:25/0 = 0 -14:25/0 = 0 -15:25/0 = 0 -16:25/0 = 0 -17:25/0 = 0 -18:25/0 = 0 -19:25/0 = 0 -20:25/0 = 0 -21:25/0 = 0 -22:25/0 = 0 -23:25/0 = 0 -24:25/0 = 0 -25:25/0 = 0 -26:25/0 = 0 -27:25/0 = 0 -28:25/0 = 0 -29:25/0 = 0 -30:25/0 = 0 -31:25/0 = 0 -32:25/0 = 0 -33:25/0 = 0 -34:25/0 = 0 -35:25/0 = 0 -36:25/0 = 0 -37:25/0 = 0 -38:25/0 = 0 -39:25/0 = 0 -40:25/0 = 0 -41:25/0 = 0 -42:25/0 = 0 -43:25/0 = 0 -44:25/0 = 0 -45:25/0 = 0 -46:25/0 = 0 -47:25/0 = 0 -0:26/0 = 0 -1:26/0 = 0 -2:26/0 = 0 -3:26/0 = 0 -4:26/0 = 0 -5:26/0 = 0 -6:26/0 = 0 -7:26/0 = 0 -8:26/0 = 0 -9:26/0 = 0 -10:26/0 = 0 -11:26/0 = 0 -12:26/0 = 0 -13:26/0 = 0 -14:26/0 = 0 -15:26/0 = 0 -16:26/0 = 0 -17:26/0 = 0 -18:26/0 = 0 -19:26/0 = 0 -20:26/0 = 0 -21:26/0 = 0 -22:26/0 = 0 -23:26/0 = 0 -24:26/0 = 0 -25:26/0 = 0 -26:26/0 = 0 -27:26/0 = 0 -28:26/0 = 0 -29:26/0 = 0 -30:26/0 = 0 -31:26/0 = 0 -32:26/0 = 0 -33:26/0 = 0 -34:26/0 = 0 -35:26/0 = 0 -36:26/0 = 0 -37:26/0 = 0 -38:26/0 = 0 -39:26/0 = 0 -40:26/0 = 0 -41:26/0 = 0 -42:26/0 = 0 -43:26/0 = 0 -44:26/0 = 0 -45:26/0 = 0 -46:26/0 = 0 -47:26/0 = 0 -0:27/0 = 0 -1:27/0 = 0 -2:27/0 = 0 -3:27/0 = 0 -4:27/0 = 0 -5:27/0 = 0 -6:27/0 = 0 -7:27/0 = 0 -8:27/0 = 0 -9:27/0 = 0 -10:27/0 = 0 -11:27/0 = 0 -12:27/0 = 0 -13:27/0 = 0 -14:27/0 = 0 -15:27/0 = 0 -16:27/0 = 0 -17:27/0 = 0 -18:27/0 = 0 -19:27/0 = 0 -20:27/0 = 0 -21:27/0 = 0 -22:27/0 = 0 -23:27/0 = 0 -24:27/0 = 0 -25:27/0 = 0 -26:27/0 = 0 -27:27/0 = 0 -28:27/0 = 0 -29:27/0 = 0 -30:27/0 = 0 -31:27/0 = 0 -32:27/0 = 0 -33:27/0 = 0 -34:27/0 = 0 -35:27/0 = 0 -36:27/0 = 0 -37:27/0 = 0 -38:27/0 = 0 -39:27/0 = 0 -40:27/0 = 0 -41:27/0 = 0 -42:27/0 = 0 -43:27/0 = 0 -44:27/0 = 0 -45:27/0 = 0 -46:27/0 = 0 -47:27/0 = 0 -0:28/0 = 0 -1:28/0 = 0 -2:28/0 = 0 -3:28/0 = 0 -4:28/0 = 0 -5:28/0 = 0 -6:28/0 = 0 -7:28/0 = 0 -8:28/0 = 0 -9:28/0 = 0 -10:28/0 = 0 -11:28/0 = 0 -12:28/0 = 0 -13:28/0 = 0 -14:28/0 = 0 -15:28/0 = 0 -16:28/0 = 0 -17:28/0 = 0 -18:28/0 = 0 -19:28/0 = 0 -20:28/0 = 0 -21:28/0 = 0 -22:28/0 = 0 -23:28/0 = 0 -24:28/0 = 0 -25:28/0 = 0 -26:28/0 = 0 -27:28/0 = 0 -28:28/0 = 0 -29:28/0 = 0 -30:28/0 = 0 -31:28/0 = 0 -32:28/0 = 0 -33:28/0 = 0 -34:28/0 = 0 -35:28/0 = 0 -36:28/0 = 0 -37:28/0 = 0 -38:28/0 = 0 -39:28/0 = 0 -40:28/0 = 0 -41:28/0 = 0 -42:28/0 = 0 -43:28/0 = 0 -44:28/0 = 0 -45:28/0 = 0 -46:28/0 = 0 -47:28/0 = 0 -0:29/0 = 0 -1:29/0 = 0 -2:29/0 = 0 -3:29/0 = 0 -4:29/0 = 0 -5:29/0 = 0 -6:29/0 = 0 -7:29/0 = 0 -8:29/0 = 0 -9:29/0 = 0 -10:29/0 = 0 -11:29/0 = 0 -12:29/0 = 0 -13:29/0 = 0 -14:29/0 = 0 -15:29/0 = 0 -16:29/0 = 0 -17:29/0 = 0 -18:29/0 = 0 -19:29/0 = 0 -20:29/0 = 0 -21:29/0 = 0 -22:29/0 = 0 -23:29/0 = 0 -24:29/0 = 0 -25:29/0 = 0 -26:29/0 = 0 -27:29/0 = 0 -28:29/0 = 0 -29:29/0 = 0 -30:29/0 = 0 -31:29/0 = 0 -32:29/0 = 0 -33:29/0 = 0 -34:29/0 = 0 -35:29/0 = 0 -36:29/0 = 0 -37:29/0 = 0 -38:29/0 = 0 -39:29/0 = 0 -40:29/0 = 0 -41:29/0 = 0 -42:29/0 = 0 -43:29/0 = 0 -44:29/0 = 0 -45:29/0 = 0 -46:29/0 = 0 -47:29/0 = 0 -0:30/0 = 0 -1:30/0 = 0 -2:30/0 = 0 -3:30/0 = 0 -4:30/0 = 0 -5:30/0 = 0 -6:30/0 = 0 -7:30/0 = 0 -8:30/0 = 0 -9:30/0 = 0 -10:30/0 = 0 -11:30/0 = 0 -12:30/0 = 0 -13:30/0 = 0 -14:30/0 = 0 -15:30/0 = 0 -16:30/0 = 0 -17:30/0 = 0 -18:30/0 = 0 -19:30/0 = 0 -20:30/0 = 0 -21:30/0 = 0 -22:30/0 = 0 -23:30/0 = 0 -24:30/0 = 0 -25:30/0 = 0 -26:30/0 = 0 -27:30/0 = 0 -28:30/0 = 0 -29:30/0 = 0 -30:30/0 = 0 -31:30/0 = 0 -32:30/0 = 0 -33:30/0 = 0 -34:30/0 = 0 -35:30/0 = 0 -36:30/0 = 0 -37:30/0 = 0 -38:30/0 = 0 -39:30/0 = 0 -40:30/0 = 0 -41:30/0 = 0 -42:30/0 = 0 -43:30/0 = 0 -44:30/0 = 0 -45:30/0 = 0 -46:30/0 = 0 -47:30/0 = 0 -0:31/0 = 0 -1:31/0 = 0 -2:31/0 = 0 -3:31/0 = 0 -4:31/0 = 0 -5:31/0 = 0 -6:31/0 = 0 -7:31/0 = 0 -8:31/0 = 0 -9:31/0 = 0 -10:31/0 = 0 -11:31/0 = 0 -12:31/0 = 0 -13:31/0 = 0 -14:31/0 = 0 -15:31/0 = 0 -16:31/0 = 0 -17:31/0 = 0 -18:31/0 = 0 -19:31/0 = 0 -20:31/0 = 0 -21:31/0 = 0 -22:31/0 = 0 -23:31/0 = 0 -24:31/0 = 0 -25:31/0 = 0 -26:31/0 = 0 -27:31/0 = 0 -28:31/0 = 0 -29:31/0 = 0 -30:31/0 = 0 -31:31/0 = 0 -32:31/0 = 0 -33:31/0 = 0 -34:31/0 = 0 -35:31/0 = 0 -36:31/0 = 0 -37:31/0 = 0 -38:31/0 = 0 -39:31/0 = 0 -40:31/0 = 0 -41:31/0 = 0 -42:31/0 = 0 -43:31/0 = 0 -44:31/0 = 0 -45:31/0 = 0 -46:31/0 = 0 -47:31/0 = 0 - -[sub_resource type="TileSet" id="TileSet_2uxl3"] -sources/0 = SubResource("TileSetAtlasSource_1n30v") - -[node name="TileMap" type="TileMap" unique_id=1815105899] -tile_set = SubResource("TileSet_2uxl3") -format = 2 -layer_0/tile_data = PackedInt32Array(-196613, 1048576, 0, -131077, 1048576, 1, -65541, 1048576, 2, -5, 1048576, 3, -196612, 1114112, 0, -131076, 1114112, 1, -65540, 1114112, 2, -4, 1114112, 3, -196611, 1179648, 0, -131075, 1179648, 1, -65539, 1179648, 2, -3, 1179648, 3, -196610, 1245184, 0, -131074, 1245184, 1, -65538, 1245184, 2, -2, 1245184, 3, -196609, 1048576, 0, -131073, 1048576, 1, -65537, 1048576, 2, -1, 1048576, 3, -262144, 1114112, 0, -196608, 1114112, 1, -131072, 1114112, 2, -65536, 1114112, 3, -262143, 1179648, 0, -196607, 1179648, 1, -131071, 1179648, 2, -65535, 1179648, 3, -262142, 1245184, 0, -196606, 1245184, 1, -131070, 1245184, 2, -65534, 1245184, 3, -262141, 1048576, 0, -196605, 1048576, 1, -131069, 1048576, 2, -65533, 1048576, 3, -262140, 1114112, 0, -196604, 1114112, 1, -131068, 1114112, 2, -65532, 1114112, 3, -262139, 1179648, 0, -196603, 1179648, 1, -131067, 1179648, 2, -65531, 1179648, 3, -262138, 1245184, 0, -196602, 1245184, 1, -131066, 1245184, 2, -65530, 1245184, 3, -262137, 1048576, 0, -196601, 1048576, 1, -131065, 1048576, 2, -65529, 1048576, 3, -262136, 1114112, 0, -196600, 1114112, 1, -131064, 1114112, 2, -65528, 1114112, 3, -262135, 1179648, 0, -196599, 1179648, 1, -131063, 1179648, 2, -65527, 1179648, 3, -262134, 1245184, 0, -196598, 1245184, 1, -131062, 1245184, 2, -65526, 1245184, 3, -262133, 1048576, 0, -196597, 1048576, 1, -131061, 1048576, 2, -65525, 1048576, 3, -262132, 1114112, 0, -196596, 1114112, 1, -131060, 1114112, 2, -65524, 1114112, 3, -262131, 1179648, 0, -196595, 1179648, 1, -131059, 1179648, 2, -65523, 1179648, 3, -262130, 1245184, 0, -196594, 1245184, 1, -131058, 1245184, 2, -65522, 1245184, 3, -262129, 1048576, 0, -196593, 1048576, 1, -131057, 1048576, 2, -65521, 1048576, 3, -262128, 1114112, 0, -196592, 1114112, 1, -131056, 1114112, 2, -65520, 1114112, 3, -262127, 1179648, 0, -196591, 1179648, 1, -131055, 1179648, 2, -65519, 1179648, 3, -262126, 1245184, 0, -196590, 1245184, 1, -131054, 1245184, 2, -65518, 1245184, 3) diff --git a/spacewar/world/world.gd b/spacewar/world/world.gd new file mode 100644 index 0000000..29d9a12 --- /dev/null +++ b/spacewar/world/world.gd @@ -0,0 +1,43 @@ +extends Node2D + +const MAP_SCENE: PackedScene = preload("res://world/maps/map_01.tscn") + +@onready var _map_container: Node2D = $MapContainer + + +func _ready() -> void: + var map := MAP_SCENE.instantiate() + _map_container.add_child(map) + var background := map.get_node_or_null("Background") as TextureRect + if background: + GameConfig.world_bounds = Rect2(background.position, background.size) + _build_tile_collisions(map) + + +# Tiles have no collision shapes of their own, so spawn one StaticBody2D per +# occupied cell. Asteroids get round hitboxes to roughly match their sprites. +# Walls only bounce the ship; asteroids also deal impact damage. +func _build_tile_collisions(map: Node) -> void: + for layer in map.find_children("*", "TileMapLayer", true, false): + var is_asteroid := layer.name == "Asteroids" + var group := "environment_hazard" if is_asteroid else "environment_wall" + _add_layer_colliders(layer, is_asteroid, group) + + +func _add_layer_colliders(layer: TileMapLayer, use_circle: bool, group: String) -> void: + var tile_size := Vector2(layer.tile_set.tile_size) + for cell in layer.get_used_cells(): + var body := StaticBody2D.new() + body.position = layer.map_to_local(cell) + body.add_to_group(group) + var shape := CollisionShape2D.new() + if use_circle: + var circle := CircleShape2D.new() + circle.radius = min(tile_size.x, tile_size.y) * 0.5 + shape.shape = circle + else: + var rect := RectangleShape2D.new() + rect.size = tile_size + shape.shape = rect + body.add_child(shape) + layer.add_child(body) diff --git a/spacewar/world/world.gd.uid b/spacewar/world/world.gd.uid new file mode 100644 index 0000000..a6fbeb1 --- /dev/null +++ b/spacewar/world/world.gd.uid @@ -0,0 +1 @@ +uid://dqgg811tgnrka diff --git a/spacewar/world/world.tscn b/spacewar/world/world.tscn index bb10b85..cbf4034 100644 --- a/spacewar/world/world.tscn +++ b/spacewar/world/world.tscn @@ -1,16 +1,14 @@ [gd_scene format=3 uid="uid://c77s15ns13p6y"] [ext_resource type="PackedScene" uid="uid://dygtdlkvo6ofl" path="res://ships/ship.tscn" id="1_f3sb7"] -[ext_resource type="Texture2D" uid="uid://d0i6jwqh131b1" path="res://assets/images/background/skybox/1.png" id="1_fj7yv"] [ext_resource type="PackedScene" uid="uid://cpausemenu01a" path="res://menu/pause_menu.tscn" id="2_pm"] [ext_resource type="PackedScene" uid="uid://dteamselect01" path="res://menu/team_select.tscn" id="3_ts"] +[ext_resource type="Script" path="res://world/world.gd" id="4_world"] [node name="World" type="Node2D" unique_id=1962020789] +script = ExtResource("4_world") -[node name="TextureRect" type="TextureRect" parent="." unique_id=1177783968] -offset_right = 1280.0 -offset_bottom = 800.0 -texture = ExtResource("1_fj7yv") +[node name="MapContainer" type="Node2D" parent="."] [node name="Player" parent="." unique_id=2118863138 instance=ExtResource("1_f3sb7")] diff --git a/spacewar/world/world_tileset.tres b/spacewar/world/world_tileset.tres new file mode 100644 index 0000000..817e10d --- /dev/null +++ b/spacewar/world/world_tileset.tres @@ -0,0 +1,66 @@ +[gd_resource type="TileSet" format=3 uid="uid://cufng7112p6a7"] + +[ext_resource type="Texture2D" uid="uid://b0arbt71qfb8l" path="res://assets/images/tiles/walls.png" id="1_walls"] +[ext_resource type="Texture2D" uid="uid://c7vt2kqf8ugux" path="res://assets/images/tiles/asteroids.png" id="2_asteroids"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_walls"] +texture = ExtResource("1_walls") +texture_region_size = Vector2i(194, 196) +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +1:0/0 = 0 +0:0/0 = 0 +0:1/0 = 0 +0:2/0 = 0 +0:3/0 = 0 +1:3/0 = 0 +2:3/0 = 0 +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +5:2/0 = 0 +4:2/0 = 0 +3:2/0 = 0 +2:2/0 = 0 +1:2/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_asteroids"] +texture = ExtResource("2_asteroids") +texture_region_size = Vector2i(194, 196) +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +5:1/0 = 0 +4:1/0 = 0 +3:1/0 = 0 +2:1/0 = 0 +1:1/0 = 0 +0:1/0 = 0 +0:2/0 = 0 +2:2/0 = 0 +1:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +5:2/0 = 0 +5:3/0 = 0 +4:3/0 = 0 +3:3/0 = 0 +2:3/0 = 0 +1:3/0 = 0 +0:3/0 = 0 + +[resource] +tile_size = Vector2i(194, 196) +physics_layer_0/collision_layer = 1 +sources/0 = SubResource("TileSetAtlasSource_walls") +sources/1 = SubResource("TileSetAtlasSource_asteroids")