- 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/
我有 jquery Draggable/droppable 来处理包含和帮助器选项集。我想做的是将放置的项目的顶部和左侧参数存储在两个变量中。 我在下面的示例中实现了这一点(将新文档图标拖到框中),但
我有一个带有两个链接下拉列表的表单,我需要制作许多克隆,但保留链接。 这是一个示例,链接组合在我的应用程序中带有 json。 链式代码:
我在使用少量 jQuery 时遇到了一些逻辑问题。 我很确定我需要一个循环设置,但我很难将其组合在一起。我引用了 tuts、视频、工作示例、幻灯片,甚至是原始 javascript,但仍然难以将逻辑端
我有一个对象,它是一个基本的树。我需要对其进行深度复制,并发现自己实现了 __clone 方法。成功的代码是: function __clone() { $object = new Custo
我可以克隆一个没有内容的文本框吗?意味着如果我在克隆后在文本框中输入一些值,我想要一个空文本框。这可能吗?或者jquery克隆将其返回为innerHtml? 最佳答案 默认情况下,克隆会复制 的值目
我想复制或克隆我自己编写的类的对象。但如果我调用复制函数,则仅复制指针。因此,如果我更改复制的对象,原始对象也会更改。 有没有一种方法/功能可以真正克隆一个对象? 最诚挚的问候梅兰妮 最佳答案 如果一
我有一些 javascripc 代码: $(this).parent().siblings().find('.year-dropdown').find('.date, .time, .details'
我们有一个包含三个命名分支的存储库,我想克隆其中一个分支。有一个善变的命令可以做到这一点吗?如果我使用 hg clone 提供(分支)路径,则会收到 404 错误。 最佳答案 hg clone htt
我有带有 ObservableCollection 和其他属性的类。所以它看起来有点像这样: public class A { public int Id { get; set; } ..
我正在尝试下载一个大型开源项目的源代码,以便我可以查看它。 它说要做: hg clone http://server/path 但是,这需要很长时间(我假设是因为这是一个大项目)。我并不真正关心变更集
我发现这段代码随处可见,用于复制列表或克隆列表。 代码随处可见: clone([],[]). clone([H|T],[H|Z]):- clone(T,Z). ?-clone([1,2,3],Z).
我正在打印一个JFrame。在此之前,我隐藏菜单栏并将 JFrame 设置为未修饰。这工作得很好,但可见的 JFrame 发生了变化,以反射(reflect)我稍后必须恢复的已删除的控件。 我想克隆
我正在尝试复制一个 div 并将其附加到它的克隆之上。不幸的是,它似乎正在创建额外的重复项。这是怎么回事? 这是一个示例:http://jsfiddle.net/QEN5N/ 最佳答案 live 会将
为什么我不能克隆 ConcurrentHashMap ? ConcurrentHashMap test = new ConcurrentHashMap(); test.put("hello",
我有这个代码: openPopup.hide(); var substr = popupId.split('-'); var clone = $("#po
这段代码几乎可以正常工作假设我的表中有 10 行,我单击顶行,它会被克隆,然后添加到表的底部,而原始数据被删除,重复这些步骤 5 次。现在,我以克隆在底部的五行结束。 现在,如果我单击第一个克隆行,它
我已经设置了JSFiddle来展示我的问题。 我改变了克隆方式,使其更加通用,因此我不需要为不同的表重用代码。通常,对于 select2 元素,我会这样做 $(".campaignType", $tr
1 2 3 $('#things').after($('#things').clone()); 克隆时如何在这两个元素之间插入中断?有没有一种巧妙的方法可以用一行代码来完成
我正在从现有类型动态装配中创建新类型,但只包含选定的属性: public class EmitTest { public Type Create(Type prototype, Type dy
在我的游戏引擎中实现对象克隆的过程中,我遇到了一些绊脚石。我的目标是拥有一个克隆系统,我不必逐个类地维护它,除非该类需要特殊处理。 我的游戏引擎的设置围绕着一个基类 Object2D,它包含一些 Te
我是一名优秀的程序员,十分优秀!