Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Help w/ collisions in my breakout/arkanoid game.
Index -> Programming, Turing -> Turing Help
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
s_climax




PostPosted: Sat May 15, 2004 6:44 pm   Post subject: Help w/ collisions in my breakout/arkanoid game.

For some reasons its not really working at all any more. It seems to be a problem with the collisions of the ball with the bricks.

code:

setscreen ("graphics:400,400;offscreenonly")
var speed, x, y, dir, size, dx, dy, px, py : real
var facing, mx, my, mb, xsize, ysize, bricknumbers : int
bricknumbers := 110
var bricks : array 1 .. bricknumbers of boolean
const midx : int := maxx div 2
const midy : int := maxy div 2
randint (facing, 0, 359)
speed := 1
size := 5
dir := intreal (facing)
dir := 270
x := midx
y := midy div 2
dx := 1
dy := 1
py := 10
px := midx
xsize := 40
ysize := 20
for i : 1 .. bricknumbers
    bricks (i) := true
end for
loop
    delay (1)
    x += cosd (dir) * speed * dx
    y += sind (dir) * speed * dy
    for xx : 0 .. maxx by xsize
        for yy : 200 .. maxy by ysize
            if bricks (round ((((xx) / xsize) + 1) * (((yy) / ysize) - 9))) = true then
                drawfillbox (xx, yy, xx + xsize, ysize + yy, 8)
                drawbox (xx, yy, xx + xsize, ysize + yy, 0)
                if x <= xx or x >= xx + xsize then
                    if dx = 1 then
                        dx := -1
                    else
                        dx := 1
                    end if
                    bricks (round ((((xx) / xsize) + 1) * (((yy) / ysize) - 9))) := false
                end if
                if y <= yy or y >= yy + ysize then
                    if dy = 1 then
                        dy := -1
                    else
                        dy := 1
                    end if
                end if
            end if
        end for
    end for

    mousewhere (mx, my, mb)


    if x - size < 0 then
        if dx = 1 then
            dx := -1
        else
            dx := 1
        end if
    elsif x + size > maxx then
        if dx = 1 then
            dx := -1
        else
            dx := 1
        end if
    elsif y - size < 10 and y <= (20 + (-dy * speed)) and x > px - 20 and x < px + 20 then
        if dy = 1 then
            dy := -1
        else
            dy := 1
        end if
        dir += ((x - px) * 2) * dx
    elsif y + size > maxy then
        if dy = 1 then
            dy := -1
        else
            dy := 1
        end if
    end if

    px := intreal (mx)

    drawfilloval (round (x), round (y), 5, 5, 7)
    drawfillbox (round (px - 20), round (py), round (px + 20), round (py - 5), 7)
    View.Update
    cls
    exit when y < 0
end loop
Sponsor
Sponsor
Sponsor
sponsor
SuperGenius




PostPosted: Sat May 15, 2004 9:48 pm   Post subject: (No subject)

when I ran your code the ball just hovers in the middle of the screen, fluctuating within a range of a couple pixels.
Dan




PostPosted: Sat May 15, 2004 11:05 pm   Post subject: (No subject)

the problem is with your colsione dection with the bricks and the ball:

1. you need to uses and not or
2. both the y and x ifs have to be the same if not 2 diffrent ones
3. you mixed up the > and < singes.

the if should look somting like this:

if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then

combinding the ifs and making thous chages will almost make the progame work right. there is still a bug in the way u are dertming witch brick was hit.

insted of usning a one dimetion arae for the bircks why not uses a 2d one? this makes it alot easer to keep track of the boxs withc are on vs off.

tho this make u have to chage alot of the closione code.

here is what i did with it:

code:

var facing, mx, my, mb, xsize, ysize, bricknumbers : int
bricknumbers := 110
xsize := 40
ysize := 20
var bricks : array 1 .. maxx div xsize, 1 .. maxy div ysize of boolean
const midx : int := maxx div 2
const midy : int := maxy div 2
randint (facing, 0, 359)
speed := 1
size := 5
dir := intreal (facing)
dir := 270
x := midx
y := midy div 2
dx := 1
dy := -1
py := 10
px := midx

for i : 1 .. maxx div xsize
    for ii : 1 .. maxy div ysize
        bricks (i, ii) := true
    end for
