Lesson 22 Space Game for Student - Laser Shutting Down his Game Too Early

[Posts in the debugging category need to have the following pieces of information included in order to help other teachers or our moderator team best help you. Feel free to delete everything in brackets before posting your request for debugging help.]

Link to the project or level: [https://studio.code.org/projects/gamelab/ztm3436Zv0ok7OSp1hGiUZMdqx0lf2LAEUZ6C50OKLY]

What I expect to happen: [

The player tries to to AVOID a laser that bounces off a ‘blank’ sprite (placed at 0, 200 at the very top of the background) to send it back toward the player. He or she has to ‘evade’ the laser in order to avoid loss of lives. If player is hit by the laser or an enemy ship they lose a life.

What we expect to happen is a normal speed of the laser bounce back rate which allows the player to have a chance at getting away and having a chance to play a spaceship game.

Please Note: As the student clicks to enter the game, the ‘space’ key fires the laser to hit the moving enemy spaceships for points.
]

What actually happens: [If you click play to enter the game, press ‘space’ to fire the lasers, and if un-comment out the code which I have inactivated… in order to help this student debug his issues — you can see any type of code to remove ONE life based on the laser hitting the player crashes the game. Instead of it taking away just ONE life as it should, any attempt for this lives = lives -1; causes GAME OVER instantly. We have not found any way to place it into the code without it crashing the game.]

What I’ve tried: [
function playerExplosion() {

laser1.bounceOff(blank);

if(player.isTouching(laser1)){
lives = lives-1;
playSound(“sound://category_explosion/8bit_explosion.mp3”, false);
resetPlayer();
}

if(player.isTouching(enemy1)){
lives = lives -1;
playSound(“sound://category_explosion/8bit_explosion.mp3”, false);
resetPlayer();
}

if(player.isTouching(enemy2)){
lives = lives -1;
playSound(“sound://category_explosion/8bit_explosion.mp3”, false);
resetPlayer();
}

if(player.isTouching(enemy3)){
lives = lives -1;
playSound(“sound://category_explosion/8bit_explosion.mp3”, false);
resetPlayer();
}

if(player.isTouching(enemy4)){
lives = lives -1;
playSound(“sound://category_explosion/8bit_explosion.mp3”, false);
resetPlayer();
}
}

function resetPlayer() {
player.x = randomNumber(50,350);
player.y = 300;
}
]


Please Note Relevant Code in Program (not in any particular order – but just for your information)

The main sprite is labeled 'player’

// This is the blank sprite in the background at the top which bounces the laser
var blank = createSprite(200,0);
blank.setAnimation(“blanks”);
blank.setCollider(“rectangle”);

//This is the laser related code here
var laser1= createGroup();
var laser1Index = 0;
laser1.add(createSprite(player.x,player.y));
laser1.setColliderEach(“circle”);
laser1.setVisibleEach(false);
laser1.setAnimationEach(“laserUp”);
laser1.setWidthEach(5);
laser1.setScaleEach(0.6);

function Laser1(){
if (keyDown(“space”)) {
laser1.setVisibleEach(true);
laser1.add(createSprite(player.x, player.y));
laser1.setAnimationEach(“laserUp”);
laser1Index = laser1Index + 1;
laser1.get(laser1Index).velocityY = -10;
playSound(“sound://category_projectile/retro_game_weapon_-laser_shot_single.mp3”, false);
} if (laser1.y < 0){
laser1.setVisibleEach(false);
}
}

//Game over code
function gameover() {
if (lives <= 0) {
player.visible = false;
enemy1.visible = false;
enemy1.velocityX = 0;
enemy2.visible = false;
enemy2.velocityX = 0;
enemy3.visible = false;
enemy3.velocityX = 0;
enemy4.visible = false;
enemy4.velocityX = 0;
loser.visible = true;
loser2.visible = true;
fill(“yellow”);
textSize(17);
background(“black”);
fill(“red”);
textSize(50);
text(“Game over”, 100, 200);
}
}

//The player starts out with three lives
var lives = 3;

Hi @faithdwsn,

It looks like your students are doing fabulous through this difficult time. What a great game!

So, if I understand the issue correctly, the laser and player are always touching because laser1 begins at player.x and player.y. So, the game instantly ends. To solve the problem, it seems like you just need to create a 2nd laser to shoot back at the player after it hits the blank. You’ll need to reset that laser as soon as it hits the player so the game doesn’t end too quickly. There may be some other nuances that need tweaking. Here is a very rough example.

Best wishes,
Michelle

Michelle, thank you for your help. I really like the code because it worked. We will use it for the time being! :slight_smile:

However, it appears to get it across the entire page, we would have to meticulously place laser sprites all across the page such as laser2, laser3, laser4, laser5, laser6, laser 7, etc. in order for its effect of bouncing back on the player to span the breadth of the entire top of the page. As it is in the example, the only location where the bounce back effect will take place is (200,-50). If the player moved anywhere else on the page, the laser2 would not bounce back.

So, rather than create a ton of laser sprites manually across the top of the page. I attempted to create a second laser 2 group.

Please see this remix code here: https://studio.code.org/projects/gamelab/vytZdEMcKXT53sNgIae7SHbzJud9P_R_xGoqftGDxuQ

It worked to create numerous random sprites in differing locations across the top of the page. However, the issue is that they are ALL triggered at once as soon as the laser1 hits the blank. Rather than just one falling laser2 from the index being triggered. Do you know of a way to get the index of the group to just let down one laser2 at a time instead of sending a giant stream of a group of laser2 sprites?

I hope that question makes sense.


Beyond the code you already see present in the remix, additionally below is what I have tried to debug and fix it so far.

Trial 1:

What I’ve Tried: laser2Index = laser2Index ++;

Instead of just laser2Index = laser2Index +1;

Result: It just brings down one laser and then it stops, plus if the ship hits that one laser the game ends immediately.

Trial 2:

I have tried using ‘for’ loops…

var laser2= createGroup();

for (var i=0; i<10; i++){

laser2.add(createSprite(randomNumber(25,350),-50));

laser2.setColliderEach(“circle”);

laser2.setVisibleEach(false);

laser2.setAnimationEach(“laserUp”);

laser2.setWidthEach(7);

laser2.setScaleEach(1.1);

}

Then I tried call the laser2.setVisibleEach(true); inside the Laser2() function.

Result: The second laser was not bouncing back or showing up. I was hoping to get at least 10 rounds of lasers that can be shot and returned instead of just one laser that stops. No laser2 would bounce back at all using the for loop method, I think I may have coded it wrong somewhere.

The Goal: To get the laser2 sprite to bounce back at the top of the page anywhere from the range of x-axis 50-350 without having to create a bunch of additional sprites. Or trying to create the illusion of a laser bouncing back at all areas of the top of the page for the player without having to individually create sprites at all those locations. Goal is to use some kind of group or for loop method to generate the sprites across the page for the student automatically.

@faithdwsn

There are probably many ways to solve the problem. When I look at the problem, my brain can’t wrap around the group for laser2 but that’s simply because I haven’t used it much before. So, the first issue was sending the laser2 back anywhere across the top. I saw that “blank” didn’t span the entire width of the top. Not sure if that was intentional but based on your primary issue, I increased the scale and width of blank so TRUE was generated for the ifTouching anywhere across the x axis. I had to remove the grouping. Again, not because it is “wrong” but just to wrap my brain around it. I then set the x of laser2 to the x of the laser1. This makes it very difficult to stay alive if you shoot many lasers so not sure it is the best solution. Here is my attempt.

We can certainly get others’ brains on this if you like. Let us know.

Michelle

Thank you Michelle, I will try to work off of the code you sent me. When I tried the simulation link, after shooting one laser it went to game over after the first hit. It did not allow three laser2 hits upon bounce back.

However, with some coding adjustments, the ideas you shared worked really well to move the debugging forward! Here are the latest additional efforts:


PS: I took your good advice and increased the size of the ‘blank’ sprite in the animation Image panel so the image itself is now 400 pixels wide. That is why the code doesn’t show blank.width = 400.

Your laser2.x = player.x idea also worked to position the laser2 to bounce back any where across the top of the page without having to create multiple sprites.

Link to the project or level:

What I’ve Tried:

function Laser2() {
if ((laser1.isTouching(blank)) && (laser2.velocityX <= 0)) {
laser2.velocityY = 10;
laser2.visible = true;
console.log(“Laser2isComingDown”);
}

if (laser2.isTouching(player) || laser2.y > 450) {
laser2.velocityY = 0;
laser2.y = -50;
console.log(“Laser2isErased”);
}
}

function playerExplosion() {

if(player.isTouching(laser2)){
console.log(“WARNING!PlayerIsTouchinglaser2”);
lives = lives-1;
//resetPlayer();
}

What Actually Happens: The three laser hits will now basically work, the appearance does not look perfect, there is a bit of an animation lag but the three lives now work.

However, the Laser2 function creates a strange side effect of no longer allowing the resetPlayer function to work at all. That function will now completely immobilize player controls, so I had to inactivate that function in order to make the game work.

What I Expect to Happen: Ideally we would be able to reposition the player sprite each time it gets hit by the laser2 using the playerReset function to (200, 350) to its original starting location at the bottom. This function should complement and work with the feature of losing lives, if the player loses a life the player will be reset and re-positioned.

I will keep working on it more, we may need more community help to debug this issue.

@faithdwsn,

I tried to follow this thread and take a look at the project. I hope I am understanding the question. Here is what I understood and tried to look at.

When the laser is fired and hits the “blank” sprite, multiple lasers are generated as part of the group, but they all fire at once. I think you were wanting only one of them to fire.

If that is the question, here is what I did that made it work for me. If that’s not the question, I guess I solved a problem that didn’t exist …

  • I created a variable called fireback and set it to 1. (yes, the blank should fire back).
  • When the laser is touching “blank”, it checks to see if fireback is 1. If so, the fireback variable is immediately changed to 0 so it won’t fire more than once. Then, it fires back one laser.
  • Then, the next time a laser is fired by the player, it sets fireback to 1 again so the process can continue again.

Here’s my remix.

If that helps, great. If not, I may be misunderstanding the question.

Mike

Mike, @mwood it is very amazing that you are able to show us how to design group code that sends down only one laser at a time! Yes, that was part of the goal with creating a group of laser2. So you were very close to the debugging target! Thank you!

The end goal is to get the laser to drop down right over the top of where the player.x directly above the player. Wherever the person shot up laser1, so that the level of difficulty is harder and makes the player have to “run away” so to speak. Like this here: https://studio.code.org/projects/gamelab/k49M8zw964QqMSHXedmY6kGJvQbvoXa5Q6BdN8GyS98

@melynn Michelle has already helped me to debug up to this point, as shown in the link above and the game. It is almost done, so if you want to take a look at this code maybe see if you can figure out how to make the resetPlayer function to work again? For example, I had to comment resetPlayer out because it was locking out the player’s controls. In this code, Michelle advised me to try changing the shape of the blank sprite and making the player.x equal to the laser2.x.

So that is one option for the debugging approach.

The second option is continuing to work with your group laser2 code and to just deal with the location of where the laser2 is coming down on the page and the tendency for it to game over on the first hit. Right now, the laser2 needs to come down over the player.x location instead of randomly across the page and to allow at least three lives across the game.

Thanks for any help you can give, I am happy with any advice you want to share. These last two approaches of debugging will make the game much better and build more complicated code for students in the future. My class and I appreciate the help.

See here for the group laser2 built off of your code that I tried:

Feel free to give me feedback on either approaches…

Personally, I would continue with the group option, but as Michelle has said, there are any number of ways to solve this and more than one could be a good solution.

Rather than give them code, here’s some pointers I would offer to the student.

In your Laser2 function, when the laser hits the “blank”, you are generating the return laser in a random location. If you want it to generate right above the player, don’t generate it in a random x location.

As far as the lives lost and the game over issue, the reason more than one lives are lost at a time is that the laser is kind of long and as it passes through the player, the program continuously checks and finds it still in contact with the player and deducts another life. Using the console log was a good way to detect this as you can tell it has multiple encounters with the player.

Two things I might consider.

One, at first contact, have the laser move away from the player. This would ensure that from the first moment of contact, there will be no more contact.

Two, since a deflecting laser may not be the desired visual effect, find a way to make the laser disappear at the same. Since the laser is currently part of a group, you may look for a way to set that group to be invisible. Since you’re making the group visible as part of the generation of the laser, that shouldn’t affect future lasers that will be launched.

Hope this gives you some good information to pass on to the student as I can tell this project is very close to being a fully functional and fun game.

Best of luck!

Mike

1 Like

Sharing concepts is a good way to go. Then as teacher, I need to have a working model of code behind the scenes which I know can work for the student to advise the concepts backed up with experience. Being on this forum has been very helpful to check out new material first!

Thank you for helping to put together the research to get this new code model working for the laser2 sprite group!