add working checkpoint and finish with timer

This commit is contained in:
interfisch 2024-11-06 07:38:44 +01:00
parent d120c82ff6
commit 36296d9b39
7 changed files with 208 additions and 89 deletions

View file

@ -39,7 +39,6 @@ target_position = Vector2(256, 128)
collision_mask = 2
[node name="resetTimer" type="Timer" parent="CharacterBody_Car"]
wait_time = 2.0
one_shot = true
[node name="RayCast_Car" type="RayCast2D" parent="CharacterBody_Car"]

View file

@ -7,26 +7,48 @@ script = ExtResource("1_7syh4")
[node name="hud" type="CanvasLayer" parent="."]
[node name="speedlabel" type="Label" parent="hud"]
[node name="debuglabel" type="Label" parent="hud"]
z_index = 8
offset_left = 38.0
offset_top = 541.0
offset_right = 454.0
offset_bottom = 586.0
theme_override_font_sizes/font_size = 32
offset_left = 14.0
offset_top = 535.0
offset_right = 430.0
offset_bottom = 580.0
theme_override_font_sizes/font_size = 20
text = "adsf"
vertical_alignment = 1
[node name="speedlabel2" type="Label" parent="hud"]
[node name="timer" type="Label" parent="hud"]
z_index = 8
offset_left = 40.0
offset_top = 582.0
offset_right = 456.0
offset_bottom = 627.0
theme_override_font_sizes/font_size = 32
text = "adsf"
offset_left = 17.0
offset_top = 562.0
offset_right = 433.0
offset_bottom = 631.0
theme_override_font_sizes/font_size = 50
text = "0.000"
vertical_alignment = 1
[node name="countdown_label" type="Label" parent="hud"]
offset_left = 604.0
offset_top = 312.0
offset_right = 644.0
offset_bottom = 342.0
theme_override_font_sizes/font_size = 50
text = "3"
horizontal_alignment = 1
vertical_alignment = 1
[node name="times_container" type="HFlowContainer" parent="hud"]
offset_left = 29.0
offset_top = 29.0
offset_right = 69.0
offset_bottom = 69.0
[node name="Camera2D" type="Camera2D" parent="."]
[node name="cars" type="Node" parent="."]
[node name="countdown" type="Timer" parent="."]
wait_time = 3.0
one_shot = true
[connection signal="timeout" from="countdown" to="." method="_on_countdown_timeout"]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=6 format=4 uid="uid://dghq8c8asg7h1"]
[gd_scene load_steps=9 format=4 uid="uid://dghq8c8asg7h1"]
[ext_resource type="TileSet" uid="uid://beswbm12qkkxk" path="res://sprites/spritesheet_road/bg_road.tres" id="2_i1338"]
[ext_resource type="TileSet" uid="uid://buu8w8n61kbxf" path="res://sprites/spritesheet_road/markings.tres" id="3_ktygs"]
@ -8,7 +8,16 @@
tile_size = Vector2i(128, 128)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_daqun"]
size = Vector2(23, 106.5)
size = Vector2(23, 222)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_dltky"]
size = Vector2(19, 108)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_uys5r"]
size = Vector2(20, 126)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_82iti"]
size = Vector2(20, 231)
[node name="Map" type="Node"]
@ -45,22 +54,30 @@ tile_set = ExtResource("4_r58io")
collision_layer = 4
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="area_finish"]
position = Vector2(89.5, -0.5)
[node name="CollisionShape2D_Fin" type="CollisionShape2D" parent="area_finish"]
position = Vector2(89.5, -1)
shape = SubResource("RectangleShape2D_daqun")
[node name="area_cp0" type="Area2D" parent="."]
collision_layer = 4
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="area_cp0"]
position = Vector2(278, 575)
shape = SubResource("RectangleShape2D_dltky")
[node name="area_cp1" type="Area2D" parent="."]
collision_layer = 4
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="area_cp1"]
position = Vector2(267, 575.5)
shape = SubResource("RectangleShape2D_daqun")
position = Vector2(194, 840)
shape = SubResource("RectangleShape2D_uys5r")
[node name="area_cp2" type="Area2D" parent="."]
collision_layer = 4
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="area_cp2"]
position = Vector2(235, 833.75)
shape = SubResource("RectangleShape2D_daqun")
position = Vector2(-384, 0)
shape = SubResource("RectangleShape2D_82iti")

View file

@ -2,6 +2,7 @@ extends CharacterBody2D
#Tutorial: https://www.youtube.com/watch?v=mJ1ZfGDTMCY t=15s
signal car_finished(playerid,finalTime)
const COLLISIONMASK_FINISH=3 #set in road_overlay
const COLLISIONMASK_CHECKPOINT=4 #set in road_overlay
@ -12,16 +13,21 @@ var checkpointtimes :Array[float]=[]
const ROAD_R_NAME="road_r"
const ROAD_L_NAME="road_l"
const COLLISION_SLOWDOWN_CAR=1.01
const COLLISION_SLOWDOWN_WALL=1.2
const STANDSTILLSPEED=0.5
var wheel_base = 60*0.5
var engine_power = 350
var engine_power = 500
var friction = -0.5
var drag = -0.0005
var braking = -200
var max_speed_reverse = 100
var slip_speed = 200
var slip_speed = 100
var traction_fast = 0.1 #traction when above slip_speed
var traction_slow = 0.5
@ -46,6 +52,7 @@ var resetcar_steerangle=120
#Variables
var running=false
var acceleration = Vector2.ZERO
var steer_direction=0
@ -64,10 +71,11 @@ var autosteer_enabled=false
@onready var collision_enable_timer: Timer = $collisionEnableTimer
var playerid=0
var finalTime=-1
func _ready() -> void:
collision_shape.disabled=true #disable collisions on start. also to avoid collision when initially setting position
finalTime=-1
func _physics_process(delta: float) -> void:
@ -80,6 +88,14 @@ func _physics_process(delta: float) -> void:
#velocity = transform.x * 200
#vel = move_and_slide()
move_and_slide()
for i in get_slide_collision_count():
var collision = get_slide_collision(i)
#if $".".name==collision.get_collider().name: #collided with another car
# velocity-=COLLISION_SLOWDOWN_CAR
if ROAD_R_NAME==collision.get_collider().name or ROAD_L_NAME==collision.get_collider().name: #collided with road
velocity/=COLLISION_SLOWDOWN_WALL
if get_slide_collision_count()>0:
velocity/=2
#for i in get_slide_collision_count():
@ -95,7 +111,6 @@ func _physics_process(delta: float) -> void:
func _on_reset_timer_timeout() -> void:
print("resetting car")
autoreset=true
func apply_friction():
@ -143,6 +158,7 @@ func get_input():
steer_direction=0 #drive straight
# Manual steering here
'''
var turn = 0
if Input.is_action_pressed("ui_right"):
turn += 1
@ -150,26 +166,26 @@ func get_input():
turn -= 1
if turn!=0:
steer_direction = turn*deg_to_rad(steering_angle)
'''
if Input.is_action_pressed("ui_up") or Input.is_action_pressed(Gamestate.userinput_prefix+str(playerid)):
#velocity = transform.x * 500
acceleration = transform.x * engine_power
if not autosteer_enabled: #start autosteer when accelerate is pressed
autosteer_enabled=true
collision_enable_timer.start()
if autoreset:
print("Cancel autoreset")
autoreset=false
if Input.is_action_pressed("ui_down"):
acceleration = transform.x * braking
if running:
if Input.is_action_pressed(Gamestate.userinput_prefix+str(playerid)):
#velocity = transform.x * 500
acceleration = transform.x * engine_power
if not autosteer_enabled: #start autosteer when accelerate is pressed
autosteer_enabled=true
collision_enable_timer.start()
if autoreset:
print("Cancel autoreset")
autoreset=false
#if Input.is_action_pressed("ui_down"):
#acceleration = transform.x * braking
if autoreset:
if autoreset and running:
acceleration = transform.x * braking #drive backwards
if distance_min>=resetcar_distance: #nothing in front of car
@ -210,28 +226,38 @@ func check_markers():
#if ray_cast_car.get_collision_mask_value(COLLISIONMASK_CHECKPOINT):
var rcc_collidername=ray_cast_car.get_collider().name
if rcc_collidername=="area_finish":
var num_cp_collected=0
for cpt in checkpointtimes:
if cpt>0:
num_cp_collected+=1
#print("Player "+str(playerid)+" drove through Finish")
if num_cp_collected==checkpointtimes.size():
if getNextCPindex()==-1 and finalTime==-1: #all checkpoints have times and did not finish
print("Player "+str(playerid)+" Finished")
#TODO: get final time
checkpointtimes.fill(0)
elif rcc_collidername.begins_with("area_cp"):
print("Final Time: "+str(Gamestate.getTimeElapsed()))
running=false
finalTime=Gamestate.getTimeElapsed()
car_finished.emit(playerid,finalTime)
elif rcc_collidername.begins_with("area_cp"):
var nextcp_i=getNextCPindex()
var checkpoint_i=checkpoints.find(rcc_collidername)
if checkpoint_i>=0 and checkpointtimes[checkpoint_i]==0: #found and no time for this cp yet
checkpointtimes[checkpoint_i]=10 # TODO: set actual time here
print("Player "+str(playerid)+" Checkpoint "+str(ray_cast_car.get_collider().name))
if checkpoint_i>=0 and nextcp_i>=0: #found and there is a next checkpoint time free
if (nextcp_i%checkpoints.size())==checkpoint_i: #this cp is next cp
checkpointtimes[nextcp_i]=Gamestate.getTimeElapsed()
print("Player "+str(playerid)+" Checkpoint "+str(ray_cast_car.get_collider().name))
print("New CP array "+str(checkpointtimes))
func constrain(val,a,b):
var vmin=min(a,b)
var vmax=max(a,b)
return min(vmax,max(vmin,val))
func getNextCPindex():
#returns index of first 0 value in times array
#-1 if all cps have times
#[10.2,15.5,12.2,0,0,0,0] -> 3
var i=0
for cpt in checkpointtimes:
if cpt==0:
return i
i+=1
return -1
func _on_collision_enable_timer_timeout() -> void:
collision_shape.disabled=false

View file

@ -16,9 +16,9 @@ func setPlayerinformation(playerid, playercolor):
cbcar.playerid=playerid
carbody.modulate = playercolor
func setCheckpoints(cps):
func setCheckpoints(cps,rounds):
cbcar.checkpoints=cps
cbcar.checkpointtimes.resize(cps.size())
cbcar.checkpointtimes.resize(cps.size()*rounds)
cbcar.checkpointtimes.fill(0.0)
func move_and_slide():
@ -28,3 +28,12 @@ func printDebug():
for i in cbcar.get_slide_collision_count():
var collision = cbcar.get_slide_collision(i)
print(""+str(cbcar.playerid)+" Collided with: "+ str( collision.get_collider().name)+" pid="+str(collision.get_collider().playerid)+" pos="+str(collision.get_collider().position))
func setRunning(r:bool):
cbcar.running=r
func getCharacterBody():
return cbcar
func hasFinished():
return cbcar.finalTime!=-1

View file

@ -1,22 +1,31 @@
extends Node2D
@onready var camera: Camera2D = $Camera2D
#@onready var car: Node2D = $car_0
@onready var countdown: Timer = $countdown
@onready var countdown_label: Label = $hud/countdown_label
@onready var cars: Node = $cars
@onready var times_container: HFlowContainer = $hud/times_container
const caroffset= 32+4 #space cars on start line
var viewCarMargin=Vector2(0.05,0.05) #proportions of viewsize. 0,0 = adjust when cars are outside view, 1,1=infinite zoom out
var viewCarMargin_zoomstart=viewCarMargin+Vector2(0.2,0.2)
var zoomspeed=0.5
var zoomspeed_backup=0.1
var viewCarMargin=Vector2(0.1,0.1) #proportions of viewsize. 0,0 = adjust when cars are outside view, 1,1=infinite zoom out
var viewCarMargin_zoomstart=viewCarMargin+Vector2(0.05,0.05)
var zoomspeed=1.0
var zoomspeed_backup=0.2
var zoom_normal=2
const CAMERA_POSITION_SPEED=0.98 #0.0 - 1.0, higher=faster
var running=false
var rounds=3
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
countdown.start()
countdown_label.visible=true
#Load Map
#var num_checkpoints=0
@ -40,7 +49,8 @@ func _ready() -> void:
newcarinstance.setPlayerinformation(i,player.color)
newcarinstance.setPosition(Vector2(0,ceil(i/2.0)*(fmod(i,2)-0.5)*2.0*caroffset))
newcarinstance.setCheckpoints(checkpoints)
newcarinstance.setCheckpoints(checkpoints,rounds)
newcarinstance.getCharacterBody().car_finished.connect(_on_car_finished)
#print("Position car "+str(i)+" = "+str(ceil(i/2.0)*(fmod(i,2)-0.5)*2.0*caroffset))
@ -51,34 +61,46 @@ func _ready() -> void:
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if running:
Gamestate.addTimeElapsed(delta)
if !countdown.is_stopped():
countdown_label.text=str(round(countdown.time_left))
var cars=cars.get_children()
var meanCarPosition=Vector2.ZERO
var displayedCarCount=0
var maxCarSpeed=0
var minPos=Vector2.ZERO #min/max x and y position of all cars
var maxPos=Vector2.ZERO
var oneDriving=false
for c in cars: #check if any one car is still driving
if !c.hasFinished():
oneDriving=true
for c in cars:
var carpos = c.getPosition()
meanCarPosition+=carpos
maxCarSpeed=max(maxCarSpeed,c.getSpeed())
if displayedCarCount==0:
minPos.x=carpos.x
minPos.y=carpos.y
maxPos.x=carpos.x
maxPos.y=carpos.y
else:
minPos.x=min(minPos.x,carpos.x)
minPos.y=min(minPos.y,carpos.y)
maxPos.x=max(maxPos.x,carpos.x)
maxPos.y=max(maxPos.y,carpos.y)
displayedCarCount+=1
if !c.hasFinished() or !oneDriving:
var carpos = c.getPosition()
meanCarPosition+=carpos
maxCarSpeed=max(maxCarSpeed,c.getSpeed())
if displayedCarCount==0:
minPos.x=carpos.x
minPos.y=carpos.y
maxPos.x=carpos.x
maxPos.y=carpos.y
else:
minPos.x=min(minPos.x,carpos.x)
minPos.y=min(minPos.y,carpos.y)
maxPos.x=max(maxPos.x,carpos.x)
maxPos.y=max(maxPos.y,carpos.y)
displayedCarCount+=1
meanCarPosition/=displayedCarCount
#camera.position=car.getPosition()
camera.position=meanCarPosition
camera.position=lerp(camera.position,meanCarPosition,CAMERA_POSITION_SPEED*delta)
#rint("zoom = "+str(camera.zoom))
#camera.zoom=Vector2(1.5,1.5)
@ -103,14 +125,8 @@ func _process(delta: float) -> void:
if camera.zoom.x<zoom_normal:
camera.zoom+=Vector2(zoomspeed_backup*delta,zoomspeed_backup*delta)
$hud/speedlabel.text=str(camera.zoom.x)
$hud/speedlabel.text=str(calculatedViewCarMargin)
#$hud/speedlabel2.text=str(viewsize.x)
#$Camera2D/speedlabel.text=str(round(maxCarSpeed))
$hud/debuglabel.text=""
$hud/timer.text=str(round(Gamestate.getTimeElapsed()*1000)/1000.0)
@ -137,3 +153,22 @@ func constrain(val,a,b):
var vmin=min(a,b)
var vmax=max(a,b)
return min(vmax,max(vmin,val))
func _on_countdown_timeout() -> void:
running=true
var cars=cars.get_children()
for c in cars:
c.setRunning(true)
countdown_label.visible=false
func _on_car_finished(playerid,finalTime) -> void:
print("Finished "+str(playerid)+" final time="+str(finalTime))
var place=times_container.get_child_count()+1
print("New Label. Place "+str(place))
var newlabel= Label.new()
times_container.add_child(newlabel)
newlabel.set("theme_override_font_sizes/font_size",40)
newlabel.text=str(place)+": "+str(round(finalTime*1000)/1000.0)+"s"
newlabel.set("theme_override_colors/font_color",Gamestate.getPlayers()[playerid].color)

View file

@ -6,6 +6,8 @@ var players: Array[Player] = []
var userinput_prefix="inputP"
var time_elapsed=0
func addPlayer(key:int):
if not getPlayerkeys().has(key):
#playerkeys.append(key)
@ -43,3 +45,12 @@ class Player:
print("i is "+str(i)+" h="+str(fmod(0.3*i,1.0))+" assigned color "+str(color))
func startGame():
for player in players:
player.setRunning(true)
func addTimeElapsed(delta):
time_elapsed+=delta
func getTimeElapsed():
return time_elapsed