#python #pygame
#python #pygame
Вопрос:
Я новичок в PyGame. Я хочу создать игру для уклонения, которую я сделал в Scratch 2. Представьте, что там летит космический корабль. У вас есть только управление по оси Y с помощью клавиш up и down. Когда спрайт движется, у него должно быть трение, подобное тому, что заставляет его скорость Y постепенно замедляться при нажатии клавиш up или down
Код:
# import sys
from random import randint
import pygame
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
fps = 60
up = False
down = False
player_location = [250 ,200]
friction = 0.9
force = 4
misy = randint(0, 400)
missile_loc = [590,misy]
player = pygame.image.load("spaceship.png")
missile = pygame.image.load("missile.png")
Window_size = (600,400)
pygame.display.set_caption("The Game")
screen = pygame.display.set_mode(Window_size, 0, 0)
player_rect = pygame.Rect(player_location[0], player_location[1], player.get_width(), player.get_height())
missile_rect = pygame.Rect(missile_loc[0], missile_loc[1], missile.get_width(), missile.get_height())
go = True
while go:
screen.fill((146, 244, 255))
pygame.draw.rect(screen, (0,0,0), player_rect)
pygame.draw.rect(screen, (255,0,0), missile_rect)
player_rect.x = player_location[0]
player_rect.y = player_location[1]
# player_location[1] *= friction
if up == True:
player_location[1] -= force
if down == True:
player_location[1] = force
for event in pygame.event.get():
if event.type == QUIT:
go = False
if event.type == KEYDOWN:
if event.key == K_UP:
up = True
if event.key == K_DOWN:
down = True
if event.type == KEYUP:
if event.key == K_UP:
up = False
if event.key == K_DOWN:
down = False
pygame.display.update()
clock.tick(fps)
pygame.quit()
Комментарии:
1. Что вы подразумеваете под трением? Вы имеете в виду сопротивление или какую-то воображаемую замедляющую силу? Нравится это ? Каким должен быть профиль скорости? Сначала корабль идет быстро, затем постепенно замедляется или что?
2. Поскольку трение как сила часто аппроксимируется с помощью F = F_n * mu , где F_n — нормальная сила, mu — коэффициент трения между двумя поверхностями скольжения (например, брюхом космического корабля и асфальтом, ой), но если он летит (особенно в космосе), трения как такового нет.
3. @Spacha На самом деле я закодировал эту строку, но я изменил ее для комментариев. Обратитесь к коду, который я предоставил. Я попробовал, и космическому кораблю показалось, что он просто прилипает к верхней части окна.
4. Я это видел. У вас было
player_location[1] *= friction
. Это делает вашеplayer_location[1]
значение равным 0.0 за долю секунды, поэтому оно застревает в верхней части экрана. Попробуйте код, который я предоставил.5. Спасибо всем за попытку мне помочь. На самом деле я сам нашел ответ после некоторых экспериментов.
Ответ №1:
Ну, вы можете продолжать умножать свою скорость на десятичное число (таким образом, имитируя трение) Кажется, что из вашего кода force
зависит ваша скорость. Итак, создайте переменную с именем «замедление = 0,95», чем меньше десятичное число, тем быстрее замедляется объект.
Итак, в вашем игровом цикле (желательно в конце для вашего случая) вы можете умножить свою силу на замедление:
force *= deceleration
Комментарии:
1. Я не думаю, что это будет работать так, как ожидалось (хотя я пока не совсем уверен, что требуется). Сила должна быть сброшена до исходного значения при
KEYUP
событии. Кроме того, он должен быть активен только тогда, когда применяется сила.2. @AntonioKaram Я пробовал, но кажется, что космический корабль застревает в верхней части экрана. У меня есть cod3d, который я превратил в комментарий, используя #.
Ответ №2:
Как я уже сказал, я не совсем уверен, чего вы хотите, но вот тот, который дает вашему космическому кораблю постоянное замедление, пока он не остановится. Сила возвращается к нормальному состоянию при отпускании клавиши. Я исправлю это, если вы проясните свой вопрос.
# import sys
from random import randint
import pygame
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
fps = 60
up = False
down = False
player_location = [250 ,200]
friction = 0.9
force = 4
misy = randint(0, 400)
missile_loc = [590,misy]
player = pygame.image.load("spaceship.png")
missile = pygame.image.load("missile.png")
Window_size = (600,400)
pygame.display.set_caption("The Game")
screen = pygame.display.set_mode(Window_size, 0, 0)
player_rect = pygame.Rect(player_location[0], player_location[1], player.get_width(), player.get_height())
missile_rect = pygame.Rect(missile_loc[0], missile_loc[1], missile.get_width(), missile.get_height())
drag = 0.0
def vertical_velocity():
global force, drag
vel = force / (drag 1)
drag = 0.05
return vel
go = True
while go:
screen.fill((146, 244, 255))
pygame.draw.rect(screen, (0,0,0), player_rect)
pygame.draw.rect(screen, (255,0,0), missile_rect)
player_rect.x = int(player_location[0])
player_rect.y = int(player_location[1])
# player_location[1] *= friction
if up == True:
player_location[1] -= vertical_velocity()
if down == True:
player_location[1] = vertical_velocity()
for event in pygame.event.get():
if event.type == QUIT:
go = False
if event.type == KEYDOWN:
if event.key == K_UP:
up = True
if event.key == K_DOWN:
down = True
if event.type == KEYUP:
if event.key == K_UP:
up = False
drag = 0.0
if event.key == K_DOWN:
down = False
drag = 0.0
pygame.display.update()
clock.tick(fps)
pygame.quit()
Редактировать
Вот, например, линейные и нелинейные профили скорости:
drag = 0.0
def vertical_velocity_nonlinear():
global force, drag
vel = force / (drag 1)
drag = 0.05
return vel
def vertical_velocity_linear():
global force, drag
vel = force (1-1/4*drag)
vel = vel if (vel >= 0) else 0.0
drag = 0.05
return vel
И профили скорости, которые они дают (это, вероятно, не очень полезно, но здесь я иду). Первый — «нелинейный», а второй — «линейный».
Ответ №3:
Я на самом деле решил это сам после некоторых экспериментов.
Код:
# import sys
from random import randint
import pygame
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
fps = 60
up = False
down = False
player_location = [250 ,200]
friction = 0.9
force = 0
misy = randint(0, 400)
missile_loc = [590,misy]
player = pygame.image.load("ship.png")
missile = pygame.image.load("missile.png")
Window_size = (600,400)
pygame.display.set_caption("The Game")
screen = pygame.display.set_mode(Window_size, 0, 0)
player_rect = pygame.Rect(player_location[0], player_location[1], player.get_width(), player.get_height())
missile_rect = pygame.Rect(missile_loc[0], missile_loc[1], missile.get_width(), missile.get_height())
go = True
while go:
screen.fill((146, 244, 255))
pygame.draw.rect(screen, (0,0,0), player_rect)
pygame.draw.rect(screen, (255,0,0), missile_rect)
screen.blit(player, player_location)
screen.blit(missile, missile_loc)
player_rect.x = player_location[0]
player_rect.y = player_location[1]
player_location[1] = force
force *= friction
if up == True:
force -= 1
if down == True:
force = 1
for event in pygame.event.get():
if event.type == QUIT:
go = False
if event.type == KEYDOWN:
if event.key == K_UP:
up = True
if event.key == K_DOWN:
down = True
if event.type == KEYUP:
if event.key == K_UP:
up = False
if event.key == K_DOWN:
down = False
pygame.display.update()
clock.tick(fps)
pygame.quit()
Ответ №4:
Для перемещения игрока я обычно использую x
, y
, moveX
и moveY
.
В этом коде игрок перемещается с помощью стрелок, с трением при движении влево-вправо и с прыжком. Просто используйте ту же операцию для движения вверх-вниз, и вы сможете видеть игрока сверху сцены.
Обратите внимание, что для проигрывателя используется класс.
pressed = pygame.key.get_pressed() # get the pressed keys
if pressed[K_LEFT]:
self.moveX -= 3000 * time_passed # time_passed is in seconds
if pressed[K_RIGHT]:
self.moveX = 3000 * time_passed
if pressed[K_UP]: # jump runs differently
self.moveY = -1200
self.moveX *= 0.95**(100 * time_passed) # slow down
# 0.95 is friction (moveX *= 0.95 if 100 FPS)
if self.moveY < 1600:
self.moveY = 5000 * time_passed # go down
self.x = self.moveX * time_passed # add the X movement
self.y = self.moveY * time_passed # add the Y movement
Комментарии:
1. Я сам ответил на решение. Просто взгляните.
2. Я видел, но я хотел помочь вам, показав вам другой способ сделать это.