Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
help with game
#11
(Nov-13-2017, 01:46 PM)heiner55 Wrote: This needs big changes.
A class for the ship and a class for the bullet.
Each class take care of the position x and y and has a draw/update function.
Then you need a function which is called every 1/100s.
This function calls all updates functions from your ship and from many bullets.

You should google for ping pong. If you understand ping pong,
you can also code your game.
See https://gist.github.com/calebrob6/4022622

Thank for your advice Smile

(Nov-13-2017, 05:16 PM)Windspar Wrote: here an example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import tkinter as tk
 
SCREEN = 600, 400
         
class Bullet:
    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
         
    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
        tk.Frame.__init__(self, master)
        self.pack()
        self.canvas = tk.Canvas(self, width=SCREEN[0], height=SCREEN[1])
        self.canvas.pack()
        self.bullets = []# store bullets
        self.tick_loop() # start the tick loop
        self.ship = self.create_ship(300, 370, "blue")
         
        master.bind("<Left>", self.go_left)
        master.bind("<Right>", self.go_right)
        master.bind("<Up>", self.go_up)
        master.bind("<Down>", self.go_down)
        master.bind("<space>", self.space_key)
         
    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 =
        for enum, bullet in enumerate(self.bullets):
            if self.canvas.coords(bullet.bullet)[1] < 0:
                remove_list.append(enum)
                self.canvas.delete(bullet.bullet)
            else:
                bullet.move(self.canvas)
                 
        for index in remove_list:
            self.bullets.pop(index)
     
        # framerate per seconds 1000/30 = 30 frames roughly
        self.after(int(1000/30), self.tick_loop)        
         
    def go_left(self, event):
        self.canvas.move(self.ship, -5, 0)
        self.canvas.update()
         
    def go_right(self, event):
        self.canvas.move(self.ship, 5, 0)
        self.canvas.update()
         
    def go_up(self, event):
        self.canvas.move(self.ship, 0, -5)
        self.canvas.update()
         
    def go_down(self, event):
        self.canvas.move(self.ship, 0, 5)
        self.canvas.update()
         
    def space_key(self, event=0):
        # 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)))
 
def main():
    root = tk.Tk()
    app = App(root)
    app.mainloop()
     
if __name__ == '__main__':
    main()
Don't like how keypress working but here it is.
Would be easier in pygame or pysfml.

fix poping bug. popping bug so far has no effect on above good. Just added little more stuff.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import tkinter as tk
 
SCREEN = 600, 400
         
class Bullet:
    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
         
    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
        tk.Frame.__init__(self, master)
        self.pack()
        self.canvas = tk.Canvas(self, width=SCREEN[0], height=SCREEN[1])
        self.canvas.pack()
        self.bullets = [] # store bullets
        self.tick_loop() # start the tick loop
        self.ship = self.create_ship(300, 370, "blue")
         
        master.bind("<Left>", self.go_left)
        master.bind("<Right>", self.go_right)
        master.bind("<Up>", self.go_up)
        master.bind("<Down>", self.go_down)
        master.bind("<space>", self.space_key)
        master.bind("<b>", self.go_b)
        master.bind("<v>", self.go_v)
         
    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 = []
        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)
         
        # fix poping bug        
        for enum, index in enumerate(remove_list):
            self.bullets.pop(index - enum)
     
        # framerate per seconds 1000/30 = 30 frames roughly
        self.after(int(1000/30), self.tick_loop)        
         
    def go_left(self, event):
        self.canvas.move(self.ship, -5, 0)
        self.canvas.update()
         
    def go_right(self, event):
        self.canvas.move(self.ship, 5, 0)
        self.canvas.update()
         
    def go_up(self, event):
        self.canvas.move(self.ship, 0, -5)
        self.canvas.update()
         
    def go_down(self, event):
        self.canvas.move(self.ship, 0, 5)
        self.canvas.update()
         
    def space_key(self, event=0):
        # 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 go_b(self, event):
        # 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 shoot striaght up
    def go_v(self, event):
        # 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()
     
if __name__ == '__main__':
    main()


That's a great help from you, thank you very much for the codes


Please can you tell me where did learned all this, or do you know any tutorials or books that help begginers to reach this advanced levels.

(Nov-13-2017, 01:01 PM)metulburr Wrote:
Quote:What i want is how to make it shoot like (space invaders), I don't know how to use coords, and I didn't found any good tutorial or explanation.
Thats because no one uses tkinter to make games. There is a better library to handle that kind of software and it called pygame. In fact, we have a tutorial on how to make a ship shoot like space invaders on this forum. Tkinter is a GUI library mainly for building window form apps.

Thank you for your advice


I know about pygame, but I don't want to use it

I want to learn how to use pure python with less libraries, just the important ones like tkinter canvas and built in functions.

I want to learn how to make games just like old style was, with functions.
Reply
#12
Quote:I want to learn how to use pure python with less libraries
You are actually not using pure python as tkinter is not apart of the standard library. Only Windows comes packaged with tkinter and you can even opt out of installing it in the python installer. Linux you have to install it like any other 3rd party lib. If you compile python on windows, tkinter is not apart of it.

The first paragraph briefly explains this
https://docs.python.org/3.6/library/tkinter.html

So you are already using a 3rd party module. Its just the build you installed, already has that 3rd party library with it.
Recommended Tutorials:
Reply
#13
Quote:I want to learn how to make games just like old style was, with functions.
    Almost all program language have some type of structures. Python and old style is not going to work.
Python has built in polymorph. Almost all python is object base. An modern programming helps reduce size of code.
    Take classes. Add a namespace to object and create many different objects quickly. Methods are just function wrap in a class. You always could check out assembly code for old programming.
linux nasm assembly example
in python
1
2
print("Hello World!")
print("Hello, brave new world!")
Quote:Please can you tell me where did learned all this, or do you know any tutorials or books that help begginers to reach this advanced levels.
I learn by making little programs.
Testing one thing to death.
learn by runtime errors. 
using print(dir(on object)) to see there variables and methods and builtins
read docs and code

There is no magic formula to making programs.
nothing but commands and pushing and altering numbers around.
strings are nothing but numbers.

I don't call this advance stuff. Just basic python.
99 percent of computer problems exists between chair and keyboard.
Reply
#14
I like these books:
https://www.nostarch.com/pythoncrashcourse
https://www.nostarch.com/automatestuff
Reply
#15
Found no solution to tkinter annoying keypress. Just compare tkinter vs pysfml.
Here pysfml example. I would recommend pygame because of better docs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from sfml import sf
 
class Bullet:
    def __init__(self, x, y, color, movement):
        self.bullet = sf.CircleShape(3, 18)
        self.bullet.position = x, y
        self.bullet.fill_color = color
        self.movement = movement
         
    def move(self, speed):
        vector = (self.movement[0] * speed + self.bullet.position.x,
                  self.movement[1] * speed + self.bullet.position.y)
        self.bullet.position = vector
 
class App:
    def __init__(self):
        self.window = sf.RenderWindow(sf.VideoMode(600, 400), "Invaders")
         
        self.bullets = []
        self.create_ship(300, 370, sf.Color(0,0,200))
         
    def create_ship(self, x, y, color):
        self.ship = sf.ConvexShape(3)
        self.ship.set_point(0, (0, 0))
        self.ship.set_point(1, (-20, 30))
        self.ship.set_point(2, ( 20, 30))
        self.ship.fill_color = color
        self.ship.position = x, y
         
    def loop(self):
        clock = sf.Clock()
        bullet_clock = sf.Clock()
        while self.window.is_open:            
            for event in self.window.events:
                if event.type == sf.Event.CLOSED:
                    self.window.close()
                elif event.type == sf.Event.KEY_PRESSED:
                    if sf.Keyboard.is_key_pressed(sf.Keyboard.ESCAPE):
                        self.window.close()
                         
            # create bullets
            if sf.Keyboard.is_key_pressed(sf.Keyboard.SPACE):
                # keeps bullet at steady intervals
                if bullet_clock.elapsed_time.milliseconds > 300:
                    bullet_clock.restart()
                    vector = self.ship.position
                    self.bullets.append(Bullet(vector.x, vector.y, sf.Color(0,0,200), (0,-2)))
                             
            # movement, speed keeps movement steady
            speed = 100 * clock.elapsed_time.seconds
            if sf.Keyboard.is_key_pressed(sf.Keyboard.LEFT):
                self.ship.move((-speed, 0))
            elif sf.Keyboard.is_key_pressed(sf.Keyboard.RIGHT):
                self.ship.move((speed, 0))
            elif sf.Keyboard.is_key_pressed(sf.Keyboard.UP):
                self.ship.move((0, -speed))
            elif sf.Keyboard.is_key_pressed(sf.Keyboard.DOWN):
                self.ship.move((0, speed))            
             
            self.window.clear()    
            # draw bullets
            bullet_remove = []
            for enum, bullet in enumerate(self.bullets):
                if bullet.bullet.position.y < 0:
                    bullet_remove.append(enum)
                else:
                    bullet.move(speed)                
                    self.window.draw(bullet.bullet)
                     
            for enum, index in enumerate(bullet_remove):
                self.bullets.pop(index - enum)
             
            self.window.draw(self.ship)
            self.window.display()
            clock.restart()
            sf.sleep(sf.milliseconds(5))
 
def main():
    app = App()
    app.loop()
     
if __name__ == '__main__':
    main()
99 percent of computer problems exists between chair and keyboard.
Reply
#16
here a pygame example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import pygame
pygame.init()
 
SCREEN = 600, 400
 
class Bullet:
    def __init__(self, x, y, color, movement):
        self.position = [x - movement[0], y - movement[1]]
        self.color = color
        self.movement = movement
 
    def blit(self, surface):
        self.position[0] += self.movement[0]
        self.position[1] += self.movement[1]
        position = int(self.position[0]), int(self.position[1])
        pygame.draw.circle(surface, self.color, position, 3)
 
class Ship:
    def __init__(self, x, y, color, pointlist):
        self.position = [x, y]
        self.pointlist = pointlist
        self.color = color
 
    def move(self, x, y):
        self.position[0] += x
        self.position[1] += y
 
    def blit(self, surface):
        points = []
        for point in self.pointlist:
            points.append((self.position[0] + point[0], self.position[1+ point[1]))
 
        pygame.draw.polygon(surface, self.color, points)
 
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
 
class App:
    def __init__(self):
        pygame.display.set_caption("Invaders")
        # create are screen. Your main surface
        self.screen = pygame.display.set_mode(SCREEN)
        # create a clock for framerate control
        self.clock = pygame.time.Clock()
        self.bullets = []
        self.bullets_pauser = Pauser(300)
        self.ship = Ship(300, 370, (0,0,200), ((0,0), (-20,30), (20,30)))
 
    def loop(self):
        running = True
        self.ticks = 0
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
 
            last_ticks = self.ticks
            self.ticks = pygame.time.get_ticks()
            speed = (self.ticks - last_ticks) * 0.05
            # grab all keys return True if pressed
            key_press = pygame.key.get_pressed()
            # creaate bullets
            if key_press[pygame.K_SPACE]:
                # shoot bullets in intervals
                if self.bullets_pauser.elaspe(self.ticks):
                    x, y = self.ship.position
                    self.bullets.append(Bullet(x, y, (0,0,200), (0,-10)))
 
            # ship movement
            ship_speed = speed * 3
            if key_press[pygame.K_LEFT]:
                self.ship.move(-ship_speed, 0)
            elif key_press[pygame.K_RIGHT]:
                self.ship.move(ship_speed, 0)
            elif key_press[pygame.K_UP]:
                self.ship.move(0, -ship_speed)
            elif key_press[pygame.K_DOWN]:
                self.ship.move(0, ship_speed)
 
            # clear screen
            self.screen.fill((0,0,0))
            # blits bullets
            remove_list = []
            for enum, bullet in enumerate(self.bullets):
                if bullet.position[1] < 0:
                    remove_list.append(enum)
                else:
                    bullet.blit(self.screen)
 
            for enum, index in enumerate(remove_list):
                self.bullets.pop(index - enum)
 
            self.ship.blit(self.screen)
 
            pygame.display.flip()
            # frame per seconds
            self.clock.tick(30)
 
def main():
    app = App()
    app.loop()
    pygame.quit()
 
if __name__ == '__main__':
    main()
99 percent of computer problems exists between chair and keyboard.
Reply
#17
if you remove the elif, to have all if, you can do two angles at the same time making it more "natural" feeling
(Nov-14-2017, 08:40 PM)Windspar Wrote: here a pygame example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import pygame
pygame.init()
 
SCREEN = 600, 400
 
class Bullet:
    def __init__(self, x, y, color, movement):
        self.position = [x - movement[0], y - movement[1]]
        self.color = color
        self.movement = movement
 
    def blit(self, surface):
        self.position[0] += self.movement[0]
        self.position[1] += self.movement[1]
        position = int(self.position[0]), int(self.position[1])
        pygame.draw.circle(surface, self.color, position, 3)
 
class Ship:
    def __init__(self, x, y, color, pointlist):
        self.position = [x, y]
        self.pointlist = pointlist
        self.color = color
 
    def move(self, x, y):
        self.position[0] += x
        self.position[1] += y
 
    def blit(self, surface):
        points = []
        for point in self.pointlist:
            points.append((self.position[0] + point[0], self.position[1+ point[1]))
 
        pygame.draw.polygon(surface, self.color, points)
 
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
 
class App:
    def __init__(self):
        pygame.display.set_caption("Invaders")
        # create are screen. Your main surface
        self.screen = pygame.display.set_mode(SCREEN)
        # create a clock for framerate control
        self.clock = pygame.time.Clock()
        self.bullets = []
        self.bullets_pauser = Pauser(300)
        self.ship = Ship(300, 370, (0,0,200), ((0,0), (-20,30), (20,30)))
 
    def loop(self):
        running = True
        self.ticks = 0
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
 
            last_ticks = self.ticks
            self.ticks = pygame.time.get_ticks()
            speed = (self.ticks - last_ticks) * 0.05
            # grab all keys return True if pressed
            key_press = pygame.key.get_pressed()
            # creaate bullets
            if key_press[pygame.K_SPACE]:
                # shoot bullets in intervals
                if self.bullets_pauser.elaspe(self.ticks):
                    x, y = self.ship.position
                    self.bullets.append(Bullet(x, y, (0,0,200), (0,-10)))
 
            # ship movement
            ship_speed = speed * 3
            if key_press[pygame.K_LEFT]:
                self.ship.move(-ship_speed, 0)
            if key_press[pygame.K_RIGHT]:
                self.ship.move(ship_speed, 0)
            if key_press[pygame.K_UP]:
                self.ship.move(0, -ship_speed)
            if key_press[pygame.K_DOWN]:
                self.ship.move(0, ship_speed)
 
            # clear screen
            self.screen.fill((0,0,0))
            # blits bullets
            remove_list = []
            for enum, bullet in enumerate(self.bullets):
                if bullet.position[1] < 0:
                    remove_list.append(enum)
                else:
                    bullet.blit(self.screen)
 
            for enum, index in enumerate(remove_list):
                self.bullets.pop(index - enum)
 
            self.ship.blit(self.screen)
 
            pygame.display.flip()
            # frame per seconds
            self.clock.tick(30)
 
def main():
    app = App()
    app.loop()
    pygame.quit()
 
if __name__ == '__main__':
    main()
Recommended Tutorials:
Reply
#18
@metulburr yeah for some reason i thought showing how it works in tkinter would be better. Instead showing what possible with pygame and pysfml. Still looking for a way to do it in tkinter. If there one. Unless it a linux side problem.

@hammza
Hope this help to show you has basic this is. Added more comments.
Anything you think is still advanced let me know. I show you how basic it is.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import tkinter as tk
 
# this makes a tuple (600, 400). tuples can be index
SCREEN = 600, 400
 
# 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
        # calls method. App.tick_loop(object)
        self.tick_loop() # start the tick loop
        # calls method. object.ship = App.create_ship(object, 300, 370, "blue")
        self.ship = self.create_ship(300, 370, "blue")
 
        master.bind("<Left>", self.go_left)
        master.bind("<Right>", self.go_right)
        master.bind("<Up>", self.go_up)
        master.bind("<Down>", self.go_down)
        master.bind("<space>", self.space_key)
        master.bind("<b>", self.go_b)
        master.bind("<v>", self.go_v)
 
    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)
 
        # fix popping bug
        for enum, index in enumerate(remove_list):
            self.bullets.pop(index - enum)
 
        # framerate per seconds 1000/30 = 30 frames roughly
        self.after(int(1000/30), self.tick_loop)
 
    def go_left(self, event):
        self.canvas.move(self.ship, -5, 0)
        self.canvas.update()
 
    def go_right(self, event):
        self.canvas.move(self.ship, 5, 0)
        self.canvas.update()
 
    def go_up(self, event):
        self.canvas.move(self.ship, 0, -5)
        self.canvas.update()
 
    def go_down(self, event):
        self.canvas.move(self.ship, 0, 5)
        self.canvas.update()
 
    def space_key(self, event=0):
        # 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 go_b(self, event):
        # 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 shoot striaght up
    def go_v(self, event):
        # 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.
Reply
#19
Okay figure out how to make tkinter keypress work smoothly. Enjoy!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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.
Reply
#20
(Nov-18-2017, 02:50 AM)Windspar Wrote: Okay figure out how to make tkinter keypress work smoothly. Enjoy!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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()

Thank you very mush Windspar Smile

Iam sorry, I was busy last weeks


The last code is just perfect, and exactly what I was looking for, just pure code without pygame or any game library.


So making games with only tkinter and canvas is possible

I hope I can reach your level programming man

I worked on the background and the Land, but I don't know how to make it work simultaneously

I think I should use threading but I didn't find a good tutorial explains it easily .


I'll put the code sooner .
Reply


Forum Jump:

User Panel Messages

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