Python realizes the pinball game

Follow the fun development of python to realize the pinball game

Game running effect

 Implementation process

1. Create a game canvas (create a ball class)

2. Add several actions (let the ball move, let the ball bounce back and forth, change the starting direction of the ball)

3. Add the racket to make the racket move left and right (circular movement)

4. Increase the winning or losing factor (judging the position of the ball)

Create a game canvas

Import toolkit tkinter, random, time

from tkinter import *  # 弹球游戏的画布
import random
import time

Use the title function in the tk object to add a title "Pinball Game" to the window through tk.title("").

We use the resizable function to make the window non-resizable. Among them, 0,0 means that the size of the window cannot be changed in the horizontal direction and the vertical direction.

Use canvas= to create a canvas object.

The line canvas.pack() tells the canvas to resize itself according to the width and height parameters given in the previous line.

tk.update() makes tkinter initialize for in-game animations. Without this last line, we don't see what we expect.

tk = Tk()
tk.title("弹球小游戏")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()

1. Create a class called Ball, which has two parameters, one is the canvas, and the other is the color of the ball.

2. Save the canvas to an object variable.

3. Draw a small ball on the canvas with the color parameter as the fill color.

4. Save the ID returned when tkinter draws the ball, because we will use it to move the ball on the screen.

class Ball:
    def __init__(self, canvas, paddle, color):
        self.canvas = canvas
        self.paddle = paddle
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        #把y改成-3 ,让小球飞快一点,我们需要再改动几个地方来保证小球不会从屏幕两边消失。
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        #在_init_函数的结尾加上下面的代码来把画布的宽度保存到一个新的对象变量canvas_width 中
        self.hit_bottom = False

We need to add an animation loop The "main loop" is the central part of the program, generally speaking it controls most of the behavior of the program. Our main loop currently just makes tkinter redraw the screen. This loop keeps running, keeps tkinter redrawing the screen, and then rests for a hundredth of a second. (Add it to the end of the program)

paddle = Paddle(canvas, 'green')  # 创建一个绿色的球拍
ball = Ball(canvas, paddle, 'yellow')  # 创建一个黄色的小球

while 1:
    if ball.hit_bottom == False:
        ball.draw()
        paddle.draw()
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

add a few actions

We pass 3 parameters to move. id is the ID of the ellipse, and x, y. x means don't move horizontally, y means move one pixel up on the screen.

Use this new object variable in the draw function to determine whether the ball hit the top or bottom of the canvas.

The code we added is to say that if hit_paddle returns true, change the object variable to -3 with self.y = -3, so that he can change the direction.

    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 3
        if pos[3] >= self.canvas_height:
            self.hit_bottom = True
        if self.hit_paddle(pos) == True:
            self.y = -3
        if pos[0] <= 0:
            self.x = 3
        if pos[2] >= self.canvas_width:
            self.x = -3

bounce the ball

It's not much fun if there's nothing to hit the bouncing ball

These newly added codes are almost exactly the same as the Ball class, except that I called create_rectangle, and moved the rectangle to coordinates 200, 300, 200 pixels horizontally, and 300 pixels vertically

First, add the object variable x to the _init_ function of the Paddle class, and a variable to save the width of the canvas, which is the same as we did in the previous Ball class

Use the following two lines of code to bind the correct keys to these two functions. Bind the number tum_left in the Paddle class to the left arrow key. Then we bind the function tum right to the right arrow key.

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)

 Use 2 functions to change the direction to the left (turn_left) and to the right (turn_right). Add them after the draw function

    def turn_left(self, evt):
        self.x = -5

    def turn_right(self, evt):
        self.x = 5

increase win-loss factor

Now it's time to turn the program into a fun game, and not just a bouncing ball and a paddle. Add a little winning factor to the game

The loop constantly checks to see if the ball has hit the bottom of the screen (hit_bottom). Assuming the ball hasn't hit the bottom yet, the code keeps the ball and paddle moving, as seen in the if statement. The ball and racket are only moved if the ball does not touch the bottom. The game ends when the ball and racket stop moving.

Code display (requires self-collection)

from tkinter import *  # 弹球游戏的画布
import random
import time


class Ball:
    def __init__(self, canvas, paddle, color):
        self.canvas = canvas
        self.paddle = paddle
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        self.hit_bottom = False

    def hit_paddle(self, pos):
        paddle_pos = self.canvas.coords(self.paddle.id)
        if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
            if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
                return True
        return False

    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 3
        if pos[3] >= self.canvas_height:
            self.hit_bottom = True
        if self.hit_paddle(pos) == True:
            self.y = -3
        if pos[0] <= 0:
            self.x = 3
        if pos[2] >= self.canvas_width:
            self.x = -3


class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)

    def draw(self):
        self.canvas.move(self.id, self.x, 0)
        pos = self.canvas.coords(self.id)
        if pos[0] <= 0:
            self.x = 0
        elif pos[2] >= self.canvas_width:
            self.x = 0

    def turn_left(self, evt):
        self.x = -5

    def turn_right(self, evt):
        self.x = 5


class setup:
    def setup_game(self):
        self.text = self.canvas.create_text(260, 200, text='单击鼠标左键开始游戏', font=('Helvetica', 36))
        # 将鼠标左键单击与开始游戏绑定在一起
        self.canvas.bind('<Button-1>', lambda start_game: self.start_game())


tk = Tk()
tk.title("弹球小游戏")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()

paddle = Paddle(canvas, 'green')  # 创建一个绿色的球拍
ball = Ball(canvas, paddle, 'yellow')  # 创建一个黄色的小球

while 1:
    if ball.hit_bottom == False:
        ball.draw()
        paddle.draw()
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

Guess you like

Origin blog.csdn.net/weixin_56043516/article/details/127963590