Removing the barrier after the collision? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm making a game (Breakout) and I have a question,
The question is how can I remove the barriers after they get hit by the ball?
Of course, the ball must be able to go through the track after that (like Breakout game in general)
the next question is that can I make the barriers in run time mode?
Thanks
private void timer1_Tick(object sender, EventArgs e)
{
ball.Top += step;
ball.Left += stepleft;
//board simulate collision
bool collisonX = ball.Location.X + ball.Width > board.Location.X && ball.Location.X < board.Location.X + board.Width;
bool collisonY = ball.Top + ball.Height == board.Location.Y || ball.Top + ball.Height - 1 == board.Location.Y;
//board2(button1) simulate collision
bool collisonX2 = ball.Location.X + ball.Width > board2.Location.X && ball.Location.X < board2.Location.X + board2.Width;
bool collisonY2 = ball.Top + ball.Height == board2.Location.Y || ball.Top + ball.Height - 1 == board2.Location.Y;
//Collision the ball with under buttons
bool collsionButtonY = ball.Top - ball.Height == board2.Location.Y || ball.Top - ball.Height == board2.Location.Y - 1;
//collision leftwall
bool leftWall = ball.Left == 0 || ball.Left == -1 || ball.Left == 1;
//collision rightwall
bool topWall = ball.Top == 0 || ball.Top == -1 || ball.Top == 1;
bool bottomWall = collisonX && collisonY;
bool toppWall = collisonX2 && collisonY2;
//collision
bool barrier = collisonX2 && collsionButtonY;
bool collisionLeft = ((ball.Location.Y + ball.Height >= board2.Location.Y) && (ball.Location.Y <= board2.Location.Y + board2.Height) && (ball.Location.X + ball.Width >= board2.Location.X) && (ball.Location.X <= board2.Location.X + board2.Height));
//rightwall
bool rightWall = ball.Left + ball.Width == this.ClientSize.Width || ball.Left + ball.Width == this.ClientSize.Width - 1;
// sidewall = collision rightwall or leftwall
bool sideWall = leftWall || rightWall;
//Check the ball hit the ground
bool check = ball.Top + ball.Height < this.ClientSize.Height;
//if topWall true,This means that the ball is hit to the topwall
if (topWall)
{
flagBottom = false;
flagTop = true;
if (stepleft > 0)
{
step = 2;
}
else if (stepleft < 0)
{
step = 2;
}
}
//if bottomWall true,This means that the ball is hit to the board
else if (bottomWall)
{
flagBottom = true;
flagTop = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if barrier true and flagbottom true,This means that the ball is hit to the board2(button1)
else if (barrier && flagBottom)
{
collisionLeft = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if toppWall true and flagTop true,This means that the ball is hit to The top button is hit
else if (toppWall && flagTop)
{
collisionLeft = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
else if (flagTop && collisionLeft)
{
barrier = false;
if (stepleft > 0)
{
stepleft = -2;
step = 2;
}
else if (stepleft < 0)
{
stepleft = 2;
step = 2;
}
}
else if (flagBottom && collisionLeft)
{
barrier = false;
if (stepleft > 0)
{
stepleft = -2;
step = -2;
}
else if (stepleft < 0)
{
stepleft = 2;
step = -2;
}
}
else if (sideWall)
{
//if leftwall true,This means that the ball is hit to the left side wall
if (leftWall)
{
if (flagTop)
{
stepleft = 2;
}
else if (flagBottom)
{
stepleft = 2;
}
}
//if rightWall true,This means that the ball is hit to the left side wall
else if (rightWall)
{
if (flagTop)
{
stepleft = -2;
}
else if (flagBottom)
{
stepleft = -2;
}
}
}
//check if ckeck==ture,this mean the ball is hit the ground
else if (!check)
{
timer1.Enabled = false;
}
}
private void board_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
private void board_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
board.Left = e.X + board.Left - MouseDownLocation.X;
}

You need to learn use lists and proper use of classes.
For example :
public class GameObject{
public GameObject(int x, int y, int width, int height){
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
int X;
int Y;
int Width;
int Height;
public bool DetectCollision(bool Ball){
//code to detect collision
}
}
Then in your main class, you can do thing like that.
List<GameObject> gameObjects = new List<GameObject>();
gameObjects.add(new GameObject(10,10,50,50));
gameObjects.add(new GameObject(20,10,20,50));
gameObjects.add(new GameObject(30,10,50,70));
gameObjects.add(new GameObject(40,10,90,50));
And to detect the collisions :
foreach (GameObject gameObject in gameObjects){
if (gameObject.DetectCollision(ball)){
//do something
}
}

Related

Agent stuck in loop MLAgents in Unity

Goal: The agent need to shoot red dots.
The agent shoots a ball that when it hits a red dot, it removes the dot and himself but when it hits an obstacle, only the ball disappear. (There's no bounce)
Example Level 1
The agent on the first level does really good, the problem is when i train on the other levels.
Example Level 2
Example Level 3 (Obstacles are moving left and right)
The agent does some success but after many episodes it gets stuck on loop, going left and right.
public class Capsule_ML : Agent
{
public GameObject sfera;
private int num, num_rossi; //tiri, numero rossi
public bool activate_shoot = false;
public Text num_sfere, punteggio, tempo_Rimanente;
//private float time_Left;
//private bool timer_Active;
public override void OnEpisodeBegin()
{
Episode_Debug.Episode += 1;
this.transform.rotation = Quaternion.Euler(Vector3.zero);
activate_shoot = false;
//timer_Active = true;
//time_Left = 60;
Active(this.transform.parent);
SearchRossiInParent(this.transform.parent);
punteggio.text = "#ROSSI: " + num_rossi;
num_sfere.text = "#SFERE: " + num;
}
//private void Update()
//{
// if (timer_Active)
// {
// time_Left -= Time.deltaTime;
// tempo_Rimanente.text = "Tempo Rimanente: " + time_Left + "s";
// if (time_Left <= 0)
// {
// timer_Active = false;
// TimeError();
// }
// }
//}
public void TimeError()
{
AddReward(-1.0f);
Episode_Debug.Fail += 1;
EndEpisode();
}
public override void CollectObservations(VectorSensor sensor)
{
}
public override void OnActionReceived(float[] action)
{
this.transform.Rotate(Vector3.back * action[0] * 60 * Time.deltaTime);
this.transform.Rotate(-Vector3.back * action[1] * 60 * Time.deltaTime);
if(UnityEditor.TransformUtils.GetInspectorRotation(this.transform).z < -90 || UnityEditor.TransformUtils.GetInspectorRotation(this.transform).z > 90)
{
AddReward(-1.0f);
Episode_Debug.Fail += 1;
EndEpisode();
}
RaycastHit2D hit = Physics2D.Raycast(this.transform.position, transform.TransformDirection(Vector3.down), Mathf.Infinity);
if (activate_shoot == false && hit.collider.tag == "red")
{
Debug.Log("Raycast colpisce " + hit.collider.name);
activate_shoot = true;
Debug.Log(activate_shoot);
Shoot();
//AddReward(1.0f);
}
//if (activate_shoot == false && action[2] == 1)
//{
// activate_shoot = true;
// Shoot();
//}
if ((num_rossi == 0 && num == 0) || (num_rossi == 0 && num > 0))
{
Episode_Debug.Success += 1;
AddReward(1.0f);
EndEpisode();
}
//if (num_rossi > 0 && num == 0)
//{
// Episode_Debug.Fail += 1;
// AddReward(-0.3f);
// EndEpisode();
//}
if (num < num_rossi)
{
Episode_Debug.Fail += 1;
AddReward(-1.0f);
EndEpisode();
}
Episode_Debug.ScreenText();
}
public void Shoot()
{
if (num > 0)
{
num -= 1;
num_sfere.text = "#SFERE: " + num;
GameObject clone = GameObject.Instantiate(sfera);
clone.transform.position = transform.position - transform.up * 1.0f;
clone.GetComponent<Rigidbody2D>().AddForce(-transform.up * 15.0f, ForceMode2D.Impulse);
}
}
public int GetCountRossi() //Numero Rossi Text
{
return num_rossi;
}
public void SetCountRossi(int x) //Numero Rossi Text
{
num_rossi = x;
}
//public void Shoot_Rosso() //check rosso colpito
//{
// AddReward(0.5f);
//}
public void Shoot_Error()
{
AddReward(-0.5f);
}
public void SearchRossiInParent(Transform parent) //Numero rossi iniziali nel livello e numero tiri
{
num_rossi = 0;
foreach(Transform red in parent)
{
if (red.gameObject.tag == "red")
num_rossi++;
}
num = num_rossi + 1;
}
public void Active(Transform parent)
{
foreach (Transform sphere in parent)
{
if (sphere.gameObject.tag == "red" || sphere.gameObject.tag == "blu")
sphere.gameObject.SetActive(true);
}
}
This is the code of the agent.
This is the .yaml config
behaviors:
Capsule_ML:
trainer_type: ppo
hyperparameters:
batch_size: 1024
buffer_size: 10240
learning_rate: 0.0004
beta: 0.005
epsilon: 0.2
lambd: 0.95
num_epoch: 5
learning_rate_schedule: linear
network_settings:
normalize: false
hidden_units: 128
num_layers: 2
vis_encode_type: simple
memory:
use_recurrent: true
sequence_length: 64
memory_size: 256
goal_conditioning_type: hyper
deterministic: false
reward_signals:
extrinsic:
gamma: 0.99
strength: 1.0
init_path: null
keep_checkpoints: 5
checkpoint_interval: 500000
max_steps: 500000
time_horizon: 64
summary_freq: 50000
threaded: false
self_play: null
behavioral_cloning: null
env_settings:
env_path: null
env_args: null
base_port: 5005
num_envs: 1
seed: -1
engine_settings:
width: 84
height: 84
quality_level: 5
time_scale: 20
target_frame_rate: -1
capture_frame_rate: 60
no_graphics: false
environment_parameters: null
checkpoint_settings:
run_id: TL1.1
initialize_from: null
load_model: false
resume: false
force: false
train_model: false
inference: false
debug: false
I'm using the RayPerception with these settings:
Settings
Tried to use a timer to end the episodes that gets stuck, but the agent is always in loop, even after many and many steps

Random Bug in Unity2D

I've been working on a project for the GMTK 2022 Game Jam recently, and I ran into a very strange problem. I have a dash that starts when you are moving and press space. It moves you in the direction of your velocity, then for a short time lets you move very quickly. It works perfectly fine in all cases, unless the direction you are moving is up and to the left, in which case, the if statement strangely won't trigger. I'm sure this is something idiotic, but I've been troubleshooting it for the last hour and it's been driving me insane.
// Update is called once per frame
void Update()
{
playerInputh = 0;
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
if (Input.GetKey("up"))
{
playerInputv = 1;
}
if (Input.GetKey("down"))
{
playerInputv = -1;
}
if (Input.GetKey("up") && Input.GetKey("down"))
{
playerInputv = 0;
}
Vector2 screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
//This is the dash that isn't working:
if ((Input.GetKeyDown(/*"right shift"*/"space")) && (playerInputh != 0 || playerInputv != 0))
{
Debug.Log("Dash");
//Vector2 transform2dposition = new Vector2(transform.position.x, transform.position.y);
m_Rigidbody.AddForce((m_Rigidbody.velocity) * 500f);
wJumpTimer = airControlAfterJump;
speed = maxSpeed*3.5f;
StartCoroutine(Roll());
}
}
void FixedUpdate()
{
//no moving while jumping!!!
if (wJumpTimer > 0)
{
wJumpTimer -= 1;
}
else
{
wJumpTimer = 0;
}
//move
if (playerInputh != 0 && playerInputv != 0) //make diagonals no super sayan
{
playerInputh *= moveLimiter;
playerInputv *= moveLimiter;
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
if ((playerInputh != 0 || playerInputv != 0) && speed < maxSpeed) //are we hitting the move buttons??
{
speed += acceleration;//accelerate
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
else
{
if (speed > 0f) //are we getting off the ride
{
speed -= deceleration; //decelerate
}
else
{
speed = 0f; //no funny buisness
}
}
m_Rigidbody.velocity = new Vector2(one_h * speed, one_v * speed); //actually move
}
void SetFace(int diceNumb)
{
rndr.sprite = sprites[diceNumb];
}
IEnumerator Roll()
{
Random diceNumb = new Random();
rndr.sprite = sprites[diceNumb.Next(0,5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
var newValue = diceNumb.Next(0, 5);
FaceValue = newValue + 1;
rndr.sprite = sprites[newValue];
}
How are your inputs setup? I am suspecting you have one key bound to multiple actions, like one key is set up as primary for an action and alternate for another action.
Personally I'd also stop using the assignment operators and increment instead. Instead of
playerInputh = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
you can do
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh += 1;
}
if (Input.GetKey("left"))
{
playerInputh += -1;
}
Net result is the same here - if you push both keys the result sums to zero, but the code is easier to read (IMO).
When you check things for key bindings also check alternates for space, because that's another one of the triggers you need to dash.

PONG Collision Need assistance

I have to make pong for a school assignment. Everything was going pretty well
until I came to the collision part. Can somebody maybe help me?
I am doing it in visual studios c#, and I am a beginner, so I don't understand a lot. I have tried a lot of different solutions, but none of them seems to have worked out.
public override void GameStart()
{
}
public override void GameEnd()
{
}
public override void Update()
{
float DeltaTime = GAME_ENGINE.GetDeltaTime();
//Frame Rate Unlock
if (GAME_ENGINE.GetKeyDown(Key.V))
{
bool isLocked = GAME_ENGINE.GetVSync();
GAME_ENGINE.SetVSync(!isLocked);
}
//Player 1 Movement
if (GAME_ENGINE.GetKey(Key.W) && m_PlayerY1 != 0)
{
m_PlayerY1 -= 250 * DeltaTime;
}
if (GAME_ENGINE.GetKey(Key.S) && m_PlayerY1 != 300)
{
m_PlayerY1 += 250 * DeltaTime;
}
if (m_PlayerY1 < 0)
{
m_PlayerY1 = 0;
}
if (m_PlayerY1 > 350)
{
m_PlayerY1 = 350;
}
//Player 2
if (GAME_ENGINE.GetKey(Key.Up) && m_PlayerY2 != 0)
{
m_PlayerY2 -= 250 * DeltaTime;
}
if (GAME_ENGINE.GetKey(Key.Down) && m_PlayerY2 != 300)
{
m_PlayerY2 += 250 * DeltaTime;
}
if (m_PlayerY2 < 0)
{
m_PlayerY2 = 0;
}
if (m_PlayerY2 > 350)
{
m_PlayerY2 = 350;
}
//Ball Stuff
Random RnD = new Random();
m_XBallSpeed = RnD.Next(2, 3);
m_YBallSpeed = RnD.Next(2, 3);
m_XBall += m_XBallSpeed;
if (m_XBall < 0)
{
m_XBallSpeed = -m_XBallSpeed;
}
else if (m_XBall + m_BallWidth > GAME_ENGINE.GetScreenWidth())
{
m_XBallSpeed = -m_XBallSpeed;
}
m_YBall += m_YBallSpeed;
if (m_YBall < 0)
{
m_YBallSpeed = -m_YBallSpeed;
}
else if (m_YBall + m_BallHeight > GAME_ENGINE.GetScreenHeight())
{
m_YBallSpeed = -m_YBallSpeed;
}
if (m_XBall >= m_PlayerHeight1 && m_YBall >= m_PlayerHeight2)
{
m_XBallSpeed += 1;
m_YBallSpeed += 1;
m_XBallSpeed = -m_YBallSpeed;
}
if (m_YBall >= m_PlayerWidth1 && m_YBall >= m_PlayerWidth2)
{
m_XBallSpeed += 1;
m_YBallSpeed += 1;
m_XBallSpeed = -m_YBallSpeed;
}
}
public override void Paint()
{
//Player 1 and 2 and Ball
GAME_ENGINE.SetColor(255, 255, 255);
GAME_ENGINE.FillRectangle(m_PlayerX1, m_PlayerY1, m_PlayerWidth1, m_PlayerHeight1);
GAME_ENGINE.FillRectangle(m_PlayerX2, m_PlayerY2, m_PlayerWidth2, m_PlayerHeight2);
GAME_ENGINE.FillRoundedRectangle(m_XBall, m_YBall, m_BallWidth, m_BallHeight, 50, 50);
}

Can't get my collision to work (platformer) XNA

I'm learning XNA right now and i'm pretty new to programming in general. I'm making a platformer now but when I walk into a platform from left or right I get teleported to the top of the platform. The collision is only working with the last platform added to the platform list.
This is in Game class:
LoadContent:
for (int i = 0; i < 3; i++)
{
platform0List.Add(new Platform0(new Vector2(70 + (i * 300), 400), platform0Texture));
}
Update:
protected override void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
player.Update(keyboard, keyboardPrev, platform0List);
foreach (Platform0 platform in platform0List)
{
if (!Move_Free(player.position.X, player.position.Y + player.gravity, player.texture.Width, player.texture.Height, platform.rectangle) && player.gravity >= 0)
{
player.ground = true;
if (player.position.Y + player.texture.Height + player.gravity > platform.position.Y)
{
player.position.Y = platform.position.Y - player.texture.Height;
}
else if (player.position.Y + player.texture.Height + player.gravity < platform.position.Y)
{
player.gravity = platform.position.Y - player.texture.Height;
}
break;
}
else
{
player.ground = false;
}
}
if (keyboard.IsKeyDown(Keys.Escape)) this.Exit();
keyboardPrev = keyboard;
base.Update(gameTime);
}
This is my Move_Free method
public static bool Move_Free(float x, float y, int width, int height, Rectangle rectangle)
{
Rectangle rect = new Rectangle((int)x,(int)y,width,height);
if(rect.Intersects(rectangle))
{
return false;
}
else
{
return true;
}
}
This is in Player class
foreach (Platform0 platform in platform0List)
{
if (keyboard.IsKeyDown(Keys.Right) && Game1.Move_Free(position.X + 5, position.Y, texture.Width, texture.Height, platform.rectangle))
{
moveRight = true;
}
else if (keyboard.IsKeyDown(Keys.Right) && ((position.X + texture.Width - platform.position.X) * -1) > 0)
{
position.X += (position.X + texture.Width - platform.position.X) * -1;
}
else
{
moveRight = false;
}
if (keyboard.IsKeyDown(Keys.Left) && Game1.Move_Free(position.X - 5, position.Y, texture.Width, texture.Height, platform.rectangle))
{
moveLeft = true;
}
else if (keyboard.IsKeyDown(Keys.Left) && position.X - (platform.position.X + platform.texture.Width) > 0)
{
position.X -= position.X - (platform.position.X + platform.texture.Width);
}
else
{
moveLeft = false;
}
}
if (moveRight) position.X += 5;
if (moveLeft) position.X -= 5;
if (keyboard.IsKeyDown(Keys.Up) && ground)
{
gravity = -10;
ground = false;
}
if(ground)
{
gravity = 0;
}
else
{
gravity += 9.8f / 60f;
position.Y += gravity;
}
Each iteration of your forloop overwrites your moveLeft and moveRight variables.
Therefore, only the last platform values will remain.

How to create time intervals between states in an FSM

I would like to create a timer interval between the execution of a state in an FSM.
What I have at the moment is pretty basic as I'm still quite new to programming. It'd be great if you could keep any possible solutions to around a basic level.
public override void Execute()
{
//Logic for Idle state
if (dirRight)
oFSM.transform.Translate(Vector2.right * speed * Time.deltaTime);
else
oFSM.transform.Translate(-Vector2.right * speed * Time.deltaTime);
if (oFSM.transform.position.x >= 2.0f)
dirRight = false;
else if (oFSM.transform.position.x <= -2.0f)
dirRight = true;
//play animation
//Transition out of Idle state
//SUBJECT TO CHANGE
float timer = 0f;
timer += Time.time;
if (timer >= 3f)
{
int rng = Random.Range(0, 5);
if (rng >= 0 && rng <= 1)
{
timer = 0;
oFSM.ChangeStateTo(FSM.States.AtkPatt1);
}
else if (rng >= 2 && rng <= 3)
{
timer = 0;
oFSM.ChangeStateTo(FSM.States.AtkPatt2);
}
else if (rng >= 4 && rng <= 5)
{
timer = 0;
oFSM.ChangeStateTo(FSM.States.AtkPatt3);
}
}
}
You need to use Coroutines, and use the method WaitForSeconds.
Then you can do something like this:
private float timeToWait = 3f;
private bool keepExecuting = false;
private Coroutine executeCR;
public void CallerMethod()
{
// If the Coroutine is != null, we will stop it.
if(executeCR != null)
{
StopCoroutine(executeCR);
}
// Start Coroutine execution:
executeCR = StartCoroutine( ExecuteCR() );
}
public void StoperMethod()
{
keepExecuting = false;
}
private IEnumerator ExecuteCR()
{
keepExecuting = true;
while (keepExecuting)
{
// do something
yield return new WaitForSeconds(timeToWait);
int rng = UnityEngine.Random.Range(0, 5);
if (rng >= 0 && rng <= 1)
{
oFSM.ChangeStateTo(FSM.States.AtkPatt1);
}
else if (rng >= 2 && rng <= 3)
{
oFSM.ChangeStateTo(FSM.States.AtkPatt2);
}
else if (rng >= 4 && rng <= 5)
{
oFSM.ChangeStateTo(FSM.States.AtkPatt3);
}
}
// All Coroutines should "return" (they use "yield") something
yield return null;
}

Categories