Cara membuat platformer dengan python

Tutorial ini menunjukkan cara menggunakan Python dan perpustakaan Arcade untuk membuat game platformer 2D. Anda akan belajar bekerja dengan Sprite dan Tiled Map Editor untuk membuat game Anda sendiri. Anda dapat menambahkan koin, landai, platform bergerak, musuh, dan lainnya

Di akhir setiap bab tutorial ini terdapat tautan ke kode sumber lengkap. Tutorial dibagi menjadi beberapa bagian ini

  • Langkah 1 - Instal dan Buka Jendela
  • Langkah 2 - Tambahkan Sprite
  • Langkah 3 - Objek Adegan
  • Langkah 4 - Tambahkan Kontrol Pengguna
  • Langkah 5 - Tambahkan Gravitasi
  • Langkah 6 - Tambahkan Kamera
  • Langkah 7 - Tambahkan Koin Dan Suara
  • Langkah 8 - Tampilkan Skor
  • Langkah 9 - Gunakan Editor Peta Ubin
  • Langkah 10 - Beberapa Level dan Lapisan Lainnya
  • Langkah 11 - Tambahkan Tangga, Properti, dan Platform Bergerak
  • Langkah 12 - Tambahkan Animasi Karakter, dan Kontrol Keyboard yang Lebih Baik
  • Langkah 13 - Tambahkan Musuh
  • Langkah 14 - Memindahkan Musuh
  • Langkah 15 - Tabrakan dengan Musuh
  • Langkah 16 - Menembak Peluru
  • Langkah 17 - Tampilan

Saat ini ada beberapa contoh lagi yang berkembang di luar tutorial. Anda dapat melihat kode sumber untuk contoh tersebut serta setiap bab dalam tutorial di Arcade Github di https. //github. com/pythonarcade/arcade/tree/development/arcade/examples/platform_tutorial

Tutorial ini juga diperluas menjadi game berfitur lengkap yang dikembangkan oleh komunitas Arcade. Anda dapat melihat proyek itu di Github di https. //github. com/pythonarcade/community-platformer

Dalam tutorial sebelumnya kami memperkenalkan pengembangan game grafis dengan PyGame, membahas cara mengembangkan game 2D dengan sprite animasi dan interaksi pengguna. Dalam tutorial ini, kita akan melangkah lebih jauh dan membuat platformer 2D, di mana Anda dapat membuat alien berjalan dan melompati ruangan yang penuh dengan kotak. Tutorial PyGame sebelumnya bukanlah prasyarat untuk mencoba yang ini

Kami akan fokus pada animasi dan gerakan dasar untuk menciptakan basis yang kokoh dari mana Anda dapat terus membangun seluruh permainan platform, lengkap dengan musuh, power-up, dan berbagai level

Mulai

Buat repl baru dan pilih "PyGame" dari tarik-turun bahasa

Cara membuat platformer dengan python

Anda akan melihat "Python3 with PyGame" ditampilkan di konsol default dan panel terpisah di Replit IDE tempat Anda dapat melihat dan berinteraksi dengan game yang akan Anda buat

Sebelum kita mulai menulis kode, kita membutuhkan beberapa sprite, yang telah kita sediakan di sini. Ekstrak file ZIP ini dan tambahkan file di dalamnya ke repl Anda menggunakan fungsi

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
0. Anda dapat memilih beberapa file untuk diunggah sekaligus. Panel file repl Anda sekarang akan terlihat seperti ini

Cara membuat platformer dengan python

Dalam tutorial ini, kita akan membangun file

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
1 secara bertahap, menambahkan kode di berbagai bagian file seiring berjalannya waktu. Setiap cuplikan kode akan berisi beberapa kode yang ada untuk memberi Anda gambaran di mana penambahan baru harus ditempatkan di file. Baris
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
_2 akan digunakan untuk mewakili kode yang ada yang telah ditinggalkan untuk singkatnya

Menyiapkan perancah

Kami akan mulai dengan kode berikut di

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
1, yang menggambar layar hitam

import pygame

WIDTH = 400
HEIGHT = 300
BACKGROUND = (0, 0, 0)

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)

