我想用tkinter用python制作一个战舰游戏, 最小可再现示例为:
from tkinter import *
from random import randint
import time
tk = Tk()
class player:
def __init__(self, master):
self.master = master
self.placedships = []
self.bombed = []
self.sunk = []
self.ship_sizes = [5, 4, 3]
self.player_canvas = Canvas(master, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
self.ai_canvas = Canvas(master, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
self.player_canvas.grid(row=1, column=0, padx=50)
self.ai_canvas.grid(row=1, column=1, padx=50)
self.direction = 'v'
self.shipChosen = 0
gridLabel_player = Label(master,text="Your grid \nA B C D E F G H I J ")
gridLabel_player.grid(row=0,column=0)
gridLabel_ai = Label(master,text="AI's grid \nA B C D E F G H I J ")
gridLabel_ai.grid(row=0,column=1)
for x in range(10):
for y in range(10):
self.player_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill = 'white')
self.ai_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill = 'white')
#variables to store data for cells on game grid
# # self.player_ocean = 10 * [10 * [0]]
# # self.ai_ocean = 10 * [10 * [0]]
self.player_ocean = []
self.ai_ocean = []
temp = []
for i in range(10):
for y in range(10):
temp += [0]
self.player_ocean += [temp]
self.ai_ocean += [temp]
temp = []
self.selectedCoord = [0,0] # [0] = x coord, [1] = y coord
def placeShip(self):
def moveShip(event):
if event.keysym == 'Down' and self.selectedCoord[1] != 9:
self.selectedCoord[1] += 1
elif event.keysym == 'Up' and self.selectedCoord[1] != 0:
self.selectedCoord[1] -= 1
elif event.keysym == 'Left' and self.selectedCoord[0] != 0:
self.selectedCoord[0] -= 1
elif event.keysym == 'Right' and self.selectedCoord[0] != 9:
self.selectedCoord[0] += 1
print('selected coord:',self.selectedCoord)
def selectPlacement(event):
col = self.selectedCoord[0]
row = self.selectedCoord[1]
if self.direction == 'v':
v_range_start = row - self.ship_sizes[self.shipChosen] + 1
for y in range(v_range_start, row+1):
'''insert validation to reject ship clashing'''
self.player_ocean[y][col] = 1
self.placedships += [y,col]
self.refresh_ocean()
self.master.bind("<Up>", moveShip)
self.master.bind("<Down>", moveShip)
self.master.bind("<Left>", moveShip)
self.master.bind("<Right>", moveShip)
self.master.bind("<Return>", selectPlacement)
def refresh_ocean(self): # 1s turns to green
for y in range(10):
for x in range(10):
if self.player_ocean[y][x] == 1:
self.player_canvas.itemconfig(self.player_canvas.create_rectangle( (x+1) * 30, (y-1) * 30,x * 30, y * 30, fill='green'))
player1 = player(tk)
player1.placeShip()
tk.mainloop()
我遇到的问题是,如果我按下向下箭头直到我选择的坐标为[0,9],代码应该在第一列从上到下给第6到第10个框上色,但是它会给第5到第9个框上色。你知道吗
我试着通过检查上一个函数refresh_ocean
中使用的坐标x和y是否错误来调试它,但是它们和预期的一样
所以最简单的方法就是改变
(y-1) to (y+1)
。你知道吗也就是说我做了一些改变:
改写你的一些名字,以遵循PEP8风格指南。
转换了
refresh_ocean
方法来处理初始绘制和所有后续绘制。以及添加一个delete('all')
来清除电路板,这样我们就不会在前面的对象上绘制了。这将防止在游戏进行过程中占用更多内存。清理导入并将
from tkinter import *
更改为import tkinter as tk
。这将有助于防止覆盖命名空间中的其他内容。通过编写
refresh_ocean
来处理所有绘图,我们可以指定需要使用'player1'
和'ai'
等标记绘制的内容。将列表生成的
+=
更改为.append()
,因为append()
的速度是'+=
的两倍。请参阅以下帖子:Difference between “.append()” and “+= []”?将标题的单个标签更改为一个循环,以便均匀地创建每个标签。这将允许一个更准确的标题,然后尝试在单个字符串中手动设置空格。
最后,因为您已经检查了键是4个箭头键之一,所以我们可以使用单个绑定
'<Key>'
并获得与所有4个绑定相同的结果。更新代码:
结果:
你的“海洋”有一个“关闭1”错误
而selectplacement是用负指数放置飞船。 我将您的迭代从
range(row-size, row)
更改为range(row, row+size)
,并添加了边界检查,但这可能应该转移到移动处理。你知道吗附言:你在旧方格上画新方格。你可能想在画画之前先清理一下大海。你知道吗
相关问题 更多 >
编程相关推荐