- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这是我第一次真正的游戏制作尝试。我知道代码可以更好使用类或函数,但我试图使代码简单(和更短)
我在球和杆/桨的碰撞检测方面遇到问题。球粘在横杆上,然后沿同一方向继续前进。我尝试了一些 pygame 碰撞函数,但它们不起作用,因为我使用的是 surface 方法而不是 rect 方法。我的问题是:
如何使球从杆/桨上反弹?和/或我应该使用哪种方法或函数?
#!\user\bin\ env python
import pygame, sys
from pygame.locals import *
from sys import exit
pygame.init()
#game constants
fps = 60
clock = pygame.time.Clock()
#Colors
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 255, 0)
RED = (255, 0, 0)
size = window_WIDTH, window_HEIGHT = 800,600
window = pygame.display.set_mode( size , pygame.RESIZABLE)
window.fill(BLACK)
ball = pygame.Surface((25, 25))
ball = ball.convert()
ball.fill(WHITE)
ball_x, ball_y = (window_WIDTH/2 -12), (window_HEIGHT/2 -12 )
ball_speed_x = 7 #ball speed = 20
ball_speed_y = 7
bar = pygame.Surface((15, 90))
bar.fill(WHITE)
bar1 = bar.convert()
bar2 = bar.convert()
bar_speed = 0
bar1_x,bar1_y = (50), (window_HEIGHT/2-60)
bar2_x,bar2_y = (window_WIDTH - 50), (window_HEIGHT/2-60)
middle_line = pygame.Surface((2,window_HEIGHT))
middle_line.fill(WHITE)
middle_line = middle_line.convert()
running = True
while running:
for event in pygame.event.get():
if ( event.type == pygame.QUIT ) or ( event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = False
if event.type == pygame.KEYDOWN:
if event.key == K_UP:
bar_speed -= 20
if event.key == K_DOWN:
bar_speed += 20
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
bar_speed = 0
if event.key == pygame.K_DOWN:
bar_speed = 0
#since i don't know anything about collision, ball hitting bars goes like this.
#colisions with the walls (veritical walls for bars)
if bar1_y >= (window_HEIGHT - 90) or bar1_y <= 0:
bar_speed = 0
if bar2_y >= (window_HEIGHT - 90) or bar2_y <= 0:
bar_speed = 0
# collisions with bars (ball)
if ball_x <= (bar1_x+15):
if ball_y >= bar1_y:
if ball_y <= (bar1_y + 45): #checks if ball y cord is between bar y cord and bar length
# To right direction up
#ball_x += (bar1_x +15)
#ball_x += ball_speed_x
#ball_speed_y *= -1
ball_y *= -1
ball_x = (bar1_x +15)
ball_speed_y = -ball_speed_y
ball_speed_x = ball_speed_x
# To right direction down
if ball_y +45 <= (bar1_y + 90):#half down bar make y cord negative
#ball_speed_y = ball_speed_y
#ball_x += (bar1_x +15)
#ball_x += ball_speed_x
ball_y *= -1
ball_x = (bar1_x +15)
ball_speed_y = -ball_speed_y
ball_speed_x = ball_speed_x
if (ball_x+25) >= bar2_x:
if ball_y >= bar2_y:
if ball_y <= (bar2_y + 44): #checks if ball y cord is between bar y cord and bar length
# To right direction up
#ball_x = (bar1_x )#+15)
#ball_x -= ball_speed_x
ball_y *= -1
ball_x = (bar1_x +15)
ball_speed_y = -ball_speed_y
ball_speed_x = -ball_speed_x
if ball_y +45 <= (bar2_y + 90):#half down bar make y cord negative
#ball_speed_y = ball_speed_y
#ball_x = (bar2_x )#+15)
#ball_x = ball_speed_x
ball_y *= -1
ball_x = (bar1_x +15)
ball_speed_y = -ball_speed_y
ball_speed_x = -ball_speed_x
#collisions of ball with up down walls
if ball_y == 0:
if ball_x > window_WIDTH/2:
ball_speed_y = ball_speed_y
ball_speed_x = ball_speed_x
if ball_x < window_WIDTH/2:
ball_speed_y = ball_speed_y
ball_speed_x *= -1
if ball_y == window_HEIGHT:
if ball_x > window_WIDTH/2:
ball_speed_y *= -1
ball_speed_x = ball_speed_x
if ball_x < window_WIDTH/2:
ball_speed_y *= -1
ball_speed_x *= -1
#AI player
if ball_x >= window_WIDTH/2:
if not bar2_y == ball_y + 7.5:
if bar2_y < ball_y + 7.5:
bar2_y += bar_speed
if bar2_y > ball_y - 42.5:
bar2_y -= bar_speed
else:
bar2_y == ball_y + 7.5
if bar1_y >= 420.: bar1_y = 420.
elif bar1_y <= 10. : bar1_y = 10.
if bar2_y >= 420.: bar2_y = 420.
elif bar2_y <= 10.: bar2_y = 10.
bar1_y+= bar_speed
ball_x += ball_speed_x
ball_y += 1
window.fill(BLACK)
window.blit(middle_line,(window_WIDTH/2,0))
window.blit(bar1,(bar1_x, bar1_y))
window.blit(bar2,(bar2_x,bar2_y))
window.blit(ball, (ball_x, ball_y))
clock.tick(fps)
pygame.display.update()
pygame.quit()
P.S 我希望最终游戏的代码少于 100 行
最佳答案
我建议你使用pygame的Rect
, Sprite
和 Group
如果原因为一个数字类:
pygame.sprite.spritecollide
的冲突pygame.sprite.collide_mask
一起使用像素完美碰撞也很容易Rect.top
和 Rect.bottom
检查球是否在屏幕的顶部或底部反弹也变得非常容易。Rect.clamp_ip
一样简单这是一个基本的 2 人乒乓球游戏,应该是一个很好的起点。请注意代码是多么简单:
import pygame
import math
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
# some helpful vector math functions
def normalize(v):
vmag = magnitude(v)
return [v[i]/vmag for i in range(len(v))]
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def add(u, v):
return [ u[i]+v[i] for i in range(len(u)) ]
class Paddle(pygame.sprite.Sprite):
def __init__(self, start_pos, up_key, down_key):
pygame.sprite.Sprite.__init__(self)
# the image is just a white rect
self.image = pygame.surface.Surface((20, 100))
self.image.fill(pygame.color.Color('White'))
self.image.set_colorkey(pygame.color.Color('Black'))
self.rect = self.image.get_rect(topleft=start_pos)
# using a mask so we can use pixel perfect collision
self.mask = pygame.mask.from_surface(self.image)
self.up_key, self.down_key = up_key, down_key
def update(self, pressed):
if pressed[self.up_key]: self.rect.move_ip(0, -3)
if pressed[self.down_key]: self.rect.move_ip(0, 3)
# keep the paddle inside the screen
self.rect.clamp_ip(pygame.display.get_surface().get_rect())
class Ball(pygame.sprite.Sprite):
def __init__(self, start_pos):
pygame.sprite.Sprite.__init__(self)
# the image is just a white ball
self.image = pygame.surface.Surface((20, 20))
self.rect = self.image.get_rect(center=start_pos)
pygame.draw.circle(self.image, pygame.color.Color('White'), self.image.get_rect().center, 10)
self.image.set_colorkey(pygame.color.Color('Black'))
# using a mask so we can use pixel perfect collision
self.mask = pygame.mask.from_surface(self.image)
# the vector we use to move the ball
self.move_v = (1, 0.7)
# store the absolute position in self.pos
# because a rect can only use integers
self.pos = self.rect.center
def update(self, pressed):
# check if the ball collides with any other sprite
collide = [s for s in pygame.sprite.spritecollide(self, self.groups()[0], False, pygame.sprite.collide_mask) if s != self]
if collide:
# warning: this does not handle the case of the ball hits
# the top or bottom of the paddle, only the sides.
self.move_v = [-self.move_v[0], self.move_v[1]]
# check if the ball would go out of screen
display = pygame.display.get_surface().get_rect()
if self.rect.top < display.top and self.move_v[1] < 0 or \
self.rect.bottom > display.bottom and self.move_v[1] > 0:
self.move_v = [self.move_v[0], -self.move_v[1]]
# apply a constant speed and update the position
move_vector = [c * 4 for c in normalize(self.move_v)]
self.pos = add(self.rect.center, move_vector)
self.rect.center = map(int, self.pos)
player1 = Paddle((30, 190), pygame.K_w , pygame.K_s)
player2 = Paddle((590, 190), pygame.K_UP, pygame.K_DOWN)
ball = Ball(screen.get_rect().center)
sprites = pygame.sprite.Group(player1, player2, ball)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: break
else:
pressed = pygame.key.get_pressed()
sprites.update(pressed)
screen.fill(pygame.color.Color('black'))
sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
continue
break
pygame.quit()
关于python - 乒乓克隆碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31402115/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!