if __name__ == "__main__":
main()
_

Di bagian atas file, kami mengimpor

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
4. Setelah itu, kami mengatur lebar dan tinggi layar dalam piksel, dan warna latar belakang. Nilai terakhir ini adalah RGB tuple, dan akan membuat background kita menjadi hitam. Untuk menggunakan latar putih sebagai gantinya, kami akan menulis
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
5

Kemudian, dalam metode

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
_6, kami memulai PyGame, membuat layar dan jam, dan memulai putaran permainan, yaitu kode ini

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_

Putaran permainan adalah tempat segala sesuatu terjadi. Karena game kita berjalan dalam waktu nyata, kode kita harus terus-menerus mengumpulkan penekanan tombol dan gerakan mouse pengguna, dan terus-menerus menggambar ulang layar sebagai respons terhadap penekanan tombol dan gerakan mouse tersebut, dan peristiwa lain dalam game. Kami mencapai ini dengan while loop yang tak terbatas. PyGame menggunakan baris

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
7 terakhir dalam loop ini untuk menyesuaikan frekuensi gambar game sejalan dengan berapa lama waktu yang dibutuhkan setiap iterasi loop, agar game tetap berjalan lancar

Sekarang mari menggambar sesuatu di layar hitam ini. Game kita akan memiliki dua sprite. alien, yang akan menjadi pemain, dan sebuah kotak. Untuk menghindari duplikasi kode, mari buat kelas induk

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
8 sebelum kita membuat salah satunya. Kelas ini akan mewarisi dari kelas
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
_9, yang memberi kita metode berguna untuk deteksi tabrakan – ini akan menjadi penting nantinya

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():

Karena class ini akan menjadi induk untuk semua objek lain dalam game kita, kita membuatnya cukup sederhana. Ini memiliki tiga metode

  •     player = Player(100, 200)

    boxes = pygame.sprite.Group()
    0, yang akan membuat sprite dengan gambar tertentu dan persegi panjang PyGame berdasarkan gambar tersebut. Persegi panjang ini awalnya akan ditempatkan pada posisi yang ditentukan oleh
        player = Player(100, 200)

    boxes = pygame.sprite.Group()
    1 dan
        player = Player(100, 200)

    boxes = pygame.sprite.Group()
    2. Persegi panjang sprite adalah apa yang akan digunakan PyGame untuk gerakan sprite dan deteksi tabrakan
  •     player = Player(100, 200)

    boxes = pygame.sprite.Group()
    3, yang akan kita gunakan di kelas anak untuk menangani peristiwa, seperti penekanan tombol, gravitasi, dan tabrakan
  •     player = Player(100, 200)

    boxes = pygame.sprite.Group()
    4, yang kita gunakan untuk menggambar sprite. Kami melakukan ini dengan memasukkannya ke layar

Sekarang kita dapat membuat objek

    player = Player(100, 200)

boxes = pygame.sprite.Group()
_5 dan
    player = Player(100, 200)

boxes = pygame.sprite.Group()
6 sebagai kelas anak dari
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
8

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():

Kami akan menambahkan lebih banyak kode ke pemain nanti, tetapi pertama-tama mari menggambar sprite ini di layar

Menggambar sprite

Mari kembali ke fungsi

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
_6 kita dan buat sprite kita. Kami akan mulai dengan pemain

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)

Maka kita perlu meletakkan kotak di bawah kaki pemain. Karena kami akan menempatkan banyak sprite, kami akan membuat PyGame untuk memasukkannya

    player = Player(100, 200)

boxes = pygame.sprite.Group()

Sprite kotak kami memiliki lebar 70 piksel, dan kami perlu menjangkau lebar layar 400 piksel. Kita bisa melakukan ini dalam

    player = Player(100, 200)

boxes = pygame.sprite.Group()
_9 loop menggunakan Python

    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

Sekarang kita perlu kembali ke loop game dan menambahkan beberapa kode untuk mewujudkannya. Pertama, kita akan membuat PyGame menempatkan acara baru di antrean acara, lalu kita akan memanggil fungsi

    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 pemain. Fungsi ini akan menangani peristiwa yang dihasilkan oleh
    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

2

    while True:
pygame.event.pump()
player.update()
# ...

Untuk permainan yang lebih kompleks, kami ingin mengulang beberapa sprite dan memanggil metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 masing-masing, tetapi untuk saat ini hanya melakukan ini dengan pemain sudah cukup. Kotak kami tidak akan memiliki perilaku dinamis, jadi tidak perlu memanggil metode
    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 mereka

Berbeda dengan

    player = Player(100, 200)

boxes = pygame.sprite.Group()
_3, kita membutuhkan semua sprite kita untuk menggambar dirinya sendiri. Setelah menggambar latar belakang, kami akan menambahkan panggilan ke metode menggambar pemain. Untuk menggambar kotak, kita dapat menghubungi PyGame di grup
    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

7 kita

    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)

Putaran permainan kami sekarang disiapkan untuk memperbarui dan menggambar setiap sprite dalam permainan di setiap siklus putaran permainan. Jika Anda menjalankan permainan sekarang, Anda akan melihat pemain dan garis kotak di layar

Cara membuat platformer dengan python

Selanjutnya, kita akan menambahkan beberapa interaksi pengguna

Membuat Pemain Berjalan

Mari kembali ke objek

    player = Player(100, 200)

boxes = pygame.sprite.Group()
_5 dan membuatnya mobile. Kami akan memindahkan pemain menggunakan
    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

_9, yang memindahkan persegi panjang tertentu dengan vektor tertentu. Ini akan dibungkus dengan metode
    while True:
pygame.event.pump()
player.update()
# ...
_0, untuk menyederhanakan kode kita. Buat metode ini sekarang

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])

Sekarang kita memiliki cara untuk memindahkan pemain, saatnya menambahkan metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 sehingga gerakan ini dapat dipicu oleh penekanan tombol. Tambahkan metode
    player = Player(100, 200)

boxes = pygame.sprite.Group()
_3 kosong sekarang

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_0

PyGame menyediakan beberapa cara berbeda untuk memeriksa status keyboard. Secara default, antrian kejadiannya mengumpulkan

    while True:
pygame.event.pump()
player.update()
# ...
3 dan
    while True:
pygame.event.pump()
player.update()
# ...
4 kejadian saat tombol tertentu ditekan dan dilepaskan. Menggunakan peristiwa
    while True:
pygame.event.pump()
player.update()
# ...
_3 untuk menggerakkan pemain tampaknya merupakan hal yang logis untuk dilakukan, tetapi karena peristiwa tersebut hanya dipicu dalam loop pembaruan yang sama saat tombol ditekan pertama kali, ini akan memaksa kita untuk mengetuk tombol panah dengan cepat untuk terus bergerak dalam

Kami membutuhkan cara untuk memindahkan pemain setiap kali tombol panah ditekan, tidak hanya setelah ditekan. Jadi alih-alih mengandalkan acara, kami akan menanyakan status saat ini dari semua tombol keyboard dengan

    while True:
pygame.event.pump()
player.update()
# ...
6

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_1

Metode ini mengembalikan tupel 0 dan 1 yang menunjukkan status penekanan setiap tombol pada keyboard. Dengan demikian, kami dapat mendeteksi apakah tombol panah kiri atau kanan saat ini ditekan dengan mengindeks tuple dengan konstanta keyboard PyGame, seperti itu

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_2

Jalankan permainan. Anda sekarang dapat menggerakkan pemain ke kiri dan ke kanan, meskipun sangat lambat. Mari kita percepat dan kurangi ketergantungan kode kita pada angka ajaib pada saat yang sama dengan memberi pemain variabel

    while True:
pygame.event.pump()
player.update()
# ...
7

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_3

Saat ini pemain meluncur dari satu sisi ke sisi lain, tetapi kami telah mengupload gambar untuk animasi siklus berjalan, jadi mari terapkan itu sekarang. Pertama, kami akan menambahkan beberapa kode pemuatan gambar ke metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
0 pemain kami

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_4

Dalam kode ini, pertama-tama kita menetapkan gambar alien awal kita sebagai

    while True:
pygame.event.pump()
player.update()
# ...
9. Ini akan memungkinkan kita menggunakannya untuk pemain saat dia berdiri diam. Kami kemudian memuat gambar berjalan kami ke dalam daftar yang disebut
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
0, menggunakan Python untuk mendapatkan format nama file yang benar (
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
1 ->
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
2). Kami kemudian membuat
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
3, yang akan merekam bingkai mana dari siklus berjalan yang dimainkan pemain, dan
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
4 yang akan membantu kami membalikkan gambar berjalan yang menghadap ke kanan saat pemain berjalan ke kiri

Sekarang mari kita terapkan animasi yang sebenarnya. Buat metode baru bernama

    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
5

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_5

Di sini kami menyetel gambar pemain saat ini ke bingkai siklus berjalan yang sedang kami jalani. Jika pemain menghadap ke kiri, kita gunakan

    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
6 untuk membalik sprite secara horizontal (dua argumen terakhir masing-masing untuk flip horizontal dan vertikal). Kemudian kami menganimasikan pemain dengan menambah
    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
7, kecuali animasi berada dalam bingkai kedua dari belakang, dalam hal ini kami kembali ke awal animasi

Mari tambahkan ini ke metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
_3 kita sekarang

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_6

Jika kita bergerak ke kiri atau kanan, kita mengatur

    while True:
pygame.event.pump()
player.update()

# Draw loop
screen.fill(BACKGROUND)
player.draw(screen)
boxes.draw(screen)
pygame.display.flip()

clock.tick(60)
4 dengan tepat dan memanggil
class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
0. Jika tidak, kami menyetel gambar pemain ke
class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
1

Jalankan game sekarang untuk melihat gerakan siklus berjalan pemain. Setelah itu, saatnya membuatnya melompat

Membuat Pemain Melompat

Agar pemain kita bisa melompat, kita perlu menerapkan empat hal

  1. Gerakan ke atas dipicu oleh tombol panah atas
  2. Gravitasi, untuk membawa pemain kembali turun setelah mencapai puncak lompatannya
  3. Deteksi tabrakan, sehingga pemain tidak jatuh ke tanah
  4. Sebuah animasi melompat

Memicu lompatan

Untuk sekadar membuat pemain naik, kita bisa menambahkan

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
2 lagi, seperti itu

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_7

Jika Anda mencoba permainan sekarang, Anda akan melihat beberapa masalah dengan pendekatan ini. Selain kekurangan gravitasi, kita hanya bisa melompat lurus ke atas, dan harus melepaskan tombol panah kiri dan kanan sebelum melakukannya. Sebagian besar gameplay di platformer bergantung pada kemampuan pemain untuk melompat ke kiri atau kanan, jadi ini tidak akan berhasil. Untuk memperbaikinya, kami akan mengubah

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
2 terakhir kami menjadi pernyataan
class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
4 yang terpisah

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_8

Kita juga mungkin ingin bisa melompat dengan kecepatan yang berbeda dengan kecepatan berjalan kita, jadi mari kita definisikan variabel lain dan gunakan itu

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_9

Itu lebih baik, tapi sekarang kita benar-benar membutuhkan gravitasi

Menambahkan gravitasi

Hingga saat ini, kami hanya memiliki satu operasi yang memanipulasi kecepatan horizontal atau vertikal kami per putaran pembaruan. Dengan penambahan gravitasi, ini akan berubah, jadi kita perlu merestrukturisasi kode kita untuk menghitung pergerakan horizontal dan vertikal bersih kita sebelum memanggil

    while True:
pygame.event.pump()
player.update()
# ...
0. Mari ubah fungsi
    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 seperti itu

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
0

Kami telah menambahkan dua variabel,

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
_7 dan
class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
8, untuk mewakili kecepatan horizontal dan kecepatan vertikal kami. Alih-alih memanggil
    while True:
pygame.event.pump()
player.update()
# ...
_0 ketika setiap tombol ditekan, kami bekerja dengan variabel-variabel ini di seluruh metode
    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 dan kemudian meneruskan nilai akhirnya menjadi satu panggilan
    while True:
pygame.event.pump()
player.update()
# ...
0 di akhir

Tapi tunggu. Masuk akal jika kecepatan horizontal disetel ke 0 pada awal setiap loop pembaruan, karena langsung dikontrol oleh penekanan tombol pemain. Saat panah kiri ditahan, pemain bergerak ke kiri dengan kecepatan 4 piksel per putaran; . Kecepatan vertikal akan kurang dapat dikendalikan – sambil menekan panah atas akan memulai lompatan, melepaskannya tidak akan menghentikan pemain di udara. Oleh karena itu, kecepatan vertikal harus bertahan di antara loop

Kita dapat melakukannya dengan memindahkan definisi

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
8 ke dalam
    player = Player(100, 200)

boxes = pygame.sprite.Group()
0 dan menjadikannya sebagai variabel instan

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
1

Sekarang kita bisa menerapkan gravitasi. Kami akan melakukan ini dengan menambahkan konstanta kecil ke kecepatan vertikal pemain (

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
8) hingga mencapai kecepatan terminal

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
2

Mulai permainan sekarang, dan pemain akan jatuh lurus ke bawah, menembus tanah dan keluar dari layar. Gravitasi berfungsi, tapi kami butuh tempat untuk mendaratkan pemain

Menambahkan deteksi tabrakan

Deteksi tabrakan adalah elemen kunci dari sebagian besar game grafis. Di PyGame, sebagian besar pendeteksian tabrakan melibatkan pemeriksaan apakah persegi panjang berpotongan satu sama lain. Untungnya, PyGame menyediakan sejumlah built-in yang berguna untuk melakukan hal ini, jadi kita tidak perlu memikirkan terlalu banyak tentang cara kerja tabrakan internal.

Mari tambahkan beberapa deteksi tabrakan sekarang, di dekat bagian atas metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 kita. Kami akan membuat variabel yang disebut
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_06 dan mengaturnya ke hasil
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
07

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
3

Metode PyGame ini membutuhkan dua argumen. satu sprite dan sekelompok sprite. Ini mengembalikan apakah sprite diberikan sebagai argumen pertama, i. e. pemain, bertabrakan dengan salah satu sprite dalam grup yang diberikan sebagai argumen kedua, i. e. kotak-kotak. Jadi kita akan tahu bahwa pemain berada di kotak saat kembali

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
08

Kita dapat meneruskan grup

    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

_7 ke dalam metode
    player = Player(100, 200)

boxes = pygame.sprite.Group()
3 pemain dengan membuat beberapa perubahan kode

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
4

Sekarang kita dapat mengetahui apakah pemain berada di tanah, kita dapat mencegah melompat di udara dengan menambahkan kondisi pada kode lompat kita

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
5

Untuk menghentikan pemain agar tidak jatuh ke tanah, kami akan menambahkan kode berikut ke implementasi gravitasi kami

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
6

Menambahkan animasi melompat

Terakhir, kami akan menggunakan gambar alien terakhir kami (

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
11) untuk memberi pemain kami animasi melompat. Pertama buat
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_12 di
    player = Player(100, 200)

boxes = pygame.sprite.Group()
0

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
7

Kemudian buat metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
5 berikut

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
8

Animasi lompat kami hanya memiliki satu bingkai, jadi kodenya jauh lebih sederhana daripada yang kami gunakan untuk animasi berjalan kami. Untuk memicu metode ini saat pemain berada di udara, ubah implementasi gravitasi seperti itu

class Sprite(pygame.sprite.Sprite):
def __init__(self, image, startx, starty):
super().__init__()

self.image = pygame.image.load(image)
self.rect = self.image.get_rect()

self.rect.center = [startx, starty]

def update(self):
pass

def draw(self, screen):
screen.blit(self.image, self.rect)

def main():
_9

Jalankan game, dan Anda harus bisa berlari dan melompat. Berhati-hatilah agar tidak jatuh dari tepi

Menyempurnakan Game

