[英]How to fix my Python 3.6 battleship code?
基本上,當我單擊鼠標左鍵並且單元格的坐標匹配時,我想將參數 self.shot 永遠更改為 True(它檢查一個單元格之前是否被拍攝過,如果一個單元格被拍攝過,它會繪制一個點或一個尖角)。 問題是該參數僅在按下鼠標按鈕時更改,並在按鈕向上時更改回其標准值。 在這一點上,我真的不知道如何重建這段代碼才能正常工作。
這是代碼:
import pygame, random, time, math
pygame.init()
clock = pygame.time.Clock()
yours = 0
enemys = 1
exitPossible = False
gameStart = False
tour = random.randint(yours,enemys)
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
one = 32
two = 63
three = 94
four = 125
five = 156
six = 187
seven = 218
eight = 249
nine = 280
ten = 301
a = 32
b = 63
c = 94
d = 125
e = 156
f = 187
g = 218
h = 249
i = 280
j = 311
#lista
m = 0
n = 0
o = 0
p = 0
playerWins = 10
botWins = 0
window = pygame.display.set_mode((760, 410))
pygame.display.set_caption("Battleship")
font = pygame.font.SysFont("Arial", 30)
class crate:
def __init__(self, sizex, sizey, shot, shiphere):
self.sizex, self.sizey = sizex, sizey
self.shot = shot
self.shiphere = shiphere
def crateShot(self):
if not exitPossible:
if not self.shot:
if event.type == pygame.MOUSEBUTTONDOWN and self.sizex + 30 > mx > self.sizex and self.sizey + 30 > my > self.sizey:
self.shot = True
if self.shot:
if self.shiphere:
pygame.draw.line(window, white, (self.sizex, self.sizey), (self.sizex + 30, self.sizey + 30), 3)
pygame.draw.line(window, white, (self.sizex + 29, self.sizey), (self.sizex, self.sizey + 29), 3)
else:
pygame.draw.circle(window, white, (self.sizex + 15, self.sizey + 15), 6, 5)
allCrates = ()
def crates(allCrates):
a1 = crate(a, a, True, False)
a1.crateShot()
a2 = crate(b, a, True, True)
a2.crateShot()
a3 = crate(c, a, False, False)
a3.crateShot()
a4 = crate(d, a, False, True)
a4.crateShot()
#slownik how to
ololollololol = {
"" : 123
}
class ship:
def __init__(self, size, amount):
self.size = size
self.amount = amount
#def drawShip(self):
def ships():
carrier = ship(4, 1)
battleship = ship(3, 2)
cruiser = ship(2, 3)
destroyer = ship(1, 4)
def playerWindow(m, n):
if not exitPossible:
window.fill(black)
for i in range(11):
pygame.draw.line(window, white, (31 + m, 0), (31 + m, 341))
m += 31
for i in range(11):
pygame.draw.line(window, white, (0, 31 + n), (341, 31 + n))
n += 31
a = font.render("A", True, white)
window.blit(a, (4, 30))
b = font.render("B", True, white)
window.blit(b, (5, 61))
c = font.render("C", True, white)
window.blit(c, (4, 92))
d = font.render("D", True, white)
window.blit(d, (4, 123))
e = font.render("E", True, white)
window.blit(e, (5, 154))
f = font.render("F", True, white)
window.blit(f, (6, 185))
g = font.render("G", False, white)
window.blit(g, (3, 216))
h = font.render("H", True, white)
window.blit(h, (4, 247))
i = font.render("I", True, white)
window.blit(i, (12, 278))
j = font.render("J", True, white)
window.blit(j, (7, 309))
a = font.render("1", True, white)
window.blit(a, (39, -2))
b = font.render("2", True, white)
window.blit(b, (70, -2))
c = font.render("3", True, white)
window.blit(c, (101, -2))
d = font.render("4", True, white)
window.blit(d, (132, -2))
e = font.render("5", True, white)
window.blit(e, (163, -2))
f = font.render("6", True, white)
window.blit(f, (194, -2))
g = font.render("7", True, white)
window.blit(g, (225, -2))
h = font.render("8", True, white)
window.blit(h, (256, -2))
i = font.render("9", True, white)
window.blit(i, (287, -2))
j = font.render("10", True, white)
window.blit(j, (308, -2))
def botWindow(o, p):
if not exitPossible:
for i in range(11):
pygame.draw.line(window, white, (419 + o, 0), (419 + o, 341))
o += 31
for i in range(11):
pygame.draw.line(window, white, (419, 31 + p), (760, 31 + p))
p += 31
a = font.render("A", True, white)
window.blit(a, (425, 30))
b = font.render("B", True, white)
window.blit(b, (425, 61))
c = font.render("C", True, white)
window.blit(c, (424, 92))
d = font.render("D", True, white)
window.blit(d, (424, 123))
e = font.render("E", True, white)
window.blit(e, (425, 154))
f = font.render("F", True, white)
window.blit(f, (426, 185))
g = font.render("G", True, white)
window.blit(g, (423, 216))
h = font.render("H", True, white)
window.blit(h, (424, 247))
i = font.render("I", True, white)
window.blit(i, (432, 278))
j = font.render("J", True, white)
window.blit(j, (427, 309))
a = font.render("1", True, white)
window.blit(a, (458, -2))
b = font.render("2", True, white)
window.blit(b, (489, -2))
c = font.render("3", True, white)
window.blit(c, (520, -2))
d = font.render("4", True, white)
window.blit(d, (551, -2))
e = font.render("5", True, white)
window.blit(e, (582, -2))
f = font.render("6", True, white)
window.blit(f, (613, -2))
g = font.render("7", True, white)
window.blit(g, (644, -2))
h = font.render("8", True, white)
window.blit(h, (675, -2))
i = font.render("9", True, white)
window.blit(i, (706, -2))
j = font.render("10", True, white)
window.blit(j, (727, -2))
def gameWindow(playerWins, botWins):
if not exitPossible:
score = font.render("SCORE:", True, white)
window.blit(score, (325, 345))
wins = font.render(str(playerWins) + " - " + str(botWins), True, white)
window.blit(wins, (325, 375))
auto = font.render("AUTO", True, white)
window.blit(auto, (13, 359))
pygame.draw.rect(window, white, (10, 361, 89, 30), 1)
while True:
mx, my = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
exitPossible = True
if exitPossible:
window.fill(black)
uSure = font.render("ARE YOU SURE YOU WANT TO EXIT?", True, white)
window.blit(uSure, (115, 145))
YES = font.render("YES", True, white)
window.blit(YES, (335, 195))
NO = font.render("NO", True, white)
window.blit(NO, (342, 230))
if event.type == pygame.MOUSEBUTTONDOWN:
if 390 >= mx >= 335 and 223 >= my >= 200:
quit()
elif 387 >= mx >= 342 and 256 >= my >= 235:
exitPossible = False
window.fill(black)
playerWindow(m, n)
botWindow(o, p)
gameWindow(playerWins, botWins)
crates(allCrates)
pygame.display.flip()
clock.tick(60)
目前代碼需要一個新特性:
檢測鼠標點擊,確定它發生在哪個單元格“板條箱”(如果有)
然而,所有現有代碼都使用一種“蠻力”方法,使用大量單個變量作為位置。 這使得如果不做 100 次就很難檢查所有位置,每個箱子一次。
我認為,如果稍微更改一下以使用玩家網格的矩形列表,代碼的向前推進會更容易。 請考慮代碼:
# Create the click-grid for the player
GRID_SIZE = 31
player_grid = []
for y_cell in [ a,b,c,d,e,f,g,h,i,j ]:
for x_cell in [ one, two, three, four, five, six, seven, eight, nine, ten ]:
player_grid.append( [ x_cell, y_cell, GRID_SIZE, GRID_SIZE ] )
這個操作之后我們得到的是一個python 列表列表,所以player_grid[0]
是[ one, a, 31, 31 ]
,然后是[ two, a, 31, 31 ]
等。 player_grid
列表中的所有元素只是 position 和大小的記錄,並不復雜。 go 的所有這些麻煩制作列表的原因是因為它允許代碼簡單地循環檢查它們內部的所有矩形。
在示例中,我使用了代碼現有a
, b
, c
, ...變量,因為它們已經在問題的代碼中定義。 但這很容易是range( 0, 10 )
和一些窗口大小的因素。
所以現在在player_grid
我們有 100 個矩形。 如果我們可以用同樣的方式制作一個crate
object,讓這個crate
“知道”它的 position,那會更好。 這允許板條箱 object(給定 x,y)告訴我們它是否被點擊。 因此,讓我們對crate
做一些小的修改 - 將__init__()
更改為采用x
和y
,並將PyGame Rect作為成員變量存儲:
class crate:
def __init__(self, x, y, sizex, sizey, shot, shiphere):
self.x = x
self.y = y
self.sizex = sizex
self.sizey = sizey
self.rect = pygame.Rect( x, y, sizex, sizey )
self.shot = shot
self.shiphere = shiphere
現在,在類似於之前的循環中創建一個crate
列表:
# Create the click-grid for the player
GRID_SIZE = 31
all_crates = []
for y_cell in [ a,b,c,d,e,f,g,h,i,j ]:
for x_cell in [ one, two, three, four, five, six, seven, eight, nine, ten ]:
all_crates.append( crate( x_cell, y_cell, GRID_SIZE, GRID_SIZE, False, False ) )
在這個操作之后,我們得到的是一個python的crate
對象列表,每個對象都包含一個PyGame Rect 。 這種意義上的 Rect 只是一個 position 和大小,它並不太復雜。 但它確實允許一些更容易的檢查,因為在 PyGame Rect 中有一堆方便的碰撞函數。
回到問題——用戶點擊了屏幕,我們需要看看它是否在 100 個crate
之一中。 現在每個板條箱都知道它是矩形 position,很容易遍歷它們,依次檢查:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
elif event.type == pygame.MOUSEBUTTONUP: # User released mouse button
mx, my = pygame.mouse.get_pos() # Position of the click
# Loop through all crate objects, seeing if any where clicked
for c in all_crates:
if c.rect.collidepoint( mx, my ) == True:
# User clicked inside a crate
c.crateShot( mx, my ) # Test for hit
break # No further checks needed
就個人而言,我會在crate
中創建一個成員 function ,並使用它而不是直接從 object 外部引用crate.rect
。
def wasClicked( self, mouse_x, mouse_y ):
return self.rect.collidepoint( mouse_x, mouse_y )
雖然在這種情況下微不足道,但它允許將任何未來的額外處理和檢查添加到crate
object 中,而不是“污染”主循環的簡單性。
注意:我嘗試盡可能少地更改代碼,同時保留樣式和現有代碼。 但是我認為重寫屏幕網格邏輯以使用 window 大小的因子並動態構建網格而不是手動調整坐標列表是一個很好的學習練習。 盡管最初需要更多的努力,但像繪制網格字母標題列表這樣的事情可能會變成一個簡單的 5 行循環。
例如,類似:
WINDOW_WIDTH = 1000
WINDOW_HEIGHT = 500
CELL_COUNT = 10
GRID_SIZE = WINDOW_HEIGHT // (CELL_COUNT * 0.7) # cells cover 70% of the window-height
GRID_OFFSET = GRID_SIZE * 2 # Leave room for headings, etc.
# Define the player grid
player_grid = []
for y in range( 0, CELL_COUNT ):
for x in range( 0, CELL_COUNT ):
pos_x = x + GRID_OFFSET # move the grid away from the edge
pos_y = y + GRID_OFFSET
player_grid.append( pygame.Rect( pos_x, pos_y, GRID_SIZE, GRID_SIZE ) )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.