Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | alexscunha |
Hi,
I just started, a few days ago, Your first 2D Game tutorial, but I’m having some issues with Hit() signal. I’m using C# and Visual Studio 2022.
I followed all instructions from the tutorial, but it seems Hit() signal can’t see the Game_Over() and New_Game() method in the Main.cs. It seems there is some bug or some mistake from my part(high probability).
Update about the Error Or Possible Bug: (I noticed only the next day!!!)
I noticed that after I deleted New_Game() and Game_Over() signals that was attached
to the Player.cs and keep only the ones attached to the Main.cs… After I save the application, close the application and open it again, the two signals that I deleted previously comes back. See the screenshots below:
I’m posting here my scripts and my screenshots so that you help me, please, finding the missing piece!
Main.sc script:
using Godot;
using System;
public class Main : Node
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";
#pragma warning disable 649
[Export]
public PackedScene MobScene;
#pragma warning restore 649
public int Score;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
GD.Randomize();
New_Game();
}
// // Called every frame. 'delta' is the elapsed time since the previous frame.
// public override void _Process(float delta)
// {
//
// }
public void Game_Over()
{
GetNode<Timer>("MobTimer").Stop();
GetNode<Timer>("ScoreTimer").Stop();
}
public void New_Game()
{
Score = 0;
var player = GetNode<Player>("/root/Main/Player");
var startPosition = GetNode<Position2D>("/root/Main/StartPosition");
player.Start(startPosition.Position);
//GetNode<Timer>("/root/Main/StartTimer").Start();
Timer StartTimer = GetNode<Timer>("/root/Main/StartTimer");
StartTimer.Start();
}
public void On_StartTimer_Timeout()
{
GetNode<Timer>("MobTimer").Start();
GetNode<Timer>("ScoreTimer").Start();
}
public void On_ScoreTimer_Timeout()
{
Score++;
}
public void On_MobTimer_Timeout()
{
//Create a new instance of the Mob Scene
var mob = (Mob)MobScene.Instance();
//Choose a random Location on Path2D
var mobSpawnLocation = GetNode<PathFollow2D>("MobPath/MobSpawnLocation");
mobSpawnLocation.Offset = GD.Randi();
//Set the mon's direction perpendicular to the path direction.
float direction = mobSpawnLocation.Rotation + Mathf.Pi / 2;
//Set the mob's position to a random location.
mob.Position = mobSpawnLocation.Position;
//Add some randomness to the direction
direction += (float)GD.RandRange(-Mathf.Pi / 4, Mathf.Pi / 4);
mob.Rotation = direction;
// Choose the velocity.
var velocity = new Vector2((float)GD.RandRange(150.0, 250.0), 0);
mob.LinearVelocity = velocity.Rotated(direction);
// Spawn the mob by adding it to the Main scene.
AddChild(mob);
}
}
Player.sc script:
using Godot;
using System;
public class Player : Area2D
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";
//How fast the player will move (pixel/sec).
[Export]
public int Speed = 400;
[Signal]
public delegate void Hit();
// Size of the game window.
public Vector2 ScreenSize;
public int Score;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
ScreenSize = GetViewportRect().Size;
Hide(); //Player is hidden when the game starts
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(float delta)
{
var velocity = Vector2.Zero; //Tha Player's movement vector
if (Input.IsActionPressed("move_right"))
{
velocity.x += 1;
}
if (Input.IsActionPressed("move_left"))
{
velocity.x -= 1;
}
if (Input.IsActionPressed("move_down"))
{
velocity.y += 1;
}
if (Input.IsActionPressed("move_up"))
{
velocity.y -= 1;
}
var animatedSprite = GetNode<AnimatedSprite>("AnimatedSprite");
if (velocity.Length() > 0)
{
velocity = velocity.Normalized() * Speed;
animatedSprite.Play();
}
else
{
animatedSprite.Stop();
}
Position += velocity * delta;
Position = new Vector2(
x: Mathf.Clamp(Position.x, 0, ScreenSize.x),
y: Mathf.Clamp(Position.y, 0, ScreenSize.y)
);
if (velocity.x != 0)
{
animatedSprite.Animation = "walk";
animatedSprite.FlipV = false;
animatedSprite.FlipH = velocity.x < 0; //Here I'm doing a boolean test
}
else if (velocity.y != 0)
{
animatedSprite.Animation = "up";
animatedSprite.FlipV = velocity.y > 0; //Here I'm doing a boolean test
}
}
public void On_Player_Body_Entered(PhysicsBody2D body)
{
Hide(); //Player disappears after being hit.
EmitSignal(nameof(Hit));//On_Player_Hit()
//Must be deferred as we can't change physics properties on a physics callback.
GetNode<CollisionShape2D>("CollisionShape2D").SetDeferred("disabled", true);
}
//Reset the player when starting the game
public void Start(Vector2 pos)
{
Position = pos;
Show();
GetNode<CollisionShape2D>("CollisionShape2D").Disabled = false;
}
}
Mob.sc script:
using Godot;
using System;
public class Mob : RigidBody2D
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
var animSprite = GetNode<AnimatedSprite>("AnimatedSprite");
animSprite.Playing = true;
string[] mobTypes = animSprite.Frames.GetAnimationNames();
animSprite.Animation = mobTypes[GD.Randi() % mobTypes.Length];
}
// // Called every frame. 'delta' is the elapsed time since the previous frame.
// public override void _Process(float delta)
// {
//
// }
public void OnVisibilityNotifier2DScreenExited()
{
QueueFree();
}
}
These are all my scripts!!!
Well, I think with all these information you can help me! If you need anything more, let me know, please!