From cde121ce5aaa9a31599010debddabab40f745c32 Mon Sep 17 00:00:00 2001 From: adrienmalin <41926238+adrienmalin@users.noreply.github.com> Date: Sun, 30 Dec 2018 14:17:04 +0100 Subject: [PATCH] Ghost Piece --- ExplodingLine.tscn | 4 +- GridMap.gd | 81 ++++++++++++++++------ GridMap.tscn | 18 +++-- Mino/Mino.tscn | 4 +- Mino/MinoMesh.tres | 2 +- Mino0.gd | 15 +++++ Tetrominos/GhostPiece.gd | 1 + Tetrominos/GhostPiece.tscn | 134 +++++++++++++++++++++++++++++++++++++ Tetrominos/TetroO.gd | 2 +- Tetrominos/TetroT.gd | 29 ++++---- Tetrominos/Tetromino.gd | 15 +++-- WorldEnvironment.tscn | 33 +++++++-- 12 files changed, 279 insertions(+), 59 deletions(-) create mode 100644 Mino0.gd create mode 100644 Tetrominos/GhostPiece.gd create mode 100644 Tetrominos/GhostPiece.tscn diff --git a/ExplodingLine.tscn b/ExplodingLine.tscn index 317e646..61c790f 100644 --- a/ExplodingLine.tscn +++ b/ExplodingLine.tscn @@ -32,7 +32,7 @@ render_priority = 0 trail_divisor = 2 trail_color_modifier = SubResource( 4 ) emission_shape = 2 -emission_box_extents = Vector3( 8, 0.5, 1 ) +emission_box_extents = Vector3( 8, 0.5, 0.5 ) flag_align_y = false flag_rotate_y = true flag_disable_z = false @@ -74,7 +74,7 @@ subdivide_width = 0 subdivide_height = 0 subdivide_depth = 0 -[node name="ExplodingLine" type="Particles"] +[node name="ExplodingLine" type="Particles" index="0"] layers = 1 material_override = null diff --git a/GridMap.gd b/GridMap.gd index 9675b4c..0122f38 100644 --- a/GridMap.gd +++ b/GridMap.gd @@ -15,6 +15,15 @@ const NB_MINOES = 4 const NEXT_POSITION = Vector3(13, 16, 0) const START_POSITION = Vector3(5, 20, 0) const HOLD_POSITION = Vector3(-5, 16, 0) +const SCORES = [ + [0, 4, 1], + [1, 8, 2], + [3, 12], + [5, 16], + [8] +] +const LINES_CLEARED_NAMES = ["", "SINGLE", "DOUBLE", "TRIPLE", "TETRIS"] +const T_SPIN_NAMES = ["", "MINI T-SPIN", "T-SPIN"] export (int) var NB_LINES export (int) var NB_COLLUMNS @@ -34,7 +43,10 @@ var exploding_lines = [] var lines_to_clear = [] var hard_dropping = false var random_bag = [] -var paused = false +var playing = true +var level = 0 +var goal = 0 +var score = 0 func _ready(): randomize() @@ -42,6 +54,15 @@ func _ready(): exploding_lines.append(ExplodingLine.instance()) add_child(exploding_lines[y]) exploding_lines[y].translation = Vector3(NB_COLLUMNS/2, y, 1) + new_level() + +func new_level(): + level += 1 + goal += 5 * level + $DropTimer.wait_time = pow(0.8 - ((level - 1) * 0.007), level - 1) + if level > 15: + $LockDelay.wait_time = 0.5 * pow(0.9, level-15) + print("LEVEL ", level, " Goal ", goal) new_piece() func random_piece(): @@ -81,7 +102,7 @@ func _process(delta): autoshift_action = "" if Input.is_action_just_pressed("pause"): pause() - if not paused and not hard_dropping: + if playing and not hard_dropping: for action in movements: if action != autoshift_action: if Input.is_action_pressed(action): @@ -100,12 +121,12 @@ func _process(delta): hold() func _on_AutoShiftDelay_timeout(): - if not paused and autoshift_action: + if playing and autoshift_action: move(movements[autoshift_action]) $AutoShiftTimer.start() func _on_AutoShiftTimer_timeout(): - if not paused and autoshift_action: + if playing and autoshift_action: move(movements[autoshift_action]) func is_free_cell(position): @@ -128,14 +149,27 @@ func possible_positions(initial_positions, movement): return [] func move(movement): - if current_piece.move(self, movement): + if current_piece.move(movement): + update_ghost_piece() $LockDelay.start() return true else: return false func rotate(direction): - current_piece.rotate(self, direction) + if current_piece.rotate(direction): + update_ghost_piece() + $LockDelay.start() + return true + else: + return false + +func update_ghost_piece(): + var positions = current_piece.positions() + for i in range(Tetromino.NB_MINOES): + $GhostPiece.minoes[i].translation = $GhostPiece.to_local(positions[i]) + while $GhostPiece.move(movements["soft_drop"]): + pass func _on_DropTimer_timeout(): move(movements["soft_drop"]) @@ -151,10 +185,6 @@ func _on_LockDelay_timeout(): lock_piece() func lock_piece(): - if current_piece.t_spin == Tetromino.T_SPIN: - print("T-SPIN") - elif current_piece.t_spin == Tetromino.MINI_T_SPIN: - print("MINI T-SPIN") for mino in current_piece.minoes: set_cell_item(current_piece.to_global(mino.translation).x, current_piece.to_global(mino.translation).y, 0, 0) remove_child(current_piece) @@ -174,8 +204,17 @@ func line_clear(): lines_to_clear.append(y) exploding_lines[y].restart() if lines_to_clear: - print(lines_to_clear.size(), " LINES CLEARED") $ExplosionDelay.start() + update_score() + +func update_score(): + if lines_to_clear or current_piece.t_spin: + var s = SCORES[lines_to_clear.size()][current_piece.t_spin] + score += 100 * s + goal -= s + print(T_SPIN_NAMES[current_piece.t_spin], ' ', LINES_CLEARED_NAMES[lines_to_clear.size()], " Score ", score) + if goal <= 0: + new_level() else: new_piece() @@ -184,7 +223,6 @@ func _on_ExplosionDelay_timeout(): for y in range(cleared_line, NB_LINES+2): for x in range(NB_COLLUMNS): set_cell_item(x, y, 0, get_cell_item(x, y+1, 0)) - new_piece() func hold(): if not current_piece_held: @@ -200,18 +238,19 @@ func hold(): current_piece_held = true func pause(): - paused = not paused - if paused: - print("PAUSE") - $DropTimer.stop() - $LockDelay.stop() - else: - print("RESUME") + playing = not playing + if playing: $DropTimer.start() $LockDelay.start() + print("RESUME") + else: + $DropTimer.stop() + $LockDelay.stop() + print("PAUSE") func game_over(): - print("GAME OVER") + playing = false $DropTimer.stop() $AutoShiftDelay.stop() - $AutoShiftTimer.stop() \ No newline at end of file + $AutoShiftTimer.stop() + print("GAME OVER") \ No newline at end of file diff --git a/GridMap.tscn b/GridMap.tscn index 7d520d4..897ccc2 100644 --- a/GridMap.tscn +++ b/GridMap.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://Mino/MinoLibrary.tres" type="MeshLibrary" id=1] [ext_resource path="res://GridMap.gd" type="Script" id=2] [ext_resource path="res://GridBack.tscn" type="PackedScene" id=3] [ext_resource path="res://Mino/BackMaterial.tres" type="Material" id=4] +[ext_resource path="res://Tetrominos/GhostPiece.tscn" type="PackedScene" id=5] [sub_resource type="CubeMesh" id=1] @@ -16,9 +17,8 @@ subdivide_depth = 0 [node name="GridMap" type="GridMap" index="0"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.657175, -0.5, -1 ) theme = ExtResource( 1 ) -cell_size = Vector3( 1, 1, 2 ) +cell_size = Vector3( 1, 1, 1 ) cell_octant_size = 8 cell_center_x = false cell_center_y = false @@ -41,28 +41,28 @@ NB_COLLUMNS = 10 [node name="DropTimer" type="Timer" parent="." index="0"] process_mode = 1 -wait_time = 0.5 +wait_time = 1.0 one_shot = false autostart = false [node name="LockDelay" type="Timer" parent="." index="1"] process_mode = 1 -wait_time = 1.0 +wait_time = 0.5 one_shot = true autostart = false [node name="AutoShiftDelay" type="Timer" parent="." index="2"] process_mode = 1 -wait_time = 0.2 +wait_time = 0.17 one_shot = true autostart = false [node name="AutoShiftTimer" type="Timer" parent="." index="3"] process_mode = 1 -wait_time = 0.03 +wait_time = 0.02 one_shot = false autostart = true @@ -95,6 +95,10 @@ mesh = SubResource( 1 ) transform = Transform( 7, 0, 0, 0, 7, 0, 0, 0, 0.1, 14, 16, -1 ) mesh = SubResource( 1 ) +[node name="GhostPiece" parent="." index="9" instance=ExtResource( 5 )] + +_sections_unfolded = [ "Transform" ] + [connection signal="timeout" from="DropTimer" to="." method="_on_DropTimer_timeout"] [connection signal="timeout" from="LockDelay" to="." method="_on_LockDelay_timeout"] diff --git a/Mino/Mino.tscn b/Mino/Mino.tscn index 6842c89..2e71900 100644 --- a/Mino/Mino.tscn +++ b/Mino/Mino.tscn @@ -105,7 +105,7 @@ _sections_unfolded = [ "Color", "Gravity" ] material = ExtResource( 3 ) custom_aabb = AABB( 0, 0, 0, 0, 0, 0 ) -size = Vector3( 0.9, 0.9, 2 ) +size = Vector3( 0.9, 0.9, 0.9 ) subdivide_width = 0 subdivide_height = 0 subdivide_depth = 0 @@ -141,7 +141,7 @@ explosiveness = 0.0 randomness = 0.0 fixed_fps = 0 fract_delta = true -visibility_aabb = AABB( -0.5, -0.5, -1, 1, 1, 2 ) +visibility_aabb = AABB( -0.5, -0.5, -0.5, 1, 1, 1 ) local_coords = false draw_order = 0 process_material = SubResource( 3 ) diff --git a/Mino/MinoMesh.tres b/Mino/MinoMesh.tres index 9b6333b..27cbf01 100644 --- a/Mino/MinoMesh.tres +++ b/Mino/MinoMesh.tres @@ -6,7 +6,7 @@ material = ExtResource( 1 ) custom_aabb = AABB( 0, 0, 0, 0, 0, 0 ) -size = Vector3( 0.9, 0.9, 1.9 ) +size = Vector3( 0.9, 0.9, 0.9 ) subdivide_width = 0 subdivide_height = 0 subdivide_depth = 0 diff --git a/Mino0.gd b/Mino0.gd new file mode 100644 index 0000000..a1332ba --- /dev/null +++ b/Mino0.gd @@ -0,0 +1,15 @@ +extends MeshInstance + +# class member variables go here, for example: +# var a = 2 +# var b = "textvar" + +func _ready(): + # Called when the node is added to the scene for the first time. + # Initialization here + pass + +#func _process(delta): +# # Called every frame. Delta is time since last frame. +# # Update game logic here. +# pass diff --git a/Tetrominos/GhostPiece.gd b/Tetrominos/GhostPiece.gd new file mode 100644 index 0000000..59d9b06 --- /dev/null +++ b/Tetrominos/GhostPiece.gd @@ -0,0 +1 @@ +extends "Tetromino.gd" diff --git a/Tetrominos/GhostPiece.tscn b/Tetrominos/GhostPiece.tscn new file mode 100644 index 0000000..390b0b3 --- /dev/null +++ b/Tetrominos/GhostPiece.tscn @@ -0,0 +1,134 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://Tetrominos/GhostPiece.gd" type="Script" id=1] + +[sub_resource type="SpatialMaterial" id=1] + +render_priority = 0 +flags_transparent = true +flags_unshaded = false +flags_vertex_lighting = false +flags_no_depth_test = false +flags_use_point_size = false +flags_world_triplanar = false +flags_fixed_size = false +flags_albedo_tex_force_srgb = false +vertex_color_use_as_albedo = false +vertex_color_is_srgb = false +params_diffuse_mode = 0 +params_specular_mode = 0 +params_blend_mode = 1 +params_cull_mode = 0 +params_depth_draw_mode = 0 +params_line_width = 1.0 +params_point_size = 1.0 +params_billboard_mode = 0 +params_grow = false +params_use_alpha_scissor = false +albedo_color = Color( 0.201977, 0.22403, 0.310547, 1 ) +metallic = 0.66 +metallic_specular = 0.5 +metallic_texture_channel = 0 +roughness = 0.0 +roughness_texture_channel = 0 +emission_enabled = false +normal_enabled = false +rim_enabled = false +clearcoat_enabled = false +anisotropy_enabled = false +ao_enabled = false +depth_enabled = false +subsurf_scatter_enabled = false +transmission_enabled = false +refraction_enabled = false +detail_enabled = false +uv1_scale = Vector3( 1, 1, 1 ) +uv1_offset = Vector3( 0, 0, 0 ) +uv1_triplanar = false +uv1_triplanar_sharpness = 1.0 +uv2_scale = Vector3( 1, 1, 1 ) +uv2_offset = Vector3( 0, 0, 0 ) +uv2_triplanar = false +uv2_triplanar_sharpness = 1.0 +proximity_fade_enable = true +proximity_fade_distance = 1.0 +distance_fade_enable = false +_sections_unfolded = [ "Albedo", "Proximity Fade" ] + +[sub_resource type="CubeMesh" id=2] + +material = SubResource( 1 ) +custom_aabb = AABB( 0, 0, 0, 0, 0, 0 ) +size = Vector3( 0.9, 0.9, 0.9 ) +subdivide_width = 0 +subdivide_height = 0 +subdivide_depth = 0 + +[node name="GhostPiece" type="Spatial"] + +script = ExtResource( 1 ) + +[node name="Mino0" type="MeshInstance" parent="." index="0"] + +layers = 1 +material_override = null +cast_shadow = 1 +extra_cull_margin = 0.0 +use_in_baked_light = false +lod_min_distance = 0.0 +lod_min_hysteresis = 0.0 +lod_max_distance = 0.0 +lod_max_hysteresis = 0.0 +mesh = SubResource( 2 ) +skeleton = NodePath("..") +material/0 = null + +[node name="Mino1" type="MeshInstance" parent="." index="1"] + +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 3, 0 ) +layers = 1 +material_override = null +cast_shadow = 1 +extra_cull_margin = 0.0 +use_in_baked_light = false +lod_min_distance = 0.0 +lod_min_hysteresis = 0.0 +lod_max_distance = 0.0 +lod_max_hysteresis = 0.0 +mesh = SubResource( 2 ) +skeleton = NodePath("..") +material/0 = null + +[node name="Mino2" type="MeshInstance" parent="." index="2"] + +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 0 ) +layers = 1 +material_override = null +cast_shadow = 1 +extra_cull_margin = 0.0 +use_in_baked_light = false +lod_min_distance = 0.0 +lod_min_hysteresis = 0.0 +lod_max_distance = 0.0 +lod_max_hysteresis = 0.0 +mesh = SubResource( 2 ) +skeleton = NodePath("..") +material/0 = null + +[node name="Mino3" type="MeshInstance" parent="." index="3"] + +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0 ) +layers = 1 +material_override = null +cast_shadow = 1 +extra_cull_margin = 0.0 +use_in_baked_light = false +lod_min_distance = 0.0 +lod_min_hysteresis = 0.0 +lod_max_distance = 0.0 +lod_max_hysteresis = 0.0 +mesh = SubResource( 2 ) +skeleton = NodePath("..") +material/0 = null + + diff --git a/Tetrominos/TetroO.gd b/Tetrominos/TetroO.gd index 15391f9..76784a2 100644 --- a/Tetrominos/TetroO.gd +++ b/Tetrominos/TetroO.gd @@ -1,4 +1,4 @@ extends "Tetromino.gd" -func rotate(grid, direction): +func rotate(direction): pass \ No newline at end of file diff --git a/Tetrominos/TetroT.gd b/Tetrominos/TetroT.gd index f5e3bf3..addbf9e 100644 --- a/Tetrominos/TetroT.gd +++ b/Tetrominos/TetroT.gd @@ -7,17 +7,20 @@ const T_SLOT = [ Vector3(-1, -1, 0) ] -func rotate(grid, direction): - if .rotate(grid, direction): - var center = to_global(minoes[0].translation) - var a = not grid.is_free_cell(center + T_SLOT[orientation]) - var b = not grid.is_free_cell(center + T_SLOT[(1+orientation)%4]) - var c = not grid.is_free_cell(center + T_SLOT[(2+orientation)%4]) - var d = not grid.is_free_cell(center + T_SLOT[(3+orientation)%4]) - if a and b and (c or d): - t_spin = T_SPIN - elif c and d and (a or b): - if t_spin != T_SPIN: - t_spin = MINI_T_SPIN +func rotate(direction): + if .rotate(direction): + detect_t_spin() return true - return false \ No newline at end of file + return false + +func detect_t_spin(): + var center = to_global(minoes[0].translation) + var a = not get_parent().is_free_cell(center + T_SLOT[orientation]) + var b = not get_parent().is_free_cell(center + T_SLOT[(1+orientation)%4]) + var c = not get_parent().is_free_cell(center + T_SLOT[(2+orientation)%4]) + var d = not get_parent().is_free_cell(center + T_SLOT[(3+orientation)%4]) + if a and b and (c or d): + t_spin = T_SPIN + elif c and d and (a or b): + if t_spin != T_SPIN: + t_spin = MINI_T_SPIN \ No newline at end of file diff --git a/Tetrominos/Tetromino.gd b/Tetrominos/Tetromino.gd index 93bf871..b15560f 100644 --- a/Tetrominos/Tetromino.gd +++ b/Tetrominos/Tetromino.gd @@ -3,8 +3,9 @@ extends Spatial const NB_MINOES = 4 const CLOCKWISE = -1 const COUNTERCLOCKWISE = 1 -const T_SPIN = 2 -const MINI_T_SPIN = 1 +const NO_T_SPIN = 0 +const T_SPIN = 1 +const MINI_T_SPIN = 2 const SUPER_ROTATION_SYSTEM = [ { COUNTERCLOCKWISE: [ @@ -74,7 +75,7 @@ const SUPER_ROTATION_SYSTEM = [ var minoes var orientation = 0 -var t_spin = 0 +var t_spin = NO_T_SPIN func _ready(): minoes = [$Mino0, $Mino1, $Mino2, $Mino3] @@ -102,20 +103,20 @@ func apply_positions(positions): for i in range(4): minoes[i].translation = to_local(positions[i]) -func move(grid, movement): - var new_positions = grid.possible_positions(positions(), movement) +func move(movement): + var new_positions = get_parent().possible_positions(positions(), movement) if new_positions: translate(movement) return true else: return false -func rotate(grid, direction): +func rotate(direction): var rotated_positions = rotated_positions(direction) var movements = rotation_movement_liberty(direction) var test_position for movement in movements: - test_position = grid.possible_positions(rotated_positions, movement) + test_position = get_parent().possible_positions(rotated_positions, movement) if test_position: orientation -= direction orientation %= NB_MINOES diff --git a/WorldEnvironment.tscn b/WorldEnvironment.tscn index 6732581..6acecc9 100644 --- a/WorldEnvironment.tscn +++ b/WorldEnvironment.tscn @@ -95,7 +95,7 @@ environment = SubResource( 2 ) [node name="Camera" type="Camera" parent="." index="0"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 4.5, 10, 20 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 4.5, 10, 12 ) keep_aspect = 1 cull_mask = 1048575 environment = null @@ -104,7 +104,7 @@ v_offset = 0.0 doppler_tracking = 0 projection = 0 current = false -fov = 70.0 +fov = 100.0 size = 1.0 near = 0.05 far = -1.22275e+007 @@ -112,10 +112,10 @@ _sections_unfolded = [ "Transform" ] [node name="DirectionalLight" type="DirectionalLight" parent="." index="1"] -transform = Transform( 1, 0, 0, 0, 0.999391, -0.0348995, 0, 0.0348995, 0.999391, 5, 10, 50 ) +transform = Transform( 1, 0, 0, 0, 0.999391, -0.0348995, 0, 0.0348995, 0.999391, 5.89099, 23.8982, 41.835 ) layers = 1 light_color = Color( 1, 1, 1, 1 ) -light_energy = 1.0 +light_energy = 0.3 light_indirect_energy = 1.0 light_negative = false light_specular = 0.5 @@ -138,7 +138,30 @@ directional_shadow_depth_range = 0 directional_shadow_max_distance = 200.0 _sections_unfolded = [ "Light", "Transform" ] -[node name="GridMap" parent="." index="2" instance=ExtResource( 2 )] +[node name="SpotLight" type="SpotLight" parent="." index="2"] + +transform = Transform( 1, 0, 0, 0, 0.999391, -0.0348995, 0, 0.0348995, 0.999391, 3, 16, 20 ) +layers = 1 +light_color = Color( 1, 1, 1, 1 ) +light_energy = 1.0 +light_indirect_energy = 1.0 +light_negative = false +light_specular = 0.5 +light_bake_mode = 1 +light_cull_mask = -1 +shadow_enabled = false +shadow_color = Color( 0, 0, 0, 1 ) +shadow_bias = 0.15 +shadow_contact = 0.0 +shadow_reverse_cull_face = false +editor_only = false +spot_range = 5.0 +spot_attenuation = 1.0 +spot_angle = 45.0 +spot_angle_attenuation = 1.0 +_sections_unfolded = [ "Light", "Transform" ] + +[node name="GridMap" parent="." index="3" instance=ExtResource( 2 )] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) data = {