• 0

[JAVA]Problem with game(simple block breaker game)


Question

Hey. I have a problem with my simple java game. It's a block breaking game and it's almost done. The last thing to do is make some of the detection methods perfect. The methods should detect if the ball hits one of the blocks in the air. My current code does it well if the ball hits one of the longer sides of the blocks(north and south), but if the ball hits the west or east side of the block, it starts bugging. The ball will move into the block, until one of the current if-tests detects it, and reacts by changing the y-axis direction. When it first reacts like this it may also bring some other blocks with it. This will all be fixed if I can get some rules/if-tests to detect when the ball hits the shorter sides of the block and then changes the x-axis direction. Could anyone help me, please? :)

The block to test is called b, and has the getX/Y/Width/Height methods to call. The ball has the ints ballX, ballY and ballSize. dy and dx are the directions the ball moves. So changing the direction on x-axis is of course dx = -dx;

Picture of the situations I need code to detect

Detection code

I really hope some of you guys could help me fix this. Been struggeling all day to get it right. The y-axis test might also need to be fixed for this to work, I actually don't know anymore :s Thanks

9 answers to this question

Recommended Posts

  • 0

I always cringe at this sort of style:

boolean predicate() {
    if (condition) {
         return true;
    }
    else {
         return false;
    }
}

Could be written in one line and much more legibly:

boolean predicate() {
    return (condition);
}

Also your:

if(checkHitY(b)) {
    if(checkHitX(b)) {
        addToScore(b.getValue());
        model.hitBlock(i);
        dy = -dy;
        i = model.getSize() - 1;
    }
}

Could be rewritten, more logically, as

if(checkHitY(b) && checkHitX(b)) {
    addToScore(b.getValue());
    model.hitBlock(i);
    dy = -dy;
    i = model.getSize() - 1;
}

Stylistic issues aside, I see a dy = -dy, but not a dx = -dx in your code. No wonder then, that side collisions are not handled correctly. You need not only to determine if the ball hits, but whether it's a side (dx = -dx) or frontal (dy = -dy) collision, before applying the right velocity adjustement.

  • 0

Dr_Asik:

Stylistic issues aside, I see a dy = -dy, but not a dx = -dx in your code. No wonder then, that side collisions are not handled correctly. You need not only to determine if the ball hits, but whether it's a side (dx = -dx) or frontal (dy = -dy) collision, before applying the right velocity adjustement.

Thank you for your answer, thought it didn't help. I'm aware of the kinda messy if-test structure at the moment, but they won't be like that. I change specifically to this style to try out new methods of detection. Siince I might need a seperate checkHitXdx() method to detect the sides, I found it would be better to seperate the if-test for checkHitY() and checkHitX() while testing.

When it comes to the dx = -dx; it's not written there because that's what I need help with. I need help finding a similar method as checkHitX and checkHitY that detects the side, because I'm struggelin to make the formulas/if-tests myself. So there's not dx = -dx; at the moment, since hitting the sides is atm not beeing looked for by the methods. I've tried multiple methods to detect just the sides, but the game just got lots of bugs when trying them out. The ball would hit the corner of a block, and always change direction in x-axis, even though it hit on the left end of the south wall, which should make it just change the y-axis direction.

  • 0

You could simply test for the ball being below or above a block. If yes, reflect on y, if no, reflect on x. This will break if the ball speed is too high, but that's a problem with all simplistic collision schemes. If you want perfect collision you need to take into account before and after points, trace a vector and find the intersections with the segments defining the blocks, so there's some linear algebra involved.

  • 0
  On 06/04/2011 at 18:46, Dr_Asik said:

You could simply test for the ball being below or above a block. If yes, reflect on y, if no, reflect on x. This will break if the ball speed is too high, but that's a problem with all simplistic collision schemes. If you want perfect collision you need to take into account before and after points, trace a vector and find the intersections with the segments defining the blocks, so there's some linear algebra involved.

Yeah, but then I'd be checking the y-axis for hit 5 times(the dy value) for each block on each frameupdate, which would be lots of work for this. I tried to fix this by adding a area it could hit on both sides. Checking if it hit on the border, or at least before (border +/- dy pixels). The problem with this is as since I'm not detecting the sides now, it may slide into the middle of a block, and both upper test(with +/-dy) and lower test would be true and the ball starts bouncing up and down inside :p

To check the movement pixel for pixel for each frameupdate, would you simply check every object dy times, with lastX + (dx/dy) and lastY + (dy/dy) to check for hit? Is that a better solution then the "overflow" tactic (or whatever you could call my current method), or would that be too heavy on resources, with lets say 5 tests just for the y-test, for 100blocks on every frameupdate ?

  • 0
  On 06/04/2011 at 19:45, Graimer said:
Yeah, but then I'd be checking the y-axis for hit 5 times(the dy value) for each block on each frameupdate, which would be lots of work for this.
No, you start by detecting if there is a collision, and only if there is a collision you check on which side it is. So this usually adds 0 test per update, and at most 2 (when there is a collision). Unless you're running a 386 this should not present any performance problems.
  • 0
  On 06/04/2011 at 21:43, Dr_Asik said:

No, you start by detecting if there is a collision, and only if there is a collision you check on which side it is. So this usually adds 0 test per update, and at most 2 (when there is a collision). Unless you're running a 386 this should not present any performance problems.

Okey, I understand how you think. But would you mind actually making the tests for me, if it isn't too much to ask for? I've tried so many methods the last days I'm actually getting dizzy :p

I know it's asking a lot, but it seems like you got both the experience and a clear vision of how to solve this puzzle :)

  • 0
  On 06/04/2011 at 23:18, Dr_Asik said:

I'm sorry but I don't have time for this atm.

Well anyways, thank you very much =) Now I'll just need to get my sketchboard and start drawing/making test-conditions.

  • 0
  On 07/04/2011 at 21:02, Graimer said:

Well anyways, thank you very much =) Now I'll just need to get my sketchboard and start drawing/making test-conditions.

Last update: Made it work now. My tries with vectors(or one pixelmovement at a time) didn't work to well. But I found another solution and thought I'd share some hints of how I did it in case someone else is wondering about the same thing.

I found out that the Rectangle class had a bool intersect(rectangle r)-method and a rectangle intersection(rectangle r)-method. So I made a rectangle out of the block to check and one for the ball, checked it ball.intersect(block), if so , found the hitZone/intersected area with ball.intersection(block) and made tests on this very small rectangle to check if the ball hit on top, left, right or bottom side and the correct action for each side. Ex. if the ball hit the left side, the ball would now change to move to the left.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Support? You mean the support that microsoft's phone lines now just direct you to their website to look for a non-existent solution to Office problems (like all the ones they've been introducing to Outlook Classic), and hangs up on you? Don't think anyone would miss such mediocre "support"...
    • Unbelievably good deal sees this AMD Ryzen Windows 11 Lenovo laptop selling for just $266 by Sayan Sen While desktops are generally more powerful, laptops can be quite handy as they offer portability while also providing about 70-80% of the performance of a similar-priced desktop. If you are in the market shopping for one, then Lenovo is offering one with AMD's Ryzen 8-core APU at a low price of just $266 (purchase link down below). The discounted model we are specifically talking about here is the Lenovo IdeaPad 3 15ALC6., It is a 15.6-inch notebook powered by the AMD Ryzen 5700U APU, built on an 8-core 16-thread Zen 2 CPU and Vega 8 integrated graphics. The device has plenty of memory too, as it packs 12 GB of DDR4-3200 memory where 4 Gigs are soldered while the remaining 8 GB SODIMM is upgradable. Since the memory configuration is asymmetrical, the laptop likely supports flex mode and thus 8 out of 12 GB should be running in dual channel mode while the remaining 4 is in single channel mode. The laptop has a 512 GB M.2 2242 SSD for storage. Get it at the link below: Lenovo 2023 Ideapad 15.6 Inch FHD Touchscreen, 12GB RAM, 512GB SSD, Wi-Fi 6, Bluetooth 5, Windows 11 Home: $265.70 (Shipped and Sold by Amazon US) You may notice the poor reviews for this laptop on Amazon but that is apparently due to a possibly fraudulent seller. This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
    • This is obviously the most buggy web browser.
    • Uhm, why the preferential treatment for 1Password instead of simply providing an API for all password managers to plug into? I ditched 1Password for Enpass soon as Agilebits began forcing their cloud sh*t into 1Password. Have no reason to switch from the 100% locally-hosted Enpass...
  • Recent Achievements

    • Week One Done
      emptyother earned a badge
      Week One Done
    • Week One Done
      DarkWun earned a badge
      Week One Done
    • Very Popular
      valkyr09 earned a badge
      Very Popular
    • Week One Done
      suprememobiles earned a badge
      Week One Done
    • Week One Done
      Marites earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      566
    2. 2
      +FloatingFatMan
      178
    3. 3
      ATLien_0
      177
    4. 4
      Xenon
      119
    5. 5
      Som
      112
  • Tell a friend

    Love Neowin? Tell a friend!