end for
loop
    delay (1)
    x += cosd (dir) * speed * dx
    y += sind (dir) * speed * dy

    for k : xsize .. maxx by xsize
        for kk : ysize .. maxy by ysize

            var xx : int := k - xsize
            var yy : int := (kk - ysize) + 200

            if bricks (k div xsize, kk div ysize) = true then

                drawfillbox (xx, yy, xx + xsize, ysize + yy, 8)
                drawbox (xx, yy, xx + xsize, ysize + yy, 0)

                if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then
                    if dx = 1 then
                        dx := -1
                    else
                        dx := 1
                    end if

                    if dy = 1 then
                        dy := -1
                    else
                        dy := 1
                    end if
                    bricks (k div xsize, kk div ysize) := false
                end if
            end if

        end for
    end for

    mousewhere (mx, my, mb)


    if x - size < 0 then
        if dx = 1 then
            dx := -1
        else
            dx := 1
        end if
    elsif x + size > maxx then
        if dx = 1 then
            dx := -1
        else
            dx := 1
        end if
    elsif y - size < 10 and y <= (20 + (-dy * speed)) and x > px - 20 and x < px + 20 then
        if dy = 1 then
            dy := -1
        else
            dy := 1
        end if
        dir += ((x - px) * 2) * dx
    elsif y + size > maxy then
        if dy = 1 then
            dy := -1
        else
            dy := 1
        end if
    end if

    px := intreal (mx)

    drawfilloval (round (x), round (y), 5, 5, 7)
    drawfillbox (round (px - 20), round (py), round (px + 20), round (py - 5), 7)
    View.Update
    cls
    exit when y < 0
end loop


it is not perfitck but it will get you on the right track.
Computer Science Canada Help with programming in C, C++, Java, PHP, Ruby, Turing, VB and more!
s_climax




PostPosted: Sun May 16, 2004 12:03 am   Post subject: (No subject)

Thanks, but how would I get the balls to bounce off the bricks in the right direction?

That is the only thing I can't figure out. I've managed to add the ability to lose, lives, make room around the edges, and add colors. I simply cannot figure out how to make the balls bounce off the bricks correctly. Any help?

code:

setscreen ("graphics:400,400;offscreenonly")
var speed, x, y, dir, size, dx, dy, px, py : real
var facing, mx, my, mb, xsize, ysize, bricknumbers, brickcol, count,offset : int
offset:=180
bricknumbers := 110
xsize := 40
ysize := 20
var bricks : array 1 .. maxx div xsize, 1 .. maxy div ysize of boolean
const midx : int := maxx div 2
const midy : int := maxy div 2
randint (facing, 240, 300)
speed := 2
size := 5
dir := -intreal (facing)
%dir := 270
x := midx
y := midy div 2
dx := 1
dy := -1
py := 10
px := midx
count := 0

for i : 1 .. maxx div xsize
    for ii : 1 .. maxy div ysize
        bricks (i, ii) := false
    end for
end for

for i : 2 .. maxx div xsize
    for ii : 1 .. (maxy div ysize) - 2
        bricks (i, ii) := true
        count += 1
    end for
end for

count -= ((maxx-xsize) div xsize) * ((maxy - offset-(ysize*2)) div ysize)
for lives : 1 .. 3
    loop
        speed += 0.0001
        delay (0)
        x += cosd (dir) * speed * dx
        y += sind (dir) * speed * dy

        for k : xsize .. maxx by xsize
            for kk : ysize .. maxy by ysize

                var xx : int := k - xsize
                var yy : int := (kk - ysize) + offset

                if bricks (k div xsize, kk div ysize) = true then
                    brickcol := RGB.AddColor (1, kk / 201, 1 - kk / 201)

                    drawfillbox (xx, yy, xx + xsize, ysize + yy, brickcol)
                    drawbox (xx, yy, xx + xsize, ysize + yy, 0)


                    if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then
                        if dx = 1 then
                            dx := -1
                        else
                            dx := 1
                        end if

                        if dy = 1 then
                            dy := -1
                        else
                            dy := 1
                        end if
                        bricks (k div xsize, kk div ysize) := false
                        count -= 1
                    end if
                end if

            end for
        end for

        mousewhere (mx, my, mb)


        if x - size < 0 then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
        elsif x + size > maxx then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
        elsif y - size < 10 and y <= (20 + (-dy * speed)) and x > px - 20 and x < px + 20 then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if

            if dx = 1 then
                dir += - ((x - px) * 2)
            else
                dir += ((x - px) * 2)
            end if


        elsif y + size > maxy then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if
        end if

        px := intreal (mx)

        %put lives
        %put count
        drawfilloval (round (x), round (y), 5, 5, 7)
        drawfillbox (round (px - 20), round (py), round (px + 20), round (py - 5), 7)
        View.Update
        cls
        exit when y < 0 or count = 0
    end loop
    dir := -intreal (facing)
    %dir := 270
    x := midx
    y := midy div 2
    dx := 1
    dy := -1
    py := 10
    px := midx
    delay (1000)
