1

私は次のように見えるはずの2人用ゲームを作成しています。
ゲーム画像
ゲームでは、シューター(緑と青、プレーヤーによって制御される)が互いに弾丸を撃つことができます。
弾丸
1.が壁(灰色)に衝突すると、破壊されます。
2.シューターに当たると、体力が失われます(シューター)。
ゲームは(想定される)ターン制であり、プレイヤーが0健康に達すると終了します。

私の問題
1.私のシューティングゲームのバレルが更新/回転していません。
2.(ny)キーが押されたかどうかを検出するためのより良い方法はありますか。
*シューター、弾丸、壁はクラスです

私のコード
(答えるのに役立つ関数が言及されていない場合はコメントしてください)

import math,random,pygame
def event_handle(event,turn):
    if turn == 1:
        c_s = p1
    elif turn == 2:
        c_s = p2
    else:
        return None
    if event.type == pygame.KEYDOWN:
        key = pygame.key.get_pressed()
        # next_pos
        if key[pygame.K_q]:
            c_s.next_x -= 1
        if key[pygame.K_e]:
            c_s.next_x += 1
        # angle
        if key[pygame.K_w]:
            c_s.angle += radians(1)
        if key[pygame.K_s]:
            c_s.angle -= radians(1)
        # power (speed)
        if key[pygame.K_d]:
            c_s.speed += 0.1
        if key[pygame.K_a]:
            c_s.speed -= 0.1

def draw_all(bullist,shooters,wall,surface):
    # draw shooters
    for shooter in shooters:
        shooter.move()
        shooter.draw(surface)
    # draw bullets
    for bullet in bullist:
        bullet.gravity()
        bullet.move()
        bullet.collides(shooters,wall,bullist)
        bullet.out(surface,bullist)
        bullet.draw(surface)
    # wall
    wall.update()
    wall.draw(surface)
    pygame.draw.aaline(surface,(255,255,255),(0,400),(640,400))

def angle(A,B,BC,theta):

    C = [0,0]
    alpha = math.atan2(A[1]-B[1] , A[0] -B[0] ) - theta
    C[0] = int(round(B[0]  + BC * math.cos(alpha),0))
    C[1] = int(round(B[1]  + BC * math.sin(alpha),0))
    return C

class Shooter:
    def __init__(self,pos,size,color,xmax,xmin):
        self.pos = pos
        self.size = size
        self.rect = pygame.Rect(pos,size)
        self.health = 100
        self.color = color
        self.angle = 0
        self.speed = 0
        self.max = xmax
        self.min = xmin
        self.next_x = pos[0]

        self.color2 = []
        for i in color:
            i = i - 100
            if i < 0:
                i = 0
            self.color2.append(i)

    def draw(self,surface):
        global C
        pygame.draw.rect(surface,self.color,self.rect)

        c = angle(self.rect.midleft,self.rect.center,
                  20,radians(self.angle))
        if c != C and c != [95,392]:
            print c
            C = c
        pygame.draw.line(surface,self.color2,self.rect.center,c,3)


## the other funcs or classes not needed

# globals
turn = 1
C = []
# pygame
(width, height) = (640, 480)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Shooter')
clock = pygame.time.Clock()
# game actors
shooters = []
bullets = []
p1 = Shooter((400,400),(30,-15),(255,0,0),0,0)
p2 = Shooter((100,400),(30,-15),(0,255,0),0,0)
shooters.extend([p1, p2])
wall = Wall(100)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            break
        else: event_handle(event,turn)
    if not running:
        break
    screen.fill((0,0,0))
    # Game draw logic + Game logic

    draw_all(bullets,shooters,wall,screen)
    pygame.display.flip()
    clock.tick(40)

私は何が間違っているのですか?

4

2 に答える 2

1

コードは実際に機能しますが、いくつかの問題があります。バレルは実際には回転しますが、キーを押すたびにごくわずかしか回転しません。

event_handle関数を次のように変更してみてください。

def event_handle(turn):
    if turn == 1:
        c_s = p1
    elif turn == 2:
        c_s = p2
    else:
        return None
    key = pygame.key.get_pressed()
    # next_pos
    if key[pygame.K_q]:
        c_s.next_x -= 1
    if key[pygame.K_e]:
        c_s.next_x += 1
    # angle
    if key[pygame.K_w]:
        c_s.angle += radians(10)
    if key[pygame.K_s]:
        c_s.angle -= radians(10)
    # power (speed)
    if key[pygame.K_d]:
        c_s.speed += 0.1
    if key[pygame.K_a]:
        c_s.speed -= 0.1

この時点ではイベントタイプにまったく関心がないため、eventパラメータとif event.type == pygame.KEYDOWN:チェックを削除しました。このようにして、バレルを回転させるためにキーを複数回押すのではなく、キーを押したままにすることができます。

また、バレルが回転する値をからに増やしましradians(1)radians(10)。それ以外の場合、変更は小さすぎて(妥当な時間内に)表示できません。

また、メインループを次のように調整する必要があります

...
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
        pygame.quit()
        break
if not running:
    break
event_handle(turn)
...

これevent_handleは、メインループのすべての反復と呼ばれます。

于 2013-01-29T11:13:02.797 に答える
0

key.get_pressedを使用している場合は、key_downイベントを検出する必要はまったくありません。if event.type == pygame.KEYDOWN:ステートメントを削除して、から返されるpygame.key.get_pressedものにキーがあるかどうかを確認してください。

pygame.event.pumpああ、ループを実行するたびに、コードのどこかで呼び出す必要があります。whileループ内に配置します。

(そして、あなたの問題とは関係のないヒント:そのメインループを関数内に移動します-このようにプログラム本体にぶら下がっているのは恐ろしいことです)

于 2013-01-29T10:59:21.580 に答える