Pada titik ini, kami memiliki permainan kami bekerja pada tingkat dasar, tetapi itu bisa menggunakan beberapa perbaikan. Pertama, lompatannya cukup tidak responsif terhadap masukan pengguna. menekan panah atas untuk waktu yang lama menghasilkan lompatan ukuran yang sama. Kedua, deteksi tabrakan kami hanya akan mencegah pemain jatuh dari lantai, tidak berjalan menembus dinding atau melompati langit-langit

Kami akan mengulangi kode kami untuk memperbaiki kedua kekurangan ini

Membuat variabel lompatan

Alangkah baiknya jika pemain dapat mengontrol ketinggian lompatan mereka dengan menahan tombol lompat untuk jangka waktu yang berbeda. Ini cukup sederhana untuk diterapkan – kita hanya perlu cara untuk mengurangi kecepatan lompatan jika pemain melepaskan tombol lompat saat pemain masih bergerak ke atas. Tambahkan kode berikut ke metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
0 pemain

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
0

Di sini kami telah menambahkan variabel instan

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_16 yang akan melacak status keyboard di loop pembaruan sebelumnya, dan variabel
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
17, yang akan menjadi lompatan terkecil yang akan kami izinkan untuk dilakukan pemain, hanya dengan mengetuk tombol lompat

Sekarang mari tambahkan variabel melompat ke metode

    player = Player(100, 200)

boxes = pygame.sprite.Group()
3, antara kode yang menangani tombol panah atas dan kode yang menangani gravitasi

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
1

Pernyataan

class Player(Sprite):
# ...
def move(self, x, y):
self.rect.move_ip([x,y])
_4 yang baru saja kita tambahkan akan dievaluasi menjadi
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
08 jika tombol panah atas ditekan pada loop sebelumnya tetapi tidak lagi ditekan, i. e. itu telah dirilis. Saat itu terjadi, kami menghentikan lompatan pemain dengan mengurangi kecepatannya menjadi
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
17. Kami kemudian mengatur
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_22 ke status keyboard saat ini sebagai persiapan untuk loop berikutnya

Coba permainan sekarang, dan Anda akan melihat ketinggian lompatan yang berbeda saat menekan tombol panah ke atas dengan ringan dibandingkan saat Anda menahannya. Bermain-main dengan nilai

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_17 dan lihat apa bedanya

Menyempurnakan deteksi tabrakan

Seperti disebutkan di atas, satu-satunya deteksi tabrakan yang kami terapkan berlaku untuk tanah di bawah kaki pemain, sehingga dia dapat berjalan menembus dinding dan melompat menembus langit-langit. Lihat ini sendiri dengan menambahkan beberapa kotak di atas dan di samping pemain dalam metode

def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

player = Player(100, 200)
6

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
2

Cara membuat platformer dengan python

Masalah lain yang mungkin telah Anda perhatikan adalah bahwa pemain tenggelam ke dalam tanah setelah beberapa lompatan – ini diakibatkan oleh ketidaktepatan pendeteksian tabrakan kami

Kami akan memperbaiki masalah ini dengan membuat perubahan halus pada cara kami menangani tabrakan dengan kotak. Daripada memutuskan bahwa kita berada di tanah saat sprite pemain bertabrakan dengan kotak, kita akan memeriksa apakah pemain berada 1 piksel di atas tabrakan dengan kotak. Kami kemudian akan menerapkan prinsip yang sama untuk kiri, kanan dan atas, menghentikan pemain tepat sebelum tabrakan

Pertama, mari beri pemain metode

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
25 untuk melakukan pemeriksaan ini

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
3

Di sini, kami memindahkan pemain dengan jumlah tertentu, memeriksa tabrakan, lalu memindahkan pemain kembali. Gerakan bolak-balik ini terjadi sebelum pemain ditarik ke layar, sehingga pengguna tidak akan melihat apapun

Mari ubah centang

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
06 kita untuk menggunakan metode ini

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
4

Jalankan game sekarang, dan Anda mungkin dapat melihat sedikit perbedaan dalam cara pemain berdiri di tanah dari sebelumnya

Ini belum menyelesaikan masalah tabrakan horizontal dan ke atas kita. Untuk itu, kita harus menerapkan metode

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
25 baru kita langsung ke metode
    while True:
