Added player
This commit is contained in:
parent
f9ec2e855d
commit
9f36f7c921
|
|
@ -1,6 +1,6 @@
|
||||||
extends Sprite2D
|
extends Sprite2D
|
||||||
|
|
||||||
var n: int = 256
|
var n: int = 64
|
||||||
var arr := []
|
var arr := []
|
||||||
|
|
||||||
var data_img: Image
|
var data_img: Image
|
||||||
|
|
@ -14,6 +14,13 @@ var gol := GoL.new()
|
||||||
var T := 0.01
|
var T := 0.01
|
||||||
var t := 0.0
|
var t := 0.0
|
||||||
|
|
||||||
|
# player (2x2 block)
|
||||||
|
var player_alive := true
|
||||||
|
var player_col := 10
|
||||||
|
var player_row := 10
|
||||||
|
var PLAYER_SHAPE := [Vector2i(0,0), Vector2i(1,0), Vector2i(0,1), Vector2i(1,1)]
|
||||||
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
data_img = Image.create(n, n, false, Image.FORMAT_R8)
|
data_img = Image.create(n, n, false, Image.FORMAT_R8)
|
||||||
|
|
@ -23,8 +30,10 @@ func _ready() -> void:
|
||||||
mat.set_shader_parameter("binDataTex", data_tex)
|
mat.set_shader_parameter("binDataTex", data_tex)
|
||||||
mat.set_shader_parameter("n", n)
|
mat.set_shader_parameter("n", n)
|
||||||
|
|
||||||
# init
|
# player
|
||||||
|
_seed_clear()
|
||||||
_fill_example()
|
_fill_example()
|
||||||
|
_spawn_player(20, 10)
|
||||||
_upload_arr()
|
_upload_arr()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,11 +46,21 @@ func _upload_arr() -> void:
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
if Input.is_action_just_pressed("move_right"):
|
||||||
|
_move_player(1, 0)
|
||||||
|
if Input.is_action_just_pressed("move_left"):
|
||||||
|
_move_player(-1, 0)
|
||||||
|
if Input.is_action_just_pressed("move_up"):
|
||||||
|
_move_player(0, -1)
|
||||||
|
if Input.is_action_just_pressed("move_down"):
|
||||||
|
_move_player(0, 1)
|
||||||
|
|
||||||
t += _delta
|
t += _delta
|
||||||
if t >= T:
|
if t >= T:
|
||||||
t = 0.0
|
t = 0.0
|
||||||
#_game_of_life_step()
|
_game_of_life_step()
|
||||||
arr = gol.step_once(arr, n) # cpp step
|
# arr = gol.step_once(arr, n) # cpp step (no player)
|
||||||
|
_track_player_after_step()
|
||||||
_upload_arr()
|
_upload_arr()
|
||||||
|
|
||||||
func _game_of_life_step() -> void:
|
func _game_of_life_step() -> void:
|
||||||
|
|
@ -75,8 +94,35 @@ func _count_neighs(x:int, y:int) -> int:
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
func _track_player_after_step() -> void:
|
||||||
|
if not player_alive:
|
||||||
|
return
|
||||||
|
var best_count := -1
|
||||||
|
var best_shift := Vector2i(0, 0)
|
||||||
|
|
||||||
|
# search a 5x5 neighborhood for where the 2x2 footprint moved
|
||||||
|
for dy in range(-2, 3):
|
||||||
|
for dx in range(-2, 3):
|
||||||
|
var cnt := 0
|
||||||
|
for off in PLAYER_SHAPE:
|
||||||
|
var x:int = (player_col + off.x + dx + n) % n
|
||||||
|
var y:int = (player_row + off.y + dy + n) % n
|
||||||
|
cnt += arr[y][x]
|
||||||
|
if cnt > best_count:
|
||||||
|
best_count = cnt
|
||||||
|
best_shift = Vector2i(dx, dy)
|
||||||
|
|
||||||
|
# if nothing from the footprint survived, the player is dead
|
||||||
|
if best_count <= 0:
|
||||||
|
player_alive = false
|
||||||
|
print("Player dead!")
|
||||||
|
return
|
||||||
|
|
||||||
|
player_col = (player_col + best_shift.x + n) % n
|
||||||
|
player_row = (player_row + best_shift.y + n) % n
|
||||||
|
|
||||||
|
|
||||||
func _fill_example() -> void:
|
func _fill_example() -> void:
|
||||||
arr.clear()
|
|
||||||
#_checkerboard()
|
#_checkerboard()
|
||||||
_ship()
|
_ship()
|
||||||
|
|
||||||
|
|
@ -105,3 +151,46 @@ func _ship() -> void:
|
||||||
arr[2][0] = 1
|
arr[2][0] = 1
|
||||||
arr[2][1] = 1
|
arr[2][1] = 1
|
||||||
arr[2][2] = 1
|
arr[2][2] = 1
|
||||||
|
|
||||||
|
|
||||||
|
# Player
|
||||||
|
func _write_player(val:int) -> void:
|
||||||
|
for off in PLAYER_SHAPE:
|
||||||
|
var x:int = (player_col + off.x + n) % n
|
||||||
|
var y:int = (player_row + off.y + n) % n
|
||||||
|
arr[y][x] = val
|
||||||
|
|
||||||
|
func _spawn_player(col:int, row:int) -> void:
|
||||||
|
player_col = (col + n) % n
|
||||||
|
player_row = (row + n) % n
|
||||||
|
player_alive = true
|
||||||
|
_write_player(1)
|
||||||
|
_upload_arr()
|
||||||
|
|
||||||
|
func _despawn_player() -> void:
|
||||||
|
if player_alive:
|
||||||
|
_write_player(0)
|
||||||
|
player_alive = false
|
||||||
|
_upload_arr()
|
||||||
|
|
||||||
|
func _move_player(dx:int, dy:int) -> void:
|
||||||
|
if not player_alive:
|
||||||
|
return
|
||||||
|
# erase old footprint
|
||||||
|
_write_player(0)
|
||||||
|
# move
|
||||||
|
player_col = (player_col + dx + n) % n
|
||||||
|
player_row = (player_row + dy + n) % n
|
||||||
|
# write new footprint
|
||||||
|
_write_player(1)
|
||||||
|
_upload_arr()
|
||||||
|
|
||||||
|
|
||||||
|
# Clear
|
||||||
|
func _seed_clear() -> void:
|
||||||
|
arr.clear()
|
||||||
|
for _y in n:
|
||||||
|
var row := []
|
||||||
|
for _x in n:
|
||||||
|
row.append(0)
|
||||||
|
arr.append(row)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
extends Area2D
|
||||||
|
|
||||||
|
@export var speed = 400 # How fast the player will move (pixels/sec).
|
||||||
|
var screen_size # Size of the game window.
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
screen_size = get_viewport_rect().size
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
var velocity = Vector2.ZERO # The player's movement vector.
|
||||||
|
if Input.is_action_pressed("move_right"):
|
||||||
|
velocity.x += 1
|
||||||
|
if Input.is_action_pressed("move_left"):
|
||||||
|
velocity.x -= 1
|
||||||
|
|
||||||
|
if velocity.length() > 0:
|
||||||
|
velocity = velocity.normalized() * speed
|
||||||
|
$AnimatedSprite2D.play()
|
||||||
|
else:
|
||||||
|
$AnimatedSprite2D.stop()
|
||||||
|
|
||||||
|
position += velocity * delta
|
||||||
|
position = position.clamp(Vector2.ZERO, screen_size)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cvxhfc50fgdyb
|
||||||
|
|
@ -19,3 +19,26 @@ config/icon="res://icon.svg"
|
||||||
|
|
||||||
window/size/viewport_width=1920
|
window/size/viewport_width=1920
|
||||||
window/size/viewport_height=1920
|
window/size/viewport_height=1920
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
move_right={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_left={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_up={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_down={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue