I am writing code for a version of "Flappy Bird". I am trying to produce a start menu, end menu, and difficulty menu. So far I have been successful with the start and end, but am struggling with the difficulty menu to show. I believe my code is also very messy and would like to tidy it up, but not sure where to start.
I tried adding boolean "diff" and including that as false in my arguments in the mousePressed method.
void mousePressed() {
//START MENU
if (menu==true&&end==false) {
if (mouseX > 175 && mouseX < 625 && mouseY > 500 && mouseY < 600) {
menu = false;
end = true;
}
if (mouseX > 175 && mouseX < 625 && mouseY > 650 && mouseY < 750) {
diff();
}
}
//GAMEPLAY
if (menu==false&&end==true) {
b.bounce();
}
//END MENU
if (menu==false&&end==false) {
if (mouseX > 200 && mouseX < 600 && mouseY > 500 && mouseY < 600) {
restart();
b.bounce();
}
if (mouseX > 200 && mouseX < 600 && mouseY > 650 && mouseY < 750) {
startMenu();
}
}
}
I expected the output to show the difficulty menu, but it only showed the difficulty menu for one frame, then snapped back to the start menu.
I'm assuming your diff() function draws the difficulty menu. I'm also assuming you have a draw() function that draws things depending on your game's current state (menu, game, end menu, etc...).
The problem is that you're drawing your difficulty menu once, when the mouse is pressed on the difficulty button, and then it's being immediately overdrawn by draw().
In programs that draw continuously (like with draw()), whenever you want to show something for more than one frame, you need to draw it each frame (i.e. in draw()).
The solution is to add a "difficulty menu" state. Your draw() function would then work something like this:
void draw() {
if (menu && !diff && !end) {
drawMenu();
} else if (!menu && diff && !end) {
diff();
} else if (!menu && !diff && end) {
//Why do you draw the game when end is TRUE?
drawGame();
} else if (!menu && !diff && !end) {
//Why do you draw the end menu when end is FALSE?
drawEndMenu();
}
}
You would, of course, need to modify the mousePressed() function as well.
You also said that you feel your code is messy. This is a type of code smell; Whenever somethings feels "wrong" when you're programming, it often means there's a better way to do it. It's good that you noticed this.
Firstly, your function names are a bit non-descriptive: Instead of diff(), I recommend something like drawDiffMenu(). Rule of thumb: Function names should almost always be verbs.
Secondly, you shouldn't be handling gamestate with a bunch of booleans; Since you can only have one state at a time, you should only have one variable. (If you ever need a state-inside-a-state, make another variable.) Best way to do that is with enums!
Example:
enum GameState {
MENU, GAME, DIFF_MENU, END
}
GameState gameState = GameState.MENU;
//...
void draw() {
// Google "java switch statement"
if (gameState == GameState.MENU) {
drawMenu();
} else if (gameState == GamesState.DIFF_MENU) {
drawDiffMenu();
} else if...
// Etc...
}
A nitpick: Calling b.bounce() after restart() is a bit odd, since in theory that bounce should be a part of your game starting.
Happy coding!
Related
So, I want to implement dodging which is something like a dash in a direction. It works pretty simple - if you move in a direction and press the button the character dodges there. The velocity should not matter for this, so that the dodging speed is always the same, no matter if you are running or standing and then pressing a direction + dodging. I've got something that seems to work but there are still problems left. It seems like that diagonal dodging is a bit too far in comparison to horizontal/vertical dodging and I tried to fix this. But I'm still not sure if it worked or not. In practice the character dodges and stuff but something still seems off, like it works pretty good with a controller but sometimes it's still wacky when using keyboard after standing still and then using dodge. The thing is - I'm not sure if the code I have is the best I could have or if there are still problems.
A good example of how it should work would be the dodging in Rune Factory 4.
Edit: If the problem lies in the Input Settings I could show them.
if (IsDodging == false)
{
Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
if (input.sqrMagnitude > 1) input.Normalize();
if (Input.GetButtonDown("Jump"))
{
// Jumping stuff I blended out
}
else if (Input.GetButtonDown("Block/Dodge") && input.x != 0 || Input.GetButtonDown("Block/Dodge") && input.z != 0) // To activate dodging
{
if (Time.time > Time_Start + DodgeCooldown) // Checks the cooldown
{
Time_Start = Time.time;
IsDodging = true;
dodge_direction = input;
if (dodge_direction.x > 0) { dodge_direction.x = 1; } // To fixate the distance traveled when dodging while ignoring how fast you are
if (dodge_direction.z > 0) { dodge_direction.z = 1; }
if (dodge_direction.x > 0 && dodge_direction.z > 0) { dodge_direction.Normalize(); } // To prevent diagonal dodging distance from becoming too big
}
}
else
{
// Walk.
transform.position += input * run_speed * Time.deltaTime;
}
}
else
{
transform.position += dodge_direction * dodge_distance;
distance_traveled += Vector3.Distance(transform.position, dodge_direction * dodge_distance) * Time.deltaTime;
if (distance_traveled > dodge_distance)
{
IsDodging = false;
dodge_direction = Vector3.zero;
distance_traveled = 0;
}
}
I have simple pop-up text animator with four attached animations (heal text animation, crit heal animation, damage animation and crit damage snimation).
The animator changes animations on a trigger received from a simple script.
public static void PopUpTextInstantiator(int text, Transform location, bool crit)
{
Initialize();
Debug.Log("Instancing POPUP with VALUE" +text +" and CRIT is "+ crit);
PopUpText instanceclone = Instantiate(popupText);
Vector2 screenPosition = new Vector2(location.position.x + Random.Range(-.5f, .5f), location.position.y + Random.Range(0.1f, 0.5f));
instanceclone.transform.SetParent(canvas.transform, false);
if (text < 0 && crit == true)
{
instanceclone.GetComponentInChildren<Animator>().SetTrigger("CritDamage");
Destroy(instanceclone, 1.2f);
}
else if (text < 0 && crit == false)
{
instanceclone.GetComponentInChildren<Animator>().SetTrigger("Damage");
Destroy(instanceclone, 1.2f);
}
else if (text > 0 && crit == false)
{
instanceclone.GetComponentInChildren<Animator>().SetTrigger("Heal");
Debug.Log("IM WORKING POPUP INSTANTIATOR NON CRIT");
Destroy(instanceclone, 1.2f);
}
else if (text > 0 && crit == true)
{
instanceclone.GetComponentInChildren<Animator>().SetTrigger("CritHeal");
Destroy(instanceclone, 1.2f);
}
//Debug.Log("Instancing POPUP at COORD VALUE" + location.transform.position);
//instanceclone.transform.position = screenPosition;
instanceclone.transform.position = screenPosition;
instanceclone.SetText(text);
}
There is problem SOMETIMES (not always but quite often) where the animation (especially "hea animation") just doesn't shown up. I see instanced parent but no animation. Same problem in the build. Crit Heal animation is always shown correctly, damage some times doesn't show, and simple Heal doesn't show very often. I just don't understand why and where the error is - the script is essentially the same. The animation by itself is working perfectly.
Context
I am making a mobile game in which the player is required to touch objects in a specified order. The correct order is determined in a List called clickOrder. To determine the current object the player is supposed to click, currClickIndex is used.
Problem
When touching a correct object, the debug text will display "Correct" for a split second, and will then immediately change to "Wrong." What I am unsure about is why both the if and else blocks are executed when only touching a single object.
Code
void Update()
{
if (Input.touchCount == 1)
{
if (this.enabled)
{
Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
if (hit != null && hit.collider != null)
{
// check if the touched object is the correct one
if (hit.collider.gameObject == clickOrder[MyData.currClickIndex])
{
debug.text = "Correct";
MyData.currClickIndex++;
}
else
{
debug.text = "Wrong";
}
}
}
}
}
As soon as the correct object is being touched, you do this:
MyData.currClickIndex++;
which moves you forward in the ordered sequence, and from then on, the previously correct object is not correct anymore. But you're still touching it.
If you want to avoid this, you need to move forward in the sequence after you've touched the correct object.
if (there are touches and the correct object is being touched)
{
set a flag;
}
else if (a flag has been set)
{
MyData.currClickIndex++;
reset the flag;
}
Please Guys help, I am new to Unity and programming:
I have a two Bouncing Ball, tag as BouncingBall1 and BouncingBall2, I want when a bullet hit both to destroy and if the time have not exceeded displaySecond and you have destroy the balls you win, but my problem is the OnCollisionEnter is not working. The part of wining is not working the rest are, my code fragment is below.
function OnCollisionEnter(col.collision) {
if ((displaySecond < 30) && (
col.gameObject.tag ==
BouncingBall1 == null &&
col.gameObject.tag ==
BouncingBall1 == null)) {
print("You have won");
}
}
col.gameObject.tag == BouncingBall1 == null
I think the problem is with the way you check if an object is destroyed. This isn't the way to do it. Also, you're checking if two identical lines of code are identical. So this will always return true if the display second is lower than 30.
Try changing it to
if ( (displaySecond < 30) &&
(col.gameObject.tag == "BouncingBall1") ) {
Debug.Log("You have won!")
}
It sounds like you want keep track of whether each ball has been destroyed and display "You have won" when both have been destroyed. This code is a little crude but should achieve this:
var ball1Destroyed = false;
var ball2Destroyed = false;
...
function OnCollisionEnter(col : Collision) {
if (col.gameObject.tag == "BouncingBall1") {
ball1Destroyed = true;
}
if (col.gameObject.tag == "BouncingBall2") {
ball2Destroyed = true;
}
if (displaySecond < 30 && ball1Destroyed && ball2Destroyed) {
Debug.Log("You have won");
}
}
This code assumes that the only collisions will be between bullets and balls (not between one ball and another), this can be done with collision layers.
I am making a 2D game in unity that has an underwater theme. To make it look really pretty, I use a script to spawn glowy objects at random locations in the map. These objects are blank sprites with Particle Systems attached to them.
The problem is, I have about 100 of them active in the map at a time, and though it looks really pretty, the game lags on computers that don't have an i5 processor or faster.
The solution I thought of was to disable the objects while they are out of camera bounds so there is only about 4 or 5 active at a time...
Here's my script:
void Update () {
if (this.transform.position.x < Camera.main.transform.position.x + 13 && this.transform.position.x > Camera.main.transform.position.x - 13 && this.transform.position.y < Camera.main.transform.position.y + 13 && this.transform.position.y > Camera.main.transform.position.y - 13) { this.gameObject.particleEmitter.emit = true;
this.gameObject.particleSystem.Play ();
}
else {
this.gameObject.particleSystem.Pause ();
}
}
Ok, it checks if the object is outside the camera bounds correctly, but when it comes to disabling the object, I get this error:
"NullReferenceException: Object reference not set to an instance of an object"
You use both particleEmitter, which refers to the legacy particle system, and particleSystem, which refers to the new Souriken system. You're probably only using Souriken particles, so I would rewrite it like this:
void Update ()
{
if (this.transform.position.x < Camera.main.transform.position.x + 13
&& this.transform.position.x > Camera.main.transform.position.x - 13
&& this.transform.position.y < Camera.main.transform.position.y + 13
&& this.transform.position.y > Camera.main.transform.position.y - 13)
{
particleSystem.Play ();
}
else
{
particleSystem.Pause ();
}
}