end for
s_climax




PostPosted: Mon May 17, 2004 6:21 pm   Post subject: (No subject)

code:

                    if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then
                        if dx = 1 then
                            dx := -1
                        else
                            dx := 1
                        end if

                        if dy = 1 then
                            dy := -1
                        else
                            dy := 1
                        end if
                        bricks (k div xsize, kk div ysize) := false
                        count -= 1
                    end if

This is my problem. The way the if statement works, it only checks that the ball has hit the brick. What I need is a way to check which side of the brick it hit. Once I can figure out that code, I can get it.
Paul




PostPosted: Mon May 17, 2004 6:32 pm   Post subject: (No subject)

you can check which direction the ball is moving in when it hits something, then move it in the appropriate direction.
LiquidDragon




PostPosted: Mon May 17, 2004 6:44 pm   Post subject: (No subject)

Yes. so if the ball is going up to the right and it hits the wall then u just switch the movement of the y. It's really that simple Laughing
s_climax




PostPosted: Mon May 17, 2004 8:04 pm   Post subject: (No subject)

Quote:

Yes. so if the ball is going up to the right and it hits the wall then u just switch the movement of the y. It's really that simple


It's more complicated than that. Of course that works with walls, but not a four-sided object.

I may be able to use direction though. I will try that, thanks.

EDIT:
After some thinking, I realized that I could determine which side of the brick the ball hit (top vs bottom or left vs right) but not whether it was the horizontal or vertical. Therefore, it seems that direction won't help me.
Sponsor
Sponsor
Sponsor
sponsor
s_climax




PostPosted: Wed May 19, 2004 4:27 pm   Post subject: (No subject)

The only thing that kind of works is if I check if the rounded value of the left sdie of the brick is equal to the rounded value of the ball's x. THe problem with this is that it does not allow me to increase the ball's speed.
How would I make it possible to make the ball's speed greater?

One other problem is that sometimes the collisions will get backwards on the paddle, so that if you hit the ball on the left side of the paddle it will change its direction and make it go right. Most of the time this is not the case though.

code:

setscreen ("graphics:400,400;offscreenonly")
var speed, x, y, dir, size, dx, dy, px, py : real
var facing, mx, my, mb, xsize, ysize, brickcol, count, offset : int
var start, finished : boolean
offset := 200
xsize := 40
ysize := 20
var bricks : array 1 .. maxx div xsize, 1 .. maxy div ysize of boolean
const midx : int := maxx div 2
const midy : int := maxy div 2
randint (facing, 240, 300)
speed := 1
size := 5
dir := -intreal (facing)
%dir := 270
x := midx
y := midy div 2
dx := 1
dy := -1
py := 10
px := midx
count := 0
start := true
finished := false

for i : 1 .. maxx div xsize
    for ii : 1 .. maxy div ysize
        bricks (i, ii) := false
    end for
end for

for i : 2 .. maxx div xsize
    for ii : 1 .. (maxy - 12 * ysize) div ysize
        bricks (i, ii) := true
        count += 1
    end for
end for

for lives : 1 .. 3
    loop
        %speed += 0.0001
        delay (0)
        x += cosd (dir) * speed * dx
        y += sind (dir) * speed * dy

        for k : xsize .. maxx by xsize
            for kk : ysize .. maxy by ysize

                var xx : int := k - xsize
                var yy : int := (kk - ysize) + offset

                if bricks (k div xsize, kk div ysize) = true then
                    brickcol := RGB.AddColor (1, kk / 201, 1 - kk / 201)

                    drawfillbox (xx, yy, xx + xsize, ysize + yy, brickcol)
                    drawbox (xx, yy, xx + xsize, ysize + yy, 0)


                    if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then
                        if floor (x) = xx or ceil (x) = xx + xsize then
                            if dx = 1 then
                                dx := -1
                            else
                                dx := 1
                            end if
                        end if
                        if floor (y) = yy or ceil (y) = yy + ysize then
                            if dy = 1 then
                                dy := -1
                            else
                                dy := 1
                            end if
                        end if
                        bricks (k div xsize, kk div ysize) := false
                        count -= 1
                    end if
                end if

            end for
        end for

        if start = true then
            for i : 0 .. 2
                locatexy (midx, midy-ysize)
                put 3 - i
                View.Update
                delay (1000)
                if i = 2 then
                    start := false
                end if
            end for
        end if

        mousewhere (mx, my, mb)


        if x - size < 0 then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
        elsif x + size > maxx then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
        elsif y - size < 10 and y <= (20 + (-dy * speed)) and x > px - 20 and x < px + 20 then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if

            if dx = 1 then
                dir += - ((x - px) * 2)
            else
                dir += ((x - px) * 2)
            end if


        elsif y + size > maxy then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if
        end if

        px := intreal (mx)

        put "Lives: ",4 - lives
        %put count
        drawfilloval (round (x), round (y), 5, 5, 7)
        drawfillbox (round (px - 20), round (py), round (px + 20), round (py - 5), 7)
        View.Update
        cls
        if count = 0 then
            finished := true
        end if
        exit when y < 0 or count = 0
    end loop
    randint (facing, 240, 300)
    dir := -intreal (facing)
    %dir := 270
    x := midx
    y := midy div 2
    dx := 1
    dy := -1
    py := 10
    px := midx
    start := true
    speed := 1
    exit when finished = true
