Okay figure out how to make tkinter keypress work smoothly. Enjoy!
import tkinter as tk # this makes a tuple (600, 400). tuples can be index SCREEN = 600, 400 class Pauser: def __init__(self, length): self.length = length self.last_tick = 0 def elaspe(self, ticks): if ticks > self.last_tick + self.length: self.last_tick = ticks return True return False def update(self, ticks): self.last_tick = ticks # Object class Bullet: # movement takes a tuple (x, y) def __init__(self, canvas, x, y, tk_fill, movement): self.bullet = canvas.create_oval(x -3 , y - 3, x + 3, y + 3, fill=tk_fill) self.movement = movement #object method. self refers to object def move(self, canvas): canvas.move(self.bullet, self.movement[0], self.movement[1]) class App(tk.Frame): def __init__(self, master): # put canvas in frame so you can have other goodies # this is from inheriting tk.Frame and calls __init__. # so the App gains all variables and methods from tk.Frame tk.Frame.__init__(self, master) self.pack() # self.canvas is an object variable self.canvas = tk.Canvas(self, width=SCREEN[0], height=SCREEN[1]) self.canvas.pack() # just a python list self.bullets = # store bullets # how fast a bullet can shoot self.shoot_pauser = Pauser(12) self.triple_pauser = Pauser(30) self.spread_pauser = Pauser(25) # storing keys to dict self.keys_press = {} # need to slow shooting self.ticks = 0 # calls method. object.ship = App.create_ship(object, 300, 370, "blue") self.ship = self.create_ship(300, 370, "blue") self.speed = 5 # calls method. App.tick_loop(object) self.tick_loop() # start the tick loop print("Keys Press:", self.keys_press) self.bind_all('<KeyPress>', self.go_press) self.bind_all('<KeyRelease>', self.go_release) def create_ship(self, x, y, tk_fill): return self.canvas.create_polygon(x, y, x - 20, y + 30, x + 20, y + 30, fill=tk_fill) def tick_loop(self): remove_list = # upacking iterable [(0, object(Bullet)), (1, object(Bullet)), etc] for enum, bullet in enumerate(self.bullets): coords = self.canvas.coords(bullet.bullet) if coords[1] < 0 or coords[0] < 0 or coords[2] > SCREEN[0]: remove_list.append(enum) self.canvas.delete(bullet.bullet) else: bullet.move(self.canvas) # NEW moving player if self.keys_press.get('Left', False): self.canvas.move(self.ship, -self.speed, 0) if self.keys_press.get('Right', False): self.canvas.move(self.ship, self.speed, 0) if self.keys_press.get('Up', False): self.canvas.move(self.ship, 0, -self.speed) if self.keys_press.get('Down', False): self.canvas.move(self.ship, 0, self.speed) if self.keys_press.get('space', False): if self.shoot_pauser.elaspe(self.ticks): self.spread_pauser.update(self.ticks) self.triple_pauser.update(self.ticks) self.shoot() if self.keys_press.get('b', False): if self.spread_pauser.elaspe(self.ticks): self.shoot_pauser.update(self.ticks) self.triple_pauser.update(self.ticks) self.spread_shot() if self.keys_press.get('v', False): if self.triple_pauser.elaspe(self.ticks): self.shoot_pauser.update(self.ticks) self.spread_pauser.update(self.ticks) self.triple_shot() # fix popping bug for enum, index in enumerate(remove_list): self.bullets.pop(index - enum) # framerate per seconds 1000/30 = 30 frames roughly self.ticks += 1 self.after(int(1000/30), self.tick_loop) def go_press(self, event): self.keys_press[event.keysym] = True def go_release(self, event): self.keys_press[event.keysym] = False def shoot(self): # only want the first two coords x, y = self.canvas.coords(self.ship)[:2] # just having shoot straight up self.bullets.append(Bullet(self.canvas, x, y, "blue", (0, -10))) # spread shooting def spread_shot(self): # only want the first two coords x, y = self.canvas.coords(self.ship)[:2] #up self.bullets.append(Bullet(self.canvas, x, y, "red", (0, -8))) #left self.bullets.append(Bullet(self.canvas, x, y, "red", (-8, 0))) #right self.bullets.append(Bullet(self.canvas, x, y, "red", (8, 0))) # triple shot striaght up def triple_shot(self): # only want the first two coords x, y = self.canvas.coords(self.ship)[:2] #up self.bullets.append(Bullet(self.canvas, x, y, "green", (0, -5))) self.bullets.append(Bullet(self.canvas, x - 50, y, "green", (0, -5))) self.bullets.append(Bullet(self.canvas, x + 50, y, "green", (0, -5))) def main(): root = tk.Tk() app = App(root) app.mainloop() # __name__ only equals '__main__' if it is execute # if import then it equals module name if __name__ == '__main__': main()
99 percent of computer problems exists between chair and keyboard.