Python 贪吃蛇游戏数学
Python Snake game math
我正在使用 python 3 并遵循[教程][1]。我遇到了问题,我的蛇没有动。它在 vec_add() 上调用无效语法,当我删除一些括号时,我得到:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 234, in 'calling callback function'
File "C:\Python34\lib\site-packages\OpenGL\GLUT\special.py", line 164, in deregister
function( value )
File "C:/Users/jay/Desktop/Python/OpenGL/Snake Game.py", line 51, in update
snake.insert(0, vec_add(snake[0], snake_dir)) # insert new position in the beginning of the snake list
TypeError: vec_add() missing 2 required positional arguments: 'x2' and 'y2'
蛇应该向右移动。
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
window = 0 # glut window number
width, height = 500, 500 # window size
field_width, field_height = 50, 50 # internal resolution
snake = [(20, 20)] # snake list of (x, u) positions
snake_dir = (1, 0) # snake movement direction
#Note: snake dir (1, 0) means that its current movement
#direction is x=1 and y=0, which means it moves to the right.
interval = 200 # update interval in milliseconds
def vec_add((x1, y1), (x2, y2)):
return (x1 + x2, y1 + y2)
def refresh2d_custom(width, height, internal_width, internal_height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, internal_width, 0.0, internal_height, 0.0, 1.0)
glMatrixMode (GL_MODELVIEW)
glLoadIdentity()
def draw_rect(x, y, width, height):
glBegin(GL_QUADS) # start drawing a rectangle
glVertex2f(x, y) # bottom left point
glVertex2f(x + width, y) # bottom right point
glVertex2f(x + width, y + height) # top right point
glVertex2f(x, y + height) # top left point
glEnd() # done drawing a rectangle
def draw_snake():
glColor3f(1.0, 1.0, 1.0) # set color to white
for x, y in snake: # go through each (x, y) entry
draw_rect(x, y, 1, 1) # draw it at (x, y) with width=1 and height=1
def draw(): # draw is called all the time
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen
glLoadIdentity() # reset position
refresh2d_custom(width, height, field_width, field_height)
draw_snake()
glutSwapBuffers() # important for double buffering
def update(value):
snake.insert(0, vec_add(snake[0], snake_dir)) # insert new position in the beginning of the snake list
snake.pop() # remove the last element
glutTimerFunc(interval, update, 0) # trigger next update
# initialization
glutInit() # initialize glut
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(width, height) # set window size
glutInitWindowPosition(0, 0) # set window position
window = glutCreateWindow(b"noobtuts.com") # create window with title
glutDisplayFunc(draw) # set draw function callback
glutIdleFunc(draw) # draw all the time
glutTimerFunc(interval, update, 0) # trigger next update
glutMainLoop() # start everything
在这个函数中:
def vec_add((x1, y1), (x2, y2)):
return (x1 + x2, y1 + y2)
Python 不支持函数参数列表中的解构。所以你可以这样写:
def vec_add(p1, p2):
return (p1[0] + p2[0], p1[1] + p2[1])
这与您对 vec_add
的现有调用兼容。
使用普通元组来存储和操作坐标很好,但您可能会发现命名元组是一种更方便的数据结构。命名元组的元素可以通过名称或索引访问,并且命名元组是 class 您可以向其添加自定义方法。
这是一个简短的演示,它向一个名为 tuple 的 2 元素添加了向量加法和减法方法,它还添加了一个有用的 __str__
方法。通过定义 __add__
和 __sub__
我们可以简单地使用 +
和 -
运算符执行向量加法和减法,这比使用更容易键入(和阅读)显式函数调用。
#!/usr/bin/env python
from collections import namedtuple
Vector = namedtuple('Vector', ['x', 'y'])
Vector.__str__ = lambda self: 'Vector({s.x}, {s.y})'.format(s=self)
Vector.__add__ = lambda self, other: Vector(self.x + other.x, self.y + other.y)
Vector.__sub__ = lambda self, other: Vector(self.x - other.x, self.y - other.y)
snake = [Vector(20, 20)]
snake_dir = Vector(x=1, y=0)
print(snake_dir.x)
print(snake[0] + snake_dir)
输出
1
Vector(21, 20)
请参阅 Python 文档中的 namedtuple for further info; here's the Python 3 version 个文档。
您也可以从头开始定义自己的 Vector 或 Point class,如 。如果你想存储很多点,你可能希望将 __slots__ = ()
添加到你的 class 定义中以最小化内存使用,如 Python 2 命名元组文档中所述。
我正在使用 python 3 并遵循[教程][1]。我遇到了问题,我的蛇没有动。它在 vec_add() 上调用无效语法,当我删除一些括号时,我得到:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 234, in 'calling callback function'
File "C:\Python34\lib\site-packages\OpenGL\GLUT\special.py", line 164, in deregister
function( value )
File "C:/Users/jay/Desktop/Python/OpenGL/Snake Game.py", line 51, in update
snake.insert(0, vec_add(snake[0], snake_dir)) # insert new position in the beginning of the snake list
TypeError: vec_add() missing 2 required positional arguments: 'x2' and 'y2'
蛇应该向右移动。
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
window = 0 # glut window number
width, height = 500, 500 # window size
field_width, field_height = 50, 50 # internal resolution
snake = [(20, 20)] # snake list of (x, u) positions
snake_dir = (1, 0) # snake movement direction
#Note: snake dir (1, 0) means that its current movement
#direction is x=1 and y=0, which means it moves to the right.
interval = 200 # update interval in milliseconds
def vec_add((x1, y1), (x2, y2)):
return (x1 + x2, y1 + y2)
def refresh2d_custom(width, height, internal_width, internal_height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, internal_width, 0.0, internal_height, 0.0, 1.0)
glMatrixMode (GL_MODELVIEW)
glLoadIdentity()
def draw_rect(x, y, width, height):
glBegin(GL_QUADS) # start drawing a rectangle
glVertex2f(x, y) # bottom left point
glVertex2f(x + width, y) # bottom right point
glVertex2f(x + width, y + height) # top right point
glVertex2f(x, y + height) # top left point
glEnd() # done drawing a rectangle
def draw_snake():
glColor3f(1.0, 1.0, 1.0) # set color to white
for x, y in snake: # go through each (x, y) entry
draw_rect(x, y, 1, 1) # draw it at (x, y) with width=1 and height=1
def draw(): # draw is called all the time
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen
glLoadIdentity() # reset position
refresh2d_custom(width, height, field_width, field_height)
draw_snake()
glutSwapBuffers() # important for double buffering
def update(value):
snake.insert(0, vec_add(snake[0], snake_dir)) # insert new position in the beginning of the snake list
snake.pop() # remove the last element
glutTimerFunc(interval, update, 0) # trigger next update
# initialization
glutInit() # initialize glut
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(width, height) # set window size
glutInitWindowPosition(0, 0) # set window position
window = glutCreateWindow(b"noobtuts.com") # create window with title
glutDisplayFunc(draw) # set draw function callback
glutIdleFunc(draw) # draw all the time
glutTimerFunc(interval, update, 0) # trigger next update
glutMainLoop() # start everything
在这个函数中:
def vec_add((x1, y1), (x2, y2)):
return (x1 + x2, y1 + y2)
Python 不支持函数参数列表中的解构。所以你可以这样写:
def vec_add(p1, p2):
return (p1[0] + p2[0], p1[1] + p2[1])
这与您对 vec_add
的现有调用兼容。
使用普通元组来存储和操作坐标很好,但您可能会发现命名元组是一种更方便的数据结构。命名元组的元素可以通过名称或索引访问,并且命名元组是 class 您可以向其添加自定义方法。
这是一个简短的演示,它向一个名为 tuple 的 2 元素添加了向量加法和减法方法,它还添加了一个有用的 __str__
方法。通过定义 __add__
和 __sub__
我们可以简单地使用 +
和 -
运算符执行向量加法和减法,这比使用更容易键入(和阅读)显式函数调用。
#!/usr/bin/env python
from collections import namedtuple
Vector = namedtuple('Vector', ['x', 'y'])
Vector.__str__ = lambda self: 'Vector({s.x}, {s.y})'.format(s=self)
Vector.__add__ = lambda self, other: Vector(self.x + other.x, self.y + other.y)
Vector.__sub__ = lambda self, other: Vector(self.x - other.x, self.y - other.y)
snake = [Vector(20, 20)]
snake_dir = Vector(x=1, y=0)
print(snake_dir.x)
print(snake[0] + snake_dir)
输出
1
Vector(21, 20)
请参阅 Python 文档中的 namedtuple for further info; here's the Python 3 version 个文档。
您也可以从头开始定义自己的 Vector 或 Point class,如 __slots__ = ()
添加到你的 class 定义中以最小化内存使用,如 Python 2 命名元组文档中所述。