Python Forum
SOLVED - Collision detection - TURTLE
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SOLVED - Collision detection - TURTLE
#1
Hello y'all!

I'm new here, so I hope my question will be clear enough!

I'm trying to create a Breakout game using Python n Turtle.
I created my lists of blocks and my main block to .clone() but
wenn the ball reaches the top of the game, where the blocks are, it only erases the first block...

I tried to solve this issue with different kind of loops, but the proble is still present...

I hope someone can help me!
THX in advence!

CODE:

# CREATING BLOCKS

block1 = turtle.Turtle()
block1.shape("square")
block1.speed(0)
block1.shapesize(2, 4) # Size of block 40x80

# BLOCKS ROW Nr.1 (10 Blocks)
blocks_row1 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
block1.clone(), block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.2 (10 Blocks)
blocks_row2 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
block1.clone(), block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.3 (10 Blocks)
blocks_row3 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
block1.clone(), block1.clone(), block1.clone(), block1.clone()]

all_blocks = [blocks_row1, blocks_row2, blocks_row3]

def starting_block_positions():
for i in range(len(blocks_row1)):
blocks_row1[i].penup()
blocks_row2[i].penup()
blocks_row3[i].penup()

blocks_row1[i].color(random.choice(colors)) # ROW Nr1
blocks_row1[i].goto((-400 + (82 * i)), 460)
blocks_row2[i].color(random.choice(colors)) # ROW Nr2
blocks_row2[i].goto((-400 + (82 * i)), 418)
blocks_row3[i].color(random.choice(colors)) # ROW Nr2
blocks_row3[i].goto((-400 + (82 * i)), 376)

# COLLISION WITH BLOCKS
elif ball.ycor() > 356: # COLLISION WITH BLOCKS
while counter_collision < len(blocks_row1):
if (abs(ball.xcor()) - abs(blocks_row3[counter_collision].xcor()) < 20) and (abs(ball.ycor()) - abs(blocks_row3[counter_collision].ycor()) < 40):
blocks_row3[counter_collision].hideturtle()
ball.setheading(270)
ball.forward(BALL_SPEED_STANDARD)
break
elif (abs(ball.xcor()) - abs(blocks_row2[counter_collision].xcor()) < 80) and (abs(ball.ycor()) - abs(blocks_row2[counter_collision].ycor()) < 40):
blocks_row2[counter_collision].hideturtle()
ball.setheading(270)
ball.forward(BALL_SPEED_STANDARD)
break
elif (abs(ball.xcor()) - abs(blocks_row1[counter_collision].xcor()) < 80) and (abs(ball.ycor()) -
abs(blocks_row1[counter_collision].ycor()) < 40):
blocks_row1[counter_collision].hideturtle()
ball.setheading(270)
ball.forward(BALL_SPEED_STANDARD)
break
counter_collision += 1
Reply
#2
There seem to be missing pieces of code:
- Import turtle ?
- Elif before if ?

Pls show indentation (python tags) because it is impossible to
see what piece of code is dependent on what.

Paul
Reply
#3
Hi Paul,

Yeah, it's only a part of the code.
Here's the complete one.

Niko

import turtle
import random
import time


#########################################################
#          VARIABLES && CONSTANTS FOR GAME              #
#########################################################

# Color List
colors = ["red", "blue", "yellow", "pink", "green", "DeepSkyBlue", "chartreuse", "DarkMagenta"]

# Constants
ball_speed = 10
WINDOW_MAIN_GAME_SIZE = 1000

# Start Variables:
life = 3


##########################################
#          CREATING WINDOW               #
##########################################

wn = turtle.Screen()
wn.title("BREAKOUT")
wn.bgcolor("black")
wn.setup(WINDOW_MAIN_GAME_SIZE, WINDOW_MAIN_GAME_SIZE)


#########################################
#          GAME BLOCKS...               #
#########################################

# CREATING BLOCKS

block1 = turtle.Turtle()
block1.shape("square")
block1.speed(0)
block1.shapesize(2, 4)  # Size of block 40x80

# BLOCKS ROW Nr.1 (10 Blocks)
blocks_row1 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.2 (10 Blocks)
blocks_row2 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.3 (10 Blocks)
blocks_row3 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone(), block1.clone()]

all_blocks = [blocks_row1, blocks_row2, blocks_row3]


def starting_block_positions():
    for i in range(len(blocks_row1)):
        blocks_row1[i].penup()
        blocks_row2[i].penup()
        blocks_row3[i].penup()

        blocks_row1[i].color(random.choice(colors))  # ROW Nr1
        blocks_row1[i].goto((-400 + (82 * i)), 460)
        blocks_row2[i].color(random.choice(colors))  # ROW Nr2
        blocks_row2[i].goto((-400 + (82 * i)), 418)
        blocks_row3[i].color(random.choice(colors))  # ROW Nr2
        blocks_row3[i].goto((-400 + (82 * i)), 376)


########################################
#          PLAYER'S PADDLE             #
########################################

paddle = turtle.Turtle()
paddle.shape("square")
paddle.color("white")
paddle.speed(0)
paddle.shapesize(2, 8)  # Size of paddle = 40*160
paddle_position_x = paddle.xcor()
paddle_position_y = paddle.ycor()


def starting_paddle_position():
    paddle.penup()
    paddle.goto(0, -470)


def move_left():
    if paddle.xcor() > -480:
        paddle.setx(paddle.xcor() - 10)


def move_right():
    if paddle.xcor() < 480:
        paddle.setx(paddle.xcor() + 10)


########################################
#           PLAYER'S BALL              #
########################################
ball = turtle.Turtle()
ball.shape("circle")
ball.color("white")
ball.fillcolor("white")
ball.speed(0)
ball_pos_y = 0
ball_pos_x = 0


def time_ball_speed(ball_speed):
    global timer
    if (time.perf_counter() - timer) % 15 == 0:
        ball_speed *= 2
    return ball_speed


def starting_ball_position():
    ball.hideturtle()
    ball.penup()
    ball.goto(0, 0)
    ball.setheading(270)


def moving_ball():
    global life
    counter_collision = 0
    # TOUCHING PADDLE
    if (abs((abs(ball.xcor()) - abs(paddle.xcor()))) < (160/life)) and (ball.ycor() <= (paddle.ycor() + 20)):
        if ball.heading() == 270 or -270:
            ball.setheading(random.randint(45, 135))
            ball.forward(ball_speed)
        else:
            ball.setheading((ball.heading() * -1))
            ball.forward(ball_speed)

    # COLLISION WITH BLOCKS
    elif ball.ycor() > 356:  # COLLISION WITH BLOCKS
        while counter_collision < len(blocks_row1):
            if (abs(ball.xcor()) - abs(blocks_row3[counter_collision].xcor()) < 20) and (abs(ball.ycor()) - abs(blocks_row3[counter_collision].ycor()) < 40):
                blocks_row3[counter_collision].hideturtle()
                ball.setheading(270)
                ball.forward(ball_speed)
                break
            elif (abs(ball.xcor()) - abs(blocks_row2[counter_collision].xcor()) < 80) and (abs(ball.ycor()) - abs(blocks_row2[counter_collision].ycor()) < 40):
                blocks_row2[counter_collision].hideturtle()
                ball.setheading(270)
                ball.forward(ball_speed)
                break
            elif (abs(ball.xcor()) - abs(blocks_row1[counter_collision].xcor()) < 80) and (abs(ball.ycor()) - abs(blocks_row1[counter_collision].ycor()) < 40):
                blocks_row1[counter_collision].hideturtle()
                ball.setheading(270)
                ball.forward(ball_speed)
                break
            counter_collision += 1

    # WN LEFT SIDE LIMIT
    elif ball.xcor() <= -490:
        ball.setheading(ball.heading() * 0.5)
        ball.forward(ball_speed)

    # WN RIGHT SIDE LIMIT
    elif ball.xcor() >= 490:
        ball.setheading(ball.heading() * 1.5)
        ball.forward(ball_speed)

    # BALL STILL IN WN
    elif (ball.ycor() >= -500) and (ball.xcor() <= 500) and (ball.xcor() >= -500) and (ball.ycor() <= 500):
        ball.forward(ball_speed)

    # LIFE -1
    else:
        life -= 1
        show_life.clear()
        starting_ball_position()
        return life


#######################################
#         DRAW TIMER                  #
#######################################
timer = 0
show_timer = turtle.Turtle()
show_timer.penup()
show_timer.pencolor("black")
show_timer.speed(0)
show_timer.goto(410, -480)
show_timer.color("white")


def draw_timer():
    global game_time_total
    show_timer.clear()
    show_timer.write(game_time_total, font=("Arial", 10, "bold"))


#######################################
#         DRAW LIFE                   #
#######################################
show_life = turtle.Turtle()
show_life.penup()
show_life.pencolor("black")
show_life.speed(0)
show_life.goto(-480, -480)
show_life.color("white")


def draw_life():
    global life
    show_life.write("Lives: " + str(life), font=("Arial", 20, "bold"))


def life_control():
    global timer
    if life == 3:
        timer = time.perf_counter()
        weidth_paddle = 8 / life
        paddle.shapesize(2, weidth_paddle)
        return timer
    elif life == 2:
        timer = time.perf_counter()
        weidth_paddle = 8 / life
        paddle.shapesize(2, weidth_paddle)
        return timer

    elif life == 1:
        timer = time.perf_counter()
        weidth_paddle = 8
        paddle.shapesize(2, weidth_paddle / life)
        return timer

    else:
        wn.clear()
        game_over = turtle.Turtle()
        game_over.penup()
        game_over.pencolor("black")
        game_over.speed(0)
        game_over.write("GAME OVER!", font=("Arial", 50, "bold"))
        time.sleep(5)


#######################################
#          MAIN CODE...               #
#######################################

# Starting position for Blocks & Paddle
starting_block_positions()
starting_paddle_position()
starting_ball_position()

while 1 == 1:
    game_time_total = time.perf_counter()
    life_control()
    time_ball_speed(ball_speed)
    ball.showturtle()
    draw_life()
    #draw_timer()
    moving_ball()

    wn.onkeypress(move_left, "a")
    wn.onkeypress(move_left, "Left")
    wn.onkeypress(move_right, "Right")
    wn.onkeypress(move_right, "d")
    wn.listen()
Reply
#4
Nice piece of work so far!
I had a quick look, and i suspect the problem starts with
your counter_collision +=1.
because of your break statements, it does not get updated as planned.

Paul
Reply
#5
(Nov-17-2020, 07:35 AM)DPaul Wrote: Nice piece of work so far!
I had a quick look, and i suspect the problem starts with
your counter_collision +=1.
because of your break statements, it does not get updated as planned.

Paul

Thank you Paul!
Was a big help, I a step closer to finishing this project!

I changed my code, Breaks were def. a problem.
now it works better, but when my ball touches the first box of a row, the whole row "hides"...
And if the ball goes back to the, now, empty row, it still thinks there is something...

Do you have a clue?
I tried to box[n][i].clear() but it doesn't accept the command?!

   
 # COLLISION WITH BLOCKS
    elif ball.ycor() > 356:
        for n in range(len(all_blocks)):
            for i in range(len(blocks_row1)):
                if (ball.xcor() - all_blocks[n][i].xcor() < 20) and \
                        (ball.ycor() - all_blocks[n][i].ycor() < 40):
                    all_blocks[n][i].hideturtle()
                    ball.setheading(360 - ball.heading())
                    ball.forward(ball_speed)
                    break
I'm REALLY thankful for any help!
THX again!
Reply
#6
I found it clever that you draw the boxes as turtle-shapes, so you can hide them when hit.
It's difficult to identify with your logic in a few minutes Smile
but probably the problem is in lines 5-6-7.
You hide the turtle, but how does the block vector know the turtle has gone?
but how do you check that the turtle has gone?
If it remains a problem, maybe another approach is helpful.
Draw the rectangles not as turtle-shapes but as simple rectangles in different colors.
Hiding is than simply redrawing the box with the background color = invisible !
Your 3 horizontal vectors could contain [1,1,1,1,1..] at the start and when one
block is hit : [1,1,0,1,1,...]
Just an idea.
Paul
Reply
#7
Hi Paul,

Thx for the help!
Found the problem, it was indeed in line 5-6-7!
I forgot to une the abs()! ^^ (stupid mistake)

BTW:
an other mistake:

# COLLISION WITH BOX CHECK
def collision_block_check():
    global nr_blocks_left
    for n in range(len(all_blocks)):
        for i in range(len(blocks_row1)):
            if (abs(ball.xcor() - all_blocks[n][i].xcor()) < 40) and \
                    (abs(ball.ycor() - all_blocks[n][i].ycor()) < 20) and (all_blocks[n][i].isvisible()  == True):
                all_blocks[n][i].hideturtle()
                ball.setheading(ball.heading() * -1)
                nr_blocks_left -= 1
all_blocks[n][i].isvisible() == True
looks if the block is still visible or not. if TRUE it will hide the .turtle and if FALSE it will move as it should.



Last problem to finishing the game are the boarder restrictions -_-
(... yeah, kind of stupid, but I have a brain F*** somewhere)

# WN SIDE LIMIT
def side_limit_check():
    if ball.xcor() <= (BORDER_LEFT + 10) or ball.xcor() >= (BORDER_RIGHT-10):
        ball.setheading(ball.heading() * -1)
doesn't work as it should and not sure why Sad

Hope we/I could help someone else have the same issue with the collider ^^
Reply
#8
Hi,

I saw that left and right there is a small problem.
Just a thought, but left : -500+10 = -490 is too far left.
Try +50 or something.
(And the same to the right of course.
Paul
Reply
#9
Hi Paul,

Yeah, at the end the "bounce off" solution was kind of obvious for the sides ^^

Solution:
ball.setheading(180 + -ball.heading())

Now i'm done! Big Grin
on to the next project! Smile

Thx again for the help!
Niko
Reply
#10
Final Code for the Breakout game:

################################################################################
#                                                                              #
#        ****   ****   ****  *****  *  *  ****  *  *  *****                    #
#        *   *  *   *  *     *   *  * *   *  *  *  *    *                      #
#        ***    ***    ***   *****  *     *  *  *  *    *                      #
#        *   *  *  *   *     *   *  * *   *  *  *  *    *                      #
#        ****   *   *  ****  *   *  *  *  ****  ****    *                      #
#                                                                              #
#                                                                              #
#        MADE FROM: OuateDePhoque                                              #
#                                                                              #
################################################################################


import turtle
import random
import time


#########################################################
#          VARIABLES && CONSTANTS FOR GAME              #
#########################################################

# Color List
colors = ["red", "blue", "yellow", "pink", "green", "DeepSkyBlue", "chartreuse", "DarkMagenta"]

# Constants
ball_speed = 10
WINDOW_MAIN_GAME_HIGHT = 1000
WINDOW_MAIN_GAME_WIDTH = 800
BORDER_LEFT = -400
BORDER_RIGHT = 400
BORDER_TOP = 500
BORDER_BOT = -500

# Start Variables:
life = 3


##########################################
#          CREATING WINDOW               #
##########################################

wn = turtle.Screen()
wn.title("BREAKOUT - By: OuateDePhoque")
wn.bgcolor("black")
wn.setup(WINDOW_MAIN_GAME_WIDTH, WINDOW_MAIN_GAME_HIGHT)

#########################################
#          GAME BLOCKS...               #
#########################################

# CREATING BLOCK TO CLONE
block1 = turtle.Turtle()
block1.shape("square")
block1.speed(0)
block1.shapesize(2, 4)  # Size of block 40x80

# BLOCKS ROW Nr.1 (9 Blocks)
blocks_row1 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.2 (9 Blocks)
blocks_row2 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone()]
# BLOCKS ROW Nr.3 (9 Blocks)
blocks_row3 = [block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(), block1.clone(),
               block1.clone(), block1.clone(), block1.clone()]

