[course]07 游戏模块01-2
添加和删除图形
使用List添加删除图形 ,不使用class的形式
from game_graphics import *
from tkinter import *
def appStarted(app):
app.circleCenters = [ ]
def mousePressed(app, event):
newCircleCenter = (event.x, event.y)
app.circleCenters.append(newCircleCenter)
def keyPressed(app, event):
if (event.key == 'd'):
if (len(app.circleCenters) > 0):
app.circleCenters.pop(0)
else:
print('No more circles to delete!')
def redrawAll(app, canvas):
# draw the circles
for circleCenter in app.circleCenters:
(cx, cy) = circleCenter
r = 20
canvas.create_oval(cx-r, cy-r, cx+r, cy+r, fill='cyan')
# draw the text
canvas.create_text(app.width/2, 20,
text='Example: Adding and Deleting Shapes')
canvas.create_text(app.width/2, 40,
text='Mouse clicks create circles')
canvas.create_text(app.width/2, 60,
text='Pressing "d" deletes circles')
runApp(width=400, height=400)
使用class添加
from game_graphics import *
from tkinter import *
import random
class Dot(object):
def __init__(self, cx, cy):
self.cx = cx
self.cy = cy
# let's add random sizes and colors, too
# (since it's so easy to store these with each Dot instance)
colors = ['red', 'orange', 'yellow', 'green', 'blue']
self.fill = random.choice(colors)
self.r = random.randint(5, 40)
def appStarted(app):
app.dots = [ ]
def mousePressed(app, event):
newDot = Dot(event.x, event.y)
app.dots.append(newDot)
def keyPressed(app, event):
if (event.key == 'd'):
if (len(app.dots) > 0):
app.dots.pop(0)
else:
print('No more circles to delete!')
def redrawAll(app, canvas):
# draw the circles
for dot in app.dots:
canvas.create_oval(dot.cx-dot.r, dot.cy-dot.r,
dot.cx+dot.r, dot.cy+dot.r,
fill=dot.fill)
# draw the text
canvas.create_text(app.width/2, 20,
text='Example: Adding and Deleting Shapes')
canvas.create_text(app.width/2, 40,
text='Mouse clicks create circles')
canvas.create_text(app.width/2, 60,
text='Pressing "d" deletes circles')
runApp(width=400, height=400)
作业:使用A按钮,来随机添加一个正方形,使用D可以删除
通过鼠标选择相应的grid
modelToView 和 viewToModel
from game_graphics import *
from tkinter import *
def appStarted(app):
app.rows = 4
app.cols = 8
app.margin = 5 # margin around grid
app.selection = (-1, -1) # (row, col) of selection, (-1,-1) for none
def pointInGrid(app, x, y):
# return True if (x, y) is inside the grid defined by app.
return ((app.margin <= x <= app.width-app.margin) and
(app.margin <= y <= app.height-app.margin))
def getCell(app, x, y):
# aka "viewToModel"
# return (row, col) in which (x, y) occurred or (-1, -1) if outside grid.
if (not pointInGrid(app, x, y)):
return (-1, -1)
gridWidth = app.width - 2*app.margin
gridHeight = app.height - 2*app.margin
cellWidth = gridWidth / app.cols
cellHeight = gridHeight / app.rows
# Note: we have to use int() here and not just // because
# row and col cannot be floats and if any of x, y, app.margin,
# cellWidth or cellHeight are floats, // would still produce floats.
row = int((y - app.margin) / cellHeight)
col = int((x - app.margin) / cellWidth)
return (row, col)
def getCellBounds(app, row, col):
# aka "modelToView"
# returns (x0, y0, x1, y1) corners/bounding box of given cell in grid
gridWidth = app.width - 2*app.margin
gridHeight = app.height - 2*app.margin
columnWidth = gridWidth / app.cols
rowHeight = gridHeight / app.rows
x0 = app.margin + col * columnWidth
x1 = app.margin + (col+1) * columnWidth
y0 = app.margin + row * rowHeight
y1 = app.margin + (row+1) * rowHeight
return (x0, y0, x1, y1)
def mousePressed(app, event):
(row, col) = getCell(app, event.x, event.y)
# select this (row, col) unless it is selected
if (app.selection == (row, col)):
app.selection = (-1, -1)
else:
app.selection = (row, col)
def redrawAll(app, canvas):
# draw grid of cells
for row in range(app.rows):
for col in range(app.cols):
(x0, y0, x1, y1) = getCellBounds(app, row, col)
fill = "orange" if (app.selection == (row, col)) else "cyan"
canvas.create_rectangle(x0, y0, x1, y1, fill=fill)
canvas.create_text(app.width/2, app.height/2 - 15, text="Click in cells!",
font="Arial 26 bold", fill="darkBlue")
runApp(width=400, height=400)
自己运动的方块
from game_graphics import *
from tkinter import *
def appStarted(app):
app.squareLeft = app.width // 2
app.squareTop = app.height // 2
app.squareSize = 25
app.dx = 10
app.dy = 15
app.isPaused = False
app.timerDelay = 50 # milliseconds
def keyPressed(app, event):
if (event.key == "p"):
app.isPaused = not app.isPaused
elif (event.key == "s"):
doStep(app)
def timerFired(app):
if (not app.isPaused):
doStep(app)
def doStep(app):
# Move horizontally
app.squareLeft += app.dx
# Check if the square has gone out of bounds, and if so, reverse
# direction, but also move the square right to the edge (instead of
# past it). Note: there are other, more sophisticated ways to
# handle the case where the square extends beyond the edges...
if app.squareLeft < 0:
# if so, reverse!
app.squareLeft = 0
app.dx = -app.dx
elif app.squareLeft > app.width - app.squareSize:
app.squareLeft = app.width - app.squareSize
app.dx = -app.dx
# Move vertically the same way
app.squareTop += app.dy
if app.squareTop < 0:
# if so, reverse!
app.squareTop = 0
app.dy = -app.dy
elif app.squareTop > app.height - app.squareSize:
app.squareTop = app.height - app.squareSize
app.dy = -app.dy
def redrawAll(app, canvas):
# draw the square
canvas.create_rectangle(app.squareLeft,
app.squareTop,
app.squareLeft + app.squareSize,
app.squareTop + app.squareSize,
fill="yellow")
# draw the text
canvas.create_text(app.width / 2, 20,
text="Pressing 'p' pauses/unpauses timer")
canvas.create_text(app.width / 2, 40,
text="Pressing 's' steps the timer once")
runApp(width=400, height=150)
贪食蛇
from game_graphics import *
from tkinter import *
import random
def appStarted(app):
app.rows = 10
app.cols = 10
app.margin = 5 # margin around grid
app.timerDelay = 250
initSnakeAndFood(app)
app.waitingForFirstKeyPress = True
def initSnakeAndFood(app):
app.snake = [(0,0)]
app.direction = (0, +1) # (drow, dcol)
placeFood(app)
app.gameOver = False
# getCellBounds from grid-demo.py
def getCellBounds(app, row, col):
# aka 'modelToView'
# returns (x0, y0, x1, y1) corners/bounding box of given cell in grid
gridWidth = app.width - 2*app.margin
gridHeight = app.height - 2*app.margin
x0 = app.margin + gridWidth * col / app.cols
x1 = app.margin + gridWidth * (col+1) / app.cols
y0 = app.margin + gridHeight * row / app.rows
y1 = app.margin + gridHeight * (row+1) / app.rows
return (x0, y0, x1, y1)
def keyPressed(app, event):
if (app.waitingForFirstKeyPress):
app.waitingForFirstKeyPress = False
elif (event.key == 'r'):
initSnakeAndFood(app)
elif app.gameOver:
return
elif (event.key == 'Up'): app.direction = (-1, 0)
elif (event.key == 'Down'): app.direction = (+1, 0)
elif (event.key == 'Left'): app.direction = (0, -1)
elif (event.key == 'Right'): app.direction = (0, +1)
# elif (event.key == 's'):
# this was only here for debugging, before we turned on the timer
# takeStep(app)
def timerFired(app):
if app.gameOver or app.waitingForFirstKeyPress: return
takeStep(app)
def takeStep(app):
(drow, dcol) = app.direction
(headRow, headCol) = app.snake[0]
(newRow, newCol) = (headRow+drow, headCol+dcol)
if ((newRow < 0) or (newRow >= app.rows) or
(newCol < 0) or (newCol >= app.cols) or
((newRow, newCol) in app.snake)):
app.gameOver = True
else:
app.snake.insert(0, (newRow, newCol))
if (app.foodPosition == (newRow, newCol)):
placeFood(app)
else:
# didn't eat, so remove old tail (slither forward)
app.snake.pop()
def placeFood(app):
# Keep trying random positions until we find one that is not in
# the snake. Note: there are more sophisticated ways to do this.
while True:
row = random.randint(0, app.rows-1)
col = random.randint(0, app.cols-1)
if (row,col) not in app.snake:
app.foodPosition = (row, col)
return
def drawBoard(app, canvas):
for row in range(app.rows):
for col in range(app.cols):
(x0, y0, x1, y1) = getCellBounds(app, row, col)
canvas.create_rectangle(x0, y0, x1, y1, fill='white')
def drawSnake(app, canvas):
for (row, col) in app.snake:
(x0, y0, x1, y1) = getCellBounds(app, row, col)
canvas.create_oval(x0, y0, x1, y1, fill='blue')
def drawFood(app, canvas):
if (app.foodPosition != None):
(row, col) = app.foodPosition
(x0, y0, x1, y1) = getCellBounds(app, row, col)
canvas.create_oval(x0, y0, x1, y1, fill='green')
def drawGameOver(app, canvas):
if (app.gameOver):
canvas.create_text(app.width/2, app.height/2, text='Game over!',
font='Arial 26 bold')
canvas.create_text(app.width/2, app.height/2+40,
text='Press r to restart!',
font='Arial 26 bold')
def redrawAll(app, canvas):
if (app.waitingForFirstKeyPress):
canvas.create_text(app.width/2, app.height/2,
text='Press any key to start!',
font='Arial 26 bold')
else:
drawBoard(app, canvas)
drawSnake(app, canvas)
drawFood(app, canvas)
drawGameOver(app, canvas)
runApp(width=400, height=400)
作业: 1. 增加游戏难度选择 1. normal:保持原本 2. hard:地图扩大1倍,游戏速度增加1倍 3. hell:地图扩大2倍,游戏速度增加2倍 2. 游戏结束后给出分数 3. 将最高分数进行记录,结束后显示 1. 只在运行时保存,运行结束后清零 2. 一直保存 4. 一次多加几个Food
Last updated
Was this helpful?