animals
This commit is contained in:
15
scripts/animal.gd
Normal file
15
scripts/animal.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
extends Node2D
|
||||
|
||||
signal liberated
|
||||
|
||||
@export var plant_need: String
|
||||
|
||||
func _on_area_2d_area_entered(area: Area2D) -> void:
|
||||
var plant = area.get_parent()
|
||||
if plant is Plant:
|
||||
if plant_need == plant.parameter.type:
|
||||
plant.grown.connect(tracked_plant_grew)
|
||||
|
||||
func tracked_plant_grew():
|
||||
print("Liberated !!")
|
||||
liberated.emit()
|
||||
@@ -1,6 +1,9 @@
|
||||
class_name Map
|
||||
|
||||
extends Node2D
|
||||
|
||||
@export var n_animals_to_liberate := 4
|
||||
|
||||
func _ready():
|
||||
var map_size = GameTerrain.TERRAIN_SIZE * GameTerrain.MAP_RATIO
|
||||
|
||||
@@ -13,3 +16,9 @@ func _ready():
|
||||
|
||||
func _on_gui_scanner_selected(type : Scanners.Type):
|
||||
$Scanners.select_scanner(type)
|
||||
|
||||
|
||||
func _on_animal_liberated() -> void:
|
||||
n_animals_to_liberate -= 1
|
||||
if n_animals_to_liberate == 0:
|
||||
print("YOU WIN")
|
||||
|
||||
162
scripts/plant.gd
Normal file
162
scripts/plant.gd
Normal file
@@ -0,0 +1,162 @@
|
||||
class_name Plant
|
||||
|
||||
extends Node2D
|
||||
|
||||
enum PlantState { SAPLING, GROWN, DEAD}
|
||||
|
||||
signal grown
|
||||
signal died
|
||||
|
||||
@onready var growing_timer: Timer = $Growing
|
||||
@onready var need_checker: Timer = $NeedChecker
|
||||
@onready var sapling_count_down: Timer = $SaplingCountDown
|
||||
@onready var reproduction: Timer = $Reproduction
|
||||
@onready var sprite_node: AnimatedSprite2D = $AnimatedSprite2D
|
||||
|
||||
const NEED_CHECK_PERIOD := 0.5
|
||||
const SAPLING_LIFETIME_MULT := 2.0 # this multiplies the time to grow to tell the time it can stay as a sapling
|
||||
const OFFSET_REPRODUCTION_PERCT_DIST := 0.5
|
||||
|
||||
var parameter: PlantType
|
||||
var state := PlantState.SAPLING
|
||||
var sapling_time_left: float
|
||||
var can_grow := true
|
||||
|
||||
func init(plant_parameter: PlantType):
|
||||
parameter = plant_parameter
|
||||
sapling_count_down.start(SAPLING_LIFETIME_MULT * parameter.growing_time)
|
||||
sprite_node.sprite_frames = parameter.sprite_frames
|
||||
need_checker.start(NEED_CHECK_PERIOD)
|
||||
|
||||
|
||||
func _on_need_checker_timeout() -> void:
|
||||
can_grow = check_terrain_viability()
|
||||
growing_timer.paused = not can_grow and state == PlantState.SAPLING
|
||||
reproduction.paused = not can_grow
|
||||
|
||||
func check_terrain_viability() -> bool:
|
||||
var water := GameTerrain.get_stat(position, GameTerrain.Stats.WATER)
|
||||
if water < parameter.water_need[0] or water > parameter.water_need[1]:
|
||||
return false
|
||||
|
||||
var fertility := GameTerrain.get_stat(position, GameTerrain.Stats.FERTILITY)
|
||||
if fertility < parameter.fertility_need[0] or fertility > parameter.fertility_need[1]:
|
||||
return false
|
||||
|
||||
var presence := GameTerrain.get_stat(position, GameTerrain.Stats.PRESENCE)
|
||||
presence += GameTerrain.LEVELS_NUMBER / 2
|
||||
if presence < parameter.presence_need[0] or presence > parameter.presence_need[1]:
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func _on_growing_timeout() -> void:
|
||||
if state == PlantState.SAPLING:
|
||||
can_grow = check_terrain_viability()
|
||||
if not can_grow:
|
||||
growing_timer.start()
|
||||
return
|
||||
|
||||
match state:
|
||||
PlantState.SAPLING:
|
||||
grow()
|
||||
PlantState.GROWN:
|
||||
die()
|
||||
PlantState.DEAD:
|
||||
remove()
|
||||
|
||||
|
||||
func plant(new_position: Vector2):
|
||||
if not GameTerrain.is_on_map(new_position):
|
||||
push_error("Planting out of the map")
|
||||
position = new_position
|
||||
state = PlantState.SAPLING
|
||||
growing_timer.start(parameter.growing_time)
|
||||
sprite_node.play("SAPLING")
|
||||
|
||||
|
||||
func grow():
|
||||
if state != PlantState.SAPLING:
|
||||
push_error("Tried to grow " + parameter.type + ", but was not at sapling state")
|
||||
return
|
||||
state = PlantState.GROWN
|
||||
sapling_count_down.stop()
|
||||
growing_timer.start(parameter.dying_time)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.WATER,
|
||||
parameter.water_prod)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.FERTILITY,
|
||||
parameter.fertility_prod)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.PRESENCE,
|
||||
parameter.presence_prod)
|
||||
|
||||
reproduction.start(parameter.dying_time / (parameter.offspring_per_lifetime + 1) + 0.1)
|
||||
|
||||
grown.emit()
|
||||
sprite_node.play("GROWN")
|
||||
|
||||
|
||||
func die():
|
||||
state = PlantState.DEAD
|
||||
# remove alive prod and add dead prod
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.WATER,
|
||||
-parameter.water_prod + parameter.dead_water_prod)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.FERTILITY,
|
||||
-parameter.fertility_prod + parameter.dead_fertility_prod)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.PRESENCE,
|
||||
-parameter.presence_prod)
|
||||
growing_timer.start(parameter.dead_time)
|
||||
died.emit()
|
||||
sprite_node.play("DEAD")
|
||||
|
||||
func remove(was_dead: bool = true):
|
||||
if was_dead:
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.WATER,
|
||||
-parameter.dead_water_prod)
|
||||
GameTerrain.modify_zone(position,
|
||||
parameter.distance_prod,
|
||||
GameTerrain.Stats.FERTILITY,
|
||||
-parameter.dead_fertility_prod)
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_sapling_count_down_timeout() -> void:
|
||||
remove(false)
|
||||
|
||||
|
||||
func _on_reproduction_timeout() -> void:
|
||||
var min_dist := parameter.distance_prod - parameter.distance_prod * OFFSET_REPRODUCTION_PERCT_DIST
|
||||
var max_dist := parameter.distance_prod + parameter.distance_prod * OFFSET_REPRODUCTION_PERCT_DIST
|
||||
var plant_pos = position + (Vector2.RIGHT * randf_range(min_dist, max_dist)).rotated(randf_range(0, PI))
|
||||
|
||||
if not GameTerrain.is_on_map(plant_pos):
|
||||
return
|
||||
|
||||
var space := get_world_2d().direct_space_state
|
||||
var parameters = PhysicsPointQueryParameters2D.new()
|
||||
parameters.position = plant_pos
|
||||
parameters.collide_with_areas = true
|
||||
parameters.collide_with_bodies = false
|
||||
parameters.collision_mask = 1
|
||||
var result := space.intersect_point(parameters, 1)
|
||||
if result.size() > 0:
|
||||
return
|
||||
|
||||
var offspring = self.duplicate()
|
||||
self.get_parent().add_child(offspring)
|
||||
offspring.init(parameter)
|
||||
offspring.plant(plant_pos)
|
||||
@@ -33,6 +33,7 @@ func _process(delta: float) -> void:
|
||||
parameters.position = camera.get_global_mouse_position()
|
||||
parameters.collide_with_areas = true
|
||||
parameters.collide_with_bodies = false
|
||||
parameters.collision_mask = 1
|
||||
var result := space.intersect_point(parameters, 1)
|
||||
can_plant = result.size() == 0
|
||||
|
||||
@@ -43,10 +44,15 @@ func take_next_seed() -> PlantType:
|
||||
return plants[plant_ind]
|
||||
|
||||
func _unhandled_input(_event: InputEvent) -> void:
|
||||
if can_plant and Input.is_action_just_pressed("plant") and timer.is_stopped():
|
||||
var chosen_type: PlantType = take_next_seed()
|
||||
var plant = plant_scene.instantiate()
|
||||
add_child(plant)
|
||||
plant.init(chosen_type)
|
||||
plant.plant(camera.get_global_mouse_position())
|
||||
timer.start()
|
||||
|
||||
if Input.is_action_just_pressed("plant") :
|
||||
var mouse_pos = camera.get_global_mouse_position()
|
||||
var click_on_map = GameTerrain.is_on_map(mouse_pos)
|
||||
|
||||
if can_plant and click_on_map and timer.is_stopped():
|
||||
var chosen_type: PlantType = take_next_seed()
|
||||
var plant = plant_scene.instantiate()
|
||||
add_child(plant)
|
||||
plant.init(chosen_type)
|
||||
plant.plant(mouse_pos)
|
||||
timer.start()
|
||||
|
||||
@@ -3,7 +3,7 @@ extends Node2D
|
||||
enum Stats {WATER, FERTILITY, PRESENCE}
|
||||
|
||||
const TERRAIN_SIZE = Vector2i(300, 300)
|
||||
const LEVELS_NUMBER : int = 10
|
||||
const LEVELS_NUMBER : int = 20
|
||||
const MAP_RATIO = 8;
|
||||
|
||||
@onready var image := Image.create_empty(
|
||||
@@ -29,6 +29,9 @@ func map_to_pixel(
|
||||
int(position.y / MAP_RATIO)
|
||||
)
|
||||
|
||||
func is_on_map(position: Vector2) -> bool:
|
||||
return position.x >= 0 and position.x <= TERRAIN_SIZE.x * MAP_RATIO and position.y >= 0 and position.y <= TERRAIN_SIZE.y * MAP_RATIO
|
||||
|
||||
func color_value_to_level(
|
||||
color_value : float
|
||||
) -> int:
|
||||
@@ -104,6 +107,8 @@ func modify_zone(
|
||||
var pixel_radius = int(radius / MAP_RATIO)
|
||||
for x in range(pixel_center.x - pixel_radius, pixel_center.x + pixel_radius + 1) :
|
||||
for y in range(pixel_center.y - pixel_radius, pixel_center.y + pixel_radius + 1):
|
||||
if not is_on_map(Vector2i(x, y)):
|
||||
continue
|
||||
if pow(x - pixel_center.x,2) + pow(y - pixel_center.y,2) <= pow(pixel_radius,2):
|
||||
modify_pixel(
|
||||
Vector2i(x, y),
|
||||
|
||||
Reference in New Issue
Block a user