end for
if count = 0 then
    put "You win!"
else
    put "You Lose!"
end if
Cervantes




PostPosted: Wed May 19, 2004 4:46 pm   Post subject: (No subject)

heheh you could use whatdotcolour and colour the brinks in a unique way.


brick.bmp
 Description:
unique colouring
 Filesize:  43.64 KB
 Viewed:  5482 Time(s)

brick.bmp


MyPistolsIn3D




PostPosted: Wed May 19, 2004 4:49 pm   Post subject: (No subject)

Do you not just have to make the xchange in the opposite direction? Like when it is going up and to the right, change it down and to the left?
Cervantes




PostPosted: Wed May 19, 2004 5:32 pm   Post subject: (No subject)

no because if its going up and to the right and you hit the bottom of a brick it should go down and to the right, not down and to the left.
s_climax




PostPosted: Thu May 20, 2004 9:23 pm   Post subject: (No subject)

code:

setscreen ("graphics:400,440;offscreenonly")
const maxxy : int := 400
var speed, x, y, dir, size, dx, dy, px, py : real
var facing, mx, my, mb, xsize, ysize, brickcol, count, offset, scol : int
var start, finished, m : boolean
m := false %Music
offset := 180
xsize := 40
ysize := 20
var bricks : array 1 .. maxx div xsize, 1 .. maxxy div ysize of int
const midx : int := maxx div 2
const midy : int := maxxy div 2
const sx := maxx - ysize
const sy := maxy - ysize
randint (facing, 240, 300)
speed := 1
size := 5
dir := -intreal (facing)
%dir := 270
x := midx
y := midy div 2
dx := 1
dy := -1
py := 10
px := midx
count := 0
start := true
finished := false
for i : 1 .. maxx div xsize
    for ii : 1 .. maxxy div ysize
        bricks (i, ii) := 0
    end for
end for
for i : 2 .. maxx div xsize
    for ii : 1 .. (maxxy - 12 * ysize) div ysize
        bricks (i, ii) := 1
        count += 1
    end for
end for
count -= 4
for i : 2 .. maxx div xsize
    for ii : 1 .. (maxxy - 19 * ysize) div ysize
        if i mod 2 = 0 then
            bricks (i, ii) := 3
        else
            bricks (i, ii) := 2
            count += 1
        end if
    end for
