我目前正在使用pygame库在python中开发一个2D弹球游戏,我选择了掩码碰撞检测,这里是一个链接到一个帖子,它很好地解释了:
2D Collision detection for Pinball Game
我认为我做了所有事情,但它没有按照要求工作。
这是我的球的物理代码:
from math import *
from Constants import *
def Getcolor(ballx,bally,screen,resources):
screen.blit(resources["CollisionMain"], (220, 0))
color=screen.get_at((ballx,bally))
colore=color[1]
return colore
def UpdateBall(ball,color):
ballx=ball[1][0]
bally=ball[1][1]
lastpos = ball[1][0], ball[1][1]
velocity=ball[2]
if -FRICTION_BALL <= velocity <= FRICTION_BALL :
velocity = 0
else:
velocity += FRICTION_BALL if velocity < 0 else -FRICTION_BALL
ball[2] = velocity
ball[1][0] += velocity
vectorx = sin(color / 255 * 2 * pi)
vectory = cos(color / 255 * 2 * pi)
if ballx+Ball_width<screen_width:
ballx=screen_width-Ball_width
if (bally+Ball_len)>screen_lenght:
bally=screen_lenght-Ball_len
#ball[1][1] -= 10
else:
if color == 255:
ball[1][1] += Gravity
else:
ball[1][0],ball[1][1]=lastpos
ball[1][0] += vectorx
ball[1][1] += vectory
def DrawBall(screen,ball,resources):
screen.blit(ball[0],(ball[1][0],ball[1][1]))
这是我的游戏引擎代码:
import pygame
import sys
from pygame.locals import *
from Constants import *
from ball import *
def Init():
pygame.init()
screen = pygame.display.set_mode((screen_width,screen_lenght))
pygame.display.set_caption('Supinball')
pygame.key.set_repeat(150,150)
pygame.mixer.init(44100, -16, 2, 1024)
return screen
def LoadResources():
resources= dict()
resources["MainLayer"] = pygame.image.load("resources/images/main_layer.png")
resources["Ball"] = pygame.image.load("resources/images/Ball.png")
resources["CollisionMain"] = pygame.image.load("resources/images/collision_main.png")
resources["CollisionSpec"] = pygame.image.load("resources/images/collision_special.png")
resources["Rflipper"] = pygame.image.load("resources/images/right_flipper.png")
resources["Lflipper"] = pygame.image.load("resources/images/left_flipper.png")
resources["Spring"] = pygame.image.load("resources/images/spring.png")
resources["Music"] = pygame.mixer.Sound("resources/sounds/music.ogg")
resources["Coin"] = pygame.mixer.Sound("resources/sounds/Coin.wav")
resources["Hit"] = pygame.mixer.Sound("resources/sounds/hit.wav")
resources["Tilted"] = pygame.mixer.Sound("resources/sounds/tilted.wav")
resources["GameOver"] = pygame.mixer.Sound("resources/sounds/GameOver.ogg")
resources["Font"] = pygame.font.Font('resources/Vdj.ttf', 30)
return resources
def GameLoop(screen,resources):
gameRunning = True
ball = [resources["Ball"],[300,20],0]
fpsClock = pygame.time.Clock()
while gameRunning:
ev = GetEvent(ball)
gameRunning = ev[GAME_RUNNING]
#resources["Music"].play(-1)
color=Getcolor(int(ball[1][0]), int(ball[1][1]), screen, resources)
print(color)
UpdateBall(ball,color)
#screen.blit(resources["MainLayer"], (0,0))
DrawBall(screen,ball,resources)
pygame.display.update()
fpsClock.tick(FPS)
def GetEvent(ball):
ev = [True,False,False,False,False,False,False,False,False,False]
for event in pygame.event.get():
if event.type == QUIT:
ev[GAME_RUNNING] = False
if event.type == MOUSEBUTTONUP:
mousepos = pygame.mouse.get_pos()
ball[1][0],ball[1][1]=mousepos
if event.type == KEYDOWN:
if event.key == K_DOWN:#compress spring
ev[KEY_DOWN] = True
if event.key == K_UP: #relax spring
ev[KEY_UP] = True
if event.key == K_LSHIFT: #left flipper
ev[KEY_LSHIFT] = True
if event.key == K_RSHIFT: #right flipper
ev[KEY_RSHIFT] = True
if event.type == KEYUP:
if event.key == K_q: #insert coin
ev[KEY_Q] = True
if event.key == K_SPACE: #launch ball
ev[KEY_SPACE] = True
if event.key == K_LEFT:#tilt left
ev[KEY_LEFT] = True
if event.key == K_RIGHT:#tilt right
ev[KEY_RIGHT] = True
if event.key == K_p:#pause
ev[KEY_P] = True
return ev
def DestroyGame():
pygame.quit()
和常量代码:
#screen
screen_lenght = 256
screen_width= 600
#fps
FPS=100
#events
GAME_RUNNING = 0
KEY_Q = 1
KEY_DOWN = 2
KEY_UP = 3
KEY_SPACE = 4
KEY_LSHIFT = 5
KEY_RSHIFT = 6
KEY_RIGHT = 7
KEY_LEFT = 8
KEY_P = 9
#ball physics
FRICTION_BALL=0.5
Gravity=1.9
Ball_width=11
Ball_len=9
但是当我跑步时,球没有完全碰撞,它只与最黑暗的斑点相撞并穿过浅灰色
如果你看这张照片
球不应该通过保险杠但它确实如此 - 如果我的代码是垃圾,我很抱歉,我是初学者。 :)
以下是我想要实现的有效工作版本的YouTube链接:
https://www.youtube.com/watch?v=SXegewcVx8A