pygame.event.pump()
player.update()
# ...
0 pemain. Hal pertama yang perlu kita lakukan adalah menyiapkan parameter
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
29 dan
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
30 untuk pemrosesan tambahan

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
5

Kemudian kita akan memeriksa tabrakan, jadi kita harus mulai meneruskan

    player = Player(100, 200)

boxes = pygame.sprite.Group()
for bx in range(0,400,70):
boxes.add(Box(bx,300))

7 ke
    while True:
pygame.event.pump()
player.update()
# ...
0. Kami akan melakukan ini untuk
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_29 dan
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
30 secara terpisah, dimulai dengan
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
30. Kami akan memeriksa tabrakan setelah memindahkan
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
36 piksel secara vertikal, mengurangi
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
36 hingga kami tidak lagi bertabrakan dengan kotak

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
6

Tapi tunggu. Kode ini hanya akan berfungsi sebagaimana mestinya jika kita bergerak ke bawah dan

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
36 positif. Jika
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_36 negatif, ini hanya akan membawa kita lebih jauh ke dalam tabrakan, bukan menjauhinya. Untuk memperbaikinya, kita harus mengimpor
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
40 di bagian atas file kita, sehingga kita dapat menggunakan
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
41

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
7

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_41 mengambil bilangan bulat dan mengembalikan 1 jika positif, -1 jika negatif, dan 0 jika 0. Inilah fungsi yang kami butuhkan

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
8

Sekarang lakukan hal yang sama untuk

    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
_43. Karena kita sudah mengetahui
    while True:
screen.fill(BACKGROUND)
pygame.display.flip()

clock.tick(60)
36 yang sesuai untuk pergerakan kita, kita akan memasukkannya ke dalam pemeriksaan tabrakan

class Sprite(pygame.sprite.Sprite):
# ...
class Player(Sprite):
def __init__(self, startx, starty):
super().__init__("p1_front.png", startx, starty)

class Box(Sprite):
def __init__(self, startx, starty):
super().__init__("boxAlt.png", startx, starty)

def main():
_9

Jalankan permainan. Pemain sekarang harus berhenti ketika dia menabrak dinding atau melompat ke langit-langit

Cara membuat platformer dengan python

Kemana Selanjutnya?

Jika Anda ingin terus mengerjakan game ini, Anda dapat menemukan sejumlah besar aset seni yang cocok di sini. Coba terapkan beberapa fitur ini

Bisakah Anda membuat platformer dengan Python?

Tutorial ini menunjukkan cara menggunakan Python dan pustaka Arcade untuk membuat game platformer 2D . Anda akan belajar bekerja dengan Sprite dan Tiled Map Editor untuk membuat game Anda sendiri. Anda dapat menambahkan koin, landai, platform bergerak, musuh, dan lainnya.

Bagaimana cara membuat game 2D dengan Python?

Instal perpustakaan arcade Python. Buat struktur permainan 2D dasar. .
Mengunduh dan Memulai Ubin
Membuat Tileset
Mendefinisikan Tileset
Mendefinisikan Layer Peta
Merancang Tingkat
Membangun Tingkat
Mendefinisikan Properti Kustom
Membaca Level Game

Bagaimana cara membuat kode game platformer?

Tutorial Game Platformer .
Langkah 1. Buat Sprite Anda. Dalam platformer, sprite digunakan untuk membuat karakter, tanah, dan platform. .
Langkah 2. Buat Skrip Sprite Sederhana. Gravitasi adalah elemen penting untuk game platform apa pun. .
Langkah 3. Buat Karakter Anda Melompat. .
Langkah 4. Buat Latar Belakang. .
Langkah 5. Uji Permainan Anda

Apakah Python bagus untuk game 2D?

Python untuk pengembangan game menyediakan dukungan untuk grafik 2D bersama dengan grafik 3D , yang menjadikannya salah satu bahasa terpopuler dalam hal . Ini memiliki banyak perpustakaan dan kerangka kerja yang tersedia yang membuat pengembangan game menjadi mudah.