end for
for lives : 1 .. 3
    loop
        colorback (7)
        drawfillbox (0, maxxy, maxx, 0, 0)
        if m = true then
            scol := 10
        else
            scol := 12
        end if
        %speed += 0.0001
        delay (0)
        x += cosd (dir) * speed * dx
        y += sind (dir) * speed * dy
        for k : xsize .. maxx by xsize
            for kk : ysize .. maxxy by ysize
                var xx : int := k - xsize
                var yy : int := (kk - ysize) + offset
                if bricks (k div xsize, kk div ysize) ~= 0 then
                    brickcol := RGB.AddColor (0, 1 - bricks (k div xsize, kk div ysize) / 6, 1 - bricks (k div xsize, kk div ysize) / 6)
                    drawfillbox (xx, yy, xx + xsize, ysize + yy, brickcol)
                    drawbox (xx, yy, xx + xsize, ysize + yy, 0)
                    if x >= xx and x <= xx + xsize and y >= yy and y <= yy + ysize then
                        if floor (x) = xx or ceil (x) = xx + xsize then
                            if dx = 1 then
                                dx := -1
                            else
                                dx := 1
                            end if
                        end if
                        if floor (y) = yy or ceil (y) = yy + ysize then
                            if dy = 1 then
                                dy := -1
                            else
                                dy := 1
                            end if
                        end if
                        bricks (k div xsize, kk div ysize) -= 1
                        if bricks (k div xsize, kk div ysize) = 0 then
                            count -= 1
                        end if
                        if m = true then
                            if bricks (k div xsize, kk div ysize) = 0 then
                                Music.Play ("16g")
                            elsif bricks (k div xsize, kk div ysize) = 1 then
                                Music.Play ("16f+")
                            elsif bricks (k div xsize, kk div ysize) = 2 then
                                Music.Play ("16f")
                            end if
                        end if
                    end if
                end if
            end for
        end for
        if start = true then
            colorback(white)
            color (7)
            for i : 0 .. 3
                locatexy (midx + 5, offset - ysize)
                if i < 3 then
                    put 3 - i
                    if m = true then
                        Music.Play ("16c")
                    end if
                else
                    put "GO!"
                    if m = true then
                        Music.Play ("16>c<")
                    end if
                end if
                View.Update
                delay (1000)
                if i = 3 then
                    start := false
                end if
            end for
        end if
        mousewhere (mx, my, mb)
        if mb = 1 and round (sqrt ((mx - sx + 5) ** 2 + (my - sy + 5) ** 2)) <= 13 then
            if m = false then
                m := true
            else
                m := false
            end if
            delay (50)
        end if
        if x - size < 0 then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
            if m = true then
                Music.Play ("16g")
            end if
        elsif x + size > maxx then
            if dx = 1 then
                dx := -1
            else
                dx := 1
            end if
            if m = true then
                Music.Play ("16g")
            end if
        elsif y - size < 10 and x > px - 20 and x < px + 20 then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if
            if m = true then
                Music.Play ("16a")
            end if
            if dx = 1 then
                dir += - ((x - px) * 2)
            else
                dir += ((x - px) * 2)
            end if
        elsif y + size > maxxy then
            if dy = 1 then
                dy := -1
            else
                dy := 1
            end if
            if m = true then
                Music.Play ("16g")
            end if
        end if
        if mx >= 20 and mx <= maxx - 20 then
            px := intreal (mx)
        elsif mx <= 20 then
            px := 20
        else
            px := maxx - 20
        end if
        color (white)
        put "Lives: ", 4 - lives
        put "Bricks Left:", count
        drawfilloval (sx, sy, 3, 3, scol)
        drawline (sx + 2, sy + 2, sx + 2, sy + 12, scol)
        drawline (sx + 2, sy + 12, sx + 12, sy + 12, scol)
        drawline (sx + 12, sy + 12, sx + 12, sy + 2, scol)
        drawfilloval (sx + 10, sy, 3, 3, scol)
        drawoval (sx + 5, sy + 5, 13, 13, scol)
        if scol = 12 then
            drawline (sx - 5, sy - 5, sx + 15, sy + 15, scol)
        end if
        drawfilloval (round (x), round (y), 5, 5, 7)
        drawfillbox (round (px - 20), round (py), round (px + 20), round (py - 5), 7)
        drawline (0, maxxy, maxx, maxxy, 7)
        View.Update
        cls
        if count = 0 then
            finished := true
        end if
        exit when y < 0 or count = 0
    end loop
    randint (facing, 240, 300)
    dir := -intreal (facing)
    %dir := 270
    x := midx
    y := midy div 2
    dx := 1
    dy := -1
    py := 10
    px := midx
    start := true
    speed := 1
    exit when finished = true
end for
if count = 0 then
    put "You win!"
    Music.Play ("2ae8e4f+2e4g+a")
else
    put "You Lose!"
    Music.Play ("<<4gf+f1e16efefefef1e")
end if


As you can tell, the game is too easy since the ball is too slow. But when I make the ball speed up it doesn't work.

Any other ideas for making my collision detection work with different speeds? I'm not so sure that whatdotcolor would work.
SuperGenius




PostPosted: Thu May 20, 2004 10:31 pm   Post subject: (No subject)

i will post my version of super breakout after i've handed it in for my summative, but how it works is there are two variables which are the rise and run of the slope of the ball's path. These are added to the ball's coords at the start of each execution of the loop. I used whatdotcolour for the bricks but the walls have coordinate detection. What i did was have two variables for the low range and high range of a random intiger which would be used to give the ball a random path, so if you increase the value of the upper and lower ranges of the random intiger, you can make the game speed up and it doesnt affect the game really unless you set it to a speed which would be too fast to play on anyways.
s_climax




PostPosted: Sun May 23, 2004 11:51 am   Post subject: (No subject)

That does not help me really.

My game speed is already at its highest. My issue is not making the ball go faster either. I have that done too.
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 2  [ 22 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: