Python 3.3 - Trouble Aligning Buttons and Labels with tkinter - python-3.x

I'm having trouble aligning my buttons and labels in a python PONG game gui I created with tkinter. I've searched for answers on how to do this but found nothing that resolved my issue.
What I'm trying to do is make the buttons not all stack on top of each other. I want the score for the left player aligned to the left of the screen, and the score for the right player aligned to the right of the screen, and to be able to understand how to move the other buttons where I want them.
Things I've tried:
anchor = "..."
justify = "..."
grid(row="...", column = "...")
Any help would be appreciated. I'm not sure how to fix this.
I'm wondering if it has to do with my use of canvas and buttons together?
Here is my code for the full program:
#PONG Game
from tkinter import *
import random
#http://www.tutorialspoint.com/python/tk_anchors.htm
#Globals
ball_x1 = 480
ball_x2 = 520
ball_y1 = 280
ball_y2 = 320
left_paddle_x1 = 0
left_paddle_x2 = 20
left_paddle_y1 = 240
left_paddle_y2 = 360
right_paddle_x1 = 980
right_paddle_x2 = 1000
right_paddle_y1 = 240
right_paddle_y2 = 360
left_player_score = 0
right_player_score = 0
paused = False
ball_x_motion = 10#random.randrange(-20, 20) #actually need to make a set number but random direction
ball_y_motion = 10#random.randrange(-20, 20)
def start():
global paused
if(field.coords(ball)[0] == 480):
paused = False
ball_movement()
else:
new_game(False)
def pause():
global paused
if(paused):
paused = False
else:
paused = True
ball_movement()
def new_game(reset):
global ball_x1, ball_x2, ball_y1, ball_y2, left_paddle_x1, left_paddle_x2, left_paddle_y1, left_paddle_yw
global right_paddle_x1, right_paddle_x2, right_paddle_y1, right_paddle_y2
global paused, left_player_score, right_player_score
print("here1")
if(reset):
left_player_score = 0
right_player_score = 0
print("here")
left_player_score_label.config(text=left_player_score)
right_player_score_label.config(text=right_player_score)
left_paddle_x1 = 0
left_paddle_x2 = 20
left_paddle_y1 = 240
left_paddle_y2 = 360
right_paddle_x1 = 980
right_paddle_x2 = 1000
right_paddle_y1 = 240
right_paddle_y2 = 360
field.coords(left_paddle, left_paddle_x1, left_paddle_y1, left_paddle_x2, left_paddle_y2)
field.coords(right_paddle, right_paddle_x1, right_paddle_y1, right_paddle_x2, right_paddle_y2)
paused = True
print("here2")
#starting positions
ball_x1 = 480
ball_x2 = 520
ball_y1 = 280
ball_y2 = 320
field.coords(ball, ball_x1, ball_y1, ball_x2, ball_y2)
#Event Handlers
def ball_movement():
#while(variable = true) move ball
# move the object
global ball_x_motion, ball_y_motion, ball_x1, ball_x2, ball_y1, ball_y2, paused
global left_player_score, right_player_score
#keep ball on playing field horizontally if ball hits paddles
print(((((left_paddle_y1 + left_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))))
if(((ball_x1 <= 20) and (-60 <= ((((left_paddle_y1 + left_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))) <= 60)) or ((ball_x2 >= 980) and (-60 <= ((((right_paddle_y1 + right_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))) <= 60))):
ball_x_motion = -ball_x_motion
#increase speed
elif(ball_x1 <=0):
right_player_score += 1
new_game(False)
#paused = True
right_player_score_label.config(text=right_player_score)
elif(ball_x2 >= 1000):
left_player_score += 1
new_game(False)
#paused = True
left_player_score_label.config(text=left_player_score)
if(field.coords(ball)[1] <= 0 or field.coords(ball)[3] >= 600): #keep ball in playing field vertically
ball_y_motion = -ball_y_motion
#increase speed
if(not paused):
field.coords(ball, ball_x1 + ball_x_motion, ball_y1 + ball_y_motion, ball_x2 + ball_x_motion, ball_y2 + ball_y_motion)
ball_x1 = field.coords(ball)[0]
ball_x2 = field.coords(ball)[2]
ball_y1 = field.coords(ball)[1]
ball_y2 = field.coords(ball)[3]
#ball moves every 10 milliseconds
field.after(10, ball_movement)
def move_left_paddle_up(event):
global left_paddle_y1, left_paddle_y2
#print(event.keysym)
if(field.coords(left_paddle)[1] > 0):
field.move("left_paddle", 0, -40)
left_paddle_y1 = field.coords(left_paddle)[1]
left_paddle_y2 = field.coords(left_paddle)[3]
def move_left_paddle_down(event):
global left_paddle_y1, left_paddle_y2
if(field.coords(left_paddle)[3] < 600):
field.move("left_paddle", 0, 40)
left_paddle_y1 = field.coords(left_paddle)[1]
left_paddle_y2 = field.coords(left_paddle)[3]
def move_right_paddle_up(event):
global right_paddle_y1, right_paddle_y2
if(field.coords(right_paddle)[1] > 0):
field.move("right_paddle", 0, -40)
right_paddle_y1 = field.coords(right_paddle)[1]
right_paddle_y2 = field.coords(right_paddle)[3]
#print(event.keysym)
def move_right_paddle_down(event):
global right_paddle_y1, right_paddle_y2
if(field.coords(right_paddle)[3] < 600):
field.move("right_paddle", 0, 40)
right_paddle_y1 = field.coords(right_paddle)[1]
right_paddle_y2 = field.coords(right_paddle)[3]
#print(event.keysym)
#Canvas
master = Tk() #master
field = Canvas(master, width=1000, height=600, bg="black") #playing field
master.bind('<w>', move_left_paddle_up) #left paddle up
master.bind('<s>', move_left_paddle_down) #left paddle down
master.bind('<Up>', move_right_paddle_up) #right paddle up
master.bind('<Down>', move_right_paddle_down) #right paddle down
#create field border lines with a rectangle
border = field.create_rectangle(0, 0, 1000, 600, fill="gray")
#create midline
midline = field.create_line(500, 0, 500, 600, fill="white", dash=(4, 4))
#create ball
ball = field.create_oval(ball_x1, ball_y1, ball_x2, ball_y2, fill="white", tags=("ball"))
#create left paddle
left_paddle = field.create_rectangle(left_paddle_x1, left_paddle_y1, left_paddle_x2, left_paddle_y2, fill="red", tags=("left_paddle"))
#create right paddle
right_paddle = field.create_rectangle(right_paddle_x1, right_paddle_y1, right_paddle_x2, right_paddle_y2, fill="blue", tags=("right_paddle"))
#create Pause Button
pause_button = Button(master, text="Pause/Unpause", command=pause)
#pause_button.grid(row=1, column=1)
pause_button.pack()
#create Start Button
start_button = Button(master, text="Start", command=start)
#start_button.grid(row=1, column=3)
start_button.pack()
#left player scorekeeper
left_player_score_label = Label(master, text=left_player_score)
left_player_score_label.pack()
#right player scorekeeper
right_player_score_label = Label(master, text=right_player_score)
right_player_score_label.pack()
#create New Game Button
new_game_button = Button(master, text="New Game", command=lambda: new_game(True))
#new_game_button.grid(row=1, column=2)
new_game_button.pack()
#pack it all together on the screen
field.pack()
#execute loop to run screen processing
mainloop()
Edit
This is the final result after changing from pack() to grid(). I realized that you don't use both, but rather one or the other.
#PONG Game
from tkinter import *
import random
#http://www.tutorialspoint.com/python/tk_anchors.htm
#Globals
ball_x1 = 480
ball_x2 = 520
ball_y1 = 280
ball_y2 = 320
left_paddle_x1 = 0
left_paddle_x2 = 20
left_paddle_y1 = 240
left_paddle_y2 = 360
right_paddle_x1 = 980
right_paddle_x2 = 1000
right_paddle_y1 = 240
right_paddle_y2 = 360
left_player_score = 0
right_player_score = 0
paused = False
direction_factor = random.randrange(0,1)
ball_x_motion = 5
ball_y_motion = random.randrange(-5, 5)
if direction_factor == 0:
ball_x_motion *= -1
def start():
global paused
if(field.coords(ball)[0] == 480):
paused = False
ball_movement()
else:
new_game(False)
def pause():
global paused
if(paused):
paused = False
else:
paused = True
ball_movement()
def new_game(reset):
global ball_x1, ball_x2, ball_y1, ball_y2, left_paddle_x1, left_paddle_x2, left_paddle_y1, left_paddle_yw
global right_paddle_x1, right_paddle_x2, right_paddle_y1, right_paddle_y2
global paused, left_player_score, right_player_score, ball_x_motion, ball_y_motion, direction_factor
direction_factor = random.randrange(0,1)
ball_x_motion = 10
ball_y_motion = random.randrange(-10, 10)
if direction_factor == 0:
ball_x_motion *= -1
if(reset):
left_player_score = 0
right_player_score = 0
left_player_score_label.config(text=left_player_score)
right_player_score_label.config(text=right_player_score)
left_paddle_x1 = 0
left_paddle_x2 = 20
left_paddle_y1 = 240
left_paddle_y2 = 360
right_paddle_x1 = 980
right_paddle_x2 = 1000
right_paddle_y1 = 240
right_paddle_y2 = 360
field.coords(left_paddle, left_paddle_x1, left_paddle_y1, left_paddle_x2, left_paddle_y2)
field.coords(right_paddle, right_paddle_x1, right_paddle_y1, right_paddle_x2, right_paddle_y2)
paused = True
#starting positions
ball_x1 = 480
ball_x2 = 520
ball_y1 = 280
ball_y2 = 320
field.coords(ball, ball_x1, ball_y1, ball_x2, ball_y2)
#Event Handlers
def ball_movement():
#while(variable = true) move ball
# move the object
global ball_x_motion, ball_y_motion, ball_x1, ball_x2, ball_y1, ball_y2, paused
global left_player_score, right_player_score
#keep ball on playing field horizontally if ball hits paddles
#print(((((left_paddle_y1 + left_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))))
if(((ball_x1 <= 20) and (-60 <= ((((left_paddle_y1 + left_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))) <= 60)) or ((ball_x2 >= 980) and (-60 <= ((((right_paddle_y1 + right_paddle_y2)/2) - ((ball_y1 + ball_y2)/2))) <= 60))):
ball_x_motion *= -1.1
#ball_y_motion = ball_y_motion + 5
elif(ball_x1 <=0):
right_player_score += 1
new_game(False)
#paused = True
right_player_score_label.config(text=right_player_score)
elif(ball_x2 >= 1000):
left_player_score += 1
new_game(False)
#paused = True
left_player_score_label.config(text=left_player_score)
if(field.coords(ball)[1] <= 0 or field.coords(ball)[3] >= 600): #keep ball in playing field vertically
ball_y_motion = -ball_y_motion
if(not paused):
field.coords(ball, ball_x1 + ball_x_motion, ball_y1 + ball_y_motion, ball_x2 + ball_x_motion, ball_y2 + ball_y_motion)
ball_x1 = field.coords(ball)[0]
ball_x2 = field.coords(ball)[2]
ball_y1 = field.coords(ball)[1]
ball_y2 = field.coords(ball)[3]
#ball moves every 10 milliseconds
field.after(10, ball_movement)
def move_left_paddle_up(event):
global left_paddle_y1, left_paddle_y2
#print(event.keysym)
if(field.coords(left_paddle)[1] > 0):
field.move("left_paddle", 0, -40)
left_paddle_y1 = field.coords(left_paddle)[1]
left_paddle_y2 = field.coords(left_paddle)[3]
def move_left_paddle_down(event):
global left_paddle_y1, left_paddle_y2
if(field.coords(left_paddle)[3] < 600):
field.move("left_paddle", 0, 40)
left_paddle_y1 = field.coords(left_paddle)[1]
left_paddle_y2 = field.coords(left_paddle)[3]
def move_right_paddle_up(event):
global right_paddle_y1, right_paddle_y2
if(field.coords(right_paddle)[1] > 0):
field.move("right_paddle", 0, -40)
right_paddle_y1 = field.coords(right_paddle)[1]
right_paddle_y2 = field.coords(right_paddle)[3]
#print(event.keysym)
def move_right_paddle_down(event):
global right_paddle_y1, right_paddle_y2
if(field.coords(right_paddle)[3] < 600):
field.move("right_paddle", 0, 40)
right_paddle_y1 = field.coords(right_paddle)[1]
right_paddle_y2 = field.coords(right_paddle)[3]
#print(event.keysym)
#Canvas
master = Tk() #master
field = Canvas(master, width=1000, height=600, bg="black") #playing field
field.grid(row=4, columnspan=10)
#field.pack()
master.bind('<w>', move_left_paddle_up) #left paddle up
master.bind('<s>', move_left_paddle_down) #left paddle down
master.bind('<Up>', move_right_paddle_up) #right paddle up
master.bind('<Down>', move_right_paddle_down) #right paddle down
#create field border lines with a rectangle
border = field.create_rectangle(0, 0, 1000, 600, fill="gray")
#create midline
midline = field.create_line(500, 0, 500, 600, fill="white", dash=(4, 4))
#create ball
ball = field.create_oval(ball_x1, ball_y1, ball_x2, ball_y2, fill="white", tags=("ball"))
#create left paddle
left_paddle = field.create_rectangle(left_paddle_x1, left_paddle_y1, left_paddle_x2, left_paddle_y2, fill="red", tags=("left_paddle"))
#create right paddle
right_paddle = field.create_rectangle(right_paddle_x1, right_paddle_y1, right_paddle_x2, right_paddle_y2, fill="blue", tags=("right_paddle"))
#create Pause Button
pause_button = Button(master, text="Pause/Unpause", command=pause)
pause_button.grid(row=1, column=6)
#pause_button.pack()
#create Start Button
start_button = Button(master, text="Start", command=start)
start_button.grid(row=1, column=4)
#start_button.pack()
#left player scorekeeper
left_player_score_label = Label(master, text=left_player_score)
left_player_score_label.grid(row=1, column=0)
#left_player_score_label.pack()
#right player scorekeeper
right_player_score_label = Label(master, text=right_player_score)
right_player_score_label.grid(row=1, column=9)
#right_player_score_label.pack()
#create New Game Button
new_game_button = Button(master, text="New Game", command=lambda: new_game(True))
new_game_button.grid(row=1, column=5)
#new_game_button.pack()
#pack it all together on the screen
#field.pack()
#execute loop to run screen processing
mainloop()

I realized that you don't use both the grid manager and the pack manager, it's one or the other. So I deleted the pack()'s that I had and used all grid()'s and posted the final result.

Related

Pygame isn't moving a rectangle that i drew on screen

Here is the code for the game i'm trying to make (a flappy bird remake)
def move():
global bird_x
global bird_y
pygame.draw.rect(win,(0,0,0), (0,0,1000,1000))
pygame.draw.rect(win,(255,0,0),(bird_x, bird_y, 30, 30))
pygame.display.update()
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
bird_y += 60
fb.move()
time.sleep(0.005)
When i try to run this code, the 'bird' (red square) doesn't move, i've changed the keys used, i've taken the movement in and out of functions, and nothing's working.
(this is trimmed code, so the variables probably wont exist)
full code:
import time
import random
pygame.init()
win = pygame.display.set_mode((400,600))
pygame.display.set_caption('Flappy Bird')
pipex = 345
pipe1y = -270
pipe2y = 420
width = 65
height1 = 400
height2 = 3000
vel = 5
bird_x = 20
bird_y = 300
isJump = False
jumpCount = 10
class fb:
def move():
global pipex
global yy
global pipe1y
global pipe2y
global bird_x
global bird_y
pipex -= 1
if pipex < -60:
pipex = 345
yy = random.randint(-350,0)
pipe1y = yy
pipe2y = pipe1y + 555
pygame.draw.rect(win,(0,0,0), (0,0,1000,1000))
pygame.draw.rect(win,(0, 255, 0), (pipex, pipe1y, width, height1))
pygame.draw.rect(win,(0, 255, 100), (pipex, pipe2y, width, height2))
pygame.draw.rect(win,(255,0,0),(bird_x, bird_y, 30, 30))
pygame.display.update()
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
bird_y += 60
fb.move()
time.sleep(0.005)
Change your main loop to this:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
bird_y -= 1
if keys[pygame.K_DOWN]:
bird_y += 1
fb.move()
time.sleep(0.005)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
break
you didn't test for events
you need to handle events
PS:
I added a down movement

My code wont run properly when other files try to use it

So my code as been acting up and I don't know what the problem is. When I try to test the file "Battle" it works like it supposed to and everything is fine. It pulls up a tkinter window like I want to, shows the buttons, My sprites, etc. But when I use my main file to run the Battle file it doesn't show the buttons, listbox, or sprites. I looked all over my code and I cant find out whats wrong. If anyone could help me then that would be great! It's a lot of code and I am kinda a rookie so it may not be the cleanest but I do leave a lot of notes.
This is the Battle code:
import tkinter as tk
import random
import time
inBattle = False
gameOver = True
i = 0
enemy_type = 0
MAX_HP = 60
MAX_MP = 40
HPval = 20
MPval = 30
POTIONSval = 3
#test
def add_text(recap):
global i
recap.insert(0, 'Damage: ' + str(i))
i += 1
#switch to turn the whole thing on or off
def GameOver():
global gameOver
if gameOver == True:
gameOver = False
else:
gameOver = True
#spells
def Cast_Fireball(spells, MP, recap):
global MPval
if MPval - 10 > 0 or MPval - 10 == 0:
MPval -= 10
MP.config(text='MP: ' + str(MPval))
hit = random.randint(0, 100)
damage = random.randint(1,10) # 1d10
if hit > 9: # 90%
recap.insert(0, 'Hit for ' + str(damage))
spells.destroy()
else:
recap.insert(0, 'Missed!')
spells.destroy()
else:
recap.insert(0, 'Not enough mana.')
spells.destroy()
def Cast_Iceball(spells, MP, recap):
global MPval
if MPval - 12 > 0 or MPval - 12 == 0:
MPval -= 12
MP.config(text='MP: ' + str(MPval))
hit = random.randint(0, 100)
damage = random.randint(1,6) * 2 # 2d6
if hit > 4: # 95%
recap.insert(0, 'Hit for ' + str(damage))
spells.destroy()
else:
recap.insert(0, 'Missed!')
spells.destroy()
else:
recap.insert(0, 'Not enough mana.')
spells.destroy()
def Cast_Heal(spells, HP, MP, recap):
global MPval
global HPval
if MPval - 15 > 0 or MPval - 15 == 0:
if HPval < MAX_HP:
MPval -= 15
MP.config(text='MP: ' + str(MPval))
damage = random.randint(7,25) # 2d10 + 5
if HPval + damage > MAX_HP:
damage = MAX_HP - HPval
recap.insert(0, 'Healed for ' + str(damage))
HPval += damage
HP.config(text='HP: ' + str(HPval))
spells.destroy()
else:
recap.insert(0, 'Not enough mana.')
spells.destroy()
def Cast_Drain(spells, MP, recap):
global MPval
hit = random.randint(0, 100)
damage = random.randint(1,6) # 1d6
if hit > 19: # 80%
recap.insert(0, 'Hit for ' + str(damage))
recap.insert(0, 'Recovered some mana!')
MPval += damage
MP.config(text='MP: ' + str(MPval))
spells.destroy()
else:
recap.insert(0, 'Missed!')
spells.destroy()
#activates window for spell list
def Spell_list(HP, MP, recap):
spells = tk.Tk()
spells.title("Spell List")
spells.minsize(150,168)
Fireball = tk.Button(spells, text='Fireball', bg='black', font=("arial", 15, "bold"), fg="white", width=12, command= lambda: Cast_Fireball(spells, MP, recap))
Fireball.pack()
Iceball = tk.Button(spells, text='Iceball', bg='black', font=("arial", 15, "bold"), fg="white", width=12, command= lambda: Cast_Iceball(spells, MP, recap))
Iceball.pack()
Mana_Drain = tk.Button(spells, text='Mana Drain', bg='black', font=("arial", 15, "bold"), fg="white", width=12, command= lambda: Cast_Drain(spells, MP, recap))
Mana_Drain.pack()
Crude_Heal = tk.Button(spells, text='Crude Heal', bg='black', font=("arial", 15, "bold"), fg="white", width=12, command= lambda: Cast_Heal(spells, HP, MP, recap))
Crude_Heal.pack()
spells.mainloop()
#drinks a max hp potion and checks if your full already and doesn't use it
def Drink_Potion(HP,POTIONS,recap):
global HPval
global POTIONSval
if POTIONSval > 0 and HPval < MAX_HP:
temp = MAX_HP - HPval
HPval = MAX_HP
POTIONSval -= 1
recap.insert(0, 'Healed for ' + str(temp))
HP.config(text="HP: " + str(HPval))
POTIONS.config(text="Potions: " + str(POTIONSval))
#main fucntion
def Battle():
#trigger so the player on the other screen is stopped and cant move
global inBattle
global HPval
global MPval
global POTIONSval
global enemy_type
inBattle = True
#screen settings
screen = tk.Tk()
screen.title("Encounter")
screen.minsize(1000,500)
screen.configure(bg='black')
#background settings and rectangle for the bottom half of screen
canvas = tk.Canvas(screen, width=1000, height=500)
canvas.configure(bg='black')
canvas.pack()
canvas.create_rectangle(3,300,1000,500,fill='white')
sprites = tk.Canvas(screen, width=200, height=200, bg='black')
sprites.place(x=285, y=50)
#choses which enemy to fight
#enemy_type = random.randint(0,6)
#spawning of the enemy
if enemy_type == 0:
img = tk.PhotoImage(file='sprites/slime.png')
sprites.create_image(20,20, image=img, anchor="nw")
#box on right to list the past actions
recap = tk.Listbox(screen, font=("arial", 14), bg="white", width=22, height=12)
recap.place(x=754, y=10)
#trackers for health, mana, and potions
HP = tk.Label(screen, text="HP: " + str(HPval), font=("arial",30), bg="white")
HP.place(x=775, y=310)
MP = tk.Label(screen, text="MP: " + str(MPval), font=("arial",30), bg="white")
MP.place(x=775, y=360)
Potions = tk.Label(screen, text="Potions: " + str(POTIONSval), font=("arial",30), bg="white")
Potions.place(x=775, y=410)
#buttons for commands
Attack = tk.Button(screen,text="Attack",width=9, height=4, bg="black", fg="white", font=("arial", 24, "bold"), command= lambda: add_text(recap))
Attack.place(x=10, y= 313)
Defend = tk.Button(screen,text="Defend",width=9, height=4, bg="black", fg="white", font=("arial", 24, "bold"))
Defend.place(x=200, y= 313)
Item = tk.Button(screen,text="Item",width=9, height=4, bg="black", fg="white", font=("arial", 24, "bold"), command= lambda: Drink_Potion(HP, Potions, recap))
Item.place(x=390, y= 313)
Magic = tk.Button(screen,text="Magic",width=9, height=4, bg="black", fg="white", font=("arial", 24, "bold"), command= lambda: Spell_list(HP, MP, recap))
Magic.place(x=580, y= 313)
screen.mainloop()
#testing purposes / comment out on release
#Battle()
This is the Main code:
import random
import turtle
import tkinter as tk
import time
import Battle
callOnce = False
GWIDTH = 800
GHEIGHT = 800
SWIDTH = 50
SHEIGHT = 50
START_Y = 0
END_Y = 0
PLAYER_X = 0
PLAYER_Y = 0
BUFFER = 80
DungeonCord = []
DungeonStorage = []
Treasure = []
pathingPlaces = []
pathingAmount = 0
start = tk.Tk()
start.title("Dungeon Generator")
start.minsize(500,500)
#generate function making it save the set x and y and passing it to the turtle functions
def Generate():
global GHEIGHT
global GWIDTH
Battle.GameOver()
GWIDTH = xInsert.get()
GHEIGHT = yInsert.get()
start.destroy()
DunGenText = tk.Label(text="Dungeon Generator", relief="solid", width = 20, font=("arial", 24, "bold"))
DunGenText.place(x=60, y=35)
xLabel = tk.Label(text="X Grid Count:", width = 10, font=("arial", 14))
xLabel.place(x=145,y=145)
xInsert = tk.Entry(start, width=5)
xInsert.place(x=280,y=150)
yLabel = tk.Label(text="Y Grid Count:", width = 10, font=("arial", 14))
yLabel.place(x=145,y=245)
yInsert = tk.Entry(start, width=5)
yInsert.place(x=280,y=250)
button = tk.Button(start,text="Generate",width=30, bg="black", fg="white", command=Generate)
button.place(x=135, y=450)
start.mainloop()
#main loop for the turtle side of things
while not Battle.gameOver:
#window settings
wn = turtle.Screen()
wn.title("Dungeon Crawler")
wn.setup(width=(int(GWIDTH) * int(SWIDTH))+BUFFER, height=(int(GHEIGHT) * int(SHEIGHT))+BUFFER)
wn.bgcolor("black")
wn.tracer(0)
#where the grid would start to draw itself
Gridx = (int(GWIDTH) * int(SWIDTH) * -1) / 2
Gridy = (int(GHEIGHT) * int(SHEIGHT)) /2
#this will determine the lowest number between the x axis and the y axis
if int(GWIDTH) > int(GHEIGHT):
LOWEST = int(GHEIGHT)
else:
LOWEST = int(GWIDTH)
#this is the formula for the dungeon count in the grid // ((x * y) - 2y) / l
DCOUNT = ((int(GHEIGHT) * int(GWIDTH)) - (2 * int(GHEIGHT))) / int(LOWEST)
#the function to draw the grid
def draw_grid(t, x, y, sx, sy,):
for i in range(int(y)):
for j in range(int(x)):
t.penup()
t.goto(x= Gridx + (sx * int(j)), y= Gridy - (sy * int(i)))
t.pendown()
t.forward(sx)
t.right(90)
t.forward(sx)
t.right(90)
t.forward(sx)
t.right(90)
t.forward(sx)
t.right(90)
#function to draw a square at a location
def draw_square(t, s):
for i in range(4):
t.forward(int(s) * 20)
t.right(90)
#drawing the circle on the left side that would be the start
def draw_start(t, t2):
global START_Y
global PLAYER_Y
START_Y = random.randint(0, int(GHEIGHT) - 1)
PLAYER_Y = START_Y
t.penup()
t.goto(x= Gridx + (SWIDTH / 2), y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * START_Y) - 10)
t.pendown()
t.circle(10)
t2.penup()
t2.goto(x= Gridx + (SWIDTH / 2), y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * START_Y))
t2.pendown()
draw_player(t2)
#drawing a circle on the right side that would be the end
def draw_end(t):
global END_Y
END_Y = random.randint(0, int(GHEIGHT) - 1)
t.penup()
t.goto(x= (Gridx + (SWIDTH / 2)) * -1, y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * END_Y) - 10)
t.pendown()
t.circle(10)
#draws the player at its location
def draw_player(t):
t.penup()
t.goto(x= (Gridx + (SWIDTH / 2)) + (SWIDTH * PLAYER_X) - 10, y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * PLAYER_Y)+3)
t.pendown()
for i in range(50):
t.forward(20)
t.right(144)
#drawing the dungeon at random locations that can be anyware between the entrance and the exit.
def draw_dungeons(t, d):
global DungeonCord
global Treasure
for i in range(int(d)):
closestX = random.randint(1, int(GWIDTH) - 2)
closestY = random.randint(0, int(GHEIGHT) - 1)
DungeonCord.append((closestX,closestY))
DungeonStorage.append((closestX,closestY))
for j in range(i):
if DungeonCord[j] == DungeonCord[i]:
closestX = random.randint(1, int(GWIDTH) - 2)
closestY = random.randint(0, int(GHEIGHT) - 1)
DungeonCord[i] = (closestX,closestY)
DungeonStorage[i] = (closestX,closestY)
if DungeonCord[j] == DungeonCord[i]:
closestX = random.randint(1, int(GWIDTH) - 2)
closestY = random.randint(0, int(GHEIGHT) - 1)
DungeonCord[i] = (closestX,closestY)
DungeonStorage[i] = (closestX,closestY)
#treasure room chance
TR = random.randint(1,5)
if TR == 5:
t.color("yellow")
Treasure.append(DungeonCord[i])
t.penup()
t.goto(x= (Gridx + (SWIDTH / 2)) + (SWIDTH * closestX) - 10, y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * closestY) + 10)
t.pendown()
draw_square(t, 1)
t.color("white")
#the pathmaking function that would go to each dungeon and from the start to the end
def draw_path(t):
global DungeonCord
global START_Y
global END_Y
global DCOUNT
global pathingAmount
global pathingPlaces
t.penup()
t.goto(x= Gridx + (SWIDTH / 2), y= (Gridy - (SHEIGHT / 2)) - (SHEIGHT * START_Y))
t.pendown()
myCordsx = 0
myCordsy = START_Y
dungeon = 0
for j in range(int(DCOUNT)):
traveling = True
closestX = 500
closestY = 500
#finds the closest dungeon
for i in range(int(DCOUNT)):
x, y = DungeonCord[i]
if abs(x - myCordsx) + abs(y - myCordsy) < abs(closestX - myCordsx) + abs(closestY - myCordsy):
closestX, closestY = x, y
dungeon = i
elif abs(x - myCordsx) + abs(y - myCordsy) == abs(closestX - myCordsx) + abs(closestY - myCordsy):
if x < closestX:
closestX, closestY = x, y
dungeon = i
#path to the current closest dungeon
while traveling:
if closestX > myCordsx: #path right
t.forward(int(SWIDTH))
myCordsx += 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif closestY > myCordsy: #path down
t.right(90)
t.forward(int(SWIDTH))
t.left(90)
myCordsy += 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif closestX < myCordsx: #path left
t.right(180)
t.forward(int(SWIDTH))
t.left(180)
myCordsx -= 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif closestY < myCordsy: #path up
t.left(90)
t.forward(int(SWIDTH))
t.right(90)
myCordsy -= 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
else:
traveling = False
i = 0 #reset on counter
DungeonCord[dungeon] = (99, 99) #null entry / dungeon is checked off
#pathing to the end
traveling = True
while traveling:
if int(GWIDTH) - 1 > myCordsx: #going right
t.forward(int(SWIDTH))
myCordsx += 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif END_Y > myCordsy: #going down
t.right(90)
t.forward(int(SWIDTH))
t.left(90)
myCordsy += 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif int(GWIDTH) - 1 != myCordsx and END_Y == myCordsy: #going left
t.right(180)
t.forward(int(SWIDTH))
t.left(180)
myCordsx -= 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
elif int(GWIDTH) - 1 == myCordsx and END_Y != myCordsy: #going up
t.left(90)
t.forward(int(SWIDTH))
t.right(90)
myCordsy -= 1
pathingPlaces.append((myCordsx, myCordsy))
pathingAmount +=1
else:
traveling = False
#all the turtle units involved in drawing
grid = turtle.Turtle()
grid.hideturtle()
grid.pencolor("white")
entrance = turtle.Turtle()
entrance.hideturtle()
entrance.pencolor("green")
end = turtle.Turtle()
end.hideturtle()
end.pencolor("red")
dun = turtle.Turtle()
dun.hideturtle()
dun.pencolor("white")
dun.shape("square")
path = turtle.Turtle()
path.hideturtle()
path.pencolor("green")
player = turtle.Turtle()
player.hideturtle()
player.pencolor("pink")
#player movement
def moveUP():
global PLAYER_X
global PLAYER_Y
for i in range(pathingAmount):
if (PLAYER_X, PLAYER_Y - 1) == pathingPlaces[i] and not Battle.inBattle:
PLAYER_Y -= 1
player.clear()
draw_player(player)
for i in range(int(DCOUNT)):
if (PLAYER_X, PLAYER_Y) == DungeonStorage[i]:
Battle.Battle()
break
def moveDOWN():
global PLAYER_X
global PLAYER_Y
for i in range(pathingAmount):
if (PLAYER_X, PLAYER_Y + 1) == pathingPlaces[i] and not Battle.inBattle:
PLAYER_Y += 1
player.clear()
draw_player(player)
for i in range(int(DCOUNT)):
if (PLAYER_X, PLAYER_Y) == DungeonStorage[i]:
Battle.Battle()
break
def moveLEFT():
global PLAYER_X
global PLAYER_Y
for i in range(pathingAmount):
if (PLAYER_X - 1, PLAYER_Y) == pathingPlaces[i] and not Battle.inBattle:
PLAYER_X -= 1
player.clear()
draw_player(player)
for i in range(int(DCOUNT)):
if (PLAYER_X, PLAYER_Y) == DungeonStorage[i]:
Battle.Battle()
break
def moveRIGHT():
global PLAYER_X
global PLAYER_Y
for i in range(pathingAmount):
if (PLAYER_X + 1, PLAYER_Y) == pathingPlaces[i] and not Battle.inBattle:
PLAYER_X += 1
player.clear()
draw_player(player)
for i in range(int(DCOUNT)):
if (PLAYER_X, PLAYER_Y) == DungeonStorage[i]:
Battle.Battle()
break
#a call once function so the dungeons, start, and end doesn't keep drawing.
if callOnce == False:
draw_grid(grid, GWIDTH, GHEIGHT, SWIDTH, SHEIGHT)
draw_start(entrance, player)
draw_end(end)
draw_dungeons(dun, DCOUNT)
draw_path(path)
callOnce = True
wn.listen()
wn.onkey(moveRIGHT, "d")
wn.onkey(moveUP, "w")
wn.onkey(moveLEFT, "a")
wn.onkey(moveDOWN, "s")
while True:
wn.update()
Never Mind, the problem was tkinter itself. Just needed to change the tk.Tk() in my battle code to tk.Toplevel() since you cant have two tk.Tk() code. Well..... Damn

Why do my player images "streak" when they go outside the court on my screen?

My players move fine until they move outside they court, until the images streak. Why is this?
I tried changing screen.fill(OUT) to drawing a rectangle the size of the screen.
import pygame
import time
pygame.init()
# Define some colors
BLACK = (0, 0, 0)
OUT = (193, 58, 34)
COURT = (69, 150, 81)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
SKIN = (232, 214, 162)
ballspeed = 2
# Create the screen
windowsize = (700, 650)
screen = pygame.display.set_mode(windowsize)
pygame.display.set_caption('Tennis')
# Player Sprites
class Robert(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Robert_tennis.png")
self.rect = self.image.get_rect()
self.rect.center = (400, 575)
self.speedx = 0
self.speedy = 0
def update(self):
self.speedx = 0
self.speedy = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speedx = -4
if keystate[pygame.K_RIGHT]:
self.speedx = 4
self.rect.x += self.speedx
if self.rect.right > 700:
self.rect.right = 700
if self.rect.right < 0:
self.rect.left = 0
if keystate[pygame.K_UP]:
self.speedy = -5
if keystate[pygame.K_DOWN]:
self.speedy = 3
self.rect.y += self.speedy
if self.rect.y < 325:
self.rect.y = 325
if self.rect.y < 0:
self.rect.y = 0
class Camden(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("camden_tennis_front.png")
self.rect = self.image.get_rect()
self.rect.center = (260, 80)
self.speedx = 0
self.speedy = 0
def update(self):
self.speedx = 0
self.speedy = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_a]:
self.speedx = -6
if keystate[pygame.K_d]:
self.speedx = 6
self.rect.x += self.speedx
if self.rect.right > 700:
self.rect.right = 700
if self.rect.right < 0:
self.rect.left = 0
if keystate[pygame.K_w]:
self.speedy = -7
if keystate[pygame.K_s]:
self.speedy = 5
self.rect.y += self.speedy
if self.rect.y > 250:
self.rect.y = 250
if self.rect.y < 0:
self.rect.y = 0
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("tennisball.png")
self.rect = self.image.get_rect()
self.rect.center = (420, 450)
self.speedx = 0
self.speedy = 0
def update(self):
#Robert's forehand
if tennisball.rect.colliderect(robert) and tennisball.rect.x > robert.rect.x + 10:
robert.image = pygame.image.load("Robert_tennis2 (1).png")
effect = pygame.mixer.Sound('tennisserve.wav')
effect.play(0)
robert.rect.y -5
self.speedy = -8
self.speedx = 4
#Robert's backhand
if tennisball.rect.colliderect(robert) and tennisball.rect.x < robert.rect.x - 10:
robert.image = pygame.image.load("Robert_tennis2_backhand.png")
effect = pygame.mixer.Sound('tennisserve.wav')
effect.play(0)
robert.rect.y -5
self.speedy = -7
self.speedx = -3
#Camden's forehand
if tennisball.rect.colliderect(camden) and tennisball.rect.x < camden.rect.x -10:
camden.image = pygame.image.load("camden_front_forehand.png")
effect = pygame.mixer.Sound('tennisserve.wav')
effect.play(0)
camden.rect.y -5
self.speedy = 9
self.speedx = 2
keystate = pygame.key.get_pressed()
if keystate[pygame.K_TAB]:
self.speedx = -7
self.speedy = -12
self.speedy = self.speedy * .98
self.speedx = self.speedx * .978
self.rect = self.rect.move(self.speedx, self.speedy)
#Add people
all_sprites = pygame.sprite.Group()
robert = Robert()
camden = Camden()
tennisball = Ball()
all_sprites.add(robert)
all_sprites.add(tennisball)
all_sprites.add(camden)
carryOn = True
clock = pygame.time.Clock()
global score
score = 0
screen.fill(OUT)
while carryOn:
font = pygame.font.Font('freesansbold.ttf', 32)
camden.update()
robert.update()
tennisball.update()
epsilonComp = .1
if abs(tennisball.speedx) < epsilonComp and abs(tennisball.speedy) < epsilonComp:
if tennisball.rect.x != 360 and tennisball.rect.y != 325:
if time.time() > 1000:
score = 15
scorebox = font.render(str(score), True, WHITE, BLACK)
scoreRect = scorebox.get_rect()
scoreRect.center = (625, 50)
screen.blit(scorebox, scoreRect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
carryOn = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
carryOn = False
all_sprites.update()
#Fill the screen with a sky color
# Draw the court
pygame.draw.rect(screen, COURT, [175, 75, 350, 500])
#outer left line
pygame.draw.line(screen, WHITE, (175,574), (175,75), 7)
#outer right line
pygame.draw.line(screen, WHITE, (525,574), (525,75), 7)
#top center line
pygame.draw.line(screen, WHITE, (175, 200), (525,200), 7)
#top outer line
pygame.draw.line(screen, WHITE, (175, 78), (525,78), 7)
#bottom outer line
pygame.draw.line(screen, WHITE, (175, 571), (525,571), 7)
#bottom center line
pygame.draw.line(screen, WHITE, (175, 450), (525,450), 7)
#center white line
pygame.draw.line(screen, WHITE, (345,200), (345,450), 7)
#net
pygame.draw.line(screen, BLACK, (175,325), (525,325), 10)
# Update
all_sprites.draw(screen)
pygame.display.update()
clock.tick(60)
pygame.quit()
I just need the player's images to not streak and stay on the screen, and for them to move normally like they do while they're on the court.
I suspect the reason you see this corruption is the code is not clearing away that part of the background.
Each frame (event-loop iteration), the "court" is being re-painted, yet the are outstide this is only painted before the main loop starts.
E.g.:
screen.fill(OUT) # <-- HERE - paint the area outside
while carryOn:
font = pygame.font.Font('freesansbold.ttf', 32)
# ... rest of loop-body
Moving the screen.fill( OUT ) to inside the loop will clear the background too:
font = pygame.font.Font('freesansbold.ttf', 32)
while carryOn:
camden.update()
robert.update()
tennisball.update()
# ... Removed code for the sake of brevity
all_sprites.update()
# ensure the whole screen is cleared
screen.fill(OUT) # <-- HERE!
#Fill the screen with a sky color
# Draw the court
pygame.draw.rect(screen, COURT, [175, 75, 350, 500])
# ... etc
I also moved the font-loading outside the loop, there's no need to load it every frame.

Basket contact isn't restarting

I'm trying to make a game called Egg Catcher currently, for personal reasons (just for fun) and I'm a little bit stuck on my code. I want my egg to reset each time it either gets caught by the basket or it reaches the bottom, but it only checks for contact once and then it stops checking.. Please help.
import pygame
import random
caught_egg = False
a = 0
egg_radius = 15
x_egg = 0
y_egg = 5 + egg_radius
x_star = []
y_star = []
x_pos = 200
y_pos = 650
x_speed = 5
x_size = 100
y_size = 70
red = [255, 0, 0]
white = [255, 255, 255]
black = [0,0,0]
yellow = [255, 255, 0]
cyan = [0, 255, 255]
magenta = [255, 0, 255]
beige = [245,245,220]
wheat = [245,222,179]
egg_color_choices = [beige,wheat]
WINDOW_HEIGHT = 800
WINDOW_WIDTH = 500
pygame.init() # initializes the graphics module
window = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT)) # define window size
pygame.display.set_caption('Egg Catcher') # title of program that
# appears on window
# frame
def InitSky(amount):
for i in range (0, amount):
x_star.append(random.randint(2, 495))
y_star.append(random.randint(2, 795))
def DrawSky(amount):
for i in range(0, amount):
pygame.draw.circle(window, white, (x_star[i], y_star[i]), 2, )
y_star[i] = y_star[i] + 1
if y_star[i] > WINDOW_HEIGHT:
y_star[i] = 0
def InitEgg():
x_egg = random.randint(1 + egg_radius, WINDOW_WIDTH - egg_radius)
return(x_egg)
def EggColor():
egg_color = random.choice(egg_color_choices)
return(egg_color)
def DrawEgg():
pygame.draw.circle(window, egg_color, (x_egg, y_egg), egg_radius,)
x_egg = InitEgg()
egg_color = EggColor()
# your code that draws to the window goes here
clock = pygame.time.Clock() # used to track time within the game (FPS)
quit = False
pygame.key.set_repeat(1)
while not quit: # main program loop
for event in pygame.event.get(): # check if there were any events
if event.type == pygame.QUIT: # check if user clicked the upper
quit = True # right quit button
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x_pos = x_pos + x_speed
if event.key == pygame.K_LEFT:
x_pos = x_pos - x_speed
if x_pos <= 0:
x_pos = x_pos + x_speed
if x_pos + x_size >= 500:
x_pos = x_pos - x_speed
if event.key == pygame.K_KP_MINUS:
x_speed = x_speed - 1
if event.key == pygame.K_KP_PLUS:
x_speed = x_speed + 1
if x_speed >= 8:
x_speed = x_speed - 1
if x_speed <= 4:
x_speed = x_speed + 1
window.fill(black)
InitSky(500)
DrawSky(500)
caught_egg = False
if caught_egg == False:
DrawEgg()
if y_egg - egg_radius <= WINDOW_HEIGHT and caught_egg == False:
y_egg = y_egg + 3
else:
y_egg = 0
x_egg = InitEgg()
if x_egg + egg_radius > x_pos and x_egg + egg_radius < x_pos + x_size and y_egg - egg_radius == y_pos:
caught_egg = True
y_egg = 0
x_egg = InitEgg()
print(y_egg)
pygame.draw.rect(window, magenta, (x_pos, y_pos, x_size, y_size))
pygame.display.update() # refresh your display
clock.tick(60) # wait a certain amount of time that
# ensures a frame rate of 60 fps
pygame.quit() # shutdown module
It's because of this condition: y_egg - egg_radius == y_pos. You start from 20 the first time (5 + egg_radius) so when you hit 665 that condition triggers. But then you reset y_egg to 0 instead of 20 so you never align on the exact condition again.
You could just replace the two y_egg = 0 resets by y_egg = 5 + egg_radius, but a better fix would be to detect if the egg geometry is contained in the bucket in the y-dimension as you do for the x:
if x_egg + egg_radius > x_pos and \
x_egg + egg_radius < x_pos + x_size and \
y_egg - egg_radius >= y_pos and \
y_egg + egg_radius <= y_pos + y_size:
caught_egg = True
y_egg = 0
x_egg = InitEgg()
Actually your x logic is only checking if the right edge is inside the bucket but I'll leave that for you to fix.