# 2 DIMENSIONAL LIST TO ACCESS ALL BLOCKS
all_blocks = [blocks_row1, blocks_row2, blocks_row3]


def starting_block_positions():
    for n in range(len(all_blocks)):
        for i in range(len(blocks_row1)):
            all_blocks[n][i].penup()

            all_blocks[n][i].color(random.choice(colors))
            all_blocks[n][i].goto(((BORDER_LEFT + 50) + (85 * i)), ((BORDER_TOP - 40) - (n * 45)))


########################################
#          PLAYER'S PADDLE             #
########################################
paddle = turtle.Turtle()
paddle.shape("square")
paddle.color("white")
paddle.speed(0)
paddle.shapesize(2, 8)  # Size of paddle = 40*160
paddle_position_x = paddle.xcor()
paddle_position_y = paddle.ycor()


def starting_paddle_position():
    paddle.penup()
    paddle.goto(0, BORDER_BOT + 30)


def move_left():
    if paddle.xcor() > (BORDER_LEFT + 20):
        paddle.setx(paddle.xcor() - 10)


def move_right():
    if paddle.xcor() < (BORDER_RIGHT - 20):
        paddle.setx(paddle.xcor() + 10)


########################################
#           PLAYER'S BALL              #
########################################
ball = turtle.Turtle()
ball.shape("circle")
ball.color("white")
ball.fillcolor("white")
ball.speed(0)


# NOT ACTIVE
def time_ball_speed():
    global ball_speed
    if (time.perf_counter() - timer) % 15 <= 1:
        ball_speed *= 2
    return ball_speed


def starting_ball_position():
    ball.hideturtle()
    ball.penup()
    ball.goto(0, 0)
    ball.setheading(270)


# BALL IS MOVING
def moving_ball():
    ball.forward(ball_speed)


# WN SIDE LIMIT
def side_limit_check():
    if ball.xcor() <= (BORDER_LEFT + 10) or ball.xcor() >= (BORDER_RIGHT - 10):
        ball.setheading(180 + -ball.heading())
        ball.forward(ball_speed)


# WN CHECK LIMIT BOT
def bot_limit_check():
    global life
    if ball.ycor() <= BORDER_BOT:
        life -= 1
        draw_life()
        starting_ball_position()
        return life


# WN CHECK LIMIT TOP
def top_limit_check():
    if ball.ycor() >= BORDER_TOP:
        ball.setheading(-ball.heading())
        ball.forward(ball_speed)


# COLLISION WITH BOX CHECK
def collision_block_check():
    global game_score
    for n in range(len(all_blocks)):
        for i in range(len(blocks_row1)):
            if (abs(ball.xcor() - all_blocks[n][i].xcor()) < 40) and \
                    (abs(ball.ycor() - all_blocks[n][i].ycor()) < 20) and (all_blocks[n][i].isvisible() == True):
                all_blocks[n][i].hideturtle()
                ball.setheading(-ball.heading())
                ball.forward(ball_speed)
                game_score += 1  # GAME SCORE +1 (FOR WIN = 27)
                draw_game_score()


# COLLISION WITH PADDLE CHECK
def collision_paddle_check():
    if (abs((abs(ball.xcor()) - abs(paddle.xcor()))) < (160 / (life+1))) and (ball.ycor() <= (paddle.ycor() + 20)):
        if ball.heading() == 270 or -270:
            ball.setheading(random.randint(45, 135))
        else:
            ball.setheading(-ball.heading())
            ball.forward(ball_speed)


##########################################
#             DRAW SCORE                 #
##########################################
game_score = 0
show_game_score = turtle.Turtle()
show_game_score.penup()
show_game_score.pencolor("DarkRed")
show_game_score.speed(0)
show_game_score.goto(300, -480)
show_game_score.color("DarkRed")
show_game_score.write("SCORE: " + str(game_score), font=("Arial", 10, "bold"))


def draw_game_score():
    global game_score
    show_game_score.clear()
    show_game_score.write("SCORE: " + str(game_score), font=("Arial", 10, "bold"))


