Added win/lose conditions, lose animation. Clicking on revealed tile with correct number of flags reveals the surrounding unflagged tiles. Added completion timer. Probably other things I'm forgetting
This commit is contained in:
parent
34a254b12c
commit
32150473c6
9
minesweeper/scenes/Minefield.tscn1397283733.tmp
Normal file
9
minesweeper/scenes/Minefield.tscn1397283733.tmp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b8ewc3373b0t2"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://du63nf81skbpt" path="res://scripts/Minefield.gd" id="1_rm6t6"]
|
||||||
|
|
||||||
|
[node name="Minefield" type="Node2D"]
|
||||||
|
script = ExtResource("1_rm6t6")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
zoom = Vector2(4, 4)
|
9
minesweeper/scenes/Minefield.tscn1403038500.tmp
Normal file
9
minesweeper/scenes/Minefield.tscn1403038500.tmp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b8ewc3373b0t2"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://du63nf81skbpt" path="res://scripts/Minefield.gd" id="1_rm6t6"]
|
||||||
|
|
||||||
|
[node name="Minefield" type="Node2D"]
|
||||||
|
script = ExtResource("1_rm6t6")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
zoom = Vector2(4, 4)
|
@ -11,8 +11,14 @@ static var instance: Minefield
|
|||||||
@export var startingSafeZone: int = 2
|
@export var startingSafeZone: int = 2
|
||||||
|
|
||||||
var tiles: Array[Tile]
|
var tiles: Array[Tile]
|
||||||
|
var mines: Array[Tile]
|
||||||
|
var falseFlags: Array[Tile]
|
||||||
var spriteWidth: int = 16
|
var spriteWidth: int = 16
|
||||||
var fieldInitialized: bool = false
|
var fieldInitialized: bool = false
|
||||||
|
var gameRunning: bool = true
|
||||||
|
var revealed: int = 0
|
||||||
|
var winCondition: int
|
||||||
|
var timer: int
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
func _enter_tree() -> void:
|
||||||
if (instance == null || is_instance_valid(instance)): instance = self
|
if (instance == null || is_instance_valid(instance)): instance = self
|
||||||
@ -20,6 +26,7 @@ func _enter_tree() -> void:
|
|||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
var scale: float = 1
|
var scale: float = 1
|
||||||
|
winCondition = (width * height) - mineCount
|
||||||
for x: int in range(width):
|
for x: int in range(width):
|
||||||
for y: int in range(height):
|
for y: int in range(height):
|
||||||
var tile: Tile = tilePrefab.instantiate()
|
var tile: Tile = tilePrefab.instantiate()
|
||||||
@ -38,10 +45,29 @@ func initField(coord: Vector2i) -> void:
|
|||||||
pickPool.erase(pick)
|
pickPool.erase(pick)
|
||||||
if (abs(coord - pick.coord) >= Vector2i(startingSafeZone, startingSafeZone)):
|
if (abs(coord - pick.coord) >= Vector2i(startingSafeZone, startingSafeZone)):
|
||||||
pick.type = Tile.TileTypes.MINE
|
pick.type = Tile.TileTypes.MINE
|
||||||
|
mines.append(pick)
|
||||||
break
|
break
|
||||||
pick = pickPool.pick_random()
|
pick = pickPool.pick_random()
|
||||||
for tile: Tile in tiles:
|
for tile: Tile in tiles:
|
||||||
tile.evaluateType()
|
tile.evaluateType()
|
||||||
|
timer = Time.get_ticks_msec()
|
||||||
|
|
||||||
|
func lose() -> void:
|
||||||
|
gameRunning = false
|
||||||
|
for mine: Tile in mines:
|
||||||
|
await get_tree().create_timer(randf_range(0.01, 0.25)).timeout
|
||||||
|
mine.reveal()
|
||||||
|
for flag: Tile in falseFlags:
|
||||||
|
await get_tree().create_timer(randf_range(0.01, 0.1)).timeout
|
||||||
|
flag.breakFlag()
|
||||||
|
|
||||||
|
func tilesRevealed(count: int) -> void:
|
||||||
|
revealed += count
|
||||||
|
if (revealed == winCondition):
|
||||||
|
gameRunning = false
|
||||||
|
var completionTime: int = Time.get_ticks_msec() - timer
|
||||||
|
var humanTime: float = float(completionTime) / 1000
|
||||||
|
print("You win.\nCompleted in " + str(humanTime) + " seconds")
|
||||||
|
|
||||||
func getTile(coord: Vector2i) -> Tile:
|
func getTile(coord: Vector2i) -> Tile:
|
||||||
if (coord.x < 0 || coord.y < 0 || coord.x >= width || coord.y >= width): return null
|
if (coord.x < 0 || coord.y < 0 || coord.x >= width || coord.y >= width): return null
|
||||||
|
@ -4,6 +4,7 @@ class_name Tile extends Node2D
|
|||||||
@onready var cover: CompressedTexture2D = preload("res://sprites/cover.png")
|
@onready var cover: CompressedTexture2D = preload("res://sprites/cover.png")
|
||||||
@onready var mine: CompressedTexture2D = preload("res://sprites/mine.png")
|
@onready var mine: CompressedTexture2D = preload("res://sprites/mine.png")
|
||||||
@onready var flag: CompressedTexture2D = preload("res://sprites/flag.png")
|
@onready var flag: CompressedTexture2D = preload("res://sprites/flag.png")
|
||||||
|
@onready var brokenFlag: CompressedTexture2D = preload("res://sprites/brokenFlag.png")
|
||||||
@onready var nums: Array[CompressedTexture2D] = [
|
@onready var nums: Array[CompressedTexture2D] = [
|
||||||
preload("res://sprites/1.png"),
|
preload("res://sprites/1.png"),
|
||||||
preload("res://sprites/2.png"),
|
preload("res://sprites/2.png"),
|
||||||
@ -36,44 +37,63 @@ var coord: Vector2i
|
|||||||
var revealed: bool = false
|
var revealed: bool = false
|
||||||
var flagged: bool = false
|
var flagged: bool = false
|
||||||
|
|
||||||
func evaluateType() -> void:
|
func getNeighbors() -> Array[Tile]:
|
||||||
if (type == TileTypes.MINE): return
|
var results: Array[Tile]
|
||||||
var count: int = 0
|
|
||||||
for x: int in range(-1, 2):
|
for x: int in range(-1, 2):
|
||||||
for y: int in range(-1, 2):
|
for y: int in range(-1, 2):
|
||||||
if (x == 0 && y == 0): continue
|
if (x == 0 && y == 0): continue
|
||||||
var tile: Tile = Minefield.instance.getTile(coord + Vector2i(x, y))
|
var tile: Tile = Minefield.instance.getTile(coord + Vector2i(x, y))
|
||||||
if (tile == null): continue
|
if (tile == null): continue
|
||||||
if (tile.type == TileTypes.MINE): count += 1
|
results.append(tile)
|
||||||
|
return results
|
||||||
|
|
||||||
|
func evaluateType() -> void:
|
||||||
|
if (type == TileTypes.MINE): return
|
||||||
|
var count: int = 0
|
||||||
|
for tile: Tile in getNeighbors():
|
||||||
|
if (tile.type == TileTypes.MINE): count += 1
|
||||||
type = count as TileTypes
|
type = count as TileTypes
|
||||||
|
|
||||||
func reveal() -> void:
|
func reveal() -> int:
|
||||||
if (revealed): return
|
if (revealed || Minefield.instance.gameRunning && flagged): return 0
|
||||||
revealed = true
|
revealed = true
|
||||||
|
var count: int = 1
|
||||||
layer1.texture = backplate
|
layer1.texture = backplate
|
||||||
match type:
|
match type:
|
||||||
TileTypes.EMPTY:
|
TileTypes.EMPTY:
|
||||||
layer2.texture = null
|
layer2.texture = null
|
||||||
for x: int in range(-1, 2):
|
for tile: Tile in getNeighbors(): count += tile.reveal()
|
||||||
for y: int in range(-1, 2):
|
|
||||||
if (x == 0 && y == 0): continue
|
|
||||||
var tile: Tile = Minefield.instance.getTile(coord + Vector2i(x, y))
|
|
||||||
if (tile == null): continue
|
|
||||||
tile.reveal()
|
|
||||||
TileTypes.MINE:
|
TileTypes.MINE:
|
||||||
layer2.texture = mine
|
layer2.texture = mine
|
||||||
|
if (Minefield.instance.gameRunning): Minefield.instance.lose()
|
||||||
_:
|
_:
|
||||||
layer2.texture = nums[type as int - 1]
|
layer2.texture = nums[type as int - 1]
|
||||||
|
return count
|
||||||
|
|
||||||
|
func breakFlag() -> void:
|
||||||
|
layer2.texture = brokenFlag
|
||||||
|
|
||||||
func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
|
func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
|
||||||
|
if (!Minefield.instance.gameRunning): return
|
||||||
if (event.is_released()):
|
if (event.is_released()):
|
||||||
if (event.is_action_released("reveal") && !flagged):
|
if (event.is_action_released("reveal") && revealed):
|
||||||
|
var count: int = 0
|
||||||
|
var neighbors: Array[Tile] = getNeighbors()
|
||||||
|
for tile: Tile in neighbors:
|
||||||
|
if (tile.flagged): count += 1
|
||||||
|
if (count == type as int):
|
||||||
|
count = 0
|
||||||
|
for tile: Tile in neighbors: count += tile.reveal()
|
||||||
|
Minefield.instance.tilesRevealed(count)
|
||||||
|
elif (event.is_action_released("reveal") && !flagged):
|
||||||
if (!Minefield.instance.fieldInitialized):
|
if (!Minefield.instance.fieldInitialized):
|
||||||
Minefield.instance.initField(coord)
|
Minefield.instance.initField(coord)
|
||||||
reveal()
|
Minefield.instance.tilesRevealed(reveal())
|
||||||
elif (event.is_action_released("flag") && !revealed):
|
elif (event.is_action_released("flag") && !revealed):
|
||||||
flagged = !flagged
|
flagged = !flagged
|
||||||
if (flagged):
|
if (flagged):
|
||||||
layer2.texture = flag
|
layer2.texture = flag
|
||||||
|
if (type != TileTypes.MINE): Minefield.instance.falseFlags.append(self)
|
||||||
else:
|
else:
|
||||||
layer2.texture = null
|
layer2.texture = null
|
||||||
|
if (type != TileTypes.MINE): Minefield.instance.falseFlags.erase(self)
|
||||||
|
BIN
minesweeper/sprites/brokenFlag.png
Normal file
BIN
minesweeper/sprites/brokenFlag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 265 B |
34
minesweeper/sprites/brokenFlag.png.import
Normal file
34
minesweeper/sprites/brokenFlag.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d353xpjsitdct"
|
||||||
|
path="res://.godot/imported/brokenFlag.png-785bad89b513c2a3f4b8d504b0f83440.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://sprites/brokenFlag.png"
|
||||||
|
dest_files=["res://.godot/imported/brokenFlag.png-785bad89b513c2a3f4b8d504b0f83440.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
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user