First Devlog :)


https://loganjbp.notion.site/133deb2031db80be9825e8b546fe0b1b?pvs=4

Over the last week and a bit, I started making my first Godot game. The concept of the game is a multiplayer parkour game where you and your teammates need to try to score the ball into the other team’s goal, I plan to add teams of one, two or three with online support and an emphasis on trick shots with the ball in order to score.

So far this week I have created a tile set, character controller with temporary visuals and the ball which can be picked up and thrown. I also started working on a dynamic camera but I haven’t got it working properly.

  • Character:

    This is a modified and upgraded version of the character from the Brackey’s tutorial game. It was created entirely by me as an attempted remake of my scratch platformer movement that you can see in Rift Brawl. It’s not the most complex thing ever but I like the slight momentum and all of the customisable constants at the top. The animation section at the bottom is basically a sequence of if-else statements checking the player’s state and playing the appropriate animation.

    • Code

      racterBody2D  @onready var animated_sprite_2d = $AnimatedSprite2D  #region variables const speed = 200 const gravity = 20 const jump_force = 500 const slam_force = 2000 const midair_jumps = 1 const midair_jump_force = 400 const friction = 1.3 const max_fall_speed = 3000 const max_x_speed = 7000 const walljump_x = 4 const walljump_y = 1.5 const dash_multiplyer = 5 const slam_jump_multiplyer = 1.5 const floor_speed_multiplyer = 0.6 const wall_slide_speed_multiplyer = 0.8 const ground_dash_x = 5000 var current_air_jumps = 1 var currently_slamming = 0 var ground_dash_cooldown = 0 var midair_dash = 0 #endregion  func _physics_process(_delta): #region MidairDash / WallJump     midair_dash -= 0.1     if !is_on_floor():         velocity.y += gravity         if velocity.y > max_fall_speed:             velocity.y = max_fall_speed         if currently_slamming < 0 and Input.is_action_just_pressed("Jump"):             if is_on_wall_only():                 current_air_jumps = midair_jumps                 velocity.y = -jump_force * walljump_y                 velocity.x = jump_force * walljump_x                 move_and_slide()                 if is_on_wall():                     velocity.x = jump_force * (0 - walljump_x)             elif !current_air_jumps == 0:                 velocity.x *= dash_multiplyer                 velocity.y = -midair_jump_force                 current_air_jumps = current_air_jumps - 1                 midair_dash = 2 #endregion      #region Jump     if is_on_floor():         current_air_jumps = midair_jumps         if Input.is_action_pressed("Jump"):             if currently_slamming > 0:                 velocity.y = -jump_force * slam_jump_multiplyer                 currently_slamming = -1             else:                 velocity.y = -jump_force         else:             currently_slamming -= 0.1 #endregion      #region Slam     if !is_on_floor() && Input.is_action_just_pressed("Down") && currently_slamming < 0:         currently_slamming = 1 #        Engine.time_scale = 0.2 #slowdown effect         await get_tree().create_timer(0.05).timeout         Engine.time_scale = 1         velocity.y = slam_force         currently_slamming = 1 #endregion      #region GroundDash     if is_on_floor() && Input.is_action_just_pressed("Down"):         if !abs(velocity.x) < 1 && ground_dash_cooldown < 0:             velocity.x = (velocity.x / abs(velocity.x)) * ground_dash_x             ground_dash_cooldown = 2     ground_dash_cooldown -= 0.1     #endregion      #region HorizontalMovement     if is_on_floor():         var horizontal_direction = (Input.get_axis("Left","Right")) * floor_speed_multiplyer         velocity.x = ((velocity.x + (speed * horizontal_direction)) / friction)     else:         var horizontal_direction = (Input.get_axis("Left","Right"))         velocity.x = ((velocity.x + (speed * horizontal_direction)) / friction)     if is_on_wall_only() && velocity.y > 0 && currently_slamming < 0:         velocity.y = velocity.y * wall_slide_speed_multiplyer     if abs(velocity.x) > max_x_speed:         velocity.x = (velocity.x / abs(velocity.x)) * max_x_speed #endregion      #region Animations     if velocity.x > 0:         animated_sprite_2d.flip_h = false         animated_sprite_2d.offset.x = abs(animated_sprite_2d.offset.x)     else:         animated_sprite_2d.flip_h = true         animated_sprite_2d.offset.x = 0 - abs(animated_sprite_2d.offset.x)     if is_on_wall_only() && currently_slamming < 0:         animated_sprite_2d.play("Wallslide")     elif midair_dash > 0 and abs(velocity.x) > 10:         animated_sprite_2d.play("DashAir")     elif ground_dash_cooldown > 0:         animated_sprite_2d.play("DashGround")     elif currently_slamming > 0:         animated_sprite_2d.play("Slam")     elif is_on_floor():         if !Input.get_axis("Left","Right") == 0:             animated_sprite_2d.play("Run")         else:             animated_sprite_2d.play("Idle")     else:         if velocity.y < 0:             animated_sprite_2d.play("Rise")         else:             animated_sprite_2d.play("Fall") #endregion          GlobalScript.player_x = position.x     GlobalScript.player_y = position.y     GlobalScript.player_x_vel = velocity.x     GlobalScript.player_y_vel = velocity.y          move_and_slide()  
    • Sprites

      Warrior-Free Animation set V1.3

  • Ball:

    The ball is quite basic, as Godot comes with an object called “RigidBody2D,” which does all of the ball physics for me. Because of this, the only coding I needed to do was about picking up and throwing the ball. It's very messy, and there are probably far easier methods, but it gets the job done. When thrown, the ball will move in the direction chosen by the player via the movement keys added on top of the player’s velocity to make it feel more natural.

    • Code

      extends RigidBody2D  var touching_player = 0 var holding_ball = 0 var key_down = 0  @onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D  func _ready() -> void:     linear_velocity.x = randf_range(-1000,1000)  func _on_area_2d_area_entered(area: Area2D) -> void:     touching_player = 1  func _on_area_2d_area_exited(area: Area2D) -> void:     touching_player = 0  func _physics_process(_delta):     if touching_player == 1:         if Input.is_action_just_pressed("Throw") && holding_ball == 0:             key_down = 1             holding_ball = 1     if holding_ball == 1:         position.x = GlobalScript.player_x         position.y = GlobalScript.player_y         if Input.is_action_just_pressed("Throw") && key_down == 0:             linear_velocity.x = 0             linear_velocity.y = 0             holding_ball = 0             key_down = 100             linear_velocity.x = (Input.get_axis("Left","Right") * 1000) + GlobalScript.player_x_vel             linear_velocity.y = (Input.get_axis("Jump","Down") * 1000) + GlobalScript.player_y_vel             linear_damp = 0         else:             key_down = 0     GlobalScript.ball_x = position.x     GlobalScript.ball_y = position.y 
    • Sprite

      Made by my friend Max, the sprite is quite basic but I think it looks really nice.

      https://imgur.com/a8Vh1I7

  • Visuals:

    Whilst it all needs a lot of work, I think the tiles turned out great. I made them using Piskel, a free pixel art tool and I made a lot of use of the lighten and darken tool to add shading which greatly improved the style. I was aiming for a vaguely sci-fi theme with a lot of contrast and shadows.

  • Camera:

    A good camera is something that will make or break a game like this, I want the camera to show all important info whilst also not permanently being incredibly zoomed out. I started this by creating a node that will sit directly between the player and the ball, this will keep them cantered if they are touching and keep the camera in the right place to show both when it’s not. The hard part was trying to set the camera zoom to an appropriate zoom to keep everything on screen. As of now, this system isn’t done and if I’m honest I don’t know how my barely functional code works so I will need to completely redo it at some point.

    • Code
    • extends Node2D @onready var camera_2d: Camera2D = $Camera2D func _process(delta: float) -> void: position.x = (GlobalScript.player_x + GlobalScript.ball_x) / 2 position.y = (GlobalScript.player_y + GlobalScript.ball_y) / 2 if abs(GlobalScript.player_y - GlobalScript.ball_y) > abs(GlobalScript.player_x - GlobalScript.ball_x): camera_2d.zoom.x = ((1 - (abs(GlobalScript.player_y - GlobalScript.ball_y) * (0.0003555556 * 0.5))) * 0.8) else: camera_2d.zoom.x = ((1 - (abs(GlobalScript.player_x - GlobalScript.ball_x) * (0.0003555556 * 0.5))) * 0.8) if camera_2d.zoom.x < 0.3: camera_2d.zoom.x = 0.3 camera_2d.zoom.y = camera_2d.zoom.x

Get Rift Slam Beta

Download NowName your own price

Comments

Log in with itch.io to leave a comment.

The formatting on the code isn't messed up if you go to the link at the top