why is my player sprite falling throught the platform? [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
It can collide properly on all sides and when i jump from the the ground onto the platform the player will land ontop of it and collide properly. However when i am standing on the platform and i jump and try to land on the platform again i fall straight through. Why does this happen?
Also if i hold down space bar then my sprite does not fall through the box and jumps ontop of it normally.
What it looks like: https://gyazo.com/6e0c9dfd15cdd99e72f14137fb5ef1cb
What it should look like: https://gyazo.com/bec5dc5a07d0d323b4d1cc8597eafb39
main.py
import pygame
from map import *
from char import *
pygame.init()
class game():
def __init__(self):
self.width = 1280
self.height = 720
self.gameRunning = True
self.clock = pygame.time.Clock()
self.FPS = 60
self.screen = pygame.display.set_mode((self.width, self.height))
self.loadMapData()
def update(self):
pygame.display.set_caption("{:.2f}".format(self.clock.get_fps()))
self.screen.fill(white)
self.screen.blit(self.map_img, (0,336))
playerGroup.draw(self.screen)
pygame.display.update()
def gameLoop(self):
self.clock.tick(self.FPS)
self.event()
player1.move()
self.update()
def event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.gameRunning = False
def loadMapData(self):
self.map = TiledMap()
self.map_img = self.map.make_mapSurface()
for tile_object in self.map.gameMap.objects:
if tile_object.name == "Floor":
Collision(tile_object.x, tile_object.y + 336, tile_object.width, tile_object.height)
if tile_object.name == "Collision Box":
Platform(tile_object.x, tile_object.y + 336, tile_object.width, tile_object.height)
g = game()
player1 = player()
while g.gameRunning == True:
g.gameLoop()
map.py
import pygame
import pytmx
from char import *
pygame.init()
class TiledMap():
def __init__(self):
self.gameMap = pytmx.load_pygame("CollisionMap.tmx")
self.mapwidth = self.gameMap.tilewidth * self.gameMap.width
self.mapheight = self.gameMap.tileheight * self.gameMap.height
def renderMap(self, surface):
for layer in self.gameMap.visible_layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x,y,gid in layer:
tile = self.gameMap.get_tile_image_by_gid(gid)
if tile:
surface.blit(tile, (x * self.gameMap.tilewidth, y * self.gameMap.tileheight))
def make_mapSurface(self):
mapSurface = pygame.Surface((self.mapwidth, self.mapheight), pygame.SRCALPHA)
self.renderMap(mapSurface)
return mapSurface
class Collision(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
self.groups = SolidGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.rect = pygame.Rect(x, y, width, height)
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
self.groups = platformGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.rect = pygame.Rect(x, y, width, height)
char.py
import pygame
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
playerGroup = pygame.sprite.Group()
SolidGroup = pygame.sprite.Group()
platformGroup = pygame.sprite.Group()
class player(pygame.sprite.Sprite):
def __init__(self):
self.groups = playerGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.image = pygame.Surface((50, 50))
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.center = (1280/2, 720/2)
self.position = pygame.math.Vector2(400, 300)
self.acceleration = pygame.math.Vector2(0, 0)
self.velocity = pygame.math.Vector2(0, 0)
self.friction = -0.18
self.falling = False
self.up = False
self.down = False
self.right = False
self.Left = False
def checkFalling(self):
self.rect.y += 1
if not pygame.sprite.spritecollideany(self, SolidGroup, False):
self.falling = True
if self.velocity.y < 0:
self.up = True
self.down = False
if self.velocity.y > 0:
self.up = False
self.down = True
else:
self.falling = False
self.up = False
self.down = False
self.rect.y -= 1
def move(self):
self.checkFalling()
if self.falling:
self.acceleration = pygame.math.Vector2(0, 0.5)
if not self.falling:
self.acceleration = pygame.math.Vector2(0, 0)
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
self.acceleration.x = 1
self.right = True
if key[pygame.K_LEFT]:
self.acceleration.x = -1
self.left = True
if key[pygame.K_SPACE]:
self.jump()
self.acceleration.x += self.velocity.x * self.friction
self.velocity += self.acceleration
if abs(self.velocity.x) < 0.1:
self.velocity.x = 0
self.position += self.velocity + 0.5 * self.acceleration
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
if hitsPlatform:
if self.up:
self.position.y -= self.velocity.y - 0.5 * self.acceleration.y
self.velocity.y = 0
self.rect.midbottom = self.position
"""
Collision Code, not in function because of screen tearing and bouncy collisions
"""
hits = pygame.sprite.spritecollide(self, SolidGroup, False)
if hits:
self.position.y = hits[0].rect.top
self.velocity.y = 0
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
if hitsPlatform:
if self.down and self.position.y <= 340:
self.position.y = hitsPlatform[0].rect.top
self.velocity.y = 0
if self.velocity.x > 0 and self.position.x + 64 < 239:
self.position.x -= self.velocity.x - 0.5 * self.acceleration.x
if self.velocity.x < 0 and self.position.x > 256:
self.position.x -= self.velocity.x - 0.5 * self.acceleration.x
self.rect.midbottom = self.position
def jump(self):
self.rect.y += 1
hits = pygame.sprite.spritecollide(self, SolidGroup, False)
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
self.rect.y -= 1
if hits:
self.velocity.y = -15
if hitsPlatform:
self.velocity.y = -15

Resources