def score_control():
    global game_score
    if game_score == 27:
        wn.clear()
        game_over = turtle.Turtle()
        game_over.penup()
        game_over.pencolor("black")
        game_over.speed(0)
        game_over.goto((BORDER_LEFT + 10), 0)
        game_over.write("YOU WON!", font=("Arial", 50, "bold"))
        time.sleep(5)

##########################################
#            DRAW TIMER                  #
##########################################
# timer = 0
# show_timer = turtle.Turtle()
# show_timer.penup()
# show_timer.pencolor("black")
# show_timer.speed(0)
# show_timer.goto(410, -480)
# show_timer.color("white")


# def draw_timer():
#    global game_time_total
#    show_timer.clear()
#    show_timer.write(game_time_total, font=("Arial", 10, "bold"))


#######################################
#         DRAW LIFE                   #
#######################################
show_life = turtle.Turtle()
show_life.penup()
show_life.pencolor("black")
show_life.speed(0)
show_life.goto((BORDER_LEFT + 2), (BORDER_BOT + 10))
show_life.color("DarkRed")


def draw_life():
    global life
    show_life.clear()
    show_life.write("Lifes: " + str(life), font=("DarkRed", 20, "bold"))


def life_control():
    global life
    if life == 3:
        # timer = time.perf_counter()
        width_paddle = 8 / life
        paddle.shapesize(2, width_paddle)
        return
    elif life == 2:
        # timer = time.perf_counter()
        width_paddle = 8 / life
        paddle.shapesize(2, width_paddle)
        return

    elif life == 1:
        # timer = time.perf_counter()
        width_paddle = 8
        paddle.shapesize(2, width_paddle / life)
        return

    else:
        wn.clear()
        game_over = turtle.Turtle()
        game_over.penup()
        game_over.pencolor("black")
        game_over.speed(0)
        game_over.goto((BORDER_LEFT + 10), 0)
        game_over.write("GAME OVER!", font=("Arial", 50, "bold"))
        time.sleep(5)


#######################################
#          MAIN CODE...               #
#######################################

# Starting position for Blocks & Paddle
starting_block_positions()
starting_paddle_position()
starting_ball_position()
draw_life()

while 1 == 1:
    # game_time_total = time.perf_counter()
    life_control()
    score_control()
    ball.showturtle()
    side_limit_check()
    # if & elif to speed up code
    if ball.ycor() > 350:
        top_limit_check()
        collision_block_check()
    elif ball.ycor() < -350:
        collision_paddle_check()
        bot_limit_check()
    # time_ball_speed()
    # draw_timer()
    moving_ball()

    wn.onkeypress(move_left, "a")
    wn.onkeypress(move_left, "Left")
    wn.onkeypress(move_right, "Right")
    wn.onkeypress(move_right, "d")
    wn.listen()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Turtle Detection ChinaPlaneFlyer 1 626 Apr-17-2023, 02:49 PM
Last Post: deanhystad
Star I was making code for collision for my character izmamonke 2 2,054 Aug-06-2021, 04:30 PM
Last Post: izmamonke
  bouncing ball with variable collision points (in time) Zhaleh 1 2,327 Jul-24-2020, 02:54 PM
Last Post: Marbelous
  Player object wont recognize collision with other objects. Jan_97 3 2,661 Dec-22-2019, 04:08 PM
Last Post: joe_momma
  wn = turtle.screen() AttributeError: module 'turtle' has no attribute 'screen' Shadower 1 6,129 Feb-06-2019, 01:25 AM
Last Post: woooee
  Help! Turtle not working, even when we click the turtle demo in IDLE nothing happens. BertyBee 3 5,545 Jan-04-2019, 02:44 AM
Last Post: SheeppOSU
  Collision function problem jtstewart95 2 2,719 May-02-2018, 11:44 PM
Last Post: scidam
  Union of dictionaries (taking max value on collision) meee 5 3,708 Jan-17-2018, 09:14 PM
Last Post: Mekire
  Need help figuring out Sprite.Group Collision code PySam 3 3,327 Sep-15-2017, 03:00 AM
Last Post: PySam

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020