joedad

  • Feb 26, 2023
  • Joined Mar 2, 2022
  • 0 best answers
  • For anyone interested in the game mechanics used I just tonight updated to correct a glitch in the game and at the same time make it more realistic. I was 'dropping' mines at about half the depth of the ocean. At that depth the player could actually motor past them in the water column. Not very realistic. The reason for this was because of the ocean floor contours which were pre-made and just loaded as 3 different scenes the game level generator chooses from.

    This turned out to not be too difficult to fix; it involved using a linear function on the one ocean floor which present problems. The mines are dropped just above the ocean floor at a height that changes based on the global x-position of the mine to be placed. Then game physics does the rest.

    The other two ocean profiles are flat enough that a simple adjustment to the proper height above the floor fixed those.

    I had a similar problem with the DISSUB - I was dropping it too low and it was spawning going through the tilemap ocean floor!

  • To solve the hose effect for my game I had to manually create the length I wanted in the editor and then write some code to reverse the deck reel when the Rescue Vessel is descending. As the rescue sub comes back shallow the reel has more torque in the positive. Coding extending the hose/rope did work. Coding the retracting part did not work. Or I could not get it to work. Has to do with moving the links and reconnecting the pin joints.

    My game which uses the hose discussed here can be played at my itch.io site; https://joehubdad.itch.io/submarine-rescue-ops.

  • Anyone following the progress of this unique platformer - a short video with the latest updates. Many bugs corrected with still more to work on.
    Known Bugs Corrected:

    • I lengthened the rescue submarine's hose to enable deeper searches.
    • Added some audio effects from the distressed submarine which get louder as you approach the vessel in need.
    • Added a short tutorial on the first stage.
    • Added keyboard and joystick control maps in main menu and pause menu during game play.
    • Updated script to increase game difficulty as player completes rescue stages.

  • Lots of improvements to the game; video link here. Enjoy.

    Status: 1. User option to transfer rescuees to the surface ship. NOT DONE 2. User option to return for the other survivors. COMPLETE 3. Slow down the rescues - it is instantaneous right now. COMPLETE, slow for injured survivors. 4. Correct my audio bus problem. COMPLETE 5. Insert game session anomalies - storms, broken air compressors, injured survivors requiring more time etc..; Partially complete. 6. Depth shader working. 7. Added a mine hazard (an anomaly.) More to follow here. 8. Two methods to lose - Rescue vessel explodes or player takes too long to rescue entire crew. 9. game over screens added. 10. pause menu with additional game play stats.

  • A picture of the effect as it stands now. My only possible add is to work out a method to get the lights to work within the ocean deep better. As it stands now the Shader works on the light2d texture as well and when it is black the lights do not help the player.

  • Final gd script code:

    ## deeptexture node script; defines uniforms for use in the material shader
    extends ColorRect
    
    ## Currently entire scene needs to be a child of GameLevel.tscn
    onready var my_parent = get_parent().get_parent().get_parent().get_node("GameLevel")
    onready var player = get_parent().get_parent().get_node("RescueSub")
    onready var global_posit = player.global_position    ## current screen depth calculated from Player y position + 450
    onready var ocean_depth = my_parent.depth_get()  ## Max ocean depth from stage generator
    onready var depth_factor
    
    func _ready():
    	pass
    
    func _physics_process(_delta):
    	ocean_depth = float(my_parent.depth_get())
    	global_posit = player.global_position
    	depth_factor = float(global_posit.y/ocean_depth)
    	self.material.set_shader_param("depth_factor", depth_factor)
  • @joedad said: Okay - I must have missed a tutorial note. Why do you have to select local to scene in the inspector when I trying to pass the uniform code to the shader? I made a couple of changes... to my script which is shown in the two pictures; I changed "self.get_material().set_shader_param()" to "self.material.set_shader_param()".

    2nd - I simply clicked "local to scene" as true. Then it started updating my parameters real time! If anyone has a quick answer to why the need for local to scene so I understand better I would appreciate it.

    EDIT: The local to scene had nothing to do with it. I tried to use "get_material()" and apparently that did not work. I changed back to self.material. and it works.

    Unfortunately, can't get my shader to actually darken the screen....

    UPDATE: Shader is working! Easily and very well I might add. So my trouble was not passing the uniform to the shader code and it was not finding the "correct shader material". The trouble turned out to be trying to change variables within the shader incorrectly. I simply changed my method of updating the shader to be based on the global position and ocean depth instead of trying to get each screen line to have a different depth factor. I feed the Depth Factor from the gd_script into the shader. Turns out this is a LOT simpler and looks more realistic in my opinion. Final Shader code below....

    shader_type canvas_item;
    
    uniform vec4 deep_color : hint_color = vec4(0.0, 0.0, 0.0, 1.0);
    uniform float depth_factor;
    
    void fragment() {
    	vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
    	c.rgb = mix(c.rgb, deep_color.rgb, depth_factor);
    	COLOR.rgb = c;
    }
  • Okay - I must have missed a tutorial note. Why do you have to select local to scene in the inspector when I trying to pass the uniform code to the shader? I made a couple of changes... to my script which is shown in the two pictures; I changed "self.get_material().set_shader_param()" to "self.material.set_shader_param()".

    2nd - I simply clicked "local to scene" as true. Then it started updating my parameters real time! If anyone has a quick answer to why the need for local to scene so I understand better I would appreciate it.

    EDIT: The local to scene had nothing to do with it. I tried to use "get_material()" and apparently that did not work. I changed back to self.material. and it works.

    Unfortunately, can't get my shader to actually darken the screen....

  • And a copy of the shader code:

    shader_type canvas_item;
    
    uniform vec2 global_posit;
    uniform float ocean_depth;
    uniform vec4 deep_color : hint_color = vec4(0.0, 0.0, 0.0, 1.0);
    varying float depth_factor; 
    //	self.material.set_shader_param("ocean_depth", ocean_depth)
    //	self.material.set_shader_param("global_posit", global_posit)
    
    void fragment() {
    	vec3 c = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
    	depth_factor = (FRAGCOORD.y)/ocean_depth;
    	c.rgb = mix(c.rgb, deep_color.rgb, depth_factor);
    	COLOR.rgb = c.rgb;
    }
  • I am working on a 2D platformer game where I need to develop what seems should be a simple screen shader which turns the ocean dark as the coordinate y pixels during game play get "deeper" or more positive. I have gd script code passing the two global values to my shader material but I must be addressing the shader incorrectly as it is not being seen by the shader. A screenshot of the game play showing the script and that the uniforms are working correctly in the script....

    And now the shader parameters are shown in the same live run.

    I have looked at tutorials - to the best of my knowledge there are no typos or misspellings. I have been struggling with this. It may be that I am not coding the "self.material" in my gd script correctly. Not sure how else to write it.

  • A current screenshot of the Submarine Rescue game.

  • @joedad said: Folks, my code works for the most part. I would say 95% right. I used DEGREES instead of RADIANS. I changed "180" to "PI" and it rotates and attaches the next segment as expected.

    When I have a more complete game to demo I will post a video.

    All, I stated above I would post a video after getting the extending and shortening code to work. The code to grow the rope works - the code to shorten proved to be too much trouble. My solution is a separate pin joint 2d node that serves as a reel system. I code a constant set torque value on the reel which keeps the full length of hose under tension. This allows the player to unreel during game play and when returning close to the reel the reel automatically reels the hose back up. Works great!

    I am going to post no further discussions on this thread.

  • More modifications and game logic fix to my submarine rescue game. See an updated test run here.

    Next things to fix: 1. User option to transfer rescuees to the surface ship. 2. User option to return for the other survivors. 3. Slow down the rescues - it is instantaneous right now. 4. Correct my audio bus problem. 5. Insert game session anomalies - storms, broken air compressors, injured survivors requiring more time etc..

  • I made some modifications and got the hose working the way I think looks much better. No bouncing jitter during game play. A little adaptive coding for the torque on the reel keeps the extra hose coiled up but the rescue submarine can counteract the torque so that the sub can go to the bottom. Seems to work well.

    Video sample of the game showing the hose reel working.

  • Folks, my code works for the most part. I would say 95% right. I used DEGREES instead of RADIANS. I changed "180" to "PI" and it rotates and attaches the next segment as expected.

    When I have a more complete game to demo I will post a video.

  • Guess I am answering my question here but the lines 7 to 13 are working. I think my problem must be where the "rotate()" function applies the rotation to each segment.

    The origin of the segment scene is center at (0,0). Anyone understand why my origin may be wrong or why rotate gives an offset rotation??

  • While I stop physics processing during the add_segment code, my problem must be the original position of the 'Segment' that I am duplicating. The 'hose' is aligned from the player to the base at about a 20 degree up angle. When the segments are duplicated it is duplicating this original copy vice the current hose segment by the player. Note lines 7 through 13 in the Add_segments() function above. this is attempting to duplicate, invert the new segment add as a child and then connect the pinjoint to the old segment.

    I guess a solution is to not 'duplicate' but find the current segment node and copy that?

  • I have made use of others' rigid body designs for rope for some time now but cannot find a good method to add links to the rope or chain. For a game I am designing (2D platformer) I need to be able to lengthen a hose as the player vehicle moves away from a starting position. The code for the most part is working - as the Player moves away a comparison is done in code and when the hose is stretched too far a segment is duplicated and attached to the previous segment.

    Now the trouble and question: I modeled my code after how I would duplicate the segments in the editor, then move the segment and attach node_b. That seemed to work but each successive segment seems to be attached at one corner where the entire length of rope (initially 20 segments) are all aligned on center. I am uncertain why the offset.

    Key Part of the Code: "link_players()", "calc_length()", and "add_segments()".

    func link_players():
    	
    	#prevents the rope from freaking out, when relocated
    	yield(get_tree(), "idle_frame")
    	
    	pjoint = get_parent().get_node("RescueSub/Player_pinjoint")
    	ppos = pjoint.global_position 
    	pjoint.node_a = $Segments.get_child(19).get_path()
    	
    	player2 = get_parent().get_node("VOO")
    	p2pos = player2.get_node("Position2D").global_position
    	var p2seg = $Segments.get_child(0)
    	var p2joint = p2seg.get_node("PinJoint2D")
    	p2joint.node_b = player2.get_path()
    
    	linked = true
    
    func calc_length():
    	hose_length = num_segs*9.7
    
    func add_segments():
    	for chld in $Segments.get_children():
    		chld.mode = 1
    		chld.set_physics_process(false)
    
    	player = get_parent().get_node("RescueSub")
    	var init_vel = player.velocity
    	player.set_process_input(false)
    	player.set_physics_process(false)
    	player.velocity = Vector2.ZERO
    	
    	var segs_list = $Segments.get_children()
    	var last_seg = segs_list[num_segs-1]
    	var seg_dup = last_seg.duplicate(15)
    	print("did we pause")
    	seg_dup.rotate(180)
    	seg_dup.set_physics_process(false)
    	$Segments.add_child(seg_dup, true)
    
    	yield(get_tree(), "idle_frame")
    	var dupjoint = seg_dup.get_node("PinJoint2D")
    	dupjoint.node_b = last_seg.get_path()
    	num_segs = $Segments.get_child_count()
    
    	ppos = pjoint.global_position 
    	seg_dup.get_node("North_Pole").global_position = ppos
    	pjoint.node_a = seg_dup.get_path()
    	
    	player.velocity = init_vel
    	player.set_process_input(true)
    	player.set_physics_process(true)
    	
    	for chld in $Segments.get_children():
    		chld.mode = 0
    		chld.set_physics_process(true)