私はpygameでpygameで開発されたゲームの始まりを、3210のチュートリアルの次のものにしています。それぞれmain.py、player.py、walls.py(プレーヤーと壁クラスがあります)があります。プレーヤークラスには、衝突の検出と移動のためのコードが含まれています。残念なことに、プレイヤーはタイルを避けますが、衝突時には予想される動き(停止のみ)ではなく、画面の右側の位置に移動します。誰もがこれの論理を助け、衝突時の誤った/望ましくない動きを修正することができますか?以下は、main.py、player.py、walls.pyの3つのファイルです。 MAIN.PYpygame不正確な衝突の検出と移動
#main.py
import pygame
import random
from player import Player
from collectable import Collectable
from walls import Wall
pygame.init()
BLACK=(0,0,0)
WHITE=(255,255,255)
RED=(255,0,0)
GREEN =(0,255,0)
BLUE=(0,0,255)
GOLD=(255,215,0)
WIDTH=500
HEIGHT=500
size= (WIDTH,HEIGHT)
screen=pygame.display.set_mode(size)
pygame.display.set_caption("The Life Game")
done = False
clock=pygame.time.Clock()
wall_list=pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
enemy_list = pygame.sprite.Group()
player=Player()
player.walls=wall_list
all_sprites.add(player)
for i in range(random.randrange(100,200)):
whiteStar = Collectable(WHITE, 3, 3, "White Star", "Rect")
whiteStar.rect.x = random.randrange(size[0])
whiteStar.rect.y = random.randrange(size[1])
all_sprites.add(whiteStar)
for i in range(50):
enemy = Collectable(RED,6, 6,"Enemy","Ellipse")
enemy.rect.x = random.randrange(300)
enemy.rect.y = random.randrange(300)
enemy_list.add(enemy)
all_sprites.add(enemy)
coin1 = Collectable(GOLD,50,50,"Coin","Ellipse")
coin1.rect.x=440
coin1.rect.y=0
all_sprites.add(coin1)
coin2 = Collectable(GOLD,50,50,"Coin","Ellipse")
coin2.rect.x=0
coin2.rect.y=440
all_sprites.add(coin2)
enemy = Collectable(RED,100,100,"Enemy","Ellipse")
enemy.rect.x=70
enemy.rect.y=230
all_sprites.add(enemy)
#Make the walls (x_pos,y_pos, width, height,colour)
wall=Wall(0,0,10,600,GREEN)
wall_list.add(wall)
all_sprites.add(wall_list)
wall = Wall(50, 300, 400, 10,RED)
wall_list.add(wall)
all_sprites.add(wall_list)
wall = Wall(10, 200, 100, 10,BLUE)
wall_list.add(wall)
all_sprites.add(wall_list)
score=0
health=100
#- - - - - - - - - - - - - -Main Program Loop - - - - - - - - - - - - - - - -
def main():
done=False
score=0
health=100
while not done:
#- - - - - - Main event loop (this is where code for handling keyboard and mouse clicks will go)
#Loop until the user clicks the 'x' button (to close program)
for event in pygame.event.get(): #User does something
if event.type == pygame.QUIT: #If the user clicked close
done = True #set the done flag to 'true' to exit the loop
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_LEFT]:
player.moveLeft(5)
if keys[pygame.K_RIGHT]:
player.moveRight(5)
if keys[pygame.K_UP]:
player.moveUp(5)
if keys[pygame.K_DOWN]:
player.moveDown(5)
#>>----------DRAW SECTION -----------------------------------
#Clear the screen to BLACK. Any drawing commands should be put BELOW this or they will be reased with this command
screen.fill(BLACK)
#Select the font to be used (size, bold, italics, etc)
font_score = pygame.font.SysFont('Calibri',20,True,False)
font_health = pygame.font.SysFont('Calibri',20,True,False)
#Printing a variable (score or health) to the screen involves converting the score (if integer) to a string first.score_label = font_score.render("Score: " + str(score),True,BLACK)
health_label = font_health.render("Health: "+str(health),True,WHITE)
score_label = font_score.render("Score: " + str(score),True, WHITE)
#Now we can use this line of code to put the image of the text on the screen at a given position
screen.blit(score_label,[100,480])
screen.blit(health_label,[190,480])
#>>---------UPDATE SECTION/Put the logic of your game here (i.e. how objects move, when to fire them, etc)
all_sprites.update()
if coin1.collision_with(player):
score=score+1
coin1.kill()
coin1.rect.x=-20
coin1.rect.y=-330
if coin2.collision_with(player):
score=score+1
coin2.kill()
coin2.rect.x=-20
coin2.rect.y=-330
if enemy.collision_with(player):
health=health-25
enemy.kill()
enemy.rect.x=-20
enemy.rect.y=-330
enemy.update()
#-------------PRINTING VARIABLES LIKE SCORE TO SCREEN
#Any drawing/graphics code should go here
all_sprites.draw(screen)
#Update the screen to show whatever you have drawn
pygame.display.flip()
#Set the frames per second (e.g. 30, 60 etc)
clock.tick(120)
main()
PLAYER.PY
import pygame
import random
from walls import Wall
class Player(pygame.sprite.Sprite):
#-------------------Define Variables here
speed=0
#------------------Initialise Constructor
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load("player.png")
self.rect = self.image.get_rect()
#SET THE INITIAL SPEED TO ZERO
self.change_x = 0
self.change_y = 0
#--------------Fetch the rectangle object that has the dimensions of the image
self.rect =self.image.get_rect()
#---------------Define movement
def moveRight(self,pixels):
self.rect.x+=pixels
def moveLeft(self,pixels):
self.rect.x-=pixels
def moveUp(self,pixels):
self.rect.y-=pixels
def moveDown(self,pixels):
self.rect.y+=pixels
# Make our top-left corner the passed-in location.
def settopleft():
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
# Set speed vector
self.change_x = 0
self.change_y = 0
self.walls = None
def changespeed(self, x, y):
""" Change the speed of the player. """
self.change_x += x
self.change_y += y
def update(self):
# Did this update cause us to hit a wall?
block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
# If we are moving right, set our right side to the left side of
# the item we hit
if self.change_x > 0:
self.rect.right = block.rect.left
else:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
# Move up/down
self.rect.y += self.change_y
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_y > 0:
self.rect.top = block.rect.top
else:
self.rect.top = block.rect.bottom
WALLS.PY
import pygame
class Wall(pygame.sprite.Sprite):
#Wall a player can run into
def __init__(self, x, y, width, height,colour):
#Constructor fo rthe wall that the player can run into
#call the parent's constructor
super().__init__()
#Make a green wall, of the size specified in paramenters
self.image=pygame.Surface([width,height])
self.image.fill(colour)
#Make the "passed-in" location ,the top left corner
self.rect=self.image.get_rect()
self.rect.y=y
self.rect.x=x
あなたの投稿を編集し、[、最小限の完全かつ検証可能な例]を提供(https://stackoverflow.com/help/mcve)してください私たちが実行してテストすることができ、そうでなければ、あなたを助けることは非常に困難または不可能かもしれません。 – skrx
@slrxご意見ありがとうございます。おそらく、それはプレーヤーファイルに単純なロジックエラーがあると思っていました。あなたのアドバイスに従って、私は今3つのファイルをすべて追加して、より正確に質問をしました。あらかじめ大変ありがとうございます – MissComputing
これはまだ*最小の*例ではありません。これを取り除くにはたくさんのことがありますが、基本的にコードの概要を簡単に説明してください。 3つではなく1つのファイルにすべてを収め、無駄な敵をすべて解読してください。シンプルな「ここの選手は、壁があります。私がこのようなプレーヤーを動かしたら、どうして衝突しないのですか?私たちにあなたのコードをすべて与えるのではなく、私たちが読むことは簡単です(誰が500行を読むのが面倒なのでしょうか?)ので、より多くの助けを得ることができますが、余分なものを解析する際に間違いを認識してしまいます。 –