I'm trying to make a simple game where there's a zombie horde coming from the top of the screen to the bottom. I want that a new zombie appears every 5 seconds, and it does, but every time a new zombie appears the previous one stops moving and the collision doesn't work on that one. Can someone help me understand this behaviour and what's the best way to make it work the way its supposed to? :)
Here is my where I create the zombie:
private void CreateZombie()
{
zombieSprite = new CCSprite ("zombie");
zombieSprite.PositionX = CCRandom.GetRandomFloat (10, 600);
zombieSprite.PositionY = 1055;
AddChild (zombieSprite);
}
and here's the code inside my gamelogic method:
void GameLogic (float frameTImeInSeconds) {
zombieYVelocity += frameTImeInSeconds * -gravity;
zombieSprite.PositionY += zombieYVelocity * frameTImeInSeconds;
if (timer % 5 == 0) {
CreateZombie ();
zombieYVelocity = 0;
}
}
I attached a screenshot that shows whats happening
Every 5 seconds when a new one is added the previous one stops, and the collision detection is no longer working with the ones that are stoped.
Related
I want to make countdown timer that will return value of bool when he is active , so I can check on other script if is active give double points if is not then you need to give normal points..
I want to make it more complicated and I want to add time on timer if the timer is active, if is not then we use default time on countdown...
I don't know how to use courutine specially when I need to add time if the timer is not over..
Lets say like a example:
I pick up power up and timer starts for 5 seconds counting to 0.
If i pick up again powerup and timer is on lets say 3 , Power up need to have now 8 seconds. When powerup is over he must go from 5 seconds when player pick up new one..
Here is my code that doesn't work how I want also my code doesn't have a function to add time to power up when power up is active.. In other words I don't know how i can check if powerup is active and if yes just to add to counter 5 more seconds..
Here is code that doesn't contain adding time it only contains working counter..
void startDoublePoints()
{
StartCoroutine("doublePoints");
Time.timeScale = 1;
}
//Simple courutine
IEnumerator doublePoints()
{
while (true)
{
yield return new WaitForSeconds(1);
timeLeft--;
}
}
I hope someone will explain me more about how I can achieve my goal.. I hope I explained what I need to achieve.. If you do not understand something please ask on comment and I will try to explain it again..
Thank you so much community I don't know how would I learn anything without this great place :)
float powerUpTimer;
bool isDoublePoints = false;
void Update()
{
// Check timer only when Power up time
if(isDoublePoints)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
if(powerUpTimer <= 0)
{
// End of power up time
isDoublePoints = false;
powerUpTimer = 0;
}
}
}
// Add any time player picks to timer
public void OnPickPowerUp(float buffTime)
{
isDoublePoints = true;
powerUpTimer += buffTime;
}
Please look at example - http://www.mathplayground.com/mancala.html
Can anyone suggest the logic to :
1) spawn objects at positions
2) Pick up all objects on click and distribute them one by one.
3) Is it better to create all objects or instantiate them on the fly. ?
I tried code below but it just instantiates all objects at once.
if (HoleHandler.gemCount_Hole1_Update_Flag == true)
{
foreach (GameObject g in gemList1)
{
Destroy(g);
//want to add a time delay of 2 secs here
}
if (gemCount_Hole1 > 0)
{
for (int i = 0; i < gemCount_Hole1; i++)
{
int Gem_prefabIndex = UnityEngine.Random.Range(0, 9);
gemList1.Add(Instantiate(Gem_prefabList[Gem_prefabIndex], new Vector2((xPos_Hole1 + (Random.Range(-20, 20))) * 2.0F, (-229 + (20 * i))), Quaternion.identity));
}
}
}
I'm not 100% sure of what you're trying to achieve but I will answer as best I can.
For a start, any gameobject you are going to be instantiating (spawning) at run time should ideally be done so from a prefab.
Secondly, to spawn them at random intervals you want to be checking if they should be spawned at different time frames. This can be achieved through a co-routine or the Update function. I would recommend Update if this is new to you.
Update is called every frame.. and it's with this that you can achieve timed events. You can use a variety of helper methods to determine the time since the last frame or the real time elapsed.
For example
public class MyGameObject : Monobehaviour {
void Start() {
//This is called first, use it to set up whatever you want.
}
void Update() {
//This will be called every frame.
//Each frame or time lapse will determine if I should spawn
// a new gameobject.
}
}
Update
After looking at the game you have linked in your post I can offer the following advice.
Something like the following may point you in the right direction.
public int[] gemsInCups = new int [] {4,4,4,4,4,4,0,4,4,4,4,4,4,0};
public void Distribute(int position){
int gems = gemsInCups[position];
for(int i = position + 1; gems > 0; i++){
gemsInCups[position] ++;
gems --;
//Check the end of the array has not been reached.
//If it has, start distributing again from the first position provided
// there are still gems to distribute.
}
}
You will need some additional logic to finish this.
What you should remember is, I usually find it much more manageable keeping my data and my view (gameobjects) under different scopes... but the view will change to reflect the data and does not directly alter it. Now you know how many gems there are in each cup, you can simply update this each frame.
Object is forced up. After 10 seconds, object will be forced back down. Alternatively, object can be clicked and thereby forced back down before 10 seconds has elapsed.
What is currently happening: If object is forced down, GAME OVER.
What I am trying to do instead: If object is forced down before you are able to click it, GAME OVER.
In other words, the GAME OVER is being shown in 10 seconds, regardless of whether or not the object was clicked.
I'm having a really difficult time with this logic and I am hoping a fresh perspective might be able to help.
public void FixedUpdate() {
// Increase the kick timer
kickTimer += Time.fixedDeltaTime;
// If the next kick time has came
if (nextKick < kickTimer) {
// Schedule the kick back corresponding to the current kick
nextKickBacks.Enqueue (nextKick + 10f);
// Apply the kick force
rb.AddForce (transform.up * thrust, ForceMode.Impulse);
// Plan the next kick
nextKick = kickTimer + Random.Range (MinKickTime, MaxKickTime);
}
// If there are more kick backs to go, and the time of the closest one has came
if (0 < nextKickBacks.Count) {
if (nextKickBacks.Peek () < kickTimer) {
// Apply the kick back force
rb.AddForce (-transform.up * thrust, ForceMode.Impulse);
// Show the GAME OVER gameObject
GameObject.Find ("icetextureONfile").transform.localScale = new Vector3 (0.02f, 0.02f, 0.02f);
// Dequeue the used kick back time
nextKickBacks.Dequeue ();
}
}
}
void OnMouseDown()
{
rb.AddForce(-transform.up * thrust,ForceMode.Impulse);
}
}
You need to add the logic for what happens when you click on the object. Right now you are applying force, but there is nothing in the code changing the state of the Update loop.
I don't know what type of game you are making. So I am not sure what you want to do when the click is executed, but I am guessing you want to reset the kickbacks.
In that way you can do something like this. Change .Clear() to whatever method suits your needs.
void OnMouseDown()
{
rb.AddForce(-transform.up * thrust,ForceMode.Impulse);
nextKick = 0; // reset timer to force a new kick to be set next frame
nextKickBacks.Clear(); // clear current set kickbacks
}
I am having a big struggle implementing a collision detect on a list of bricks.
I have a game which randomly drops bricks that are supposed to stack up at the bottom of the screen. I managed to make them stop at the bottom of the screen but they don't stack.
I have this in my update function:
if (r.Next(0, 50) == 8)
{
_bricks.Add(new NormalBrick(this, new Vector2(r.Next(0, 700), 100)));
}
foreach(Brick b in _bricks)
{
b.move(GraphicsDevice.Viewport);
}
My move() function has the following code:
public void move(Viewport viewport)
{
if (_position.Y == (viewport.Height - _texture.Height ))
{
_position = new Vector2(_position.X, _position.Y);
}
else
{
_position = new Vector2(_position.X, _position.Y + _speed);
}
}
How can I make sure that the bricks don't all stop at the bottom of the screen, instead the brick has to check if there is a brick beneath it?
I have checked other questions on here but I couldn't find my answer and I have tried several things to get it fixed. Any help would be appreciated.
I would create Rectangles for each of your Bricks (unless you have already done so). Then in the Update() method, use something like brick.Rectangle.Intersects(anotherBrick) after movement. If true, then position the current brick above the intersecting bottom brick.
Make sure to move the brick's rectangle each time the brick moves.
I hope this helps. Let me know if you require any further assistance.
I have a real brain teaser right here and I can't figure out what I am doing wrong since the code looks absolutely normal.
Little background information:
Since I've started working in the XNA/MonoGame environment for about 2 days now I wanted to start off with something easy. I'm currently building an astroid defender like game, and I'm working on a collision check. Before I even got to the collision, I found that I got a rather odd null reference while im using a for loop to loop through all enemies inside a list. The list however is in another class.
Upon startup I initizalize a SpawnManager class that immediately creates 20 enemies when the class has been made like so:
class SpawnManager
{
//Draw
ContentManager myContentManager;
//Enemies
public List<Enemy> enemy = new List<Enemy>();
public void LoadContent(ContentManager theContentManager)
{
myContentManager = theContentManager;
for (int i = 0; i < 20; i++)
{
Enemy newEnemy = new Enemy(new Vector2((800 / (20 + 1) * i + 16.5f), 20), 500, 50, 25, 10, 2500, 100, 1, 3, 2, false);
newEnemy.LoadContent(myContentManager);
enemy.Add(newEnemy);
}
}
Then whenever I fire a bullet with my spaceship, it will create a bulletclass like so:
public class Bullet : PlayerScript
{
//Enemy enemy;
SpawnManager spawnManager;
PlayerScript playerScript;
private Texture2D _bullet;
private Rectangle _hitBox;
public float xPos = 0;
public float yPos = 0;
public bool isActive = false;
public void LoadContent(ContentManager theContentManager)
{
_bullet = theContentManager.Load<Texture2D>("Graphics/citem");
_hitBox = new Rectangle(0, 0, _bullet.Width, _bullet.Height);
}
public void Update(GameTime gameTime)
{
//Movement.
yPos -= 13.5f;
//Collision.
for (int i = 0; i < spawnManager.enemy.Count; i++)
{
//Console.WriteLine(spawnManager.enemy.Count);
}
}
When while im holding space to fire bullets, I immediately get a null reference error, hightlighting the for loop part. I've read some posts on the internet saying that the Enemy List might be null or empty, but even if that is the case, that shouldn't really matter as my code structure goes as follows:
Game1 Initialize -> add SpawnManager -> add Enemies + push them in the Enemy list.
So when the enemies are on the screen, they are basically already added to the Enemy list and the List shouldn't be null or empty.
Also, might there be an easier or more efficient way to check for collision? Because everytime I'm creating a bullet, a bullet.Update script will start looping through all enemies like a madman until it reaches an enemy, checking which enemy it is, applying changes to it and adding itself to a pool. (Ofcourse when its in the pool I wont update the Bullet script). Since this astroid defender is more like a little bullet hell, shooting 100 bullets per few seconds, will cause a lot of looping in total. I just came over to XNA / MonoGame C# after spending 1.5 years in Unity, and in Unity everything seems so simple, OnCollisionEnter ftw! :)
Still, I'm pretty sure its a total ID-10-T error on my side, but I just cant wrap my head around it, any help would be gratefully appreciated :)
P.S: If anything is stated unclear, I'd be glad to edit this question!